diff options
Diffstat (limited to 'libglusterfs/src')
71 files changed, 2580 insertions, 7539 deletions
diff --git a/libglusterfs/src/Makefile.am b/libglusterfs/src/Makefile.am index 79ab7ee93f2..385e8ef4600 100644 --- a/libglusterfs/src/Makefile.am +++ b/libglusterfs/src/Makefile.am @@ -7,13 +7,13 @@ libglusterfs_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$(top_srcdir)/rpc/xdr/src/ -I$(top_builddir)/rpc/xdr/src/ \ - -I$(top_srcdir)/rpc/rpc-lib/src/ -I$(CONTRIBDIR)/rbtree \ + -I$(CONTRIBDIR)/rbtree \ -I$(CONTRIBDIR)/libexecinfo ${ARGP_STANDALONE_CPPFLAGS} \ -DSBIN_DIR=\"$(sbindir)\" -I$(CONTRIBDIR)/timer-wheel \ -I$(CONTRIBDIR)/xxhash -libglusterfs_la_LIBADD = $(ZLIB_LIBS) $(MATH_LIB) $(UUID_LIBS) +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 @@ -40,12 +40,9 @@ libglusterfs_la_SOURCES = dict.c xlator.c logging.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 protocol-common.h +nodist_libglusterfs_la_HEADERS = y.tab.h -BUILT_SOURCES = graph.lex.c defaults.c eventtypes.h protocol-common.h - -protocol-common.h: $(top_srcdir)/rpc/rpc-lib/src/protocol-common.h - cp $(top_srcdir)/rpc/rpc-lib/src/protocol-common.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 \ @@ -69,7 +66,7 @@ libglusterfs_la_HEADERS = glusterfs/common-utils.h glusterfs/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/async.h glusterfs/glusterfs-fops.h libglusterfs_ladir = $(includedir)/glusterfs @@ -82,8 +79,7 @@ noinst_HEADERS = unittest/unittest.h \ $(CONTRIBDIR)/userspace-rcu/wfcqueue.h \ $(CONTRIBDIR)/userspace-rcu/wfstack.h \ $(CONTRIBDIR)/userspace-rcu/static-wfcqueue.h \ - $(CONTRIBDIR)/userspace-rcu/static-wfstack.h \ - tier-ctr-interface.h + $(CONTRIBDIR)/userspace-rcu/static-wfstack.h eventtypes.h: $(top_srcdir)/events/eventskeygen.py $(PYTHON) $(top_srcdir)/events/eventskeygen.py C_HEADER diff --git a/libglusterfs/src/call-stub.c b/libglusterfs/src/call-stub.c index 3c7c7748c99..ee84f08acd4 100644 --- a/libglusterfs/src/call-stub.c +++ b/libglusterfs/src/call-stub.c @@ -41,7 +41,6 @@ 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); stub = stub_new(frame, 1, GF_FOP_LOOKUP); @@ -60,8 +59,6 @@ fop_lookup_cbk_stub(call_frame_t *frame, fop_lookup_cbk_t fn, int32_t op_ret, { call_stub_t *stub = NULL; - GF_VALIDATE_OR_GOTO("call-stub", frame, out); - stub = stub_new(frame, 0, GF_FOP_LOOKUP); GF_VALIDATE_OR_GOTO("call-stub", stub, out); @@ -77,7 +74,6 @@ fop_stat_stub(call_frame_t *frame, fop_stat_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); stub = stub_new(frame, 1, GF_FOP_STAT); @@ -95,8 +91,6 @@ fop_stat_cbk_stub(call_frame_t *frame, fop_stat_cbk_t fn, int32_t op_ret, { call_stub_t *stub = NULL; - GF_VALIDATE_OR_GOTO("call-stub", frame, out); - stub = stub_new(frame, 0, GF_FOP_STAT); GF_VALIDATE_OR_GOTO("call-stub", stub, out); @@ -111,8 +105,6 @@ fop_fstat_stub(call_frame_t *frame, fop_fstat_t fn, fd_t *fd, dict_t *xdata) { 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); @@ -128,8 +120,6 @@ fop_fstat_cbk_stub(call_frame_t *frame, fop_fstat_cbk_t fn, int32_t op_ret, { call_stub_t *stub = NULL; - GF_VALIDATE_OR_GOTO("call-stub", frame, out); - stub = stub_new(frame, 0, GF_FOP_FSTAT); GF_VALIDATE_OR_GOTO("call-stub", stub, out); @@ -145,7 +135,6 @@ fop_truncate_stub(call_frame_t *frame, fop_truncate_t fn, loc_t *loc, off_t off, { 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_TRUNCATE); @@ -164,8 +153,6 @@ fop_truncate_cbk_stub(call_frame_t *frame, fop_truncate_cbk_t fn, { call_stub_t *stub = NULL; - GF_VALIDATE_OR_GOTO("call-stub", frame, out); - stub = stub_new(frame, 0, GF_FOP_TRUNCATE); GF_VALIDATE_OR_GOTO("call-stub", stub, out); @@ -182,8 +169,6 @@ fop_ftruncate_stub(call_frame_t *frame, fop_ftruncate_t fn, fd_t *fd, off_t off, { call_stub_t *stub = NULL; - GF_VALIDATE_OR_GOTO("call-stub", frame, out); - stub = stub_new(frame, 1, GF_FOP_FTRUNCATE); GF_VALIDATE_OR_GOTO("call-stub", stub, out); @@ -201,8 +186,6 @@ fop_ftruncate_cbk_stub(call_frame_t *frame, fop_ftruncate_cbk_t fn, { 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); @@ -220,7 +203,6 @@ fop_access_stub(call_frame_t *frame, fop_access_t fn, loc_t *loc, int32_t mask, { 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_ACCESS); @@ -238,8 +220,6 @@ fop_access_cbk_stub(call_frame_t *frame, fop_access_cbk_t fn, int32_t op_ret, { call_stub_t *stub = NULL; - GF_VALIDATE_OR_GOTO("call-stub", frame, out); - stub = stub_new(frame, 0, GF_FOP_ACCESS); GF_VALIDATE_OR_GOTO("call-stub", stub, out); @@ -255,7 +235,6 @@ fop_readlink_stub(call_frame_t *frame, fop_readlink_t fn, loc_t *loc, { 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_READLINK); @@ -274,8 +253,6 @@ fop_readlink_cbk_stub(call_frame_t *frame, fop_readlink_cbk_t fn, { 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); @@ -292,7 +269,6 @@ fop_mknod_stub(call_frame_t *frame, fop_mknod_t fn, loc_t *loc, mode_t mode, { 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_MKNOD); @@ -312,8 +288,6 @@ fop_mknod_cbk_stub(call_frame_t *frame, fop_mknod_cbk_t fn, int32_t op_ret, { 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); @@ -330,7 +304,6 @@ fop_mkdir_stub(call_frame_t *frame, fop_mkdir_t fn, loc_t *loc, mode_t mode, { 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_MKDIR); @@ -350,8 +323,6 @@ fop_mkdir_cbk_stub(call_frame_t *frame, fop_mkdir_cbk_t fn, int32_t op_ret, { 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); @@ -368,7 +339,6 @@ fop_unlink_stub(call_frame_t *frame, fop_unlink_t fn, loc_t *loc, int xflag, { 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_UNLINK); @@ -388,8 +358,6 @@ fop_unlink_cbk_stub(call_frame_t *frame, fop_unlink_cbk_t fn, int32_t op_ret, { call_stub_t *stub = NULL; - GF_VALIDATE_OR_GOTO("call-stub", frame, out); - stub = stub_new(frame, 0, GF_FOP_UNLINK); GF_VALIDATE_OR_GOTO("call-stub", stub, out); @@ -406,7 +374,6 @@ fop_rmdir_stub(call_frame_t *frame, fop_rmdir_t fn, loc_t *loc, int flags, { 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_RMDIR); @@ -426,8 +393,6 @@ fop_rmdir_cbk_stub(call_frame_t *frame, fop_rmdir_cbk_t fn, int32_t op_ret, { call_stub_t *stub = NULL; - GF_VALIDATE_OR_GOTO("call-stub", frame, out); - stub = stub_new(frame, 0, GF_FOP_RMDIR); GF_VALIDATE_OR_GOTO("call-stub", stub, out); @@ -444,7 +409,6 @@ fop_symlink_stub(call_frame_t *frame, fop_symlink_t fn, const char *linkname, { 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); @@ -465,8 +429,6 @@ fop_symlink_cbk_stub(call_frame_t *frame, fop_symlink_cbk_t fn, int32_t op_ret, { call_stub_t *stub = NULL; - GF_VALIDATE_OR_GOTO("call-stub", frame, out); - stub = stub_new(frame, 0, GF_FOP_SYMLINK); GF_VALIDATE_OR_GOTO("call-stub", stub, out); @@ -483,7 +445,6 @@ fop_rename_stub(call_frame_t *frame, fop_rename_t fn, loc_t *oldloc, { 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); @@ -505,8 +466,6 @@ fop_rename_cbk_stub(call_frame_t *frame, fop_rename_cbk_t fn, int32_t op_ret, { call_stub_t *stub = NULL; - GF_VALIDATE_OR_GOTO("call-stub", frame, out); - stub = stub_new(frame, 0, GF_FOP_RENAME); GF_VALIDATE_OR_GOTO("call-stub", stub, out); @@ -523,7 +482,6 @@ fop_link_stub(call_frame_t *frame, fop_link_t fn, loc_t *oldloc, loc_t *newloc, { 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); @@ -544,8 +502,6 @@ fop_link_cbk_stub(call_frame_t *frame, fop_link_cbk_t fn, int32_t op_ret, { call_stub_t *stub = NULL; - GF_VALIDATE_OR_GOTO("call-stub", frame, out); - stub = stub_new(frame, 0, GF_FOP_LINK); GF_VALIDATE_OR_GOTO("call-stub", stub, out); @@ -562,7 +518,6 @@ fop_create_stub(call_frame_t *frame, fop_create_t fn, loc_t *loc, int32_t flags, { 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_CREATE); @@ -582,8 +537,6 @@ fop_create_cbk_stub(call_frame_t *frame, fop_create_cbk_t fn, int32_t op_ret, { 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); @@ -600,7 +553,6 @@ fop_open_stub(call_frame_t *frame, fop_open_t fn, loc_t *loc, int32_t flags, { 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_OPEN); @@ -618,8 +570,6 @@ fop_open_cbk_stub(call_frame_t *frame, fop_open_cbk_t fn, int32_t op_ret, { 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); @@ -635,8 +585,6 @@ fop_readv_stub(call_frame_t *frame, fop_readv_t fn, fd_t *fd, size_t size, { call_stub_t *stub = NULL; - GF_VALIDATE_OR_GOTO("call-stub", frame, out); - stub = stub_new(frame, 1, GF_FOP_READ); GF_VALIDATE_OR_GOTO("call-stub", stub, out); @@ -653,8 +601,6 @@ fop_readv_cbk_stub(call_frame_t *frame, fop_readv_cbk_t fn, int32_t op_ret, { 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); @@ -672,7 +618,6 @@ fop_writev_stub(call_frame_t *frame, fop_writev_t fn, fd_t *fd, { 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, 1, GF_FOP_WRITE); @@ -692,8 +637,6 @@ fop_writev_cbk_stub(call_frame_t *frame, fop_writev_cbk_t fn, int32_t op_ret, { call_stub_t *stub = NULL; - GF_VALIDATE_OR_GOTO("call-stub", frame, out); - stub = stub_new(frame, 0, GF_FOP_WRITE); GF_VALIDATE_OR_GOTO("call-stub", stub, out); @@ -709,8 +652,6 @@ fop_flush_stub(call_frame_t *frame, fop_flush_t fn, fd_t *fd, dict_t *xdata) { 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); @@ -726,8 +667,6 @@ fop_flush_cbk_stub(call_frame_t *frame, fop_flush_cbk_t fn, int32_t op_ret, { call_stub_t *stub = NULL; - GF_VALIDATE_OR_GOTO("call-stub", frame, out); - stub = stub_new(frame, 0, GF_FOP_FLUSH); GF_VALIDATE_OR_GOTO("call-stub", stub, out); @@ -743,8 +682,6 @@ fop_fsync_stub(call_frame_t *frame, fop_fsync_t fn, fd_t *fd, int32_t datasync, { 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); @@ -761,8 +698,6 @@ fop_fsync_cbk_stub(call_frame_t *frame, fop_fsync_cbk_t fn, int32_t op_ret, { call_stub_t *stub = NULL; - GF_VALIDATE_OR_GOTO("call-stub", frame, out); - stub = stub_new(frame, 0, GF_FOP_FSYNC); GF_VALIDATE_OR_GOTO("call-stub", stub, out); @@ -779,7 +714,6 @@ fop_opendir_stub(call_frame_t *frame, fop_opendir_t fn, loc_t *loc, fd_t *fd, { 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_OPENDIR); @@ -797,8 +731,6 @@ fop_opendir_cbk_stub(call_frame_t *frame, fop_opendir_cbk_t fn, int32_t op_ret, { call_stub_t *stub = NULL; - GF_VALIDATE_OR_GOTO("call-stub", frame, out); - stub = stub_new(frame, 0, GF_FOP_OPENDIR); GF_VALIDATE_OR_GOTO("call-stub", stub, out); @@ -814,8 +746,6 @@ fop_fsyncdir_stub(call_frame_t *frame, fop_fsyncdir_t fn, fd_t *fd, { call_stub_t *stub = NULL; - GF_VALIDATE_OR_GOTO("call-stub", frame, out); - stub = stub_new(frame, 1, GF_FOP_FSYNCDIR); GF_VALIDATE_OR_GOTO("call-stub", stub, out); @@ -831,8 +761,6 @@ fop_fsyncdir_cbk_stub(call_frame_t *frame, fop_fsyncdir_cbk_t fn, { call_stub_t *stub = NULL; - GF_VALIDATE_OR_GOTO("call-stub", frame, out); - stub = stub_new(frame, 0, GF_FOP_FSYNCDIR); GF_VALIDATE_OR_GOTO("call-stub", stub, out); @@ -847,7 +775,6 @@ fop_statfs_stub(call_frame_t *frame, fop_statfs_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); stub = stub_new(frame, 1, GF_FOP_STATFS); @@ -865,8 +792,6 @@ fop_statfs_cbk_stub(call_frame_t *frame, fop_statfs_cbk_t fn, int32_t op_ret, { call_stub_t *stub = NULL; - GF_VALIDATE_OR_GOTO("call-stub", frame, out); - stub = stub_new(frame, 0, GF_FOP_STATFS); GF_VALIDATE_OR_GOTO("call-stub", stub, out); @@ -882,7 +807,6 @@ fop_setxattr_stub(call_frame_t *frame, fop_setxattr_t fn, loc_t *loc, { 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_SETXATTR); @@ -900,8 +824,6 @@ fop_setxattr_cbk_stub(call_frame_t *frame, fop_setxattr_cbk_t fn, { 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); @@ -917,7 +839,6 @@ fop_getxattr_stub(call_frame_t *frame, fop_getxattr_t fn, loc_t *loc, { 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_GETXATTR); @@ -936,8 +857,6 @@ fop_getxattr_cbk_stub(call_frame_t *frame, fop_getxattr_cbk_t fn, { call_stub_t *stub = NULL; - GF_VALIDATE_OR_GOTO("call-stub", frame, out); - stub = stub_new(frame, 0, GF_FOP_GETXATTR); GF_VALIDATE_OR_GOTO("call-stub", stub, out); @@ -953,7 +872,6 @@ fop_fsetxattr_stub(call_frame_t *frame, fop_fsetxattr_t fn, fd_t *fd, { 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, 1, GF_FOP_FSETXATTR); @@ -971,8 +889,6 @@ fop_fsetxattr_cbk_stub(call_frame_t *frame, fop_fsetxattr_cbk_t fn, { call_stub_t *stub = NULL; - GF_VALIDATE_OR_GOTO("call-stub", frame, out); - stub = stub_new(frame, 0, GF_FOP_FSETXATTR); GF_VALIDATE_OR_GOTO("call-stub", stub, out); @@ -988,7 +904,6 @@ fop_fgetxattr_stub(call_frame_t *frame, fop_fgetxattr_t fn, fd_t *fd, { 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, 1, GF_FOP_FGETXATTR); @@ -1007,8 +922,6 @@ fop_fgetxattr_cbk_stub(call_frame_t *frame, fop_fgetxattr_cbk_t fn, { call_stub_t *stub = NULL; - GF_VALIDATE_OR_GOTO("call-stub", frame, out); - stub = stub_new(frame, 0, GF_FOP_GETXATTR); GF_VALIDATE_OR_GOTO("call-stub", stub, out); @@ -1024,7 +937,6 @@ fop_removexattr_stub(call_frame_t *frame, fop_removexattr_t fn, loc_t *loc, { 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); @@ -1043,8 +955,6 @@ fop_removexattr_cbk_stub(call_frame_t *frame, fop_removexattr_cbk_t fn, { call_stub_t *stub = NULL; - GF_VALIDATE_OR_GOTO("call-stub", frame, out); - stub = stub_new(frame, 0, GF_FOP_REMOVEXATTR); GF_VALIDATE_OR_GOTO("call-stub", stub, out); @@ -1060,7 +970,6 @@ fop_fremovexattr_stub(call_frame_t *frame, fop_fremovexattr_t fn, fd_t *fd, { 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); @@ -1079,8 +988,6 @@ fop_fremovexattr_cbk_stub(call_frame_t *frame, fop_fremovexattr_cbk_t fn, { call_stub_t *stub = NULL; - GF_VALIDATE_OR_GOTO("call-stub", frame, out); - stub = stub_new(frame, 0, GF_FOP_FREMOVEXATTR); GF_VALIDATE_OR_GOTO("call-stub", stub, out); @@ -1096,7 +1003,6 @@ fop_lk_stub(call_frame_t *frame, fop_lk_t fn, fd_t *fd, int32_t cmd, { 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, 1, GF_FOP_LK); @@ -1114,8 +1020,6 @@ fop_lk_cbk_stub(call_frame_t *frame, fop_lk_cbk_t fn, int32_t op_ret, { call_stub_t *stub = NULL; - GF_VALIDATE_OR_GOTO("call-stub", frame, out); - stub = stub_new(frame, 0, GF_FOP_LK); GF_VALIDATE_OR_GOTO("call-stub", stub, out); @@ -1131,7 +1035,6 @@ fop_inodelk_stub(call_frame_t *frame, fop_inodelk_t fn, const char *volume, { 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, 1, GF_FOP_INODELK); @@ -1149,8 +1052,6 @@ fop_inodelk_cbk_stub(call_frame_t *frame, fop_inodelk_cbk_t fn, int32_t op_ret, { call_stub_t *stub = NULL; - GF_VALIDATE_OR_GOTO("call-stub", frame, out); - stub = stub_new(frame, 0, GF_FOP_INODELK); GF_VALIDATE_OR_GOTO("call-stub", stub, out); @@ -1166,7 +1067,6 @@ fop_finodelk_stub(call_frame_t *frame, fop_finodelk_t fn, const char *volume, { 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, 1, GF_FOP_FINODELK); @@ -1185,8 +1085,6 @@ fop_finodelk_cbk_stub(call_frame_t *frame, fop_inodelk_cbk_t fn, int32_t op_ret, { call_stub_t *stub = NULL; - GF_VALIDATE_OR_GOTO("call-stub", frame, out); - stub = stub_new(frame, 0, GF_FOP_FINODELK); GF_VALIDATE_OR_GOTO("call-stub", stub, out); @@ -1203,8 +1101,6 @@ fop_entrylk_stub(call_frame_t *frame, fop_entrylk_t fn, const char *volume, { 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); @@ -1221,8 +1117,6 @@ fop_entrylk_cbk_stub(call_frame_t *frame, fop_entrylk_cbk_t fn, int32_t op_ret, { call_stub_t *stub = NULL; - GF_VALIDATE_OR_GOTO("call-stub", frame, out); - stub = stub_new(frame, 0, GF_FOP_ENTRYLK); GF_VALIDATE_OR_GOTO("call-stub", stub, out); @@ -1239,8 +1133,6 @@ fop_fentrylk_stub(call_frame_t *frame, fop_fentrylk_t fn, const char *volume, { call_stub_t *stub = NULL; - GF_VALIDATE_OR_GOTO("call-stub", frame, out); - stub = stub_new(frame, 1, GF_FOP_FENTRYLK); GF_VALIDATE_OR_GOTO("call-stub", stub, out); @@ -1256,8 +1148,6 @@ fop_fentrylk_cbk_stub(call_frame_t *frame, fop_fentrylk_cbk_t fn, { call_stub_t *stub = NULL; - GF_VALIDATE_OR_GOTO("call-stub", frame, out); - stub = stub_new(frame, 0, GF_FOP_FENTRYLK); GF_VALIDATE_OR_GOTO("call-stub", stub, out); @@ -1274,8 +1164,6 @@ fop_readdirp_cbk_stub(call_frame_t *frame, fop_readdirp_cbk_t fn, { call_stub_t *stub = NULL; - GF_VALIDATE_OR_GOTO("call-stub", frame, out); - stub = stub_new(frame, 0, GF_FOP_READDIRP); GF_VALIDATE_OR_GOTO("call-stub", stub, out); @@ -1291,8 +1179,6 @@ fop_readdir_cbk_stub(call_frame_t *frame, fop_readdir_cbk_t fn, int32_t op_ret, { call_stub_t *stub = NULL; - GF_VALIDATE_OR_GOTO("call-stub", frame, out); - stub = stub_new(frame, 0, GF_FOP_READDIR); GF_VALIDATE_OR_GOTO("call-stub", stub, out); @@ -1338,7 +1224,6 @@ fop_rchecksum_stub(call_frame_t *frame, fop_rchecksum_t fn, fd_t *fd, { 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, 1, GF_FOP_RCHECKSUM); @@ -1357,8 +1242,6 @@ fop_rchecksum_cbk_stub(call_frame_t *frame, fop_rchecksum_cbk_t fn, { 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); @@ -1375,8 +1258,6 @@ fop_xattrop_cbk_stub(call_frame_t *frame, fop_xattrop_cbk_t fn, int32_t op_ret, { call_stub_t *stub = NULL; - GF_VALIDATE_OR_GOTO("call-stub", frame, out); - stub = stub_new(frame, 0, GF_FOP_XATTROP); GF_VALIDATE_OR_GOTO("call-stub", stub, out); @@ -1392,7 +1273,6 @@ fop_fxattrop_cbk_stub(call_frame_t *frame, fop_fxattrop_cbk_t fn, dict_t *xdata) { call_stub_t *stub = NULL; - GF_VALIDATE_OR_GOTO("call-stub", frame, out); stub = stub_new(frame, 0, GF_FOP_FXATTROP); GF_VALIDATE_OR_GOTO("call-stub", stub, out); @@ -1409,7 +1289,6 @@ fop_xattrop_stub(call_frame_t *frame, fop_xattrop_t fn, loc_t *loc, { 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); @@ -1427,7 +1306,6 @@ fop_fxattrop_stub(call_frame_t *frame, fop_fxattrop_t fn, fd_t *fd, { 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_FXATTROP); @@ -1446,8 +1324,6 @@ fop_setattr_cbk_stub(call_frame_t *frame, fop_setattr_cbk_t fn, int32_t op_ret, { call_stub_t *stub = NULL; - GF_VALIDATE_OR_GOTO("call-stub", frame, out); - stub = stub_new(frame, 0, GF_FOP_SETATTR); GF_VALIDATE_OR_GOTO("call-stub", stub, out); @@ -1465,8 +1341,6 @@ fop_fsetattr_cbk_stub(call_frame_t *frame, fop_setattr_cbk_t fn, int32_t op_ret, { call_stub_t *stub = NULL; - GF_VALIDATE_OR_GOTO("call-stub", frame, out); - stub = stub_new(frame, 0, GF_FOP_FSETATTR); GF_VALIDATE_OR_GOTO("call-stub", stub, out); @@ -1483,7 +1357,6 @@ fop_setattr_stub(call_frame_t *frame, fop_setattr_t fn, loc_t *loc, { 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_SETATTR); @@ -1501,7 +1374,6 @@ fop_fsetattr_stub(call_frame_t *frame, fop_fsetattr_t fn, fd_t *fd, { 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); @@ -1520,8 +1392,6 @@ fop_fallocate_cbk_stub(call_frame_t *frame, fop_fallocate_cbk_t fn, { call_stub_t *stub = NULL; - GF_VALIDATE_OR_GOTO("call-stub", frame, out); - stub = stub_new(frame, 0, GF_FOP_FALLOCATE); GF_VALIDATE_OR_GOTO("call-stub", stub, out); @@ -1539,7 +1409,6 @@ fop_fallocate_stub(call_frame_t *frame, fop_fallocate_t fn, fd_t *fd, { 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_FALLOCATE); @@ -1558,8 +1427,6 @@ fop_discard_cbk_stub(call_frame_t *frame, fop_discard_cbk_t fn, int32_t op_ret, { call_stub_t *stub = NULL; - GF_VALIDATE_OR_GOTO("call-stub", frame, out); - stub = stub_new(frame, 0, GF_FOP_DISCARD); GF_VALIDATE_OR_GOTO("call-stub", stub, out); @@ -1577,7 +1444,6 @@ fop_discard_stub(call_frame_t *frame, fop_discard_t fn, fd_t *fd, off_t offset, { 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); @@ -1596,8 +1462,6 @@ fop_zerofill_cbk_stub(call_frame_t *frame, fop_zerofill_cbk_t fn, { 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); @@ -1615,7 +1479,6 @@ fop_zerofill_stub(call_frame_t *frame, fop_zerofill_t fn, fd_t *fd, { 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_ZEROFILL); @@ -1633,8 +1496,6 @@ fop_ipc_cbk_stub(call_frame_t *frame, fop_ipc_cbk_t fn, int32_t op_ret, { call_stub_t *stub = NULL; - GF_VALIDATE_OR_GOTO("call-stub", frame, out); - stub = stub_new(frame, 0, GF_FOP_IPC); GF_VALIDATE_OR_GOTO("call-stub", stub, out); @@ -1650,7 +1511,6 @@ fop_ipc_stub(call_frame_t *frame, fop_ipc_t fn, int32_t op, 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_IPC); @@ -1668,8 +1528,6 @@ fop_lease_cbk_stub(call_frame_t *frame, fop_lease_cbk_t fn, int32_t op_ret, { call_stub_t *stub = NULL; - GF_VALIDATE_OR_GOTO("call-stub", frame, out); - stub = stub_new(frame, 0, GF_FOP_LEASE); GF_VALIDATE_OR_GOTO("call-stub", stub, out); @@ -1685,7 +1543,6 @@ fop_lease_stub(call_frame_t *frame, fop_lease_t fn, loc_t *loc, { 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); @@ -1704,8 +1561,6 @@ fop_seek_cbk_stub(call_frame_t *frame, fop_seek_cbk_t fn, int32_t op_ret, { 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); @@ -1722,7 +1577,6 @@ fop_seek_stub(call_frame_t *frame, fop_seek_t fn, fd_t *fd, off_t offset, { 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_SEEK); @@ -1741,8 +1595,6 @@ fop_getactivelk_cbk_stub(call_frame_t *frame, fop_getactivelk_cbk_t fn, { call_stub_t *stub = NULL; - GF_VALIDATE_OR_GOTO("call-stub", frame, out); - stub = stub_new(frame, 0, GF_FOP_GETACTIVELK); GF_VALIDATE_OR_GOTO("call-stub", stub, out); @@ -1759,7 +1611,6 @@ fop_getactivelk_stub(call_frame_t *frame, fop_getactivelk_t fn, loc_t *loc, { 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_GETACTIVELK); @@ -1781,8 +1632,6 @@ fop_setactivelk_cbk_stub(call_frame_t *frame, fop_setactivelk_cbk_t fn, { 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); @@ -1803,7 +1652,6 @@ fop_setactivelk_stub(call_frame_t *frame, fop_setactivelk_t fn, loc_t *loc, { 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_SETACTIVELK); @@ -1825,7 +1673,6 @@ fop_copy_file_range_stub(call_frame_t *frame, fop_copy_file_range_t fn, { 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_COPY_FILE_RANGE); @@ -1848,7 +1695,6 @@ fop_copy_file_range_cbk_stub(call_frame_t *frame, fop_copy_file_range_cbk_t fn, { 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_COPY_FILE_RANGE); @@ -1869,7 +1715,6 @@ fop_put_stub(call_frame_t *frame, fop_put_t fn, loc_t *loc, mode_t mode, { 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, 1, GF_FOP_PUT); @@ -1889,8 +1734,6 @@ fop_put_cbk_stub(call_frame_t *frame, fop_put_cbk_t fn, int32_t op_ret, { call_stub_t *stub = NULL; - GF_VALIDATE_OR_GOTO("call-stub", frame, out); - stub = stub_new(frame, 0, GF_FOP_PUT); GF_VALIDATE_OR_GOTO("call-stub", stub, out); @@ -1907,7 +1750,6 @@ fop_icreate_stub(call_frame_t *frame, fop_icreate_t fn, loc_t *loc, mode_t mode, { 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_ICREATE); @@ -1947,8 +1789,6 @@ fop_icreate_cbk_stub(call_frame_t *frame, fop_icreate_cbk_t fn, int32_t op_ret, { call_stub_t *stub = NULL; - GF_VALIDATE_OR_GOTO("call-stub", frame, out); - stub = stub_new(frame, 0, GF_FOP_ICREATE); GF_VALIDATE_OR_GOTO("call-stub", stub, out); @@ -1966,7 +1806,6 @@ fop_namelink_stub(call_frame_t *frame, fop_namelink_t fn, loc_t *loc, { 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_NAMELINK); @@ -2006,8 +1845,6 @@ fop_namelink_cbk_stub(call_frame_t *frame, fop_namelink_cbk_t fn, { call_stub_t *stub = NULL; - GF_VALIDATE_OR_GOTO("call-stub", frame, out); - stub = stub_new(frame, 0, GF_FOP_NAMELINK); GF_VALIDATE_OR_GOTO("call-stub", stub, out); diff --git a/libglusterfs/src/client_t.c b/libglusterfs/src/client_t.c index e875c8b6b69..9d377c3c2e1 100644 --- a/libglusterfs/src/client_t.c +++ b/libglusterfs/src/client_t.c @@ -13,7 +13,6 @@ #include "glusterfs/statedump.h" #include "glusterfs/client_t.h" #include "glusterfs/list.h" -#include "rpcsvc.h" #include "glusterfs/libglusterfs-messages.h" static int @@ -110,50 +109,13 @@ gf_clienttable_alloc(void) return clienttable; } -void -gf_client_clienttable_destroy(clienttable_t *clienttable) -{ - 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); - } -} - /* * 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; @@ -181,11 +143,10 @@ gf_client_get(xlator_t *this, struct rpcsvc_auth_data *cred, char *client_uid, * 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))) { + (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; } @@ -227,7 +188,7 @@ gf_client_get(xlator_t *this, struct rpcsvc_auth_data *cred, char *client_uid, GF_ATOMIC_INIT(client->fd_cnt, 0); client->auth.flavour = cred->flavour; - if (cred->flavour != AUTH_NONE) { + 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); @@ -353,8 +314,6 @@ client_destroy(client_t *client) clienttable = client->this->ctx->clienttable; - LOCK_DESTROY(&client->scratch_ctx.lock); - LOCK(&clienttable->lock); { clienttable->cliententries[client->tbl_index].client = NULL; @@ -372,6 +331,8 @@ client_destroy(client_t *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); @@ -581,62 +542,6 @@ client_ctx_del(client_t *client, void *key, void **value) } void -client_dump(client_t *client, char *prefix) -{ - if (!client) - return; - - gf_proc_dump_write("refcount", "%" GF_PRI_ATOMIC, - GF_ATOMIC_GET(client->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; - } - 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("%s", key); - cliententry_dump(&clienttable->cliententries[i], key); - } - } - } - UNLOCK(&clienttable->lock); -} - -void client_ctx_dump(client_t *client, char *prefix) { #if 0 /* TBD, FIXME */ diff --git a/libglusterfs/src/common-utils.c b/libglusterfs/src/common-utils.c index 8e2ffa3accd..682cbf28055 100644 --- a/libglusterfs/src/common-utils.c +++ b/libglusterfs/src/common-utils.c @@ -37,6 +37,9 @@ #ifndef GF_LINUX_HOST_OS #include <sys/resource.h> #endif +#ifdef HAVE_SYNCFS_SYS +#include <sys/syscall.h> +#endif #include "glusterfs/compat-errno.h" #include "glusterfs/common-utils.h" @@ -45,13 +48,12 @@ #include "glusterfs/stack.h" #include "glusterfs/lkowner.h" #include "glusterfs/syscall.h" -#include "cli1-xdr.h" #include "glusterfs/globals.h" #define XXH_INLINE_ALL #include "xxhash.h" #include <ifaddrs.h> #include "glusterfs/libglusterfs-messages.h" -#include "protocol-common.h" +#include "glusterfs/glusterfs-acl.h" #ifdef __FreeBSD__ #include <pthread_np.h> #undef BIT_SET @@ -77,6 +79,15 @@ char *vol_type_str[] = { 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); +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 gf_xxh64_wrapper(const unsigned char *data, size_t const len, unsigned long long const seed, char *xxh64) @@ -304,8 +315,7 @@ mkdir_p(char *path, mode_t mode, gf_boolean_t allow_symlinks) dir[i] = '\0'; ret = sys_mkdir(dir, mode); if (ret && errno != EEXIST) { - gf_msg("", GF_LOG_ERROR, errno, LG_MSG_DIR_OP_FAILED, - "Failed due to reason"); + gf_smsg("", GF_LOG_ERROR, errno, LG_MSG_DIR_OP_FAILED, NULL); goto out; } @@ -316,10 +326,8 @@ mkdir_p(char *path, mode_t mode, gf_boolean_t allow_symlinks) if (S_ISLNK(stbuf.st_mode)) { ret = -1; - gf_msg("", GF_LOG_ERROR, 0, LG_MSG_DIR_IS_SYMLINK, - "%s is a " - "symlink", - dir); + gf_smsg("", GF_LOG_ERROR, 0, LG_MSG_DIR_IS_SYMLINK, "dir=%s", + dir, NULL); goto out; } } @@ -332,10 +340,10 @@ mkdir_p(char *path, mode_t mode, gf_boolean_t allow_symlinks) if (ret == 0) errno = 0; 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, errno, LG_MSG_DIR_OP_FAILED, + "possibly some of the components" + " were not directories", + NULL); goto out; } @@ -408,10 +416,8 @@ gf_rev_dns_lookup(const char *ip) /* Get the FQDN */ ret = gf_get_hostname_from_ip((char *)ip, &fqdn); if (ret != 0) { - gf_msg("resolver", GF_LOG_INFO, errno, LG_MSG_RESOLVE_HOSTNAME_FAILED, - "could not resolve " - "hostname for %s", - ip); + gf_smsg("resolver", GF_LOG_INFO, errno, LG_MSG_RESOLVE_HOSTNAME_FAILED, + "hostname=%s", ip, NULL); } out: return fqdn; @@ -432,7 +438,7 @@ gf_resolve_path_parent(const char *path) GF_VALIDATE_OR_GOTO(THIS->name, path, out); - if (strlen(path) <= 0) { + if (0 == strlen(path)) { gf_msg_callingfn(THIS->name, GF_LOG_DEBUG, 0, LG_MSG_INVALID_STRING, "invalid string for 'path'"); goto out; @@ -500,9 +506,8 @@ gf_resolve_ip6(const char *hostname, uint16_t port, int family, void **dnscache, } if ((ret = getaddrinfo(hostname, port_str, &hints, &cache->first)) != 0) { - gf_msg("resolver", GF_LOG_ERROR, 0, LG_MSG_GETADDRINFO_FAILED, - "getaddrinfo failed (family:%d) (%s)", family, - gai_strerror(ret)); + 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; @@ -519,10 +524,8 @@ gf_resolve_ip6(const char *hostname, uint16_t port, int family, void **dnscache, 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)); + gf_smsg("resolver", GF_LOG_ERROR, 0, LG_MSG_GETNAMEINFO_FAILED, + "ret=%s", gai_strerror(ret), NULL); goto err; } @@ -541,10 +544,8 @@ gf_resolve_ip6(const char *hostname, uint16_t port, int family, void **dnscache, 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)); + gf_smsg("resolver", GF_LOG_ERROR, 0, LG_MSG_GETNAMEINFO_FAILED, + "ret=%s", gai_strerror(ret), NULL); goto err; } @@ -576,8 +577,14 @@ struct dnscache * gf_dnscache_init(time_t ttl) { struct dnscache *cache = GF_MALLOC(sizeof(*cache), gf_common_mt_dnscache); - if (cache) { - cache->cache_dict = NULL; + if (!cache) + return NULL; + + cache->cache_dict = dict_new(); + if (!cache->cache_dict) { + GF_FREE(cache); + cache = NULL; + } else { cache->ttl = ttl; } @@ -585,6 +592,20 @@ gf_dnscache_init(time_t ttl) } /** + * 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 @@ -632,12 +653,6 @@ gf_rev_dns_lookup_cached(const char *ip, struct dnscache *dnscache) if (!dnscache) goto out; - if (!dnscache->cache_dict) { - dnscache->cache_dict = dict_new(); - if (!dnscache->cache_dict) { - goto out; - } - } cache = dnscache->cache_dict; /* Quick cache lookup to see if we already hold it */ @@ -645,7 +660,7 @@ gf_rev_dns_lookup_cached(const char *ip, struct dnscache *dnscache) if (entrydata) { dnsentry = (struct dnscache_entry *)entrydata->data; /* First check the TTL & timestamp */ - if (time(NULL) - dnsentry->timestamp > dnscache->ttl) { + 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 @@ -676,23 +691,16 @@ gf_rev_dns_lookup_cached(const char *ip, struct dnscache *dnscache) from_cache = _gf_false; out: /* Insert into the cache */ - if (fqdn && !from_cache) { + if (fqdn && !from_cache && ip) { struct dnscache_entry *entry = gf_dnscache_entry_init(); - if (!entry) { - goto out; + 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); } - entry->fqdn = fqdn; - if (!ip) { - gf_dnscache_entry_deinit(entry); - goto out; - } - - entry->ip = gf_strdup(ip); - entry->timestamp = time(NULL); - - entrydata = bin_to_data(entry, sizeof(*entry)); - dict_set(cache, (char *)ip, entrydata); } return fqdn; } @@ -901,7 +909,7 @@ gf_print_trace(int32_t signum, glusterfs_ctx_t *ctx) char msg[1024] = { 0, }; - char timestr[64] = { + char timestr[GF_TIMESTR_SIZE] = { 0, }; call_stack_t *stack = NULL; @@ -941,7 +949,7 @@ gf_print_trace(int32_t signum, glusterfs_ctx_t *ctx) { /* 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_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); } @@ -1943,6 +1951,74 @@ gf_string2boolean(const char *str, gf_boolean_t *b) } int +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; + } + + switch (len) { + case 1: + if (strcasecmp(str, "1") == 0) { + *b = _gf_true; + return 0; + } else if (strcasecmp(str, "0") == 0) { + *b = _gf_false; + return 0; + } + 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) { struct gf_flock fl; @@ -2037,8 +2113,8 @@ get_checksum_for_path(char *path, uint32_t *checksum, int op_version) 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); + gf_smsg(THIS->name, GF_LOG_ERROR, errno, LG_MSG_PATH_OPEN_FAILED, + "path=%s", path, NULL); goto out; } @@ -2071,8 +2147,8 @@ get_file_mtime(const char *path, time_t *stamp) ret = sys_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); + gf_smsg(THIS->name, GF_LOG_ERROR, errno, LG_MSG_FILE_STAT_FAILED, + "path=%s", path, NULL); goto out; } @@ -2131,14 +2207,14 @@ gf_is_ip_in_net(const char *network, const char *ip_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"); + 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_msg("common-utils", GF_LOG_ERROR, errno, LG_MSG_INET_PTON_FAILED, - "inet_pton() failed"); + gf_smsg("common-utils", GF_LOG_ERROR, errno, LG_MSG_INET_PTON_FAILED, + NULL); goto out; } @@ -2718,8 +2794,8 @@ gf_boolean_t 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"); + gf_smsg("common-utils", GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, + "gf_sock_union_equal_addr", NULL); return _gf_false; } @@ -2947,8 +3023,8 @@ gf_roundup_power_of_two(int32_t nr) int32_t result = 1; if (nr < 0) { - gf_msg("common-utils", GF_LOG_WARNING, 0, LG_MSG_NEGATIVE_NUM_PASSED, - "negative number passed"); + gf_smsg("common-utils", GF_LOG_WARNING, 0, LG_MSG_NEGATIVE_NUM_PASSED, + NULL); result = -1; goto out; } @@ -2971,8 +3047,8 @@ gf_roundup_next_power_of_two(int32_t nr) int32_t result = 1; if (nr < 0) { - gf_msg("common-utils", GF_LOG_WARNING, 0, LG_MSG_NEGATIVE_NUM_PASSED, - "negative number passed"); + gf_smsg("common-utils", GF_LOG_WARNING, 0, LG_MSG_NEGATIVE_NUM_PASSED, + NULL); result = -1; goto out; } @@ -2985,16 +3061,6 @@ out: } 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; -} - -int validate_brick_name(char *brick) { char *delimiter = NULL; @@ -3067,7 +3133,7 @@ get_mem_size() memsize = page_size * num_pages; #endif -#if defined GF_DARWIN_HOST_OS +#if defined GF_DARWIN_HOST_OS || defined __FreeBSD__ size_t len = sizeof(memsize); int name[] = {CTL_HW, HW_PHYSMEM}; @@ -3156,8 +3222,7 @@ gf_canonicalize_path(char *path) out: if (ret) - gf_msg("common-utils", GF_LOG_ERROR, 0, LG_MSG_PATH_ERROR, - "Path manipulation failed"); + gf_smsg("common-utils", GF_LOG_ERROR, 0, LG_MSG_PATH_ERROR, NULL); GF_FREE(tmppath); @@ -3211,19 +3276,15 @@ gf_get_reserved_ports() * 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"); + gf_smsg("glusterfs", GF_LOG_WARNING, errno, LG_MSG_FILE_OP_FAILED, + " /proc/sys/net/ipv4/ip_local_reserved_ports", NULL); goto out; } ret = sys_read(proc_fd, buffer, sizeof(buffer) - 1); 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); + gf_smsg("glusterfs", GF_LOG_WARNING, errno, LG_MSG_FILE_OP_FAILED, + "file=%s", proc_file, NULL); goto out; } @@ -3251,10 +3312,8 @@ gf_process_reserved_ports(unsigned char *ports, uint32_t ceiling) 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"); + gf_smsg("glusterfs", GF_LOG_WARNING, 0, LG_MSG_RESERVED_PORTS_ERROR, + NULL); goto out; } @@ -3291,8 +3350,8 @@ gf_ports_reserved(char *blocked_port, unsigned char *ports, uint32_t ceiling) 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_msg("glusterfs-socket", GF_LOG_WARNING, 0, - LG_MSG_INVALID_PORT, "invalid port %d", tmp_port1); + gf_smsg("glusterfs-socket", GF_LOG_WARNING, 0, + LG_MSG_INVALID_PORT, "port=%d", tmp_port1, NULL); result = _gf_true; goto out; } else { @@ -3303,10 +3362,8 @@ gf_ports_reserved(char *blocked_port, unsigned char *ports, uint32_t ceiling) BIT_SET(ports, tmp_port1); } } else { - gf_msg("glusterfs-socket", GF_LOG_WARNING, 0, LG_MSG_INVALID_PORT, - "%s is not a valid port " - "identifier", - blocked_port); + gf_smsg("glusterfs-socket", GF_LOG_WARNING, 0, LG_MSG_INVALID_PORT, + "port=%s", blocked_port, NULL); result = _gf_true; goto out; } @@ -3408,10 +3465,8 @@ gf_get_hostname_from_ip(char *client_ip, char **hostname) ret = getnameinfo(client_sockaddr, addr_sz, 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)); + 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; } @@ -3440,8 +3495,8 @@ gf_interface_search(char *ip) ret = getifaddrs(&ifaddr); if (ret != 0) { - gf_msg(this->name, GF_LOG_ERROR, 0, LG_MSG_GETIFADDRS_FAILED, - "getifaddrs() failed: %s\n", gai_strerror(ret)); + gf_smsg(this->name, GF_LOG_ERROR, 0, LG_MSG_GETIFADDRS_FAILED, "ret=%s", + gai_strerror(ret), NULL); goto out; } @@ -3465,10 +3520,8 @@ gf_interface_search(char *ip) 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)); + gf_smsg(this->name, GF_LOG_ERROR, 0, LG_MSG_GETNAMEINFO_FAILED, + "ret=%s", gai_strerror(ret), NULL); goto out; } @@ -3518,14 +3571,12 @@ get_ip_from_addrinfo(struct addrinfo *addr, char **ip) break; default: - gf_msg("glusterd", GF_LOG_ERROR, 0, LG_MSG_INVALID_FAMILY, - "Invalid family"); + gf_smsg("glusterd", GF_LOG_ERROR, 0, LG_MSG_INVALID_FAMILY, NULL); return NULL; } 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"); + gf_smsg("glusterd", GF_LOG_ERROR, 0, LG_MSG_CONVERSION_FAILED, NULL); return NULL; } @@ -3560,10 +3611,9 @@ gf_is_loopback_localhost(const struct sockaddr *sa, char *hostname) default: if (hostname) - gf_msg("glusterd", GF_LOG_ERROR, 0, LG_MSG_INVALID_FAMILY, - "unknown " - "address family %d for %s", - sa->sa_family, hostname); + gf_smsg("glusterd", GF_LOG_ERROR, 0, LG_MSG_INVALID_FAMILY, + "family=%d", sa->sa_family, "hostname=%s", hostname, + NULL); break; } @@ -3593,8 +3643,8 @@ gf_is_local_addr(char *hostname) ret = getaddrinfo(hostname, NULL, &hints, &result); if (ret != 0) { - gf_msg(this->name, GF_LOG_ERROR, 0, LG_MSG_GETADDRINFO_FAILED, - "error in getaddrinfo: %s\n", gai_strerror(ret)); + gf_smsg(this->name, GF_LOG_ERROR, 0, LG_MSG_GETADDRINFO_FAILED, + "ret=%s", gai_strerror(ret), NULL); goto out; } @@ -3642,15 +3692,15 @@ gf_is_same_address(char *name1, char *name2) gai_err = getaddrinfo(name1, NULL, &hints, &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)); + 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_msg(name2, GF_LOG_WARNING, 0, LG_MSG_GETADDRINFO_FAILED, - "error in getaddrinfo: %s\n", gai_strerror(gai_err)); + gf_smsg(name2, GF_LOG_WARNING, 0, LG_MSG_GETADDRINFO_FAILED, "error=%s", + gai_strerror(gai_err), NULL); goto out; } @@ -3787,8 +3837,10 @@ gf_set_volfile_server_common(cmd_args_t *cmd_args, const char *host, if ((!strcmp(tmp->volfile_server, server->volfile_server) && !strcmp(tmp->transport, server->transport) && (tmp->port == server->port))) { - errno = EEXIST; - ret = -1; + /* Duplicate option given, log and ignore */ + gf_smsg("gluster", GF_LOG_INFO, EEXIST, LG_MSG_DUPLICATE_ENTRY, + NULL); + ret = 0; goto out; } } @@ -3965,15 +4017,14 @@ gf_thread_set_vname(pthread_t thread, const char *name, va_list args) sizeof(thread_name) - sizeof(GF_THREAD_NAME_PREFIX) + 1, name, args); if (ret < 0) { - gf_msg(THIS->name, GF_LOG_WARNING, 0, LG_MSG_PTHREAD_NAMING_FAILED, - "Failed to compose thread name ('%s')", name); + gf_smsg(THIS->name, GF_LOG_WARNING, 0, LG_MSG_PTHREAD_NAMING_FAILED, + "name=%s", name, NULL); return; } if (ret >= sizeof(thread_name)) { - gf_msg(THIS->name, GF_LOG_WARNING, 0, LG_MSG_PTHREAD_NAMING_FAILED, - "Thread name is too long. It has been truncated ('%s')", - 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 @@ -3987,8 +4038,8 @@ gf_thread_set_vname(pthread_t thread, const char *name, va_list args) ret = ENOSYS; #endif if (ret != 0) { - gf_msg(THIS->name, GF_LOG_WARNING, ret, LG_MSG_PTHREAD_NAMING_FAILED, - "Could not set thread name: %s", thread_name); + gf_smsg(THIS->name, GF_LOG_WARNING, ret, LG_MSG_SET_THREAD_FAILED, + "name=%s", thread_name, NULL); } } @@ -4023,8 +4074,8 @@ gf_thread_vcreate(pthread_t *thread, const pthread_attr_t *attr, ret = pthread_create(thread, attr, start_routine, arg); if (ret != 0) { - gf_msg(THIS->name, GF_LOG_ERROR, ret, LG_MSG_PTHREAD_FAILED, - "Thread creation failed"); + 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); @@ -4060,8 +4111,8 @@ gf_thread_create_detached(pthread_t *thread, void *(*start_routine)(void *), ret = pthread_attr_init(&attr); if (ret) { - gf_msg(THIS->name, GF_LOG_ERROR, ret, LG_MSG_PTHREAD_ATTR_INIT_FAILED, - "Thread attribute initialization failed"); + gf_smsg(THIS->name, GF_LOG_ERROR, ret, LG_MSG_PTHREAD_ATTR_INIT_FAILED, + NULL); return -1; } @@ -4083,8 +4134,7 @@ gf_skip_header_section(int fd, int header_len) ret = sys_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"); + gf_smsg("", GF_LOG_ERROR, 0, LG_MSG_SKIP_HEADER_FAILED, NULL); } else { ret = 0; } @@ -4097,6 +4147,14 @@ gf_skip_header_section(int fd, int header_len) gf_boolean_t gf_is_pid_running(int pid) { +#ifdef __FreeBSD__ + int ret = -1; + + ret = sys_kill(pid, 0); + if (ret < 0) { + return _gf_false; + } +#else char fname[32] = { 0, }; @@ -4110,6 +4168,7 @@ gf_is_pid_running(int pid) } sys_close(fd); +#endif return _gf_true; } @@ -4134,8 +4193,8 @@ gf_is_service_running(char *pidfile, int *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); + gf_smsg("", GF_LOG_ERROR, errno, LG_MSG_FILE_OP_FAILED, "pidfile=%s", + pidfile, NULL); *pid = -1; running = _gf_false; goto out; @@ -4209,10 +4268,10 @@ gf_check_log_format(const char *value) 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); + 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; } @@ -4228,9 +4287,9 @@ gf_check_logger(const char *value) 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); + gf_smsg(THIS->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_LOG, + "possible_values=" GF_LOGGER_GLUSTER_LOG "|" GF_LOGGER_SYSLOG, + NULL); return logger; } @@ -4302,8 +4361,8 @@ gf_set_timestamp(const char *src, const char *dest) ret = sys_stat(src, &sb); if (ret) { - gf_msg(this->name, GF_LOG_ERROR, errno, LG_MSG_FILE_STAT_FAILED, - "stat on %s", src); + 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, @@ -4319,8 +4378,8 @@ gf_set_timestamp(const char *src, const char *dest) /* dirfd = 0 is ignored because `dest` is an absolute path. */ ret = sys_utimensat(AT_FDCWD, dest, new_time, AT_SYMLINK_NOFOLLOW); if (ret) { - gf_msg(this->name, GF_LOG_ERROR, errno, LG_MSG_UTIMENSAT_FAILED, - "utimensat on %s", dest); + 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; @@ -4331,8 +4390,8 @@ gf_set_timestamp(const char *src, const char *dest) ret = sys_utimes(dest, new_time); if (ret) { - gf_msg(this->name, GF_LOG_ERROR, errno, LG_MSG_UTIMES_FAILED, - "utimes on %s", dest); + gf_smsg(this->name, GF_LOG_ERROR, errno, LG_MSG_UTIMES_FAILED, + "dest=%s", dest, NULL); } #endif out: @@ -4351,7 +4410,7 @@ gf_backtrace_end(char *buf, size_t frames) frames = min(frames, GF_BACKTRACE_LEN - pos - 1); - if (frames <= 0) + if (0 == frames) return; memset(buf + pos, ')', frames); @@ -4397,8 +4456,8 @@ gf_backtrace_fillframes(char *buf) */ ret = sys_unlink(tmpl); if (ret < 0) { - gf_msg(THIS->name, GF_LOG_INFO, 0, LG_MSG_FILE_OP_FAILED, - "Unable to delete temporary file: %s", tmpl); + 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 @@ -4458,8 +4517,7 @@ gf_backtrace_save(char *buf) 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."); + gf_smsg(THIS->name, GF_LOG_WARNING, 0, LG_MSG_BACKTRACE_SAVE_FAILED, NULL); return NULL; } @@ -4550,16 +4608,16 @@ gf_build_absolute_path(char *current_path, char *relative_path, char **path) */ 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); + 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_msg(THIS->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, - "Wrong value for relative path %s", relative_path); + gf_smsg(THIS->name, GF_LOG_ERROR, 0, LG_MSG_WRONG_VALUE, + "relative-path=%s", relative_path, NULL); ret = -EINVAL; goto err; } @@ -4675,8 +4733,9 @@ recursive_rmdir(const char *delete_path) goto out; } - GF_SKIP_IRRELEVANT_ENTRIES(entry, dir, scratch); - while (entry) { + 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) { @@ -4702,8 +4761,6 @@ recursive_rmdir(const char *delete_path) gf_msg_debug(this->name, 0, "%s %s", ret ? "Failed to remove" : "Removed", entry->d_name); - - GF_SKIP_IRRELEVANT_ENTRIES(entry, dir, scratch); } ret = sys_closedir(dir); @@ -5027,8 +5084,8 @@ gf_zero_fill_stat(struct iatt *buf) gf_boolean_t gf_is_valid_xattr_namespace(char *key) { - static char *xattr_namespaces[] = {"trusted.", "security.", "system.", - "user.", NULL}; + static char *xattr_namespaces[] = {"trusted.", "system.", "user.", + "security.", NULL}; int i = 0; for (i = 0; xattr_namespaces[i]; i++) { @@ -5251,62 +5308,6 @@ glusterfs_compute_sha256(const unsigned char *content, size_t size, return 0; } -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; -} - /* * 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 @@ -5421,3 +5422,44 @@ gf_d_type_from_ia_type(ia_type_t type) 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() +{ + return xattrs_to_heal; +} diff --git a/libglusterfs/src/compat.c b/libglusterfs/src/compat.c index 877cda282de..8a05a30a8fe 100644 --- a/libglusterfs/src/compat.c +++ b/libglusterfs/src/compat.c @@ -176,7 +176,7 @@ solaris_xattr_resolve_path(const char *real_path, char **path) if (!ret && export_path) { strcat(export_path, "/" GF_SOLARIS_XATTR_DIR); if (lstat(export_path, &statbuf)) { - ret = mkdir(export_path, 0777); + ret = mkdir(export_path, 0755); if (ret && (errno != EEXIST)) { gf_msg_debug(THIS->name, 0, "mkdir failed," diff --git a/libglusterfs/src/ctx.c b/libglusterfs/src/ctx.c index 4a001c29209..3d890b04ec9 100644 --- a/libglusterfs/src/ctx.c +++ b/libglusterfs/src/ctx.c @@ -37,8 +37,12 @@ glusterfs_ctx_new() ctx->log.loglevel = DEFAULT_LOG_LEVEL; -#ifdef RUN_WITH_VALGRIND - ctx->cmd_args.valgrind = _gf_true; +#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 /* lock is never destroyed! */ diff --git a/libglusterfs/src/defaults-tmpl.c b/libglusterfs/src/defaults-tmpl.c index 82e7f78d7f3..3cf707f42aa 100644 --- a/libglusterfs/src/defaults-tmpl.c +++ b/libglusterfs/src/defaults-tmpl.c @@ -171,8 +171,11 @@ default_notify(xlator_t *this, int32_t event, void *data, ...) /* Make sure this is not a daemon with master xlator */ pthread_mutex_lock(&graph->mutex); { - graph->used = 0; - pthread_cond_broadcast(&graph->child_down_cond); + if (graph->parent_down == + graph_total_client_xlator(graph)) { + graph->used = 0; + pthread_cond_broadcast(&graph->child_down_cond); + } } pthread_mutex_unlock(&graph->mutex); } diff --git a/libglusterfs/src/dict.c b/libglusterfs/src/dict.c index b44dda33f00..1d9be9217a6 100644 --- a/libglusterfs/src/dict.c +++ b/libglusterfs/src/dict.c @@ -57,7 +57,6 @@ get_new_data() GF_ATOMIC_INIT(data->refcount, 0); data->is_static = _gf_false; - LOCK_INIT(&data->lock); return data; } @@ -98,6 +97,8 @@ get_new_dict_full(int size_hint) } } + dict->free_pair.key = NULL; + dict->totkvlen = 0; LOCK_INIT(&dict->lock); return dict; @@ -293,8 +294,6 @@ void data_destroy(data_t *data) { if (data) { - LOCK_DESTROY(&data->lock); - if (!data->is_static) GF_FREE(data->data); @@ -325,7 +324,6 @@ data_copy(data_t *old) } newdata->data_type = old->data_type; - LOCK_INIT(&newdata->lock); return newdata; err_out: @@ -339,7 +337,7 @@ err_out: * checked by callers. */ static data_pair_t * -dict_lookup_common(dict_t *this, char *key, uint32_t hash) +dict_lookup_common(const dict_t *this, const char *key, const uint32_t hash) { int hashval = 0; data_pair_t *pair; @@ -386,8 +384,8 @@ dict_lookup(dict_t *this, char *key, data_t **data) } static int32_t -dict_set_lk(dict_t *this, char *key, data_t *value, const uint32_t hash, - gf_boolean_t replace) +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; @@ -403,7 +401,7 @@ dict_set_lk(dict_t *this, char *key, data_t *value, const uint32_t hash, key_free = 1; key_hash = (uint32_t)XXH64(key, keylen, 0); } else { - keylen = strlen(key); + keylen = key_len; key_hash = hash; } @@ -413,6 +411,7 @@ dict_set_lk(dict_t *this, char *key, data_t *value, const uint32_t 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); @@ -421,16 +420,15 @@ dict_set_lk(dict_t *this, char *key, data_t *value, const uint32_t hash, } } - if (this->free_pair_in_use) { + 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 { + } else { /* assign the pair to the free pair */ pair = &this->free_pair; - this->free_pair_in_use = _gf_true; } if (key_free) { @@ -440,9 +438,7 @@ dict_set_lk(dict_t *this, char *key, data_t *value, const uint32_t hash, } else { pair->key = (char *)GF_MALLOC(keylen + 1, gf_common_mt_char); if (!pair->key) { - if (pair == &this->free_pair) { - this->free_pair_in_use = _gf_false; - } else { + if (pair != &this->free_pair) { mem_put(pair); } return -1; @@ -451,6 +447,7 @@ dict_set_lk(dict_t *this, char *key, data_t *value, const uint32_t hash, } 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. @@ -500,12 +497,12 @@ dict_setn(dict_t *this, char *key, const int keylen, data_t *value) } if (key) { - key_hash = (int32_t)XXH64(key, keylen, 0); + key_hash = (uint32_t)XXH64(key, keylen, 0); } LOCK(&this->lock); - ret = dict_set_lk(this, key, value, key_hash, 1); + ret = dict_set_lk(this, key, keylen, value, key_hash, 1); UNLOCK(&this->lock); @@ -539,7 +536,7 @@ dict_addn(dict_t *this, char *key, const int keylen, data_t *value) LOCK(&this->lock); - ret = dict_set_lk(this, key, value, key_hash, 0); + ret = dict_set_lk(this, key, keylen, value, key_hash, 0); UNLOCK(&this->lock); @@ -648,6 +645,7 @@ dict_deln(dict_t *this, char *key, const int keylen) else this->members[hashval] = pair->hash_next; + this->totkvlen -= pair->value->len; data_unref(pair->value); if (pair->prev) @@ -658,9 +656,10 @@ dict_deln(dict_t *this, char *key, const int keylen) if (pair->next) pair->next->prev = pair->prev; + this->totkvlen -= (strlen(pair->key) + 1); GF_FREE(pair->key); if (pair == &this->free_pair) { - this->free_pair_in_use = _gf_false; + this->free_pair.key = NULL; } else { mem_put(pair); } @@ -700,16 +699,18 @@ dict_destroy(dict_t *this) GF_FREE(prev->key); if (prev != &this->free_pair) { mem_put(prev); + } else { + this->free_pair.key = NULL; } total_pairs++; prev = pair; } + this->totkvlen = 0; if (this->members != &this->members_internal) { mem_put(this->members); } - GF_FREE(this->extra_free); free(this->extra_stdfree); /* update 'ctx->stats.dict.details' using max_count */ @@ -808,6 +809,7 @@ int_to_data(int64_t value) 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 */ @@ -827,6 +829,7 @@ data_from_int64(int64_t value) 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 */ @@ -846,6 +849,7 @@ data_from_int32(int32_t value) data->len = gf_asprintf(&data->data, "%" PRId32, value); if (-1 == data->len) { gf_msg_debug("dict", 0, "asprintf failed"); + data_destroy(data); return NULL; } @@ -866,6 +870,7 @@ data_from_int16(int16_t value) data->len = gf_asprintf(&data->data, "%" PRId16, value); if (-1 == data->len) { gf_msg_debug("dict", 0, "asprintf failed"); + data_destroy(data); return NULL; } @@ -886,6 +891,7 @@ data_from_int8(int8_t value) data->len = gf_asprintf(&data->data, "%d", value); if (-1 == data->len) { gf_msg_debug("dict", 0, "asprintf failed"); + data_destroy(data); return NULL; } @@ -906,6 +912,7 @@ data_from_uint64(uint64_t value) data->len = gf_asprintf(&data->data, "%" PRIu64, value); if (-1 == data->len) { gf_msg_debug("dict", 0, "asprintf failed"); + data_destroy(data); return NULL; } @@ -926,6 +933,8 @@ data_from_double(double value) 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 */ @@ -945,6 +954,7 @@ data_from_uint32(uint32_t value) data->len = gf_asprintf(&data->data, "%" PRIu32, value); if (-1 == data->len) { gf_msg_debug("dict", 0, "asprintf failed"); + data_destroy(data); return NULL; } @@ -964,6 +974,8 @@ data_from_uint16(uint16_t value) } data->len = gf_asprintf(&data->data, "%" PRIu16, value); if (-1 == data->len) { + gf_msg_debug("dict", 0, "asprintf failed"); + data_destroy(data); return NULL; } @@ -1099,117 +1111,146 @@ data_to_int64(data_t *data) { VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_INT, "null", -1); - return (int64_t)strtoull(data->data, NULL, 0); + char *endptr = NULL; + int64_t value = 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) { - VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_INT, "null", -1); + char *endptr = NULL; + int64_t value = 0; - return strtoul(data->data, 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) { - VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_INT, "null", -1); - - int16_t value = 0; - - errno = 0; - value = strtol(data->data, 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) { + char *endptr = NULL; + int64_t value = 0; + 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) +{ + VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_UINT, "null", -1); - int8_t value = 0; + char *endptr = NULL; + uint64_t value = 0; errno = 0; - value = strtol(data->data, NULL, 0); + value = strtoull(data->data, &endptr, 0); - if ((value > SCHAR_MAX) || (value < SCHAR_MIN)) { - errno = ERANGE; + 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: detected overflow"); + "Error in data conversion: '%s' can't " + "be represented as uint64_t", + data->data); return -1; } - - return (int8_t)value; + return value; } -uint64_t -data_to_uint64(data_t *data) -{ - VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_UINT, "null", -1); +/* Like above but implies unsigned range check. */ - return strtoll(data->data, NULL, 0); -} +#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) { - VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_UINT, "null", -1); + char *endptr = NULL; + uint64_t value = 0; - return strtol(data->data, 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) { - VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_UINT, "null", -1); - - uint16_t value = 0; - - errno = 0; - value = strtol(data->data, 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; - } + char *endptr = NULL; + uint64_t value = 0; - 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) { - VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_UINT, "null", -1); - - errno = 0; - uint32_t value = strtol(data->data, NULL, 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; - } + char *endptr = NULL; + uint64_t value = 0; - 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 * @@ -1243,8 +1284,8 @@ data_to_iatt(data_t *data, char *key) * 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_msg("glusterfs", GF_LOG_ERROR, ENOBUFS, LG_MSG_UNDERSIZED_BUF, - "data value for '%s' is smaller than expected", key); + gf_smsg("glusterfs", GF_LOG_ERROR, ENOBUFS, LG_MSG_UNDERSIZED_BUF, + "key=%s", key, NULL); return NULL; } @@ -1261,8 +1302,8 @@ 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"); + gf_smsg("glusterfs", GF_LOG_WARNING, EINVAL, LG_MSG_KEY_OR_VALUE_NULL, + "d=%s", d ? "key" : "dictionary", NULL); return -1; } @@ -1454,32 +1495,13 @@ fail: * -val error, val = errno */ -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); -} - -int +static int dict_get_with_refn(dict_t *this, char *key, const int keylen, data_t **data) { 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); @@ -1492,10 +1514,22 @@ dict_get_with_refn(dict_t *this, char *key, const int keylen, data_t **data) } } UNLOCK(&this->lock); -err: + 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) { @@ -1669,7 +1703,7 @@ dict_get_int8(dict_t *this, char *key, int8_t *val) data_t *data = NULL; int ret = 0; - if (!this || !key || !val) { + if (!val) { ret = -EINVAL; goto err; } @@ -1715,7 +1749,7 @@ dict_get_int16(dict_t *this, char *key, int16_t *val) data_t *data = NULL; int ret = 0; - if (!this || !key || !val) { + if (!val) { ret = -EINVAL; goto err; } @@ -1787,7 +1821,7 @@ dict_get_int32(dict_t *this, char *key, int32_t *val) data_t *data = NULL; int ret = 0; - if (!this || !key || !val) { + if (!val) { ret = -EINVAL; goto err; } @@ -1852,7 +1886,7 @@ dict_get_int64(dict_t *this, char *key, int64_t *val) data_t *data = NULL; int ret = 0; - if (!this || !key || !val) { + if (!val) { ret = -EINVAL; goto err; } @@ -1897,7 +1931,7 @@ dict_get_uint16(dict_t *this, char *key, uint16_t *val) data_t *data = NULL; int ret = 0; - if (!this || !key || !val) { + if (!val) { ret = -EINVAL; goto err; } @@ -1942,7 +1976,7 @@ dict_get_uint32(dict_t *this, char *key, uint32_t *val) data_t *data = NULL; int ret = 0; - if (!this || !key || !val) { + if (!val) { ret = -EINVAL; goto err; } @@ -1987,7 +2021,7 @@ dict_get_uint64(dict_t *this, char *key, uint64_t *val) data_t *data = NULL; int ret = 0; - if (!this || !key || !val) { + if (!val) { ret = -EINVAL; goto err; } @@ -2083,7 +2117,7 @@ _dict_modify_flag(dict_t *this, char *key, int flag, int op) */ GF_ASSERT(flag >= 0 && flag < DICT_MAX_FLAGS); - hash = (int32_t)XXH64(key, strlen(key), 0); + hash = (uint32_t)XXH64(key, strlen(key), 0); LOCK(&this->lock); { pair = dict_lookup_common(this, key, hash); @@ -2097,8 +2131,8 @@ _dict_modify_flag(dict_t *this, char *key, int flag, int op) } else { ptr = GF_CALLOC(1, DICT_MAX_FLAGS / 8, gf_common_mt_char); if (!ptr) { - gf_msg("dict", GF_LOG_ERROR, ENOMEM, LG_MSG_NO_MEMORY, - "unable to allocate flag bit array"); + gf_smsg("dict", GF_LOG_ERROR, ENOMEM, LG_MSG_NO_MEMORY, + "flag bit array", NULL); ret = -ENOMEM; goto err; } @@ -2106,8 +2140,8 @@ _dict_modify_flag(dict_t *this, char *key, int flag, int op) data = data_from_dynptr(ptr, DICT_MAX_FLAGS / 8); if (!data) { - gf_msg("dict", GF_LOG_ERROR, ENOMEM, LG_MSG_NO_MEMORY, - "unable to allocate data"); + gf_smsg("dict", GF_LOG_ERROR, ENOMEM, LG_MSG_NO_MEMORY, "data", + NULL); GF_FREE(ptr); ret = -ENOMEM; goto err; @@ -2118,30 +2152,29 @@ _dict_modify_flag(dict_t *this, char *key, int flag, int op) else BIT_CLEAR((unsigned char *)(data->data), flag); - if (this->free_pair_in_use) { + if (this->free_pair.key) { /* the free pair is in use */ pair = mem_get0(THIS->ctx->dict_pair_pool); if (!pair) { - gf_msg("dict", GF_LOG_ERROR, ENOMEM, LG_MSG_NO_MEMORY, - "unable to allocate dict pair"); + gf_smsg("dict", GF_LOG_ERROR, ENOMEM, LG_MSG_NO_MEMORY, + "dict pair", NULL); ret = -ENOMEM; goto err; } - } else { + } else { /* use the free pair */ pair = &this->free_pair; - this->free_pair_in_use = _gf_true; } pair->key = (char *)GF_MALLOC(strlen(key) + 1, gf_common_mt_char); if (!pair->key) { - gf_msg("dict", GF_LOG_ERROR, ENOMEM, LG_MSG_NO_MEMORY, - "unable to allocate dict pair"); + 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; @@ -2166,12 +2199,11 @@ err: UNLOCK(&this->lock); if (pair) { - if (pair->key) - free(pair->key); - - if (pair == &this->free_pair) { - this->free_pair_in_use = _gf_false; - } else { + if (pair->key) { + GF_FREE(pair->key); + pair->key = NULL; + } + if (pair != &this->free_pair) { mem_put(pair); } } @@ -2179,8 +2211,8 @@ err: if (data) data_destroy(data); - gf_msg("dict", GF_LOG_ERROR, EINVAL, LG_MSG_DICT_SET_FAILED, - "unable to set key (%s) in dict ", key); + gf_smsg("dict", GF_LOG_ERROR, EINVAL, LG_MSG_DICT_SET_FAILED, "key=%s", key, + NULL); return ret; } @@ -2212,7 +2244,7 @@ dict_get_double(dict_t *this, char *key, double *val) data_t *data = NULL; int ret = 0; - if (!this || !key || !val) { + if (!val) { ret = -EINVAL; goto err; } @@ -2295,7 +2327,7 @@ dict_get_ptr(dict_t *this, char *key, void **ptr) data_t *data = NULL; int ret = 0; - if (!this || !key || !ptr) { + if (!ptr) { ret = -EINVAL; goto err; } @@ -2325,7 +2357,7 @@ dict_get_ptr_and_len(dict_t *this, char *key, void **ptr, int *len) data_t *data = NULL; int ret = 0; - if (!this || !key || !ptr) { + if (!ptr) { ret = -EINVAL; goto err; } @@ -2383,7 +2415,7 @@ dict_get_str(dict_t *this, char *key, char **str) data_t *data = NULL; int ret = -EINVAL; - if (!this || !key || !str) { + if (!str) { goto err; } ret = dict_get_with_ref(this, key, &data); @@ -2557,7 +2589,7 @@ dict_get_bin(dict_t *this, char *key, void **bin) data_t *data = NULL; int ret = -EINVAL; - if (!this || !key || !bin) { + if (!bin) { goto err; } @@ -2660,7 +2692,7 @@ dict_get_gfuuid(dict_t *this, char *key, uuid_t *gfid) data_t *data = NULL; int ret = -EINVAL; - if (!this || !key || !gfid) { + if (!gfid) { goto err; } ret = dict_get_with_ref(this, key, &data); @@ -2693,7 +2725,7 @@ dict_get_mdata(dict_t *this, char *key, struct mdata_iatt *mdata) data_t *data = NULL; int ret = -EINVAL; - if (!this || !key || !mdata) { + if (!mdata) { goto err; } ret = dict_get_with_ref(this, key, &data); @@ -2703,8 +2735,8 @@ dict_get_mdata(dict_t *this, char *key, struct mdata_iatt *mdata) VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_MDATA, key, -EINVAL); if (data->len < sizeof(struct mdata_iatt)) { - gf_msg("glusterfs", GF_LOG_ERROR, ENOBUFS, LG_MSG_UNDERSIZED_BUF, - "data value for '%s' is smaller than expected", key); + gf_smsg("glusterfs", GF_LOG_ERROR, ENOBUFS, LG_MSG_UNDERSIZED_BUF, + "key=%s", key, NULL); ret = -ENOBUFS; goto err; } @@ -2731,7 +2763,7 @@ dict_get_iatt(dict_t *this, char *key, struct iatt *iatt) data_t *data = NULL; int ret = -EINVAL; - if (!this || !key || !iatt) { + if (!iatt) { goto err; } ret = dict_get_with_ref(this, key, &data); @@ -2791,7 +2823,7 @@ dict_get_str_boolean(dict_t *this, char *key, int default_val) VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_INT, key, -EINVAL); - ret = gf_string2boolean(data->data, &boo); + ret = gf_strn2boolean(data->data, data->len - 1, &boo); if (ret == -1) goto err; @@ -2811,6 +2843,7 @@ dict_rename_key(dict_t *this, char *key, char *replace_key) 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) @@ -2823,7 +2856,8 @@ dict_rename_key(dict_t *this, char *key, char *replace_key) } hash = (uint32_t)XXH64(key, strlen(key), 0); - replacekey_hash = (uint32_t)XXH64(replace_key, strlen(replace_key), 0); + replacekey_len = strlen(replace_key); + replacekey_hash = (uint32_t)XXH64(replace_key, replacekey_len, 0); LOCK(&this->lock); { @@ -2832,8 +2866,8 @@ dict_rename_key(dict_t *this, char *key, char *replace_key) if (!pair) ret = -ENODATA; else - ret = dict_set_lk(this, replace_key, pair->value, replacekey_hash, - 1); + ret = dict_set_lk(this, replace_key, replacekey_len, pair->value, + replacekey_hash, 1); } UNLOCK(&this->lock); @@ -2866,53 +2900,15 @@ dict_serialized_length_lk(dict_t *this) { int ret = -EINVAL; int count = this->count; - int len = DICT_HDR_LEN; - data_pair_t *pair = this->members_list; + const int keyhdrlen = DICT_DATA_HDR_KEY_LEN + DICT_DATA_HDR_VAL_LEN; if (count < 0) { - gf_msg("dict", GF_LOG_ERROR, EINVAL, LG_MSG_COUNT_LESS_THAN_ZERO, - "count (%d) < 0!", count); + gf_smsg("dict", GF_LOG_ERROR, EINVAL, LG_MSG_COUNT_LESS_THAN_ZERO, + "count=%d", count, NULL); goto out; } - 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 (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; } @@ -2939,14 +2935,13 @@ dict_serialize_lk(dict_t *this, char *buf) int32_t netword = 0; if (!buf) { - gf_msg("dict", GF_LOG_ERROR, EINVAL, LG_MSG_INVALID_ARG, - "buf is null!"); + gf_smsg("dict", GF_LOG_ERROR, EINVAL, LG_MSG_INVALID_ARG, NULL); goto out; } if (count < 0) { - gf_msg("dict", GF_LOG_ERROR, 0, LG_MSG_COUNT_LESS_THAN_ZERO, - "count (%d) < 0!", count); + gf_smsg("dict", GF_LOG_ERROR, 0, LG_MSG_COUNT_LESS_THAN_ZERO, + "count=%d", count, NULL); goto out; } @@ -2956,14 +2951,13 @@ dict_serialize_lk(dict_t *this, char *buf) while (count) { if (!pair) { - gf_msg("dict", GF_LOG_ERROR, 0, LG_MSG_PAIRS_LESS_THAN_COUNT, - "less than count data pairs found!"); + gf_smsg("dict", GF_LOG_ERROR, 0, LG_MSG_PAIRS_LESS_THAN_COUNT, + NULL); goto out; } if (!pair->key) { - gf_msg("dict", GF_LOG_ERROR, 0, LG_MSG_NULL_PTR, - "pair->key is null!"); + gf_smsg("dict", GF_LOG_ERROR, 0, LG_MSG_NULL_PTR, NULL); goto out; } @@ -2973,8 +2967,7 @@ dict_serialize_lk(dict_t *this, char *buf) buf += DICT_DATA_HDR_KEY_LEN; if (!pair->value) { - gf_msg("dict", GF_LOG_ERROR, 0, LG_MSG_NULL_PTR, - "pair->value is null!"); + gf_smsg("dict", GF_LOG_ERROR, 0, LG_MSG_NULL_PTR, NULL); goto out; } @@ -3122,8 +3115,8 @@ dict_unserialize(char *orig_buf, int32_t size, dict_t **fill) buf += DICT_HDR_LEN; if (count < 0) { - gf_msg("dict", GF_LOG_ERROR, 0, LG_MSG_COUNT_LESS_THAN_ZERO, - "count (%d) <= 0", count); + gf_smsg("dict", GF_LOG_ERROR, 0, LG_MSG_COUNT_LESS_THAN_ZERO, + "count=%d", count, NULL); goto out; } @@ -3193,7 +3186,7 @@ dict_unserialize(char *orig_buf, int32_t size, dict_t **fill) value->is_static = _gf_false; buf += vallen; - ret = dict_add(*fill, key, value); + ret = dict_addn(*fill, key, keylen, value); if (ret < 0) goto out; } @@ -3279,32 +3272,30 @@ dict_serialize_value_with_delim_lk(dict_t *this, char *buf, int32_t *serz_len, data_pair_t *pair = this->members_list; if (!buf) { - gf_msg("dict", GF_LOG_ERROR, EINVAL, LG_MSG_INVALID_ARG, "buf is null"); + gf_smsg("dict", GF_LOG_ERROR, EINVAL, LG_MSG_INVALID_ARG, NULL); goto out; } if (count < 0) { - gf_msg("dict", GF_LOG_ERROR, EINVAL, LG_MSG_INVALID_ARG, - "count (%d) < 0", count); + 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"); + 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"); + 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"); + gf_smsg("dict", GF_LOG_ERROR, 0, LG_MSG_NULL_VALUE_IN_DICT, NULL); goto out; } @@ -3396,12 +3387,11 @@ dict_dump_to_log(dict_t *dict) ret = dict_dump_to_str(dict, dump, dump_size, format); if (ret) { - gf_msg("dict", GF_LOG_WARNING, 0, LG_MSG_FAILED_TO_LOG_DICT, - "Failed to log dictionary"); + gf_smsg("dict", GF_LOG_WARNING, 0, LG_MSG_FAILED_TO_LOG_DICT, NULL); goto out; } - gf_msg("dict", GF_LOG_INFO, 0, LG_MSG_DICT_ERROR, "dict=%p (%s)", dict, - dump); + gf_smsg("dict", GF_LOG_INFO, 0, LG_MSG_DICT_ERROR, "dict=%p", dict, + "dump=%s", dump, NULL); out: GF_FREE(dump); @@ -3434,8 +3424,8 @@ dict_dump_to_statedump(dict_t *dict, char *dict_name, char *domain) ret = dict_dump_to_str(dict, dump, dump_size, format); if (ret) { - gf_msg(domain, GF_LOG_WARNING, 0, LG_MSG_FAILED_TO_LOG_DICT, - "Failed to log dictionary %s", dict_name); + 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); diff --git a/libglusterfs/src/event-epoll.c b/libglusterfs/src/event-epoll.c index bfe2648a920..fb4fb845b40 100644 --- a/libglusterfs/src/event-epoll.c +++ b/libglusterfs/src/event-epoll.c @@ -296,9 +296,8 @@ event_pool_new_epoll(int count, int eventthreadcount) 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_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; @@ -332,8 +331,8 @@ __slot_update_events(struct event_slot_epoll *slot, int poll_in, int poll_out) /* do nothing */ break; default: - gf_msg("epoll", GF_LOG_ERROR, 0, LG_MSG_INVALID_POLL_IN, - "invalid poll_in value %d", poll_in); + gf_smsg("epoll", GF_LOG_ERROR, 0, LG_MSG_INVALID_POLL_IN, + "value=%d", poll_in, NULL); break; } @@ -348,8 +347,8 @@ __slot_update_events(struct event_slot_epoll *slot, int poll_in, int poll_out) /* do nothing */ break; default: - gf_msg("epoll", GF_LOG_ERROR, 0, LG_MSG_INVALID_POLL_OUT, - "invalid poll_out value %d", poll_out); + gf_smsg("epoll", GF_LOG_ERROR, 0, LG_MSG_INVALID_POLL_OUT, + "value=%d", poll_out, NULL); break; } } @@ -390,8 +389,8 @@ event_register_epoll(struct event_pool *event_pool, int fd, idx = event_slot_alloc(event_pool, fd, notify_poller_death, &slot); if (idx == -1) { - gf_msg("epoll", GF_LOG_ERROR, 0, LG_MSG_SLOT_NOT_FOUND, - "could not find slot for fd=%d", fd); + gf_smsg("epoll", GF_LOG_ERROR, 0, LG_MSG_SLOT_NOT_FOUND, "fd=%d", fd, + NULL); return -1; } @@ -426,10 +425,8 @@ event_register_epoll(struct event_pool *event_pool, int fd, 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); + 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; } @@ -458,8 +455,8 @@ event_unregister_epoll_common(struct event_pool *event_pool, int fd, int idx, slot = event_slot_get(event_pool, idx); if (!slot) { - gf_msg("epoll", GF_LOG_ERROR, 0, LG_MSG_SLOT_NOT_FOUND, - "could not find slot for fd=%d idx=%d", fd, idx); + gf_smsg("epoll", GF_LOG_ERROR, 0, LG_MSG_SLOT_NOT_FOUND, "fd=%d", fd, + "idx=%d", idx, NULL); return -1; } @@ -470,10 +467,8 @@ event_unregister_epoll_common(struct event_pool *event_pool, int fd, int idx, 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); + 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; } @@ -525,8 +520,8 @@ event_select_on_epoll(struct event_pool *event_pool, int fd, int idx, slot = event_slot_get(event_pool, idx); if (!slot) { - gf_msg("epoll", GF_LOG_ERROR, 0, LG_MSG_SLOT_NOT_FOUND, - "could not find slot for fd=%d idx=%d", fd, idx); + gf_smsg("epoll", GF_LOG_ERROR, 0, LG_MSG_SLOT_NOT_FOUND, "fd=%d", fd, + "idx=%d", idx, NULL); return -1; } @@ -557,10 +552,8 @@ event_select_on_epoll(struct event_pool *event_pool, int fd, int idx, 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); + gf_smsg("epoll", GF_LOG_ERROR, errno, LG_MSG_EPOLL_FD_MODIFY_FAILED, + "fd=%d", fd, "events=%d", epoll_event.events, NULL); } } unlock: @@ -595,8 +588,8 @@ event_dispatch_epoll_handler(struct event_pool *event_pool, slot = event_slot_get(event_pool, idx); if (!slot) { - gf_msg("epoll", GF_LOG_ERROR, 0, LG_MSG_SLOT_NOT_FOUND, - "could not find slot for idx=%d", idx); + gf_smsg("epoll", GF_LOG_ERROR, 0, LG_MSG_SLOT_NOT_FOUND, "idx=%d", idx, + NULL); return -1; } @@ -604,20 +597,17 @@ event_dispatch_epoll_handler(struct event_pool *event_pool, { 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); + 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; } 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); + 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; } @@ -676,10 +666,8 @@ event_dispatch_epoll_worker(void *data) GF_VALIDATE_OR_GOTO("event", event_pool, out); - gf_msg("epoll", GF_LOG_INFO, 0, LG_MSG_STARTED_EPOLL_THREAD, - "Started" - " thread with index %d", - myindex - 1); + gf_smsg("epoll", GF_LOG_INFO, 0, LG_MSG_STARTED_EPOLL_THREAD, "index=%d", + myindex - 1, NULL); pthread_mutex_lock(&event_pool->mutex); { @@ -743,8 +731,8 @@ event_dispatch_epoll_worker(void *data) } pthread_mutex_unlock(&event_pool->mutex); - gf_msg("epoll", GF_LOG_INFO, 0, LG_MSG_EXITED_EPOLL_THREAD, - "Exited thread with index %d", myindex); + gf_smsg("epoll", GF_LOG_INFO, 0, LG_MSG_EXITED_EPOLL_THREAD, + "index=%d", myindex, NULL); goto out; } @@ -762,8 +750,8 @@ event_dispatch_epoll_worker(void *data) ret = event_dispatch_epoll_handler(event_pool, &event); if (ret) { - gf_msg("epoll", GF_LOG_ERROR, 0, LG_MSG_EXITED_EPOLL_THREAD, - "Failed to dispatch handler"); + gf_smsg("epoll", GF_LOG_ERROR, 0, LG_MSG_DISPATCH_HANDLER_FAILED, + NULL); } } out: @@ -827,9 +815,8 @@ event_dispatch_epoll(struct event_pool *event_pool) 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); + 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; @@ -922,11 +909,9 @@ event_reconfigure_threads_epoll(struct event_pool *event_pool, int value) event_dispatch_epoll_worker, ev_data, "epoll%03hx", i & 0x3ff); if (ret) { - gf_msg("epoll", GF_LOG_WARNING, 0, - LG_MSG_START_EPOLL_THREAD_FAILED, - "Failed to start thread" - " for index %d", - i); + 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); @@ -989,8 +974,8 @@ event_handled_epoll(struct event_pool *event_pool, int fd, int idx, int gen) slot = event_slot_get(event_pool, idx); if (!slot) { - gf_msg("epoll", GF_LOG_ERROR, 0, LG_MSG_SLOT_NOT_FOUND, - "could not find slot for fd=%d idx=%d", fd, idx); + gf_smsg("epoll", GF_LOG_ERROR, 0, LG_MSG_SLOT_NOT_FOUND, "fd=%d", fd, + "idx=%d", idx, NULL); return -1; } diff --git a/libglusterfs/src/event-poll.c b/libglusterfs/src/event-poll.c index 14dc5e3180c..2cba963f096 100644 --- a/libglusterfs/src/event-poll.c +++ b/libglusterfs/src/event-poll.c @@ -48,10 +48,8 @@ __flush_fd(int fd, int idx, int gen, void *data, int poll_in, int poll_out, do { ret = sys_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); + gf_smsg("poll", GF_LOG_ERROR, errno, LG_MSG_READ_FILE_FAILED, + "fd=%d", fd, NULL); } } while (ret == 64); @@ -111,8 +109,7 @@ event_pool_new_poll(int count, int eventthreadcount) ret = pipe(event_pool->breaker); if (ret == -1) { - gf_msg("poll", GF_LOG_ERROR, errno, LG_MSG_PIPE_CREATE_FAILED, - "pipe creation failed"); + gf_smsg("poll", GF_LOG_ERROR, errno, LG_MSG_PIPE_CREATE_FAILED, NULL); GF_FREE(event_pool->reg); GF_FREE(event_pool); return NULL; @@ -120,8 +117,7 @@ event_pool_new_poll(int count, int eventthreadcount) 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"); + 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; @@ -133,8 +129,7 @@ event_pool_new_poll(int count, int eventthreadcount) 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_smsg("poll", GF_LOG_ERROR, errno, LG_MSG_SET_PIPE_FAILED, NULL); sys_close(event_pool->breaker[0]); sys_close(event_pool->breaker[1]); @@ -148,8 +143,7 @@ event_pool_new_poll(int count, int eventthreadcount) ret = event_register_poll(event_pool, event_pool->breaker[0], __flush_fd, NULL, 1, 0, 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"); + 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; @@ -160,11 +154,8 @@ event_pool_new_poll(int count, int eventthreadcount) } 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_smsg("poll", GF_LOG_INFO, 0, LG_MSG_POLL_IGNORE_MULTIPLE_THREADS, + "count=%d", eventthreadcount, NULL); } /* although, eventhreadcount for poll implementation is always @@ -215,8 +206,8 @@ event_register_poll(struct event_pool *event_pool, int fd, /* do nothing */ break; default: - gf_msg("poll", GF_LOG_ERROR, 0, LG_MSG_INVALID_POLL_IN, - "invalid poll_in value %d", poll_in); + gf_smsg("poll", GF_LOG_ERROR, 0, LG_MSG_INVALID_POLL_IN, + "value=%d", poll_in, NULL); break; } @@ -231,8 +222,8 @@ event_register_poll(struct event_pool *event_pool, int fd, /* do nothing */ break; default: - gf_msg("poll", GF_LOG_ERROR, 0, LG_MSG_INVALID_POLL_OUT, - "invalid poll_out value %d", poll_out); + gf_smsg("poll", GF_LOG_ERROR, 0, LG_MSG_INVALID_POLL_OUT, + "value=%d", poll_out, NULL); break; } @@ -257,8 +248,8 @@ event_unregister_poll(struct event_pool *event_pool, int fd, int idx_hint) 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); + 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; } @@ -298,8 +289,8 @@ event_select_on_poll(struct event_pool *event_pool, int fd, int idx_hint, 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); + 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; } @@ -361,10 +352,8 @@ event_dispatch_poll_handler(struct event_pool *event_pool, struct pollfd *ufds, 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); + gf_smsg("poll", GF_LOG_ERROR, 0, LG_MSG_INDEX_NOT_FOUND, "fd=%d", + ufds[i].fd, "idx_hint=%d", i, NULL); goto unlock; } diff --git a/libglusterfs/src/event.c b/libglusterfs/src/event.c index 235128b6044..402c253ca25 100644 --- a/libglusterfs/src/event.c +++ b/libglusterfs/src/event.c @@ -17,6 +17,7 @@ #include <string.h> #include "glusterfs/gf-event.h" +#include "glusterfs/timespec.h" #include "glusterfs/common-utils.h" #include "glusterfs/libglusterfs-messages.h" #include "glusterfs/syscall.h" @@ -266,7 +267,7 @@ gf_event_dispatch_destroy(struct event_pool *event_pool) if (sys_write(fd[1], "dummy", 6) == -1) { break; } - clock_gettime(CLOCK_REALTIME, &sleep_till); + timespec_now_realtime(&sleep_till); sleep_till.tv_sec += 1; ret = pthread_cond_timedwait(&event_pool->cond, &event_pool->mutex, &sleep_till); diff --git a/libglusterfs/src/events.c b/libglusterfs/src/events.c index 25097675a9e..33157549897 100644 --- a/libglusterfs/src/events.c +++ b/libglusterfs/src/events.c @@ -34,62 +34,66 @@ _gf_event(eventtypes_t event, const char *fmt, ...) int ret = 0; int sock = -1; char *eventstr = NULL; - struct sockaddr_in server; 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; + ctx = this->ctx; if (event < 0 || event >= EVENT_LAST) { ret = EVENT_ERROR_INVALID_INPUTS; goto out; } - /* Initialize UDP socket */ - sock = socket(AF_INET, SOCK_DGRAM, 0); - if (sock < 0) { - ret = EVENT_ERROR_SOCKET; - 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; - /* Get Host name to send message */ - if (ctx && ctx->cmd_args.volfile_server) { - /* If it is client code then volfile_server is set - use that information to push the events. */ - if ((getaddrinfo(ctx->cmd_args.volfile_server, NULL, &hints, - &result)) != 0) { - ret = EVENT_ERROR_RESOLVE; - goto out; - } + if ((getaddrinfo(host, TOSTRING(EVENT_PORT), &hints, &result)) != 0) { + ret = EVENT_ERROR_RESOLVE; + goto out; + } - if (get_ip_from_addrinfo(result, &host) == NULL) { - 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; } - } else { - /* Localhost, Use the defined IP for localhost */ - host = gf_strdup(EVENT_HOST); } - - /* Socket Configurations */ - server.sin_family = AF_INET; - server.sin_port = htons(EVENT_PORT); - ret = inet_pton(server.sin_family, host, &server.sin_addr); - if (ret <= 0) { - gf_msg(this->name, GF_LOG_ERROR, EINVAL, LG_MSG_INVALID_ARG, - "inet_pton failed with return code %d", ret); + /* + * 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; } - memset(&server.sin_zero, '\0', sizeof(server.sin_zero)); va_start(arguments, fmt); ret = gf_vasprintf(&msg, fmt, arguments); @@ -100,16 +104,16 @@ _gf_event(eventtypes_t event, const char *fmt, ...) goto out; } - ret = gf_asprintf(&eventstr, "%u %d %s", (unsigned)time(NULL), event, msg); - + 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, (struct sockaddr *)&server, - sizeof(server)) <= 0) { + if (sendto(sock, eventstr, strlen(eventstr), 0, result->ai_addr, + result->ai_addrlen) <= 0) { ret = EVENT_ERROR_SEND; goto out; } @@ -121,17 +125,10 @@ out: sys_close(sock); } - /* Allocated by gf_vasprintf */ - if (msg) - GF_FREE(msg); - /* Allocated by gf_asprintf */ if (eventstr) GF_FREE(eventstr); - if (host) - GF_FREE(host); - if (result) freeaddrinfo(result); diff --git a/libglusterfs/src/fd.c b/libglusterfs/src/fd.c index e0767a7e61f..62606e91164 100644 --- a/libglusterfs/src/fd.c +++ b/libglusterfs/src/fd.c @@ -502,6 +502,32 @@ out: } void +fd_close(fd_t *fd) +{ + xlator_t *xl, *old_THIS; + + old_THIS = THIS; + + 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)) { + if (xl->cbks->fdclosedir != NULL) { + xl->cbks->fdclosedir(xl, fd); + } + } else { + if (xl->cbks->fdclose != NULL) { + xl->cbks->fdclose(xl, fd); + } + } + } + } + + THIS = old_THIS; +} + +void fd_unref(fd_t *fd) { int32_t refcount = 0; diff --git a/libglusterfs/src/gf-dirent.c b/libglusterfs/src/gf-dirent.c index 9c8c74beb54..a809efc97ef 100644 --- a/libglusterfs/src/gf-dirent.c +++ b/libglusterfs/src/gf-dirent.c @@ -276,7 +276,7 @@ gf_fill_iatt_for_dirent(gf_dirent_t *entry, inode_t *parent, xlator_t *subvol) gf_uuid_copy(loc.pargfid, parent->gfid); loc.name = entry->d_name; loc.parent = inode_ref(parent); - ret = inode_path(loc.inode, entry->d_name, &path); + ret = inode_path(loc.parent, entry->d_name, &path); loc.path = path; if (ret < 0) goto out; diff --git a/libglusterfs/src/gfdb/Makefile.am b/libglusterfs/src/gfdb/Makefile.am deleted file mode 100644 index 3931e694c24..00000000000 --- a/libglusterfs/src/gfdb/Makefile.am +++ /dev/null @@ -1,37 +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 \ - -I$(top_srcdir)/rpc/xdr/src \ - -I$(top_builddir)/rpc/xdr/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_data_store_helper.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 \ - gfdb_data_store_helper.h - -libgfdb_HEADERS = gfdb_data_store.h gfdb_data_store_types.h \ - gfdb_data_store_helper.h gfdb_sqlite3.h gfdb_mem-types.h \ - gfdb_sqlite3_helper.h - -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 02894cf7785..00000000000 --- a/libglusterfs/src/gfdb/gfdb_data_store.c +++ /dev/null @@ -1,802 +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 "glusterfs/list.h" -#include "glusterfs/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; - goto out; - /*TODO What if the unlock fails. - * Will it lead to deadlock? - * Most of the gluster code - * no check for unlock or destroy 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 destroy 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 connection 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."); - 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"); - goto init_db_failed; - } - _conn_node->gfdb_connection.gfdb_db_type = gfdb_db_type; - - 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 separate 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, - _gfdb_log_level(GF_LOG_ERROR, gfdb_db_record->ignore_errors), - 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: Compact the database. - * - * Arguments: - * _conn_node : GFDB Connection node - * _compact_active : Is compaction currently on? - * _compact_mode_switched : Was the compaction switch flipped? - * Returns : if successful return 0 or - * -ve value in case of failure*/ -int -compact_db(gfdb_conn_node_t *_conn_node, gf_boolean_t _compact_active, - gf_boolean_t _compact_mode_switched) -{ - 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->compact_db_op) { - ret = db_operations_t->compact_db_op(gf_db_connection, _compact_active, - _compact_mode_switched); - if (ret) { - gf_msg(GFDB_DATA_STORE, GF_LOG_ERROR, 0, LG_MSG_COMPACT_FAILED, - "Compaction 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 - * query_limit : number to limit number of rows returned by the query - * 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 query_limit) -{ - 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, query_limit); - 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 = NULL; - void *gf_db_connection = NULL; - - CHECK_CONN_NODE(conn_node); - - db_operations = &conn_node->gfdb_connection.gfdb_db_operations; - gf_db_connection = conn_node->gfdb_connection.gf_db_connection; - - if (db_operations->clear_files_heat_op) { - ret = db_operations->clear_files_heat_op(gf_db_connection); - if (ret) { - gf_msg(GFDB_DATA_STORE, GF_LOG_ERROR, 0, - LG_MSG_INSERT_OR_UPDATE_FAILED, - "Clear files heat operation failed"); - } - } - - return ret; -} - -/* Libgfdb API Function: Function to extract version of the db - * Input: - * gfdb_conn_node_t *conn_node : GFDB Connection node - * char **version : the version is extracted as a string and will be stored in - * this variable. The freeing of the memory should be done by - * the caller. - * Return: - * On success return the length of the version string that is - * extracted. - * On failure return -1 - * */ -int -get_db_version(gfdb_conn_node_t *conn_node, char **version) -{ - int ret = 0; - gfdb_db_operations_t *db_operations = NULL; - void *gf_db_connection = NULL; - - CHECK_CONN_NODE(conn_node); - - db_operations = &conn_node->gfdb_connection.gfdb_db_operations; - gf_db_connection = conn_node->gfdb_connection.gf_db_connection; - - if (db_operations->get_db_version) { - ret = db_operations->get_db_version(gf_db_connection, version); - if (ret < 0) { - gf_msg(GFDB_DATA_STORE, GF_LOG_ERROR, 0, LG_MSG_FIND_OP_FAILED, - "Get version failed"); - } - } - - return ret; -} - -int -get_db_params(gfdb_conn_node_t *conn_node, char *param_key, char **param_value) -{ - int ret = -1; - gfdb_db_operations_t *db_operations = NULL; - void *gf_db_connection = NULL; - - CHECK_CONN_NODE(conn_node); - - db_operations = &conn_node->gfdb_connection.gfdb_db_operations; - gf_db_connection = conn_node->gfdb_connection.gf_db_connection; - - if (db_operations->get_db_params) { - ret = db_operations->get_db_params(gf_db_connection, param_key, - param_value); - if (ret < 0) { - gf_msg(GFDB_DATA_STORE, GF_LOG_ERROR, 0, LG_MSG_FIND_OP_FAILED, - "Get setting failed"); - } - } - - return ret; -} - -int -set_db_params(gfdb_conn_node_t *conn_node, char *param_key, char *param_value) -{ - int ret = -1; - gfdb_db_operations_t *db_operations = NULL; - void *gf_db_connection = NULL; - - CHECK_CONN_NODE(conn_node); - - db_operations = &conn_node->gfdb_connection.gfdb_db_operations; - gf_db_connection = conn_node->gfdb_connection.gf_db_connection; - - if (db_operations->set_db_params) { - ret = db_operations->set_db_params(gf_db_connection, param_key, - param_value); - if (ret < 0) { - gf_msg(GFDB_DATA_STORE, GF_LOG_ERROR, 0, - LG_MSG_INSERT_OR_UPDATE_FAILED, - "Failed to set database setting"); - } - } - - 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_all = find_all; - 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->clear_files_heat = clear_files_heat; - methods->get_db_version = get_db_version; - methods->get_db_params = get_db_params; - methods->set_db_params = set_db_params; - methods->get_db_path_key = get_db_path_key; - - /* Query Record related functions */ - methods->gfdb_query_record_new = gfdb_query_record_new; - methods->gfdb_query_record_free = gfdb_query_record_free; - methods->gfdb_add_link_to_query_record = gfdb_add_link_to_query_record; - methods->gfdb_write_query_record = gfdb_write_query_record; - methods->gfdb_read_query_record = gfdb_read_query_record; - - /* Link info related functions */ - methods->gfdb_link_info_new = gfdb_link_info_new; - methods->gfdb_link_info_free = gfdb_link_info_free; - - /* Compaction related functions */ - methods->compact_db = compact_db; -} diff --git a/libglusterfs/src/gfdb/gfdb_data_store.h b/libglusterfs/src/gfdb/gfdb_data_store.h deleted file mode 100644 index 55b2fb1bc55..00000000000 --- a/libglusterfs/src/gfdb/gfdb_data_store.h +++ /dev/null @@ -1,331 +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/glusterfs.h" -#include "glusterfs/xlator.h" -#include "glusterfs/logging.h" -#include "glusterfs/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 separate 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 - * query_limit : 0 - umlimited, - * any positive value - adds the LIMIT clause - * to the SQL query - * - * 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, int query_limit); - -typedef int (*find_all_t)(gfdb_conn_node_t *, - gf_query_callback_t query_callback, - void *_query_cbk_args, int query_limit); - -/*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 int (*clear_files_heat_t)(gfdb_conn_node_t *_conn_node); - -/* Libgfdb API Function: Function to extract version of the db - * Arguments: - * gfdb_conn_node_t *_conn_node : GFDB Connection node - * char **version : the version is extracted as a string - * and will be stored in this variable. - * The freeing of the memory should be done by the caller. - * Return: - * On success return the length of the version string that is - * extracted. - * On failure return -1 - * */ -int -get_db_version(gfdb_conn_node_t *_conn_node, char **version); - -typedef int (*get_db_version_t)(gfdb_conn_node_t *_conn_node, char **version); - -/* Libgfdb API Function: Function to extract param from the db - * Arguments: - * gfdb_conn_node_t *_conn_node : GFDB Connection node - * char *param_key : param to be extracted - * char **param_value : the value of the param that is - * extracted. This function will allocate memory - * to pragma_value. The caller should free the memory. - * Return: - * On success return the length of the param value that is - * extracted. - * On failure return -1 - * */ -int -get_db_params(gfdb_conn_node_t *_conn_node, char *param_key, - char **param_value); - -typedef int (*get_db_params_t)(gfdb_conn_node_t *db_conn, char *param_key, - char **param_value); - -/* Libgfdb API Function: Function to set db params - * Arguments: - * gfdb_conn_node_t *_conn_node : GFDB Connection node - * char *param_key : param to be set - * char *param_value : param value - * Return: - * On success return 0 - * On failure return -1 - * */ -int -set_db_params(gfdb_conn_node_t *_conn_node, char *param_key, char *param_value); - -typedef int (*set_db_params_t)(gfdb_conn_node_t *db_conn, char *param_key, - char *param_value); - -/*Libgfdb API Function: Compact the database. - * - * Arguments: - * _conn_node : GFDB Connection node - * _compact_active : Is compaction currently on? - * _compact_mode_switched : Was the compaction switch flipped? - * Returns : if successful return 0 or - * -ve value in case of failure*/ -int -compact_db(gfdb_conn_node_t *_conn_node, gf_boolean_t _compact_active, - gf_boolean_t _compact_mode_switched); - -typedef int (*compact_db_t)(gfdb_conn_node_t *db_conn, - gf_boolean_t compact_active, - gf_boolean_t compact_mode_switched); - -typedef struct gfdb_methods_s { - init_db_t init_db; - fini_db_t fini_db; - find_all_t find_all; - 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; - clear_files_heat_t clear_files_heat; - get_db_version_t get_db_version; - get_db_params_t get_db_params; - set_db_params_t set_db_params; - /* 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; - - /* Query Record related functions */ - gfdb_query_record_new_t gfdb_query_record_new; - gfdb_query_record_free_t gfdb_query_record_free; - gfdb_add_link_to_query_record_t gfdb_add_link_to_query_record; - gfdb_write_query_record_t gfdb_write_query_record; - gfdb_read_query_record_t gfdb_read_query_record; - - /* Link info related functions */ - gfdb_link_info_new_t gfdb_link_info_new; - gfdb_link_info_free_t gfdb_link_info_free; - - /* Compaction related functions */ - compact_db_t compact_db; -} 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_helper.c b/libglusterfs/src/gfdb/gfdb_data_store_helper.c deleted file mode 100644 index 5f33312ad9b..00000000000 --- a/libglusterfs/src/gfdb/gfdb_data_store_helper.c +++ /dev/null @@ -1,588 +0,0 @@ - -#include "gfdb_data_store_helper.h" -#include "glusterfs/syscall.h" - -/****************************************************************************** - * - * Query record related functions - * - * ****************************************************************************/ - -/*Create a single link info structure*/ -gfdb_link_info_t * -gfdb_link_info_new() -{ - gfdb_link_info_t *link_info = NULL; - - link_info = GF_CALLOC(1, sizeof(gfdb_link_info_t), gf_mt_gfdb_link_info_t); - if (!link_info) { - gf_msg(GFDB_DATA_STORE, GF_LOG_ERROR, ENOMEM, LG_MSG_NO_MEMORY, - "Memory allocation failed for " - "link_info "); - goto out; - } - - INIT_LIST_HEAD(&link_info->list); - -out: - - return link_info; -} - -/*Destroy a link info structure*/ -void -gfdb_link_info_free(gfdb_link_info_t *link_info) -{ - GF_FREE(link_info); -} - -/*Function to create the query_record*/ -gfdb_query_record_t * -gfdb_query_record_new() -{ - int ret = -1; - gfdb_query_record_t *query_record = NULL; - - query_record = GF_CALLOC(1, sizeof(gfdb_query_record_t), - gf_mt_gfdb_query_record_t); - if (!query_record) { - gf_msg(GFDB_DATA_STORE, GF_LOG_ERROR, ENOMEM, LG_MSG_NO_MEMORY, - "Memory allocation failed for " - "query_record "); - goto out; - } - - INIT_LIST_HEAD(&query_record->link_list); - - ret = 0; -out: - if (ret == -1) { - GF_FREE(query_record); - } - return query_record; -} - -/*Function to delete a single linkinfo from list*/ -static void -gfdb_delete_linkinfo_from_list(gfdb_link_info_t **link_info) -{ - GF_VALIDATE_OR_GOTO(GFDB_DATA_STORE, link_info, out); - GF_VALIDATE_OR_GOTO(GFDB_DATA_STORE, *link_info, out); - - /*Remove hard link from list*/ - list_del(&(*link_info)->list); - gfdb_link_info_free(*link_info); - link_info = NULL; -out: - return; -} - -/*Function to destroy link_info list*/ -void -gfdb_free_link_info_list(gfdb_query_record_t *query_record) -{ - gfdb_link_info_t *link_info = NULL; - gfdb_link_info_t *temp = NULL; - - GF_VALIDATE_OR_GOTO(GFDB_DATA_STORE, query_record, out); - - list_for_each_entry_safe(link_info, temp, &query_record->link_list, list) - { - gfdb_delete_linkinfo_from_list(&link_info); - link_info = NULL; - } - -out: - return; -} - -/* Function to add linkinfo to the query record */ -int -gfdb_add_link_to_query_record(gfdb_query_record_t *query_record, uuid_t pgfid, - char *base_name) -{ - int ret = -1; - gfdb_link_info_t *link_info = NULL; - int base_name_len = 0; - - GF_VALIDATE_OR_GOTO(GFDB_DATA_STORE, query_record, out); - GF_VALIDATE_OR_GOTO(GFDB_DATA_STORE, pgfid, out); - GF_VALIDATE_OR_GOTO(GFDB_DATA_STORE, base_name, out); - - link_info = gfdb_link_info_new(); - if (!link_info) { - goto out; - } - - gf_uuid_copy(link_info->pargfid, pgfid); - base_name_len = strlen(base_name); - memcpy(link_info->file_name, base_name, base_name_len); - link_info->file_name[base_name_len] = '\0'; - - list_add_tail(&link_info->list, &query_record->link_list); - - query_record->link_count++; - - ret = 0; -out: - if (ret) { - gfdb_link_info_free(link_info); - link_info = NULL; - } - return ret; -} - -/*Function to destroy query record*/ -void -gfdb_query_record_free(gfdb_query_record_t *query_record) -{ - if (query_record) { - gfdb_free_link_info_list(query_record); - GF_FREE(query_record); - } -} - -/****************************************************************************** - SERIALIZATION/DE-SERIALIZATION OF QUERY RECORD -*******************************************************************************/ -/****************************************************************************** - The on disk format of query record is as follows, - -+---------------------------------------------------------------------------+ -| Length of serialized query record | Serialized Query Record | -+---------------------------------------------------------------------------+ - 4 bytes Length of serialized query record - | - | - -------------------------------------------------| - | - | - V - Serialized Query Record Format: - +---------------------------------------------------------------------------+ - | GFID | Link count | <LINK INFO> |..... | FOOTER | - +---------------------------------------------------------------------------+ - 16 B 4 B Link Length 4 B - | | - | | - -----------------------------| | - | | - | | - V | - Each <Link Info> will be serialized as | - +-----------------------------------------------+ | - | PGID | BASE_NAME_LENGTH | BASE_NAME | | - +-----------------------------------------------+ | - 16 B 4 B BASE_NAME_LENGTH | - | - | - ------------------------------------------------------------------------| - | - | - V - FOOTER is a magic number 0xBAADF00D indicating the end of the record. - This also serves as a serialized schema validator. - * ****************************************************************************/ - -#define GFDB_QUERY_RECORD_FOOTER 0xBAADF00D -#define UUID_LEN 16 - -/*Function to get the potential length of the serialized buffer*/ -static int32_t -gfdb_query_record_serialized_length(gfdb_query_record_t *query_record) -{ - int32_t len = -1; - gfdb_link_info_t *link_info = NULL; - - GF_VALIDATE_OR_GOTO(GFDB_DATA_STORE, query_record, out); - - /* Length of GFID */ - len = UUID_LEN; - - /* length of number of links*/ - len += sizeof(int32_t); - - list_for_each_entry(link_info, &query_record->link_list, list) - { - /* length of PFID */ - len += UUID_LEN; - - /* Add size of base name length*/ - len += sizeof(int32_t); - - /* Length of base_name */ - len += strlen(link_info->file_name); - } - - /* length of footer */ - len += sizeof(int32_t); -out: - return len; -} - -/* Function for serializing query record. - * - * Query Record Serialization Format - * +---------------------------------------------------------------------------+ - * | GFID | Link count | <LINK INFO> |..... | FOOTER | - * +---------------------------------------------------------------------------+ - * 16 B 4 B Link Length 4 B - * - * - * Each <Link Info> will be serialized as - * +-----------------------------------------------+ - * | PGID | BASE_NAME_LENGTH | BASE_NAME | - * +-----------------------------------------------+ - * 16 B 4 B BASE_NAME_LENGTH - * - * - * FOOTER is a magic number 0xBAADF00D indicating the end of the record. - * This also serves as a serialized schema validator. - * - * The function will allocate memory to the serialized buffer, - * the caller needs to free it. - * Returns the length of the serialized buffer on success - * or -1 on failure. - * - * */ -static int -gfdb_query_record_serialize(gfdb_query_record_t *query_record, char **in_buffer) -{ - gfdb_link_info_t *link_info = NULL; - int count = -1; - int base_name_len = 0; - int buffer_length = 0; - int footer = GFDB_QUERY_RECORD_FOOTER; - char *buffer = NULL; - char *ret_buffer = NULL; - - GF_VALIDATE_OR_GOTO(GFDB_DATA_STORE, query_record, out); - GF_VALIDATE_OR_GOTO(GFDB_DATA_STORE, (query_record->link_count > 0), out); - GF_VALIDATE_OR_GOTO(GFDB_DATA_STORE, in_buffer, out); - - /* Calculate the total length of the serialized buffer */ - buffer_length = gfdb_query_record_serialized_length(query_record); - if (buffer_length <= 0) { - gf_msg(GFDB_DATA_STORE, GF_LOG_ERROR, 0, LG_MSG_DB_ERROR, - "Failed to calculate the length of " - "serialized buffer"); - goto out; - } - - /* Allocate memory to the serialized buffer */ - ret_buffer = GF_CALLOC(1, buffer_length, gf_common_mt_char); - if (!ret_buffer) { - gf_msg(GFDB_DATA_STORE, GF_LOG_ERROR, 0, LG_MSG_DB_ERROR, - "Memory allocation failed for " - "serialized buffer."); - goto out; - } - - buffer = ret_buffer; - - count = 0; - - /* Copying the GFID */ - memcpy(buffer, query_record->gfid, UUID_LEN); - buffer += UUID_LEN; - count += UUID_LEN; - - /* Copying the number of links */ - memcpy(buffer, &query_record->link_count, sizeof(int32_t)); - buffer += sizeof(int32_t); - count += sizeof(int32_t); - - list_for_each_entry(link_info, &query_record->link_list, list) - { - /* Copying the PFID */ - memcpy(buffer, link_info->pargfid, UUID_LEN); - buffer += UUID_LEN; - count += UUID_LEN; - - /* Copying base name length*/ - base_name_len = strlen(link_info->file_name); - memcpy(buffer, &base_name_len, sizeof(int32_t)); - buffer += sizeof(int32_t); - count += sizeof(int32_t); - - /* Length of base_name */ - memcpy(buffer, link_info->file_name, base_name_len); - buffer += base_name_len; - count += base_name_len; - } - - /* Copying the Footer of the record */ - memcpy(buffer, &footer, sizeof(int32_t)); - count += sizeof(int32_t); - -out: - if (count < 0) { - GF_FREE(ret_buffer); - ret_buffer = NULL; - } - *in_buffer = ret_buffer; - return count; -} - -static gf_boolean_t -is_serialized_buffer_valid(char *in_buffer, int buffer_length) -{ - gf_boolean_t ret = _gf_false; - int footer = 0; - - /* Read the footer */ - in_buffer += (buffer_length - sizeof(int32_t)); - memcpy(&footer, in_buffer, sizeof(int32_t)); - - /* - * if the footer is not GFDB_QUERY_RECORD_FOOTER - * then the serialized record is invalid - * - * */ - if (footer != GFDB_QUERY_RECORD_FOOTER) { - goto out; - } - - ret = _gf_true; -out: - return ret; -} - -static int -gfdb_query_record_deserialize(char *in_buffer, int buffer_length, - gfdb_query_record_t **query_record) -{ - int ret = -1; - char *buffer = NULL; - int i = 0; - gfdb_link_info_t *link_info = NULL; - int count = 0; - int base_name_len = 0; - gfdb_query_record_t *ret_qrecord = NULL; - - GF_VALIDATE_OR_GOTO(GFDB_DATA_STORE, in_buffer, out); - GF_VALIDATE_OR_GOTO(GFDB_DATA_STORE, query_record, out); - GF_VALIDATE_OR_GOTO(GFDB_DATA_STORE, (buffer_length > 0), out); - - if (!is_serialized_buffer_valid(in_buffer, buffer_length)) { - gf_msg(GFDB_DATA_STORE, GF_LOG_ERROR, 0, LG_MSG_DB_ERROR, - "Invalid serialized query record"); - goto out; - } - - buffer = in_buffer; - - ret_qrecord = gfdb_query_record_new(); - if (!ret_qrecord) { - gf_msg(GFDB_DATA_STORE, GF_LOG_ERROR, 0, LG_MSG_DB_ERROR, - "Failed to allocate space to " - "gfdb_query_record_t"); - goto out; - } - - /* READ GFID */ - memcpy((ret_qrecord)->gfid, buffer, UUID_LEN); - buffer += UUID_LEN; - count += UUID_LEN; - - /* Read the number of link */ - memcpy(&(ret_qrecord->link_count), buffer, sizeof(int32_t)); - buffer += sizeof(int32_t); - count += sizeof(int32_t); - - /* Read all the links */ - for (i = 0; i < ret_qrecord->link_count; i++) { - if (count >= buffer_length) { - gf_msg(GFDB_DATA_STORE, GF_LOG_ERROR, 0, LG_MSG_DB_ERROR, - "Invalid serialized " - "query record"); - ret = -1; - goto out; - } - - link_info = gfdb_link_info_new(); - if (!link_info) { - gf_msg(GFDB_DATA_STORE, GF_LOG_ERROR, 0, LG_MSG_DB_ERROR, - "Failed to create link_info"); - goto out; - } - - /* READ PGFID */ - memcpy(link_info->pargfid, buffer, UUID_LEN); - buffer += UUID_LEN; - count += UUID_LEN; - - /* Read base name length */ - memcpy(&base_name_len, buffer, sizeof(int32_t)); - buffer += sizeof(int32_t); - count += sizeof(int32_t); - - /* READ basename */ - memcpy(link_info->file_name, buffer, base_name_len); - buffer += base_name_len; - count += base_name_len; - link_info->file_name[base_name_len] = '\0'; - - /* Add link_info to the list */ - list_add_tail(&link_info->list, &(ret_qrecord->link_list)); - - /* Resetting link_info */ - link_info = NULL; - } - - ret = 0; -out: - if (ret) { - gfdb_query_record_free(ret_qrecord); - ret_qrecord = NULL; - } - *query_record = ret_qrecord; - return ret; -} - -/* Function to write query record to file - * - * Disk format - * +---------------------------------------------------------------------------+ - * | Length of serialized query record | Serialized Query Record | - * +---------------------------------------------------------------------------+ - * 4 bytes Length of serialized query record - * - * Please refer gfdb_query_record_serialize () for format of - * Serialized Query Record - * - * */ -int -gfdb_write_query_record(int fd, gfdb_query_record_t *query_record) -{ - int ret = -1; - int buffer_len = 0; - char *buffer = NULL; - int write_len = 0; - char *write_buffer = NULL; - - GF_VALIDATE_OR_GOTO(GFDB_DATA_STORE, (fd >= 0), out); - GF_VALIDATE_OR_GOTO(GFDB_DATA_STORE, query_record, out); - - buffer_len = gfdb_query_record_serialize(query_record, &buffer); - if (buffer_len < 0) { - gf_msg(GFDB_DATA_STORE, GF_LOG_ERROR, 0, LG_MSG_DB_ERROR, - "Failed to serialize query record"); - goto out; - } - - /* Serialize the buffer length and write to file */ - ret = write(fd, &buffer_len, sizeof(int32_t)); - if (ret < 0) { - gf_msg(GFDB_DATA_STORE, GF_LOG_ERROR, 0, LG_MSG_DB_ERROR, - "Failed to write buffer length" - " to file"); - goto out; - } - - /* Write the serialized query record to file */ - write_len = buffer_len; - write_buffer = buffer; - while ((ret = write(fd, write_buffer, write_len)) < write_len) { - if (ret < 0) { - gf_msg(GFDB_DATA_STORE, GF_LOG_ERROR, errno, LG_MSG_DB_ERROR, - "Failed to write serialized " - "query record to file"); - goto out; - } - - write_buffer += ret; - write_len -= ret; - } - - ret = 0; -out: - GF_FREE(buffer); - return ret; -} - -/* Function to read query record from file. - * Allocates memory to query record and - * returns length of serialized query record when successful - * Return -1 when failed. - * Return 0 when reached EOF. - * */ -int -gfdb_read_query_record(int fd, gfdb_query_record_t **query_record) -{ - int ret = -1; - int buffer_len = 0; - int read_len = 0; - char *buffer = NULL; - char *read_buffer = NULL; - - GF_VALIDATE_OR_GOTO(GFDB_DATA_STORE, (fd >= 0), out); - GF_VALIDATE_OR_GOTO(GFDB_DATA_STORE, query_record, out); - - /* Read serialized query record length from the file*/ - ret = sys_read(fd, &buffer_len, sizeof(int32_t)); - if (ret < 0) { - gf_msg(GFDB_DATA_STORE, GF_LOG_ERROR, 0, LG_MSG_DB_ERROR, - "Failed reading buffer length" - " from file"); - goto out; - } - /* EOF */ - else if (ret == 0) { - ret = 0; - goto out; - } - - /* Assumed sane range is 1B - 10MB */ - if ((buffer_len <= 0) || (buffer_len > (10 * 1024 * 1024))) { - ret = -1; - gf_msg(GFDB_DATA_STORE, GF_LOG_ERROR, 0, LG_MSG_DB_ERROR, - "buffer length range is out of bound %d", buffer_len); - goto out; - } - - /* Allocating memory to the serialization buffer */ - buffer = GF_CALLOC(1, buffer_len, gf_common_mt_char); - if (!buffer) { - gf_msg(GFDB_DATA_STORE, GF_LOG_ERROR, 0, LG_MSG_DB_ERROR, - "Failed to allocate space to " - "serialized buffer"); - goto out; - } - - /* Read the serialized query record from file */ - read_len = buffer_len; - read_buffer = buffer; - while ((ret = sys_read(fd, read_buffer, read_len)) < read_len) { - /*Any error */ - if (ret < 0) { - gf_msg(GFDB_DATA_STORE, GF_LOG_ERROR, errno, LG_MSG_DB_ERROR, - "Failed to read serialized " - "query record from file"); - goto out; - } - /* EOF */ - else if (ret == 0) { - gf_msg(GFDB_DATA_STORE, GF_LOG_ERROR, 0, LG_MSG_DB_ERROR, - "Invalid query record or " - "corrupted query file"); - ret = -1; - goto out; - } - - read_buffer += ret; - read_len -= ret; - } - - ret = gfdb_query_record_deserialize(buffer, buffer_len, query_record); - if (ret) { - gf_msg(GFDB_DATA_STORE, GF_LOG_ERROR, 0, LG_MSG_DB_ERROR, - "Failed to de-serialize query record"); - goto out; - } - - ret = buffer_len; -out: - GF_FREE(buffer); - return ret; -} diff --git a/libglusterfs/src/gfdb/gfdb_data_store_helper.h b/libglusterfs/src/gfdb/gfdb_data_store_helper.h deleted file mode 100644 index 3c4499bdd3b..00000000000 --- a/libglusterfs/src/gfdb/gfdb_data_store_helper.h +++ /dev/null @@ -1,95 +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_HELPER_H -#define __GFDB_DATA_STORE_HELPER_H - -#include <time.h> -#include <sys/time.h> -#include <string.h> -#include <fcntl.h> - -#include "glusterfs/common-utils.h" -#include "glusterfs/compat-uuid.h" -#include "gfdb_mem-types.h" -#include "glusterfs/dict.h" -#include "glusterfs/byte-order.h" -#include "glusterfs/libglusterfs-messages.h" - -#define GFDB_DATA_STORE "gfdbdatastore" - -/******************************************************************************* - * - * Query related data structure and functions - * - * ****************************************************************************/ - -#ifdef NAME_MAX -#define GF_NAME_MAX NAME_MAX -#else -#define GF_NAME_MAX 255 -#endif - -/*Structure to hold the link information*/ -typedef struct gfdb_link_info { - uuid_t pargfid; - char file_name[GF_NAME_MAX]; - struct list_head list; -} gfdb_link_info_t; - -/*Structure used for querying purpose*/ -typedef struct gfdb_query_record { - uuid_t gfid; - /*This is the hardlink list*/ - struct list_head link_list; - int link_count; -} gfdb_query_record_t; - -/*Create a single link info structure*/ -gfdb_link_info_t * -gfdb_link_info_new(); -typedef gfdb_link_info_t *(*gfdb_link_info_new_t)(); - -/*Destroy a link info structure*/ -void -gfdb_link_info_free(gfdb_link_info_t *gfdb_link_info); -typedef void (*gfdb_link_info_free_t)(gfdb_link_info_t *gfdb_link_info); - -/* Function to create the query_record */ -gfdb_query_record_t * -gfdb_query_record_new(); -typedef gfdb_query_record_t *(*gfdb_query_record_new_t)(); - -/* Function to add linkinfo to query record */ -int -gfdb_add_link_to_query_record(gfdb_query_record_t *gfdb_query_record, - uuid_t pgfid, char *base_name); -typedef int (*gfdb_add_link_to_query_record_t)(gfdb_query_record_t *, uuid_t, - char *); - -/*Function to destroy query record*/ -void -gfdb_query_record_free(gfdb_query_record_t *gfdb_query_record); -typedef void (*gfdb_query_record_free_t)(gfdb_query_record_t *); - -/* Function to write query record to file */ -int -gfdb_write_query_record(int fd, gfdb_query_record_t *gfdb_query_record); -typedef int (*gfdb_write_query_record_t)(int, gfdb_query_record_t *); - -/* Function to read query record from file. - * Allocates memory to query record and return 0 when successful - * Return -1 when failed. - * Return 0 when EOF. - * */ -int -gfdb_read_query_record(int fd, gfdb_query_record_t **gfdb_query_record); -typedef int (*gfdb_read_query_record_t)(int, gfdb_query_record_t **); - -#endif
\ No newline at end of file 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 5ee050d4fab..00000000000 --- a/libglusterfs/src/gfdb/gfdb_data_store_types.h +++ /dev/null @@ -1,532 +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 "gfdb_data_store_helper.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, - GFDB_DB_COMPACT_DB_OP /* Added for VACUUM/manual compaction support */ -} 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_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_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 { - /* GFID */ - uuid_t gfid; - /* Used during a rename refer ctr_rename() in changetimerecorder - * xlator*/ - uuid_t old_gfid; - /* Parent GFID */ - uuid_t pargfid; - uuid_t old_pargfid; - /* File names */ - char file_name[GF_NAME_MAX + 1]; - char old_file_name[GF_NAME_MAX + 1]; - /* FOP type and FOP path*/ - 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 consistency 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; - -/******************************************************************************* - * - * 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); - -/*Used to compact the database - * Arguments: - * db_conn : GFDB Connection node - * compact_active : Is compaction currently on? - * compact_mode_switched : Was the compaction switch flipped? - * Returns : if successful return 0 or - * -ve value in case of failure*/ -typedef int (*gfdb_compact_db_t)(void *db_conn, gf_boolean_t compact_active, - gf_boolean_t compact_mode_switched); - -/* 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 - * query_limit : 0 - list all files - * positive value - add the LIMIT clause to - * the SQL query to limit the number of records - * returned - * - * 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, int query_limit); - -/* 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); - -typedef int (*gfdb_get_db_version_t)(void *db_conn, char **version); - -typedef int (*gfdb_get_db_params_t)(void *db_conn, char *param_key, - char **param_value); - -typedef int (*gfdb_set_db_params_t)(void *db_conn, char *param_key, - char *param_value); - -/*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_compact_db_t compact_db_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_get_db_version_t get_db_version; - gfdb_get_db_params_t get_db_params; - gfdb_set_db_params_t set_db_params; -} 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); \ - data_destroy(data); \ - 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_TRACE, 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_mem-types.h b/libglusterfs/src/gfdb/gfdb_mem-types.h deleted file mode 100644 index b97cdf89446..00000000000 --- a/libglusterfs/src/gfdb/gfdb_mem-types.h +++ /dev/null @@ -1,17 +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 __GFDB_MEM_TYPES_H__ -#define __GFDB_MEM_TYPES_H__ - -#include "glusterfs/mem-types.h" - -enum gfdb_mem_types_ { gfdb_mtstart = gf_common_mt_end + 1, gfdb_mt_end }; -#endif diff --git a/libglusterfs/src/gfdb/gfdb_sqlite3.c b/libglusterfs/src/gfdb/gfdb_sqlite3.c deleted file mode 100644 index 98232d5e379..00000000000 --- a/libglusterfs/src/gfdb/gfdb_sqlite3.c +++ /dev/null @@ -1,1542 +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 "glusterfs/libglusterfs-messages.h" -#include "glusterfs/syscall.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_av_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_av_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 performance */ -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 performance */ -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->compact_db_op = gf_sqlite3_vacuum; - - 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; - - gfdb_db_ops->get_db_version = gf_sqlite3_version; - - gfdb_db_ops->get_db_params = gf_sqlite3_pragma; - - gfdb_db_ops->set_db_params = gf_sqlite3_set_pragma; -} - -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[GF_NAME_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 = (sys_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); - - 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, - _gfdb_log_level(GF_LOG_ERROR, - gfdb_db_record->ignore_errors), - 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, - _gfdb_log_level(GF_LOG_ERROR, - gfdb_db_record->ignore_errors), - 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, - _gfdb_log_level(GF_LOG_ERROR, - gfdb_db_record->ignore_errors), - 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, - _gfdb_log_level(GF_LOG_ERROR, - gfdb_db_record->ignore_errors), - 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 - * - * - * ***************************************************************************/ - -static int -gf_get_basic_query_stmt(char **out_stmt) -{ - int ret = -1; - ret = gf_asprintf(out_stmt, - "select GF_FILE_TB.GF_ID," - "GF_FLINK_TB.GF_PID ," - "GF_FLINK_TB.FNAME " - "from GF_FLINK_TB, GF_FILE_TB " - "where " - "GF_FILE_TB.GF_ID = GF_FLINK_TB.GF_ID "); - if (ret <= 0) { - gf_msg(GFDB_STR_SQLITE3, GF_LOG_ERROR, 0, LG_MSG_QUERY_FAILED, - "Failed to create base query statement"); - *out_stmt = NULL; - } - return ret; -} - -/* - * Find All files recorded in the DB - * Input: - * query_callback : query callback function 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 query_limit) -{ - int ret = -1; - char *query_str = NULL; - gf_sql_connection_t *sql_conn = db_conn; - sqlite3_stmt *prep_stmt = NULL; - char *limit_query = NULL; - char *query = NULL; - - CHECK_SQL_CONN(sql_conn, out); - GF_VALIDATE_OR_GOTO(GFDB_STR_SQLITE3, query_callback, out); - - ret = gf_get_basic_query_stmt(&query_str); - if (ret <= 0) { - goto out; - } - - query = query_str; - - if (query_limit > 0) { - ret = gf_asprintf(&limit_query, "%s LIMIT %d", query, query_limit); - if (ret < 0) { - gf_msg(GFDB_STR_SQLITE3, GF_LOG_ERROR, 0, LG_MSG_QUERY_FAILED, - "Failed creating limit query statement"); - limit_query = NULL; - goto out; - } - - query = limit_query; - } - - ret = sqlite3_prepare(sql_conn->sqlite3_db_conn, query, -1, &prep_stmt, 0); - if (ret != SQLITE_OK) { - gf_msg(GFDB_STR_SQLITE3, GF_LOG_ERROR, 0, LG_MSG_PREPARE_FAILED, - "Failed to prepare statement %s: %s", query, - 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); - goto out; - } - - ret = 0; -out: - sqlite3_finalize(prep_stmt); - GF_FREE(query_str); - - if (limit_query) - GF_FREE(limit_query); - - return ret; -} - -/* - * Find recently changed files from the DB - * Input: - * query_callback : query callback function 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; - char *base_query_str = NULL; - - CHECK_SQL_CONN(sql_conn, out); - GF_VALIDATE_OR_GOTO(GFDB_STR_SQLITE3, query_callback, out); - - ret = gf_get_basic_query_stmt(&base_query_str); - if (ret <= 0) { - goto out; - } - - ret = gf_asprintf( - &query_str, - "%s AND" - /*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 - ") >= ?) )" - /* Order by write wind time in a - * descending order i.e most hot - * files w.r.t to write */ - " ORDER BY GF_FILE_TB.W_SEC DESC", - base_query_str); - - if (ret < 0) { - gf_msg(GFDB_STR_SQLITE3, GF_LOG_ERROR, 0, LG_MSG_QUERY_FAILED, - "Failed creating query statement"); - query_str = NULL; - goto out; - } - - 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 to prepare statement %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 to bind 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 to bind 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); - GF_FREE(base_query_str); - GF_FREE(query_str); - return ret; -} - -/* - * Find unchanged files from a specified time from the DB - * Input: - * query_callback : query callback function 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; - char *base_query_str = NULL; - - CHECK_SQL_CONN(sql_conn, out); - GF_VALIDATE_OR_GOTO(GFDB_STR_SQLITE3, query_callback, out); - - ret = gf_get_basic_query_stmt(&base_query_str); - if (ret <= 0) { - goto out; - } - - ret = gf_asprintf( - &query_str, - "%s AND " - /*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 - ") <= ?) )" - /* Order by write wind time in a - * ascending order i.e most cold - * files w.r.t to write */ - " ORDER BY GF_FILE_TB.W_SEC ASC", - base_query_str); - - if (ret < 0) { - gf_msg(GFDB_STR_SQLITE3, GF_LOG_ERROR, 0, LG_MSG_QUERY_FAILED, - "Failed to create query statement"); - query_str = NULL; - goto out; - } - - 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 to prepare statement %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 to bind 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 to bind 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); - GF_FREE(base_query_str); - GF_FREE(query_str); - return ret; -} - -/* - * Find recently changed files with a specific frequency from the DB - * Input: - * db_conn : db connection object - * query_callback : query callback function 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; - char *base_query_str = NULL; - - CHECK_SQL_CONN(sql_conn, out); - GF_VALIDATE_OR_GOTO(GFDB_STR_SQLITE3, query_callback, out); - - ret = gf_get_basic_query_stmt(&base_query_str); - if (ret <= 0) { - goto out; - } - ret = gf_asprintf( - &query_str, - "%s AND " - /*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 - " >= ? ) ) )" - /* Order by write wind time and - * write freq in a descending - * order - * i.e most hot files w.r.t to - * write */ - " ORDER BY GF_FILE_TB.W_SEC " - "DESC, " - "GF_FILE_TB.WRITE_FREQ_CNTR DESC", - base_query_str); - - if (ret < 0) { - gf_msg(GFDB_STR_SQLITE3, GF_LOG_ERROR, 0, LG_MSG_QUERY_FAILED, - "Failed to create query statement"); - query_str = NULL; - goto out; - } - - 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 to prepare statement %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 to bind 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 to bind 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 to bind 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 to bind 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 to clear" - " counters!"); - goto out; - } - } - ret = 0; -out: - sqlite3_finalize(prep_stmt); - GF_FREE(base_query_str); - GF_FREE(query_str); - return ret; -} - -/* - * Find unchanged files from a specified time, w.r.t to frequency, from the DB - * Input: - * query_callback : query callback function 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; - char *base_query_str = NULL; - - CHECK_SQL_CONN(sql_conn, out); - GF_VALIDATE_OR_GOTO(GFDB_STR_SQLITE3, query_callback, out); - - ret = gf_get_basic_query_stmt(&base_query_str); - if (ret <= 0) { - goto out; - } - - ret = gf_asprintf (&query_str, "%s AND " - /*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 read_frequency less than freq_read_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 ") >= ? ) ) ) )" - /* Order by write wind time and write freq in ascending order - * i.e most cold files w.r.t to write */ - " ORDER BY GF_FILE_TB.W_SEC ASC, " - "GF_FILE_TB.WRITE_FREQ_CNTR ASC", - base_query_str); - - if (ret < 0) { - gf_msg(GFDB_STR_SQLITE3, GF_LOG_ERROR, 0, LG_MSG_QUERY_FAILED, - "Failed to create query statement"); - query_str = NULL; - goto out; - } - - 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 to prepare delete " - "statement %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 to bind 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 to bind 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 to bind 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 to bind 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 to bind 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 to bind 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 to clear " - "counters!"); - goto out; - } - } - - ret = 0; -out: - sqlite3_finalize(prep_stmt); - GF_FREE(base_query_str); - GF_FREE(query_str); - 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 to clear " - "files heat"); - goto out; - } - - ret = 0; -out: - return ret; -} - -/* Function to extract version of sqlite db - * Input: - * void *db_conn : Sqlite connection - * char **version : the version is extracted as a string and will be stored in - * this variable. The freeing of the memory should be done by - * the caller. - * Return: - * On success return the length of the version string that is - * extracted. - * On failure return -1 - * */ -int -gf_sqlite3_version(void *db_conn, char **version) -{ - int ret = -1; - gf_sql_connection_t *sql_conn = db_conn; - sqlite3_stmt *pre_stmt = NULL; - - CHECK_SQL_CONN(sql_conn, out); - - ret = sqlite3_prepare_v2(sql_conn->sqlite3_db_conn, - "SELECT SQLITE_VERSION()", -1, &pre_stmt, 0); - if (ret != SQLITE_OK) { - gf_msg(GFDB_STR_SQLITE3, GF_LOG_ERROR, 0, LG_MSG_PREPARE_FAILED, - "Failed init prepare stmt %s", sqlite3_errmsg(db_conn)); - ret = -1; - goto out; - } - - ret = sqlite3_step(pre_stmt); - if (ret != SQLITE_ROW) { - gf_msg(GFDB_STR_SQLITE3, GF_LOG_ERROR, 0, LG_MSG_GET_RECORD_FAILED, - "Failed to get records " - "from db : %s", - sqlite3_errmsg(db_conn)); - ret = -1; - goto out; - } - - ret = gf_asprintf(version, "%s", sqlite3_column_text(pre_stmt, 0)); - if (ret <= 0) { - gf_msg(GFDB_STR_SQLITE3, GF_LOG_ERROR, 0, LG_MSG_QUERY_FAILED, - "Failed extracting version"); - } - -out: - sqlite3_finalize(pre_stmt); - - return ret; -} - -/* Function to extract PRAGMA from sqlite db - * Input: - * void *db_conn : Sqlite connection - * char *pragma_key : PRAGMA or setting to be extracted - * char **pragma_value : the value of the PRAGMA or setting that is - * extracted. This function will allocate memory - * to pragma_value. The caller should free the memory - * Return: - * On success return the length of the pragma/setting value that is - * extracted. - * On failure return -1 - * */ -int -gf_sqlite3_pragma(void *db_conn, char *pragma_key, char **pragma_value) -{ - int ret = -1; - gf_sql_connection_t *sql_conn = db_conn; - sqlite3_stmt *pre_stmt = NULL; - char *sqlstring = NULL; - - CHECK_SQL_CONN(sql_conn, out); - GF_VALIDATE_OR_GOTO(GFDB_STR_SQLITE3, pragma_key, out); - - ret = gf_asprintf(&sqlstring, "PRAGMA %s;", pragma_key); - if (ret <= 0) { - gf_msg(GFDB_STR_SQLITE3, GF_LOG_ERROR, 0, LG_MSG_PREPARE_FAILED, - "Failed allocating memory"); - goto out; - } - - ret = sqlite3_prepare_v2(sql_conn->sqlite3_db_conn, sqlstring, -1, - &pre_stmt, 0); - if (ret != SQLITE_OK) { - gf_msg(GFDB_STR_SQLITE3, GF_LOG_ERROR, 0, LG_MSG_PREPARE_FAILED, - "Failed init prepare stmt %s", sqlite3_errmsg(db_conn)); - ret = -1; - goto out; - } - - ret = sqlite3_step(pre_stmt); - if (ret != SQLITE_ROW) { - gf_msg(GFDB_STR_SQLITE3, GF_LOG_ERROR, 0, LG_MSG_GET_RECORD_FAILED, - "Failed to get records " - "from db : %s", - sqlite3_errmsg(db_conn)); - ret = -1; - goto out; - } - - if (pragma_value) { - ret = gf_asprintf(pragma_value, "%s", sqlite3_column_text(pre_stmt, 0)); - if (ret <= 0) { - gf_msg(GFDB_STR_SQLITE3, GF_LOG_ERROR, 0, LG_MSG_QUERY_FAILED, - "Failed to get %s from db", pragma_key); - } - } - - ret = 0; -out: - GF_FREE(sqlstring); - - sqlite3_finalize(pre_stmt); - - return ret; -} - -/* Function to set PRAGMA to sqlite db - * Input: - * void *db_conn : Sqlite connection - * char *pragma_key : PRAGMA to be set - * char *pragma_value : the value of the PRAGMA - * Return: - * On success return 0 - * On failure return -1 - * */ -int -gf_sqlite3_set_pragma(void *db_conn, char *pragma_key, char *pragma_value) -{ - int ret = -1; - gf_sql_connection_t *sql_conn = db_conn; - char sqlstring[GF_NAME_MAX] = ""; - char *db_pragma_value = NULL; - - CHECK_SQL_CONN(sql_conn, out); - GF_VALIDATE_OR_GOTO(GFDB_STR_SQLITE3, pragma_key, out); - GF_VALIDATE_OR_GOTO(GFDB_STR_SQLITE3, pragma_value, out); - - GF_SQLITE3_SET_PRAGMA(sqlstring, pragma_key, "%s", pragma_value, ret, out); - - ret = gf_sqlite3_pragma(db_conn, pragma_key, &db_pragma_value); - if (ret < 0) { - gf_msg(GFDB_STR_SQLITE3, GF_LOG_ERROR, 0, LG_MSG_QUERY_FAILED, - "Failed to get %s pragma", pragma_key); - } else { - gf_msg(GFDB_STR_SQLITE3, GF_LOG_TRACE, 0, 0, "Value set on DB %s : %s", - pragma_key, db_pragma_value); - } - GF_FREE(db_pragma_value); - - ret = 0; - -out: - - return ret; -} - -/* Function to vacuum of sqlite db - * Input: - * void *db_conn : Sqlite connection - * gf_boolean_t compact_active : Is compaction on? - * gf_boolean_t compact_mode_switched : Did we just flip the compaction switch? - * Return: - * On success return 0 - * On failure return -1 - * */ -int -gf_sqlite3_vacuum(void *db_conn, gf_boolean_t compact_active, - gf_boolean_t compact_mode_switched) -{ - int ret = -1; - gf_sql_connection_t *sql_conn = db_conn; - char *sqlstring = NULL; - char *sql_strerror = NULL; - gf_boolean_t changing_pragma = _gf_true; - - CHECK_SQL_CONN(sql_conn, out); - - if (GF_SQL_COMPACT_DEF == GF_SQL_COMPACT_NONE) { - gf_msg(GFDB_STR_SQLITE3, GF_LOG_INFO, 0, LG_MSG_COMPACT_STATUS, - "VACUUM type is off: no VACUUM to do"); - goto out; - } - - if (compact_mode_switched) { - if (compact_active) { /* Then it was OFF before. - So turn everything on */ - ret = 0; - switch (GF_SQL_COMPACT_DEF) { - case GF_SQL_COMPACT_FULL: - ret = gf_sqlite3_set_pragma(db_conn, "auto_vacuum", - GF_SQL_AV_FULL); - break; - case GF_SQL_COMPACT_INCR: - ret = gf_sqlite3_set_pragma(db_conn, "auto_vacuum", - GF_SQL_AV_INCR); - break; - case GF_SQL_COMPACT_MANUAL: - changing_pragma = _gf_false; - break; - default: - ret = -1; - gf_msg(GFDB_STR_SQLITE3, GF_LOG_ERROR, 0, - LG_MSG_COMPACT_FAILED, "VACUUM type undefined"); - goto out; - break; - } - - } else { /* Then it was ON before, so turn it all off */ - if (GF_SQL_COMPACT_DEF == GF_SQL_COMPACT_FULL || - GF_SQL_COMPACT_DEF == GF_SQL_COMPACT_INCR) { - ret = gf_sqlite3_set_pragma(db_conn, "auto_vacuum", - GF_SQL_AV_NONE); - } else { - changing_pragma = _gf_false; - } - } - - if (ret) { - gf_msg(GFDB_STR_SQLITE3, GF_LOG_TRACE, 0, LG_MSG_PREPARE_FAILED, - "Failed to set the pragma"); - goto out; - } - - gf_msg(GFDB_STR_SQLITE3, GF_LOG_INFO, 0, LG_MSG_COMPACT_STATUS, - "Turning compaction %i", GF_SQL_COMPACT_DEF); - - /* If we move from an auto_vacuum scheme to off, */ - /* or vice-versa, we must VACUUM to save the change. */ - /* In the case of a manual VACUUM scheme, we might as well */ - /* run a manual VACUUM now if we */ - if (changing_pragma || compact_active) { - ret = gf_asprintf(&sqlstring, "VACUUM;"); - if (ret <= 0) { - gf_msg(GFDB_STR_SQLITE3, GF_LOG_ERROR, 0, LG_MSG_PREPARE_FAILED, - "Failed allocating memory"); - goto out; - } - gf_msg(GFDB_STR_SQLITE3, GF_LOG_INFO, 0, LG_MSG_COMPACT_STATUS, - "Sealed with a VACUUM"); - } - } else { /* We are active, so it's time to VACUUM */ - if (!compact_active) { /* Did we somehow enter an inconsistent - state? */ - ret = -1; - gf_msg(GFDB_STR_SQLITE3, GF_LOG_ERROR, 0, LG_MSG_PREPARE_FAILED, - "Tried to VACUUM when compaction inactive"); - goto out; - } - - gf_msg(GFDB_STR_SQLITE3, GF_LOG_TRACE, 0, LG_MSG_COMPACT_STATUS, - "Doing regular vacuum of type %i", GF_SQL_COMPACT_DEF); - - switch (GF_SQL_COMPACT_DEF) { - case GF_SQL_COMPACT_INCR: /* INCR auto_vacuum */ - ret = gf_asprintf(&sqlstring, "PRAGMA incremental_vacuum;"); - if (ret <= 0) { - gf_msg(GFDB_STR_SQLITE3, GF_LOG_ERROR, 0, - LG_MSG_PREPARE_FAILED, "Failed allocating memory"); - goto out; - } - gf_msg(GFDB_STR_SQLITE3, GF_LOG_INFO, 0, LG_MSG_COMPACT_STATUS, - "Will commence an incremental VACUUM"); - break; - /* (MANUAL) Invoke the VACUUM command */ - case GF_SQL_COMPACT_MANUAL: - ret = gf_asprintf(&sqlstring, "VACUUM;"); - if (ret <= 0) { - gf_msg(GFDB_STR_SQLITE3, GF_LOG_ERROR, 0, - LG_MSG_PREPARE_FAILED, "Failed allocating memory"); - goto out; - } - gf_msg(GFDB_STR_SQLITE3, GF_LOG_INFO, 0, LG_MSG_COMPACT_STATUS, - "Will commence a VACUUM"); - break; - /* (FULL) The database does the compaction itself. */ - /* We cannot do anything else, so we can leave */ - /* without sending anything to the database */ - case GF_SQL_COMPACT_FULL: - ret = 0; - goto success; - /* Any other state must be an error. Note that OFF */ - /* cannot hit this statement since we immediately leave */ - /* in that case */ - default: - ret = -1; - gf_msg(GFDB_STR_SQLITE3, GF_LOG_ERROR, 0, LG_MSG_COMPACT_FAILED, - "VACUUM type undefined"); - goto out; - break; - } - } - - gf_msg(GFDB_STR_SQLITE3, GF_LOG_TRACE, 0, LG_MSG_COMPACT_STATUS, - "SQLString == %s", sqlstring); - - ret = sqlite3_exec(sql_conn->sqlite3_db_conn, sqlstring, NULL, NULL, - &sql_strerror); - - if (ret != SQLITE_OK) { - gf_msg(GFDB_STR_SQLITE3, GF_LOG_ERROR, 0, LG_MSG_GET_RECORD_FAILED, - "Failed to vacuum " - "the db : %s", - sqlite3_errmsg(db_conn)); - ret = -1; - goto out; - } -success: - gf_msg(GFDB_STR_SQLITE3, GF_LOG_INFO, 0, LG_MSG_COMPACT_STATUS, - compact_mode_switched ? "Successfully changed VACUUM on/off" - : "DB successfully VACUUM"); -out: - GF_FREE(sqlstring); - - return ret; -} diff --git a/libglusterfs/src/gfdb/gfdb_sqlite3.h b/libglusterfs/src/gfdb/gfdb_sqlite3.h deleted file mode 100644 index d8240e905f7..00000000000 --- a/libglusterfs/src/gfdb/gfdb_sqlite3.h +++ /dev/null @@ -1,328 +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 "glusterfs/logging.h" -#include "gfdb_data_store_types.h" -#include "gfdb_mem-types.h" -#include "glusterfs/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, " \ - "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 "incremental" - -#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" - -#define GF_SQL_COMPACT_NONE 0 -#define GF_SQL_COMPACT_FULL 1 -#define GF_SQL_COMPACT_INCR 2 -#define GF_SQL_COMPACT_MANUAL 3 - -#define GF_SQL_COMPACT_DEF GF_SQL_COMPACT_INCR -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 %s = " format, param_key, 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 "12500" -#define GF_SQL_DEFAULT_WAL_AUTOCHECKPOINT "25000" -#define GF_SQL_DEFAULT_JOURNAL_MODE GF_SQL_JM_WAL -#define GF_SQL_DEFAULT_SYNC GF_SQL_SYNC_OFF -#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); - - /*Extract 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 query_limit); -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); - -/* Function to extract version of sqlite db - * Input: - * void *db_conn : Sqlite connection - * char **version : the version is extracted as a string and will be stored in - * this variable. The freeing of the memory should be done by - * the caller. - * Return: - * On success return the length of the version string that is - * extracted. - * On failure return -1 - * */ -int -gf_sqlite3_version(void *db_conn, char **version); - -/* Function to extract PRAGMA or setting from sqlite db - * Input: - * void *db_conn : Sqlite connection - * char *pragma_key : PRAGMA or setting to be extracted - * char **pragma_value : the value of the PRAGMA or setting that is - * extracted. This function will allocate memory - * to pragma_value. The caller should free the memory - * Return: - * On success return the length of the pragma/setting value that is - * extracted. - * On failure return -1 - * */ -int -gf_sqlite3_pragma(void *db_conn, char *pragma_key, char **pragma_value); - -/* Function to set PRAGMA to sqlite db - * Input: - * void *db_conn : Sqlite connection - * char *pragma_key : PRAGMA to be set - * char *pragma_value : the value of the PRAGMA - * Return: - * On success return 0 - * On failure return -1 - * */ -int -gf_sqlite3_set_pragma(void *db_conn, char *pragma_key, char *pragma_value); - -/* Function to vacuum of sqlite db - * Input: - * void *db_conn : Sqlite connection - * gf_boolean_t compact_active : Is compaction on? - * gf_boolean_t compact_mode_switched : Did we just flip the compaction switch? - * Return: - * On success return 0 - * On failure return -1 - * */ -int -gf_sqlite3_vacuum(void *db_conn, gf_boolean_t compact_active, - gf_boolean_t compact_mode_switched); - -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 60dd5e25e66..00000000000 --- a/libglusterfs/src/gfdb/gfdb_sqlite3_helper.c +++ /dev/null @@ -1,1260 +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, - gf_boolean_t ignore_errors) -{ - 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 " - "statement %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, _gfdb_log_level(GF_LOG_ERROR, ignore_errors), - 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 " - "statement %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, _gfdb_log_level(GF_LOG_ERROR, ignore_errors), - 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, gf_boolean_t ignore_errors) -{ - 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 " - "statement %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, _gfdb_log_level(GF_LOG_ERROR, ignore_errors), - 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, - gf_boolean_t ignore_errors) -{ - 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 " - "statement %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, _gfdb_log_level(GF_LOG_ERROR, ignore_errors), - 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, 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," - " 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); - - /*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 " - "statement %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 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 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; - } - - /*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", - gfid, pargfid, basename, 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 *old_pargfid, char *old_basename, - 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," - " 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, 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, - ignore_errors); - if (ret) { - gf_msg(GFDB_STR_SQLITE3, _gfdb_log_level(GF_LOG_ERROR, ignore_errors), - 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 " - "statement %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; - } - - /*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", 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, - gf_boolean_t ignore_errors) -{ - 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 " - "statement %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, _gfdb_log_level(GF_LOG_ERROR, ignore_errors), - 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, - gf_boolean_t ignore_errors) -{ - 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 statement 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" - : ""; - - /*Perfectly 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 { - /*Perfectly 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" - : ""; - - /*Perfectly 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 { - /*Perfectly 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 " - "statement %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, _gfdb_log_level(GF_LOG_ERROR, ignore_errors), - 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->link_consistency, _gf_true); - if (ret) { - gf_msg(GFDB_STR_SQLITE3, - _gfdb_log_level(GF_LOG_WARNING, - gfdb_db_record->ignore_errors), - 0, LG_MSG_INSERT_FAILED, - "Failed " - "inserting link in DB"); - /* Even if link creation is failed we - * continue with the creation of file record. - * This covers to cases - * 1) Lookup heal: If the file record from - * gf_file_tb is deleted but the link record - * still exist. Lookup heal will attempt a heal - * with create_wind set. The link heal will fail - * as there is already a record and if we don't - * ignore the error we will not heal the - * gf_file_tb. - * 2) Rename file in cold tier: During a rename - * of a file that is there in cold tier. We get - * an link record created in hot tier for the - * linkto file. When the file gets heated and - * moves to hot tier there will be attempt from - * ctr lookup heal to create link and file - * record and If we don't ignore the error we - * will not heal the gf_file_tb. - * */ - } - 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, - gfdb_db_record->ignore_errors); - if (ret) { - gf_msg(GFDB_STR_SQLITE3, - _gfdb_log_level(GF_LOG_ERROR, - gfdb_db_record->ignore_errors), - 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, - old_pargfid_str, gfdb_db_record->old_file_name, - gfdb_db_record->link_consistency, - gfdb_db_record->ignore_errors); - if (ret) { - gf_msg(GFDB_STR_SQLITE3, - _gfdb_log_level(GF_LOG_ERROR, - gfdb_db_record->ignore_errors), - 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->link_consistency, - gfdb_db_record->ignore_errors); - if (ret) { - gf_msg(GFDB_STR_SQLITE3, - _gfdb_log_level(GF_LOG_ERROR, - gfdb_db_record->ignore_errors), - 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), - gfdb_db_record->ignore_errors); - if (ret) { - gf_msg(GFDB_STR_SQLITE3, - _gfdb_log_level(GF_LOG_ERROR, gfdb_db_record->ignore_errors), - 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), - gfdb_db_record->ignore_errors); - if (ret) { - gf_msg(GFDB_STR_SQLITE3, - _gfdb_log_level(GF_LOG_ERROR, gfdb_db_record->ignore_errors), - 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, - gfdb_db_record->ignore_errors); - if (ret) { - gf_msg(GFDB_STR_SQLITE3, - _gfdb_log_level(GF_LOG_ERROR, gfdb_db_record->ignore_errors), - 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, - gfdb_db_record->ignore_errors); - if (ret) { - gf_msg(GFDB_STR_SQLITE3, - _gfdb_log_level(GF_LOG_ERROR, gfdb_db_record->ignore_errors), - 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, gfdb_db_record->ignore_errors); - } - /*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), - gfdb_db_record->ignore_errors); - if (ret) { - gf_msg(GFDB_STR_SQLITE3, - _gfdb_log_level(GF_LOG_ERROR, - gfdb_db_record->ignore_errors), - 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, - gfdb_db_record->ignore_errors); - 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), - gfdb_db_record->ignore_errors); - if (ret) { - gf_msg(GFDB_STR_SQLITE3, - _gfdb_log_level(GF_LOG_ERROR, - gfdb_db_record->ignore_errors), - 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 *query_record = NULL; - char *text_column = NULL; - sqlite3 *db_conn = NULL; - uuid_t prev_gfid = {0}; - uuid_t curr_gfid = {0}; - uuid_t pgfid = {0}; - char *base_name = NULL; - gf_boolean_t is_first_record = _gf_true; - gf_boolean_t is_query_empty = _gf_true; - - 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); - - /* - * Loop to access queried rows - * Each db record will have 3 columns - * GFID, PGFID, FILE_NAME - * - * For file with multiple hard links we will get multiple query rows - * with the same GFID, but different PGID and FILE_NAME Combination - * For Example if a file with - * GFID = 00000000-0000-0000-0000-000000000006 - * has 3 hardlinks file1, file2 and file3 in 3 different folder - * with GFID's - * 00000000-0000-0000-0000-0000EFC00001, - * 00000000-0000-0000-0000-00000ABC0001 and - * 00000000-0000-0000-0000-00000ABC00CD - * Then there will be 3 records - * GFID : 00000000-0000-0000-0000-000000000006 - * PGFID : 00000000-0000-0000-0000-0000EFC00001 - * FILE_NAME : file1 - * - * GFID : 00000000-0000-0000-0000-000000000006 - * PGFID : 00000000-0000-0000-0000-00000ABC0001 - * FILE_NAME : file2 - * - * GFID : 00000000-0000-0000-0000-000000000006 - * PGFID : 00000000-0000-0000-0000-00000ABC00CD - * FILE_NAME : file3 - * - * This is retrieved and added to a single query_record - * - * query_record->gfid = 00000000-0000-0000-0000-000000000006 - * ->link_info = {00000000-0000-0000-0000-0000EFC00001, - * "file1"} - * | - * V - * link_info = {00000000-0000-0000-0000-00000ABC0001, - * "file2"} - * | - * V - * link_info = {00000000-0000-0000-0000-00000ABC0001, - * "file3", - * list} - * - * This query record is sent to the registered query_callback() - * - * */ - while ((ret = sqlite3_step(prep_stmt)) == SQLITE_ROW) { - if (sqlite3_column_count(prep_stmt) > 0) { - is_query_empty = _gf_false; - - /*Retrieving 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 to" - "retrieve GFID"); - goto out; - } - ret = gf_uuid_parse(text_column, curr_gfid); - if (ret) { - gf_msg(GFDB_STR_SQLITE3, GF_LOG_ERROR, 0, LG_MSG_PARSE_FAILED, - "Failed to parse " - "GFID"); - goto out; - } - - /* - * if the previous record was not of the current gfid - * call the call_back function and send the - * query record, which will have all the link_info - * objects associated with this gfid - * - * */ - if (gf_uuid_compare(curr_gfid, prev_gfid) != 0) { - /* If this is not the first record */ - if (!is_first_record) { - /*Call the call_back function provided*/ - ret = query_callback(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; - } - } - - /*Clear the query record*/ - gfdb_query_record_free(query_record); - query_record = NULL; - query_record = gfdb_query_record_new(); - if (!query_record) { - gf_msg(GFDB_STR_SQLITE3, GF_LOG_ERROR, 0, - LG_MSG_CREATE_FAILED, - "Failed to create " - "query_record"); - goto out; - } - - gf_uuid_copy(query_record->gfid, curr_gfid); - gf_uuid_copy(prev_gfid, curr_gfid); - } - - /* Get PGFID */ - text_column = (char *)sqlite3_column_text(prep_stmt, 1); - if (!text_column) { - gf_msg(GFDB_STR_SQLITE3, GF_LOG_ERROR, 0, LG_MSG_GET_ID_FAILED, - "Failed to" - " retrieve GF_ID"); - goto out; - } - ret = gf_uuid_parse(text_column, pgfid); - if (ret) { - gf_msg(GFDB_STR_SQLITE3, GF_LOG_ERROR, 0, LG_MSG_PARSE_FAILED, - "Failed to parse " - "GF_ID"); - goto out; - } - - /* Get Base name */ - text_column = (char *)sqlite3_column_text(prep_stmt, 2); - if (!text_column) { - gf_msg(GFDB_STR_SQLITE3, GF_LOG_ERROR, 0, LG_MSG_GET_ID_FAILED, - "Failed to" - " retrieve GF_ID"); - goto out; - } - base_name = text_column; - - /* Add link info to the list */ - ret = gfdb_add_link_to_query_record(query_record, pgfid, base_name); - if (ret) { - gf_msg(GFDB_STR_SQLITE3, GF_LOG_ERROR, 0, LG_MSG_GET_ID_FAILED, - "Failed to" - " add link info to query record"); - goto out; - } - - is_first_record = _gf_false; - } - } - - if (ret != SQLITE_DONE) { - gf_msg(GFDB_STR_SQLITE3, GF_LOG_ERROR, 0, LG_MSG_GET_RECORD_FAILED, - "Failed to retrieve records " - "from db : %s", - sqlite3_errmsg(db_conn)); - ret = -1; - goto out; - } - - if (!is_query_empty) { - /* - * Call the call_back function for the last record from the - * Database - * */ - ret = query_callback(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; - } - } - - ret = 0; -out: - gfdb_query_record_free(query_record); - query_record = NULL; - 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 to execute: %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 f19344a353c..00000000000 --- a/libglusterfs/src/gfdb/gfdb_sqlite3_helper.h +++ /dev/null @@ -1,51 +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 40fcffbb35e..64a93802f76 100644 --- a/libglusterfs/src/gidcache.c +++ b/libglusterfs/src/gidcache.c @@ -10,6 +10,7 @@ #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 @@ -64,7 +65,7 @@ gid_cache_lookup(gid_cache_t *cache, uint64_t id, uint64_t uid, uint64_t gid) time_t now; const gid_list_t *agl; - now = time(NULL); + now = gf_time(); LOCK(&cache->gc_lock); bucket = id % cache->gc_nbuckets; agl = BUCKET_START(cache->gc_cache, bucket); @@ -132,7 +133,7 @@ gid_cache_add(gid_cache_t *cache, gid_list_t *gl) if (!cache->gc_max_age) return 0; - now = time(NULL); + now = gf_time(); LOCK(&cache->gc_lock); /* diff --git a/libglusterfs/src/globals.c b/libglusterfs/src/globals.c index 63b6358bbe0..ae06f8be386 100644 --- a/libglusterfs/src/globals.c +++ b/libglusterfs/src/globals.c @@ -314,7 +314,18 @@ glusterfs_cleanup(void *ptr) GF_FREE(thread_syncopctx.groups); } - mem_pool_thread_destructor(); + mem_pool_thread_destructor(NULL); +} + +void +gf_thread_needs_cleanup(void) +{ + /* 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 diff --git a/libglusterfs/src/glusterfs/client_t.h b/libglusterfs/src/glusterfs/client_t.h index 8ef3665a9c2..a2c508e1d5c 100644 --- a/libglusterfs/src/glusterfs/client_t.h +++ b/libglusterfs/src/glusterfs/client_t.h @@ -15,6 +15,17 @@ #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; @@ -78,21 +89,12 @@ typedef struct clienttable clienttable_t; */ #define GF_CLIENTENTRY_ALLOCATED -2 -struct rpcsvc_auth_data; - -client_t * -gf_client_get(xlator_t *this, struct rpcsvc_auth_data *cred, char *client_uid, - char *subdir_mount); - 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); @@ -138,4 +140,8 @@ 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/common-utils.h b/libglusterfs/src/glusterfs/common-utils.h index d52904021e1..f297fdab5c9 100644 --- a/libglusterfs/src/glusterfs/common-utils.h +++ b/libglusterfs/src/glusterfs/common-utils.h @@ -18,6 +18,7 @@ #include <string.h> #include <assert.h> #include <pthread.h> +#include <unistd.h> #include <openssl/md5.h> #ifndef GF_BSD_HOST_OS #include <alloca.h> @@ -26,6 +27,11 @@ #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 @@ -42,7 +48,6 @@ trap(void); #include "glusterfs/compat-uuid.h" #include "glusterfs/iatt.h" #include "glusterfs/libglusterfs-messages.h" -#include "protocol-common.h" #define STRINGIFY(val) #val #define TOSTRING(val) STRINGIFY(val) @@ -78,7 +83,6 @@ trap(void); #define GF_UNIT_PERCENT_STRING "%" #define GEOREP "geo-replication" -#define GHADOOP "glusterfs-hadoop" #define GLUSTERD_NAME "glusterd" #define GF_SELINUX_XATTR_KEY "security.selinux" @@ -116,12 +120,16 @@ trap(void); #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 @@ -146,6 +154,9 @@ trap(void); #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 @@ -165,7 +176,8 @@ enum _gf_special_pid { 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_ADD_REPLICA_MOUNT = -12, + GF_CLIENT_PID_SET_UTIME = -13, }; enum _gf_xlator_ipc_targets { @@ -177,6 +189,12 @@ enum _gf_xlator_ipc_targets { 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 @@ -237,6 +255,8 @@ 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 @@ -423,9 +443,6 @@ BIT_VALUE(unsigned char *array, unsigned int index) } \ } 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 @@ -438,6 +455,15 @@ BIT_VALUE(unsigned char *array, unsigned int index) } 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, \ @@ -468,18 +494,15 @@ union gf_sock_union { #define IOV_MIN(n) min(IOV_MAX, n) -#define GF_SKIP_IRRELEVANT_ENTRIES(entry, dir, scr) \ - do { \ - entry = NULL; \ - if (dir) { \ - entry = sys_readdir(dir, scr); \ - while (entry && (!strcmp(entry->d_name, ".") || \ - !fnmatch("*.tmp", entry->d_name, 0) || \ - !strcmp(entry->d_name, ".."))) { \ - entry = sys_readdir(dir, scr); \ - } \ - } \ - } while (0) +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) @@ -790,7 +813,7 @@ typedef enum { } gf_timefmts; static inline char * -gf_time_fmt(char *dst, size_t sz_dst, time_t utime, unsigned int fmt) +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; @@ -798,6 +821,8 @@ gf_time_fmt(char *dst, size_t sz_dst, time_t utime, unsigned int fmt) 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); @@ -807,15 +832,35 @@ gf_time_fmt(char *dst, size_t sz_dst, time_t utime, unsigned int fmt) fmt = gf_timefmt_default; } localtime = gf_log_get_localtime(); - res = localtime ? localtime_r(&utime, &tm) : gmtime_r(&utime, &tm); - if (utime && (res != NULL)) { - strftime(dst, sz_dst, fmts[fmt], &tm); + 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. */ @@ -906,6 +951,8 @@ gf_string2percent_or_bytesize(const char *str, double *n, 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); @@ -992,8 +1039,6 @@ gf_is_str_int(const char *value); char *gf_uint64_2human_readable(uint64_t); int -get_vol_type(int type, int dist_count, int brick_count); -int validate_brick_name(char *brick); char * get_host_name(char *word, char **host); @@ -1145,8 +1190,6 @@ 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 * -get_struct_variable(int mem_num, gf_gsync_status_t *sts_val); char * gf_strncpy(char *dest, const char *src, const size_t dest_size); @@ -1166,4 +1209,48 @@ 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.h b/libglusterfs/src/glusterfs/compat.h index d2686499973..bf00d903152 100644 --- a/libglusterfs/src/glusterfs/compat.h +++ b/libglusterfs/src/glusterfs/compat.h @@ -528,6 +528,9 @@ dirname_r(char *path); /* 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 diff --git a/libglusterfs/src/glusterfs/dict.h b/libglusterfs/src/glusterfs/dict.h index 35337251360..d0467c6dfb6 100644 --- a/libglusterfs/src/glusterfs/dict.h +++ b/libglusterfs/src/glusterfs/dict.h @@ -25,9 +25,6 @@ typedef struct _data_pair data_pair_t; #define dict_add_sizen(this, key, value) dict_addn(this, key, SLEN(key), value) -#define dict_get_with_ref_sizen(this, key, value) \ - dict_get_with_refn(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)) @@ -97,9 +94,8 @@ typedef struct _data_pair data_pair_t; struct _data { char *data; gf_atomic_t refcount; - gf_lock_t lock; gf_dict_data_type_t data_type; - int32_t len; + uint32_t len; gf_boolean_t is_static; }; @@ -119,12 +115,12 @@ struct _dict { gf_atomic_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; + /* 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); @@ -139,6 +135,7 @@ 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); @@ -146,8 +143,6 @@ 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); -int -dict_get_with_refn(dict_t *this, char *key, const int keylen, data_t **data); data_t * dict_get(dict_t *this, char *key); data_t * diff --git a/libglusterfs/src/glusterfs/fd.h b/libglusterfs/src/glusterfs/fd.h index 28906d34e4d..3ffaaa60504 100644 --- a/libglusterfs/src/glusterfs/fd.h +++ b/libglusterfs/src/glusterfs/fd.h @@ -106,6 +106,9 @@ 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); diff --git a/libglusterfs/src/glusterfs/gf-event.h b/libglusterfs/src/glusterfs/gf-event.h index c0f05e7c83b..40f8fbdf10a 100644 --- a/libglusterfs/src/glusterfs/gf-event.h +++ b/libglusterfs/src/glusterfs/gf-event.h @@ -12,6 +12,7 @@ #define _GF_EVENT_H_ #include <pthread.h> +#include "common-utils.h" #include "list.h" struct event_pool; @@ -31,6 +32,9 @@ typedef void (*event_handler_t)(int fd, int idx, int gen, void *data, #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; diff --git a/libglusterfs/src/glusterfs/globals.h b/libglusterfs/src/glusterfs/globals.h index e19a7cf8b95..b22eaae6c2f 100644 --- a/libglusterfs/src/glusterfs/globals.h +++ b/libglusterfs/src/glusterfs/globals.h @@ -45,7 +45,7 @@ 1 /* MIN is the fresh start op-version, mostly \ should not change */ #define GD_OP_VERSION_MAX \ - GD_OP_VERSION_7_0 /* MAX VERSION is the maximum \ + GD_OP_VERSION_9_0 /* MAX VERSION is the maximum \ count in VME table, should \ keep changing with \ introduction of newer \ @@ -116,6 +116,13 @@ #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 @@ -162,6 +169,9 @@ glusterfs_leaseid_exist(void); 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 diff --git a/libglusterfs/src/glusterfs/glusterfs-acl.h b/libglusterfs/src/glusterfs/glusterfs-acl.h index cae55e8062f..987bf5fab0b 100644 --- a/libglusterfs/src/glusterfs/glusterfs-acl.h +++ b/libglusterfs/src/glusterfs/glusterfs-acl.h @@ -143,7 +143,7 @@ gf_posix_acl_get_key(const acl_type_t type) return acl_key; } -static inline const acl_type_t +static inline acl_type_t gf_posix_acl_get_type(const char *key) { acl_type_t type = 0; 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 index 3e010fa93c1..e6425618b7f 100644 --- a/libglusterfs/src/glusterfs/glusterfs.h +++ b/libglusterfs/src/glusterfs/glusterfs.h @@ -31,21 +31,7 @@ #include <limits.h> /* For PATH_MAX */ #include <openssl/sha.h> -#include "glusterfs-fops.h" /* generated XDR values for FOPs */ - -#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 - +#include "glusterfs/glusterfs-fops.h" #include "glusterfs/list.h" #include "glusterfs/locking.h" #include "glusterfs/logging.h" @@ -57,6 +43,9 @@ #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 */ @@ -91,7 +80,7 @@ #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" @@ -320,7 +309,6 @@ enum gf_internal_fop_indicator { #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 TIER_LINKFILE_GFID "tier-linkfile-gfid" #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" @@ -437,7 +425,7 @@ 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 (pri < 0) + if (IS_ERROR(pri)) return "UNSPEC"; if (pri >= GF_FOP_PRI_MAX) @@ -478,6 +466,8 @@ typedef struct _server_cmdline server_cmdline_t; #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; @@ -543,6 +533,7 @@ struct _cmd_args { 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; @@ -569,7 +560,8 @@ struct _cmd_args { /* Run this process with valgrind? Might want to prevent calling * functions that prevent valgrind from working correctly, like * dlclose(). */ - int valgrind; + gf_valgrind_tool vgtool; + int localtime_logging; /* For the subdir mount */ @@ -589,6 +581,8 @@ struct _cmd_args { bool global_threading; bool brick_mux; + + uint32_t fuse_dev_eperm_ratelimit_ns; }; typedef struct _cmd_args cmd_args_t; @@ -607,7 +601,9 @@ struct _glusterfs_graph { 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; @@ -737,12 +733,15 @@ struct _glusterfs_ctx { } stats; struct list_head volfile_list; - /* Add members to manage janitor threads for cleanup fd */ struct list_head janitor_fds; - pthread_cond_t janitor_cond; - pthread_mutex_t janitor_lock; + 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; diff --git a/libglusterfs/src/glusterfs/inode.h b/libglusterfs/src/glusterfs/inode.h index 5cf2ab5080b..4b28da510c7 100644 --- a/libglusterfs/src/glusterfs/inode.h +++ b/libglusterfs/src/glusterfs/inode.h @@ -61,6 +61,10 @@ struct _inode_table { 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 { @@ -107,6 +111,7 @@ struct _inode { 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 */ }; diff --git a/libglusterfs/src/glusterfs/iobuf.h b/libglusterfs/src/glusterfs/iobuf.h index 792d4fe1529..4bd443efd5e 100644 --- a/libglusterfs/src/glusterfs/iobuf.h +++ b/libglusterfs/src/glusterfs/iobuf.h @@ -95,14 +95,14 @@ struct iobuf_arena { 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 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 max_active; /* max active buffers at a given time */ + int active_cnt; + int passive_cnt; + int max_active; /* max active buffers at a given time */ }; struct iobuf_pool { @@ -111,7 +111,6 @@ struct iobuf_pool { 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 @@ -125,6 +124,7 @@ struct iobuf_pool { 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]; diff --git a/libglusterfs/src/glusterfs/latency.h b/libglusterfs/src/glusterfs/latency.h index ed47b1f0cbc..4d601bbcbd6 100644 --- a/libglusterfs/src/glusterfs/latency.h +++ b/libglusterfs/src/glusterfs/latency.h @@ -11,13 +11,23 @@ #ifndef __LATENCY_H__ #define __LATENCY_H__ -#include "glusterfs/glusterfs.h" +#include <inttypes.h> +#include <time.h> -typedef struct fop_latency { - double min; /* min time for the call (microseconds) */ - double max; /* max time for the call (microseconds) */ - double total; /* total time (microseconds) */ +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; -} fop_latency_t; +} 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 index 7e0eebbe535..cb31dd7614b 100644 --- a/libglusterfs/src/glusterfs/libglusterfs-messages.h +++ b/libglusterfs/src/glusterfs/libglusterfs-messages.h @@ -112,6 +112,134 @@ GLFS_MSGID( 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_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/lkowner.h b/libglusterfs/src/glusterfs/lkowner.h index b49e9af6bcb..692de34bc7a 100644 --- a/libglusterfs/src/glusterfs/lkowner.h +++ b/libglusterfs/src/glusterfs/lkowner.h @@ -11,7 +11,7 @@ #ifndef _LK_OWNER_H #define _LK_OWNER_H -#include "glusterfs-fops.h" +#include "glusterfs/glusterfs-fops.h" /* LKOWNER to string functions */ static inline void diff --git a/libglusterfs/src/glusterfs/logging.h b/libglusterfs/src/glusterfs/logging.h index 31ecbfcbdb6..b3a6ac191f0 100644 --- a/libglusterfs/src/glusterfs/logging.h +++ b/libglusterfs/src/glusterfs/logging.h @@ -369,10 +369,6 @@ gf_log_disable_suppression_before_exit(struct _glusterfs_ctx *ctx); gf_log((xl)->name, GF_LOG_ERROR, format, ##args) int -_gf_slog(const char *domain, const char *file, const char *function, int line, - gf_loglevel_t level, const char *event, ...); - -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, ...); @@ -381,12 +377,7 @@ _gf_smsg(const char *domain, const char *file, const char *function, #define gf_smsg(dom, level, errnum, msgid, event...) \ do { \ _gf_smsg(dom, __FILE__, __FUNCTION__, __LINE__, level, errnum, 0, \ - msgid, ##event); \ - } while (0) - -#define gf_slog(dom, level, event...) \ - do { \ - _gf_slog(dom, __FILE__, __FUNCTION__, __LINE__, level, ##event); \ + msgid, msgid##_STR, ##event); \ } while (0) #endif /* __LOGGING_H__ */ diff --git a/libglusterfs/src/glusterfs/mem-pool.h b/libglusterfs/src/glusterfs/mem-pool.h index e0441756be7..e5b3276d047 100644 --- a/libglusterfs/src/glusterfs/mem-pool.h +++ b/libglusterfs/src/glusterfs/mem-pool.h @@ -202,6 +202,24 @@ 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 { @@ -209,10 +227,11 @@ struct mem_pool { unsigned long sizeof_type; unsigned long count; /* requested pool size (unused) */ char *name; - gf_atomic_t active; /* current allocations */ + 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 */ + 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 */ @@ -244,24 +263,26 @@ typedef struct per_thread_pool { } per_thread_pool_t; typedef struct per_thread_pool_list { - /* - * These first two members are protected by the global pool lock. When - * a thread first tries to use any pool, we create one of these. We - * link it into the global list using thr_list so the pool-sweeper - * thread can find it, and use pthread_setspecific so this thread can - * find it. When the per-thread destructor runs, we "poison" the pool - * list to prevent further allocations. This also signals to the - * pool-sweeper thread that the list should be detached and freed after - * the next time it's swept. - */ + /* 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; - unsigned int poison; + + /* 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. */ - pthread_spinlock_t lock; per_thread_pool_t pools[1]; } per_thread_pool_list_t; @@ -284,6 +305,10 @@ 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, @@ -306,9 +331,6 @@ void mem_pool_destroy(struct mem_pool *pool); void -mem_pool_thread_destructor(void); - -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 index 832f68c968e..d45d5b68c91 100644 --- a/libglusterfs/src/glusterfs/mem-types.h +++ b/libglusterfs/src/glusterfs/mem-types.h @@ -101,11 +101,6 @@ enum gf_common_mem_types_ { 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, - /*related to gfdb library*/ - gf_mt_gfdb_link_info_t, /* used only in one location */ - gf_mt_sql_connection_t, /* used only in one location */ - gf_mt_db_conn_node_t, /* used only in one location */ - /*related to gfdb library*/ 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 */ @@ -138,6 +133,7 @@ enum gf_common_mem_types_ { 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/stack.h b/libglusterfs/src/glusterfs/stack.h index 17585508a22..536a330d38b 100644 --- a/libglusterfs/src/glusterfs/stack.h +++ b/libglusterfs/src/glusterfs/stack.h @@ -45,6 +45,9 @@ 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; @@ -149,8 +152,6 @@ struct _call_stack { } while (0); struct xlator_fops; -void -gf_update_latency(call_frame_t *frame); static inline void FRAME_DESTROY(call_frame_t *frame) @@ -158,7 +159,7 @@ FRAME_DESTROY(call_frame_t *frame) void *local = NULL; if (frame->root->ctx->measure_latency) - gf_update_latency(frame); + gf_frame_latency_update(frame); list_del_init(&frame->frames); if (frame->local) { @@ -429,6 +430,7 @@ 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) @@ -442,6 +444,12 @@ call_stack_alloc_groups(call_stack_t *stack, int ngrps) } 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; diff --git a/libglusterfs/src/glusterfs/statedump.h b/libglusterfs/src/glusterfs/statedump.h index 89d04f94587..ce082706bdf 100644 --- a/libglusterfs/src/glusterfs/statedump.h +++ b/libglusterfs/src/glusterfs/statedump.h @@ -127,4 +127,6 @@ 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 index 6e6e3b9ad6d..a1f70c7b840 100644 --- a/libglusterfs/src/glusterfs/store.h +++ b/libglusterfs/src/glusterfs/store.h @@ -59,8 +59,8 @@ int32_t gf_store_unlink_tmppath(gf_store_handle_t *shandle); int -gf_store_read_and_tokenize(FILE *file, char *str, int size, 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 gf_store_retrieve_value(gf_store_handle_t *handle, char *key, char **value); @@ -95,7 +95,7 @@ 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); +gf_store_iter_destroy(gf_store_iter_t **iter); char * gf_store_strerror(gf_store_op_errno_t op_errno); diff --git a/libglusterfs/src/glusterfs/syncop.h b/libglusterfs/src/glusterfs/syncop.h index 3614d969264..4e9241a32fc 100644 --- a/libglusterfs/src/glusterfs/syncop.h +++ b/libglusterfs/src/glusterfs/syncop.h @@ -16,6 +16,8 @@ #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 @@ -29,9 +31,15 @@ #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); @@ -55,9 +63,12 @@ struct synctask { call_frame_t *opframe; synctask_cbk_t synccbk; synctask_fn_t syncfn; - synctask_state_t state; + struct timespec *delta; + gf_timer_t *timer; + struct synccond *synccond; void *opaque; void *stack; + synctask_state_t state; int woken; int slept; int ret; @@ -65,6 +76,13 @@ struct synctask { 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; @@ -77,6 +95,14 @@ struct synctask { 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; @@ -85,19 +111,21 @@ struct syncproc { /* hosts the scheduler thread and framework for executing synctasks */ struct syncenv { struct syncproc proc[SYNCENV_PROC_MAX]; - int procs; + + pthread_mutex_t mutex; + pthread_cond_t cond; struct list_head runq; - int runcount; struct list_head waitq; - int waitcount; + + int procs; + int procs_idle; + + int runcount; 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 @@ -123,6 +151,13 @@ struct synclock { }; 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 */ @@ -219,7 +254,7 @@ struct syncopctx { #define __yield(args) \ do { \ if (args->task) { \ - synctask_yield(args->task); \ + synctask_yield(args->task, NULL); \ } else { \ pthread_mutex_lock(&args->mutex); \ { \ @@ -240,7 +275,7 @@ struct syncopctx { task = synctask_get(); \ stb->task = task; \ if (task) \ - frame = task->opframe; \ + frame = copy_frame(task->opframe); \ else \ frame = syncop_create_frame(THIS); \ \ @@ -261,10 +296,7 @@ struct syncopctx { STACK_WIND_COOKIE(frame, cbk, (void *)stb, subvol, fn_op, params); \ \ __yield(stb); \ - if (task) \ - STACK_RESET(frame->root); \ - else \ - STACK_DESTROY(frame->root); \ + STACK_DESTROY(frame->root); \ } while (0) /* @@ -313,7 +345,9 @@ synctask_join(struct synctask *task); void synctask_wake(struct synctask *task); void -synctask_yield(struct synctask *task); +synctask_yield(struct synctask *task, struct timespec *delta); +void +synctask_sleep(int32_t secs); void synctask_waitfor(struct synctask *task, int count); @@ -411,6 +445,24 @@ 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 diff --git a/libglusterfs/src/glusterfs/syscall.h b/libglusterfs/src/glusterfs/syscall.h index 6b33c141a5e..b6d3ab4f2ad 100644 --- a/libglusterfs/src/glusterfs/syscall.h +++ b/libglusterfs/src/glusterfs/syscall.h @@ -96,18 +96,27 @@ 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 @@ -257,4 +266,13 @@ 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/xlator.h b/libglusterfs/src/glusterfs/xlator.h index 42cbdc1ac93..4fd3abdaeff 100644 --- a/libglusterfs/src/glusterfs/xlator.h +++ b/libglusterfs/src/glusterfs/xlator.h @@ -11,12 +11,12 @@ #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-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 <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" @@ -32,6 +32,8 @@ #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) @@ -700,6 +702,8 @@ 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; @@ -710,6 +714,8 @@ struct xlator_cbks { 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); @@ -799,7 +805,7 @@ struct _xlator { struct { /* for latency measurement */ - fop_latency_t latencies[GF_FOP_MAXVALUE]; + gf_latency_t latencies[GF_FOP_MAXVALUE]; /* for latency measurement */ fop_metrics_t metrics[GF_FOP_MAXVALUE]; @@ -858,6 +864,9 @@ struct _xlator { /* 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 @@ -1092,4 +1101,6 @@ 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.c b/libglusterfs/src/graph.c index 51704560164..13f298eb3bd 100644 --- a/libglusterfs/src/graph.c +++ b/libglusterfs/src/graph.c @@ -21,12 +21,12 @@ #include <sys/stat.h> // for stat #include <sys/time.h> // for gettimeofday #include <unistd.h> // for gethostname, getpid -#include "glusterfs-fops.h" // for GF_EVENT_GRAPH_NEW, GF_... #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 @@ -41,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, }, }; @@ -469,7 +469,7 @@ _xlator_check_unknown_options(xlator_t *xl, void *data) dict_foreach(xl->options, _log_if_unknown_option, xl); } -int +static int glusterfs_graph_unknown_options(glusterfs_graph_t *graph) { xlator_foreach(graph->first, _xlator_check_unknown_options, NULL); @@ -482,7 +482,7 @@ fill_uuid(char *uuid, int size, struct timeval tv) char hostname[50] = { 0, }; - char now_str[64]; + char now_str[GF_TIMESTR_SIZE]; if (gethostname(hostname, sizeof(hostname) - 1) != 0) { gf_msg("graph", GF_LOG_ERROR, errno, LG_MSG_GETHOSTNAME_FAILED, @@ -490,9 +490,8 @@ fill_uuid(char *uuid, int size, struct timeval tv) 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; } @@ -568,14 +567,13 @@ glusterfs_graph_prepare(glusterfs_graph_t *graph, glusterfs_ctx_t *ctx, } else { ret = glusterfs_graph_settop(graph, volume_name, _gf_false); } - if (!ret) { - goto ok; - } - gf_msg("graph", GF_LOG_ERROR, 0, LG_MSG_GRAPH_ERROR, - "glusterfs graph settop failed"); - return -1; -ok: + 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); @@ -1379,7 +1377,7 @@ glusterfs_graph_cleanup(void *arg) ret = pthread_mutex_lock(&graph->mutex); if (ret != 0) { gf_msg("glusterfs", GF_LOG_ERROR, EAGAIN, LG_MSG_GRAPH_CLEANUP_FAILED, - "Failed to aquire a lock"); + "Failed to acquire a lock"); goto out; } /* check and wait for CHILD_DOWN for top xlator*/ @@ -1695,6 +1693,7 @@ glusterfs_process_svc_attach_volfp(glusterfs_ctx_t *ctx, FILE *fp, "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) { @@ -1763,6 +1762,7 @@ glusterfs_process_svc_attach_volfp(glusterfs_ctx_t *ctx, FILE *fp, 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; } } diff --git a/libglusterfs/src/inode.c b/libglusterfs/src/inode.c index 3a1f097e1af..dbadf77442d 100644 --- a/libglusterfs/src/inode.c +++ b/libglusterfs/src/inode.c @@ -232,15 +232,15 @@ __foreach_ancestor_dentry(dentry_t *dentry, 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); + 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_msg(THIS->name, GF_LOG_WARNING, 0, LG_MSG_PARENT_DENTRY_NOT_FOUND, - "parent not found"); + gf_smsg(THIS->name, GF_LOG_WARNING, 0, LG_MSG_PARENT_DENTRY_NOT_FOUND, + NULL); goto out; } @@ -274,11 +274,9 @@ __is_dentry_cyclic(dentry_t *dentry) ret = __foreach_ancestor_dentry(dentry, __check_cycle, dentry->inode); if (ret) { - 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(dentry->inode->gfid), dentry->name); + 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; @@ -337,8 +335,7 @@ __inode_ctx_free(inode_t *inode) xlator_t *old_THIS = NULL; if (!inode->_ctx) { - gf_msg(THIS->name, GF_LOG_WARNING, 0, LG_MSG_CTX_NULL, - "_ctx not found"); + gf_smsg(THIS->name, GF_LOG_WARNING, 0, LG_MSG_CTX_NULL, NULL); goto noctx; } @@ -473,10 +470,45 @@ __inode_unref(inode_t *inode, bool clear) 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) + /* + * 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. + */ + return inode; + this = THIS; - if (clear && inode->invalidate_sent) { - inode->invalidate_sent = false; + if (clear && inode->in_invalidate_list) { + inode->in_invalidate_list = false; inode->table->invalidate_size--; __inode_activate(inode); } @@ -490,7 +522,7 @@ __inode_unref(inode_t *inode, bool clear) inode->_ctx[index].ref--; } - if (!inode->ref && !inode->invalidate_sent) { + if (!inode->ref && !inode->in_invalidate_list) { inode->table->active_size--; nlookup = GF_ATOMIC_GET(inode->nlookup); @@ -526,14 +558,14 @@ __inode_ref(inode_t *inode, bool is_invalidate) return inode; if (!inode->ref) { - if (inode->invalidate_sent) { - inode->invalidate_sent = false; + if (inode->in_invalidate_list) { + inode->in_invalidate_list = false; inode->table->invalidate_size--; } else { inode->table->lru_size--; } if (is_invalidate) { - inode->invalidate_sent = true; + inode->in_invalidate_list = true; inode->table->invalidate_size++; list_move_tail(&inode->list, &inode->table->invalidate); } else { @@ -922,6 +954,7 @@ __inode_link(inode_t *inode, inode_t *parent, const char *name, 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}; table = inode->table; @@ -996,11 +1029,12 @@ __inode_link(inode_t *inode, inode_t *parent, const char *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)); + 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; } @@ -1206,10 +1240,10 @@ __inode_unlink(inode_t *inode, inode_t *parent, const char *name) if (dentry) { 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)); + 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; @@ -1393,10 +1427,8 @@ __inode_path(inode_t *inode, const char *name, char **bufp) 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); + gf_smsg(table->name, GF_LOG_CRITICAL, 0, LG_MSG_DENTRY_CYCLIC_LOOP, + "name=%s", name, NULL); ret = -ENOENT; goto out; } @@ -1509,6 +1541,7 @@ static int inode_table_prune(inode_table_t *table) { int ret = 0; + int ret1 = 0; struct list_head purge = { 0, }; @@ -1547,6 +1580,10 @@ inode_table_prune(inode_table_t *table) /* 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; @@ -1568,9 +1605,19 @@ inode_table_prune(inode_table_t *table) if (tmp) { xlator_t *old_THIS = THIS; THIS = table->invalidator_xl; - table->invalidator_fn(table->invalidator_xl, tmp); + ret1 = table->invalidator_fn(table->invalidator_xl, tmp); THIS = old_THIS; - inode_unref(tmp); + pthread_mutex_lock(&table->lock); + { + 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); } /* Just so that if purge list is handled too, then clear it off */ @@ -1679,6 +1726,8 @@ inode_table_with_invalidator(uint32_t lru_limit, xlator_t *xl, ; } + new->cleanup_started = _gf_false; + __inode_table_init_root(new); pthread_mutex_init(&new->lock, NULL); @@ -1829,6 +1878,7 @@ inode_table_destroy(inode_table_t *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 diff --git a/libglusterfs/src/iobuf.c b/libglusterfs/src/iobuf.c index 0e37c4fc6e2..4e7d2958764 100644 --- a/libglusterfs/src/iobuf.c +++ b/libglusterfs/src/iobuf.c @@ -21,7 +21,7 @@ (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[] = { +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}, @@ -41,32 +41,31 @@ gf_iobuf_get_arena_index(const size_t page_size) } static size_t -gf_iobuf_get_pagesize(const size_t page_size) +gf_iobuf_get_pagesize(const size_t page_size, int *index) { 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 (page_size <= size) { + if (index != NULL) + *index = i; return size; + } } return -1; } -void +static void __iobuf_arena_init_iobufs(struct iobuf_arena *iobuf_arena) { - int iobuf_cnt = 0; + const int iobuf_cnt = iobuf_arena->page_count; 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) @@ -88,27 +87,23 @@ __iobuf_arena_init_iobufs(struct iobuf_arena *iobuf_arena) iobuf++; } -out: return; } -void +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); - - 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; } + 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); @@ -120,11 +115,10 @@ __iobuf_arena_destroy_iobufs(struct iobuf_arena *iobuf_arena) GF_FREE(iobuf_arena->iobufs); -out: return; } -void +static void __iobuf_arena_destroy(struct iobuf_pool *iobuf_pool, struct iobuf_arena *iobuf_arena) { @@ -143,12 +137,13 @@ out: return; } -struct iobuf_arena * +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; + int index = 0; /* unused */ GF_VALIDATE_OR_GOTO("iobuf", iobuf_pool, out); @@ -162,7 +157,7 @@ __iobuf_arena_alloc(struct iobuf_pool *iobuf_pool, size_t page_size, 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; @@ -173,8 +168,7 @@ __iobuf_arena_alloc(struct iobuf_pool *iobuf_pool, size_t page_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"); + gf_smsg(THIS->name, GF_LOG_WARNING, 0, LG_MSG_MAPPING_FAILED, NULL); goto err; } @@ -186,8 +180,7 @@ __iobuf_arena_alloc(struct iobuf_pool *iobuf_pool, size_t page_size, __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"); + gf_smsg(THIS->name, GF_LOG_ERROR, 0, LG_MSG_INIT_IOBUF_FAILED, NULL); goto err; } @@ -232,8 +225,8 @@ __iobuf_pool_add_arena(struct iobuf_pool *iobuf_pool, const size_t page_size, 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"); + gf_smsg(THIS->name, GF_LOG_WARNING, 0, LG_MSG_ARENA_NOT_FOUND, + NULL); return NULL; } } @@ -332,7 +325,6 @@ iobuf_pool_new(void) size_t page_size = 0; size_t arena_size = 0; int32_t num_pages = 0; - int index; iobuf_pool = GF_CALLOC(sizeof(*iobuf_pool), 1, gf_common_mt_iobuf_pool); if (!iobuf_pool) @@ -355,28 +347,16 @@ iobuf_pool_new(void) iobuf_pool->mr_list[i] = NULL; } - pthread_mutex_lock(&iobuf_pool->mutex); - { - 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; - - index = gf_iobuf_get_arena_index(page_size); - if (index == -1) { - pthread_mutex_unlock(&iobuf_pool->mutex); - 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; - } - - __iobuf_pool_add_arena(iobuf_pool, page_size, num_pages, index); + /* 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; - } } - pthread_mutex_unlock(&iobuf_pool->mutex); /* Need an arena to handle all the bigger iobuf requests */ iobuf_create_stdalloc_arena(iobuf_pool); @@ -501,8 +481,8 @@ __iobuf_get(struct iobuf_pool *iobuf_pool, const size_t page_size, 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; @@ -555,7 +535,7 @@ iobuf_get2(struct iobuf_pool *iobuf_pool, size_t page_size) page_size = iobuf_pool->default_page_size; } - rounded_size = gf_iobuf_get_pagesize(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 */ @@ -569,14 +549,9 @@ iobuf_get2(struct iobuf_pool *iobuf_pool, size_t page_size) iobuf_pool->request_misses++; return iobuf; - } - - 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); + } else if (index == -1) { + gf_smsg("iobuf", GF_LOG_ERROR, 0, LG_MSG_PAGE_SIZE_EXCEEDED, + "page_size=%zu", page_size, NULL); return NULL; } @@ -584,16 +559,16 @@ iobuf_get2(struct iobuf_pool *iobuf_pool, size_t page_size) { iobuf = __iobuf_get(iobuf_pool, rounded_size, index); if (!iobuf) { - gf_msg(THIS->name, GF_LOG_WARNING, 0, LG_MSG_IOBUF_NOT_FOUND, - "iobuf not found"); - goto unlock; + pthread_mutex_unlock(&iobuf_pool->mutex); + gf_smsg(THIS->name, GF_LOG_WARNING, 0, LG_MSG_IOBUF_NOT_FOUND, + NULL); + goto post_unlock; } iobuf_ref(iobuf); } -unlock: pthread_mutex_unlock(&iobuf_pool->mutex); - +post_unlock: return iobuf; } @@ -639,10 +614,8 @@ iobuf_get(struct iobuf_pool *iobuf_pool) index = gf_iobuf_get_arena_index(iobuf_pool->default_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", - iobuf_pool->default_page_size); + gf_smsg("iobuf", GF_LOG_ERROR, 0, LG_MSG_PAGE_SIZE_EXCEEDED, + "page_size=%zu", iobuf_pool->default_page_size, NULL); return NULL; } @@ -650,29 +623,26 @@ iobuf_get(struct iobuf_pool *iobuf_pool) { iobuf = __iobuf_get(iobuf_pool, iobuf_pool->default_page_size, index); if (!iobuf) { - gf_msg(THIS->name, GF_LOG_WARNING, 0, LG_MSG_IOBUF_NOT_FOUND, - "iobuf not found"); - goto unlock; + pthread_mutex_unlock(&iobuf_pool->mutex); + gf_smsg(THIS->name, GF_LOG_WARNING, 0, LG_MSG_IOBUF_NOT_FOUND, + NULL); + goto out; } iobuf_ref(iobuf); } -unlock: pthread_mutex_unlock(&iobuf_pool->mutex); out: return iobuf; } -void +static void __iobuf_put(struct iobuf *iobuf, struct iobuf_arena *iobuf_arena) { struct iobuf_pool *iobuf_pool = NULL; int index = 0; - GF_VALIDATE_OR_GOTO("iobuf", iobuf_arena, out); - GF_VALIDATE_OR_GOTO("iobuf", iobuf, out); - iobuf_pool = iobuf_arena->iobuf_pool; index = gf_iobuf_get_arena_index(iobuf_arena->page_size); @@ -725,15 +695,14 @@ iobuf_put(struct iobuf *iobuf) iobuf_arena = iobuf->iobuf_arena; if (!iobuf_arena) { - gf_msg(THIS->name, GF_LOG_WARNING, 0, LG_MSG_ARENA_NOT_FOUND, - "arena not found"); + 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"); + gf_smsg(THIS->name, GF_LOG_WARNING, 0, LG_MSG_POOL_NOT_FOUND, "iobuf", + NULL); return; } @@ -972,14 +941,12 @@ iobuf_size(struct iobuf *iobuf) 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"); + 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"); + gf_smsg(THIS->name, GF_LOG_WARNING, 0, LG_MSG_POOL_NOT_FOUND, NULL); goto out; } diff --git a/libglusterfs/src/latency.c b/libglusterfs/src/latency.c index 06a973e0e7c..ce4b0e8255d 100644 --- a/libglusterfs/src/latency.c +++ b/libglusterfs/src/latency.c @@ -16,35 +16,32 @@ #include "glusterfs/glusterfs.h" #include "glusterfs/statedump.h" -void -gf_update_latency(call_frame_t *frame) +gf_latency_t * +gf_latency_new(size_t n) { - double elapsed; - struct timespec *begin, *end; - - fop_latency_t *lat; - - begin = &frame->begin; - end = &frame->end; + int i = 0; + gf_latency_t *lat = NULL; - if (!(begin->tv_sec && end->tv_sec)) - goto out; + lat = GF_MALLOC(n * sizeof(*lat), gf_common_mt_latency_t); + if (!lat) + return NULL; - elapsed = (end->tv_sec - begin->tv_sec) * 1e9 + - (end->tv_nsec - begin->tv_nsec); + for (i = 0; i < n; i++) { + gf_latency_reset(lat + i); + } + return lat; +} - if (frame->op < 0 || frame->op >= GF_FOP_MAXVALUE) { - gf_log("[core]", GF_LOG_WARNING, "Invalid frame op value: %d", - frame->op); +void +gf_latency_update(gf_latency_t *lat, struct timespec *begin, + struct timespec *end) +{ + if (!(begin->tv_sec && end->tv_sec)) { + /*Measure latency might have been enabled/disabled during the op*/ return; } - /* 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; - - lat = &frame->this->stats.interval.latencies[frame->op]; + double elapsed = gf_tsdiff(begin, end); if (lat->max < elapsed) lat->max = elapsed; @@ -54,40 +51,34 @@ gf_update_latency(call_frame_t *frame) lat->total += elapsed; lat->count++; -out: - return; } 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("%s", key_prefix); - - for (i = 0; i < GF_FOP_MAXVALUE; i++) { - gf_proc_dump_build_key(key, key_prefix, "%s", (char *)gf_fop_list[i]); - - fop_latency_t *lat = &xl->stats.interval.latencies[i]; + 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 */ +} - /* Doesn't make sense to continue if there are no fops - came in the given interval */ - if (!lat->count) - continue; +void +gf_frame_latency_update(call_frame_t *frame) +{ + 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; - gf_proc_dump_write(key, "%.03f,%" PRId64 ",%.03f", - (lat->total / lat->count), lat->count, lat->total); + if (frame->op < 0 || frame->op >= GF_FOP_MAXVALUE) { + gf_log("[core]", GF_LOG_WARNING, "Invalid frame op value: %d", + frame->op); + return; } - memset(xl->stats.interval.latencies, 0, - sizeof(xl->stats.interval.latencies)); - - /* make sure 'min' is set to high value, so it would be - properly set later */ - for (i = 0; i < GF_FOP_MAXVALUE; i++) { - xl->stats.interval.latencies[i].min = 0xffffffff; - } + lat = &frame->this->stats.interval.latencies[frame->op]; + gf_latency_update(lat, &frame->begin, &frame->end); } diff --git a/libglusterfs/src/libglusterfs.sym b/libglusterfs/src/libglusterfs.sym index 0de3836efc5..5f18cd56cbe 100644 --- a/libglusterfs/src/libglusterfs.sym +++ b/libglusterfs/src/libglusterfs.sym @@ -451,6 +451,7 @@ gf_event_unregister_close fd_anonymous fd_anonymous_with_flags fd_bind +fd_close fd_create fd_create_uint64 __fd_ctx_del @@ -547,8 +548,6 @@ get_file_mtime get_host_name get_mem_size get_path_name -get_struct_variable -get_vol_type get_xlator_by_name get_xlator_by_type gf_array_insertionsort @@ -586,6 +585,7 @@ 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 @@ -939,6 +939,12 @@ 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 @@ -1016,6 +1022,7 @@ synctask_new synctask_new1 synctask_set synctask_setid +synctask_sleep synctask_wake synctask_yield sys_access @@ -1041,6 +1048,7 @@ sys_futimes sys_lchown sys_lgetxattr sys_link +sys_linkat sys_llistxattr sys_lremovexattr sys_lseek @@ -1064,13 +1072,17 @@ 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 @@ -1170,3 +1182,12 @@ 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/logging.c b/libglusterfs/src/logging.c index 0134d237cb4..a930d3e3b63 100644 --- a/libglusterfs/src/logging.c +++ b/libglusterfs/src/logging.c @@ -35,7 +35,6 @@ #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 #define GF_MAX_SLOG_PAIR_COUNT 100 #include "glusterfs/logging.h" @@ -48,7 +47,7 @@ #define TEST_LOG(__msg, __args...) \ gf_log("logging-infra", GF_LOG_DEBUG, __msg, ##__args); -void +static void gf_log_flush_timeout_cbk(void *data); int @@ -57,26 +56,24 @@ 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; -}; - -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 @@ -314,18 +311,16 @@ gf_log_rotate(glusterfs_ctx_t *ctx) fd = sys_open(ctx->log.filename, O_CREAT | O_WRONLY | O_APPEND, S_IRUSR | S_IWUSR); if (fd < 0) { - gf_msg("logrotate", GF_LOG_ERROR, errno, LG_MSG_FILE_OP_FAILED, - "failed to open " - "logfile"); + gf_smsg("logrotate", GF_LOG_ERROR, errno, + LG_MSG_OPEN_LOGFILE_FAILED, NULL); return; } new_logfile = fdopen(fd, "a"); if (!new_logfile) { - gf_msg("logrotate", GF_LOG_CRITICAL, errno, LG_MSG_FILE_OP_FAILED, - "failed to open logfile" - " %s", - ctx->log.filename); + gf_smsg("logrotate", GF_LOG_CRITICAL, errno, + LG_MSG_OPEN_LOGFILE_FAILED, "filename=%s", + ctx->log.filename, NULL); sys_close(fd); return; } @@ -478,7 +473,7 @@ 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] = { @@ -687,9 +682,8 @@ gf_log_init(void *data, const char *file, const char *ident) } if (mkdir_p(logdir, 0755, true)) { /* EEXIST is handled in mkdir_p() itself */ - gf_msg("logging", GF_LOG_ERROR, 0, LG_MSG_STRDUP_ERROR, - "failed to create metrics dir %s (%s)", logdir, - strerror(errno)); + gf_smsg("logging", GF_LOG_ERROR, 0, LG_MSG_STRDUP_ERROR, + "logdir=%s", logdir, "errno=%s", strerror(errno), NULL); GF_FREE(logdir); return -1; } @@ -765,7 +759,7 @@ _gf_log_callingfn(const char *domain, const char *file, const char *function, xlator_t *this = THIS; char *logline = NULL; char *msg = NULL; - char timestr[GF_LOG_TIMESTR_SIZE] = { + char timestr[GF_TIMESTR_SIZE] = { 0, }; char *callstr = NULL; @@ -782,18 +776,6 @@ _gf_log_callingfn(const char *domain, const char *file, const char *function, if (skip_logging(this, level)) goto out; - static const 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__); @@ -837,12 +819,12 @@ _gf_log_callingfn(const char *domain, const char *file, const char *function, if (-1 == ret) goto out; - gf_time_fmt(timestr, sizeof timestr, tv.tv_sec, gf_timefmt_FT); + gf_time_fmt_tv(timestr, sizeof timestr, &tv, gf_timefmt_FT); - ret = gf_asprintf( - &logline, "[%s.%" GF_PRI_SUSECONDS "] %s [%s:%d:%s] %s %d-%s: %s\n", - timestr, tv.tv_usec, level_strings[level], basename, line, function, - callstr, ((this->graph) ? this->graph->id : 0), domain, msg); + 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; } @@ -1105,7 +1087,7 @@ _gf_msg_nomem(const char *domain, const char *file, const char *function, char msg[2048] = { 0, }; - char timestr[GF_LOG_TIMESTR_SIZE] = { + char timestr[GF_TIMESTR_SIZE] = { 0, }; glusterfs_ctx_t *ctx = NULL; @@ -1133,20 +1115,20 @@ _gf_msg_nomem(const char *domain, const char *file, const char *function, ret = gettimeofday(&tv, NULL); if (-1 == ret) goto out; - gf_time_fmt(timestr, sizeof timestr, tv.tv_sec, gf_timefmt_FT); + 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.%" GF_PRI_SUSECONDS "] %s [MSGID: %" PRIu64 + "[%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, tv.tv_usec, gf_level_strings[level], (uint64_t)0, basename, - line, function, domain, size, + 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; @@ -1292,7 +1274,7 @@ gf_log_glusterlog(glusterfs_ctx_t *ctx, const char *domain, const char *file, 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] = { + char timestr[GF_TIMESTR_SIZE] = { 0, }; char *header = NULL; @@ -1303,7 +1285,7 @@ gf_log_glusterlog(glusterfs_ctx_t *ctx, const char *domain, const char *file, gf_log_rotate(ctx); /* format the time stamp */ - gf_time_fmt(timestr, sizeof timestr, tv.tv_sec, gf_timefmt_FT); + gf_time_fmt_tv(timestr, sizeof timestr, &tv, gf_timefmt_FT); /* generate footer */ if (errnum) { @@ -1319,40 +1301,35 @@ gf_log_glusterlog(glusterfs_ctx_t *ctx, const char *domain, const char *file, if (fmt == gf_logformat_traditional) { if (!callstr) { ret = gf_asprintf(&header, - "[%s.%" GF_PRI_SUSECONDS - "] %s [%s:%d:%s]" + "[%s] %c [%s:%d:%s]" " %d-%s: %s", - timestr, tv.tv_usec, gf_level_strings[level], - file, line, function, graph_id, domain, - *appmsgstr); + timestr, gf_level_strings[level], file, line, + function, graph_id, domain, *appmsgstr); } else { ret = gf_asprintf(&header, - "[%s.%" GF_PRI_SUSECONDS - "] %s [%s:%d:%s] %s" + "[%s] %c [%s:%d:%s] %s" " %d-%s: %s", - timestr, tv.tv_usec, gf_level_strings[level], - file, line, function, callstr, graph_id, domain, - *appmsgstr); + 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.%" GF_PRI_SUSECONDS "] %s [MSGID: %" PRIu64 + "[%s] %c [MSGID: %" PRIu64 "]" " [%s:%d:%s] %d-%s: %s", - timestr, tv.tv_usec, gf_level_strings[level], - msgid, file, line, function, graph_id, domain, - *appmsgstr); + timestr, gf_level_strings[level], msgid, file, + line, function, graph_id, domain, *appmsgstr); } else { ret = gf_asprintf(&header, - "[%s.%" GF_PRI_SUSECONDS "] %s [MSGID: %" PRIu64 + "[%s] %c [MSGID: %" PRIu64 "]" " [%s:%d:%s] %s %d-%s: %s", - timestr, tv.tv_usec, gf_level_strings[level], - msgid, file, line, function, callstr, graph_id, - domain, *appmsgstr); + timestr, gf_level_strings[level], msgid, file, + line, function, callstr, graph_id, domain, + *appmsgstr); } } if (-1 == ret) { @@ -1403,39 +1380,36 @@ gf_syslog_log_repetitions(const char *domain, const char *file, int graph_id) { int priority; - char timestr_latest[GF_LOG_TIMESTR_SIZE] = { + char timestr_latest[GF_TIMESTR_SIZE] = { 0, }; - char timestr_oldest[GF_LOG_TIMESTR_SIZE] = { + char timestr_oldest[GF_TIMESTR_SIZE] = { 0, }; SET_LOG_PRIO(level, priority); - gf_time_fmt(timestr_latest, sizeof timestr_latest, latest.tv_sec, - gf_timefmt_FT); - gf_time_fmt(timestr_oldest, sizeof timestr_oldest, oldest.tv_sec, - gf_timefmt_FT); + 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.%" GF_PRI_SUSECONDS - " and %s.%" GF_PRI_SUSECONDS, - msgid, file, line, function, graph_id, domain, *appmsgstr, - strerror(errnum), refcount, timestr_oldest, oldest.tv_usec, - timestr_latest, latest.tv_usec); + 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.%" GF_PRI_SUSECONDS - " and %s.%" GF_PRI_SUSECONDS, + "%d-%s: %s \" repeated %d times between %s" + " and %s", msgid, file, line, function, graph_id, domain, *appmsgstr, - refcount, timestr_oldest, oldest.tv_usec, timestr_latest, - latest.tv_usec); + refcount, timestr_oldest, timestr_latest); } return 0; } @@ -1449,10 +1423,10 @@ gf_glusterlog_log_repetitions(glusterfs_ctx_t *ctx, const char *domain, struct timeval latest, int graph_id) { int ret = 0; - char timestr_latest[GF_LOG_TIMESTR_SIZE] = { + char timestr_latest[GF_TIMESTR_SIZE] = { 0, }; - char timestr_oldest[GF_LOG_TIMESTR_SIZE] = { + char timestr_oldest[GF_TIMESTR_SIZE] = { 0, }; char errstr[256] = { @@ -1467,7 +1441,7 @@ gf_glusterlog_log_repetitions(glusterfs_ctx_t *ctx, const char *domain, gf_log_rotate(ctx); ret = gf_asprintf(&header, - "The message \"%s [MSGID: %" PRIu64 + "The message \"%c [MSGID: %" PRIu64 "]" " [%s:%d:%s] %d-%s: %s", gf_level_strings[level], msgid, file, line, function, @@ -1476,21 +1450,17 @@ gf_glusterlog_log_repetitions(glusterfs_ctx_t *ctx, const char *domain, goto err; } - gf_time_fmt(timestr_latest, sizeof timestr_latest, latest.tv_sec, - gf_timefmt_FT); + gf_time_fmt_tv(timestr_latest, sizeof timestr_latest, &latest, + gf_timefmt_FT); - gf_time_fmt(timestr_oldest, sizeof timestr_oldest, oldest.tv_sec, - 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.%" GF_PRI_SUSECONDS "] and [%s.%" GF_PRI_SUSECONDS - "]", - errstr, refcount, timestr_oldest, oldest.tv_usec, - timestr_latest, latest.tv_usec); + 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; @@ -1547,6 +1517,11 @@ gf_log_print_with_repetitions(glusterfs_ctx_t *ctx, const char *domain, 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 */ + case gf_logger_glusterlog: ret = gf_glusterlog_log_repetitions( ctx, domain, file, function, line, level, errnum, msgid, @@ -1940,20 +1915,11 @@ _gf_msg(const char *domain, const char *file, const char *function, int ret = 0; char *msgstr = NULL; va_list ap; - xlator_t *this = NULL; + xlator_t *this = THIS; glusterfs_ctx_t *ctx = NULL; char *callstr = NULL; 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; @@ -1967,6 +1933,13 @@ _gf_msg(const char *domain, const char *file, const char *function, 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); @@ -2027,7 +2000,7 @@ _gf_log(const char *domain, const char *file, const char *function, int line, const char *basename = NULL; FILE *new_logfile = NULL; va_list ap; - char timestr[GF_LOG_TIMESTR_SIZE] = { + char timestr[GF_TIMESTR_SIZE] = { 0, }; struct timeval tv = { @@ -2046,18 +2019,6 @@ _gf_log(const char *domain, const char *file, const char *function, int line, if (skip_logging(this, level)) goto out; - static const 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__); @@ -2097,16 +2058,17 @@ _gf_log(const char *domain, const char *file, const char *function, int line, fd = sys_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"); + gf_smsg("logrotate", GF_LOG_ERROR, errno, + LG_MSG_OPEN_LOGFILE_FAILED, NULL); return -1; } sys_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); + gf_smsg("logrotate", GF_LOG_CRITICAL, errno, + LG_MSG_OPEN_LOGFILE_FAILED, "filename=%s", + ctx->log.filename, NULL); goto log; } @@ -2125,12 +2087,11 @@ log: if (-1 == ret) goto out; - gf_time_fmt(timestr, sizeof timestr, tv.tv_sec, gf_timefmt_FT); + gf_time_fmt_tv(timestr, sizeof timestr, &tv, gf_timefmt_FT); - ret = gf_asprintf( - &logline, "[%s.%" GF_PRI_SUSECONDS "] %s [%s:%d:%s] %d-%s: %s\n", - timestr, tv.tv_usec, level_strings[level], basename, line, function, - ((this->graph) ? this->graph->id : 0), domain, msg); + 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; } @@ -2213,8 +2174,8 @@ gf_cmd_log_init(const char *filename) return -1; if (!filename) { - gf_msg(this->name, GF_LOG_CRITICAL, 0, LG_MSG_INVALID_ENTRY, - "gf_cmd_log_init: no filename specified\n"); + gf_smsg(this->name, GF_LOG_CRITICAL, 0, LG_MSG_FILENAME_NOT_SPECIFIED, + "gf_cmd_log_init", NULL); return -1; } @@ -2231,17 +2192,15 @@ gf_cmd_log_init(const char *filename) 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"); + 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_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); + 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; } @@ -2252,7 +2211,7 @@ int gf_cmd_log(const char *domain, const char *fmt, ...) { va_list ap; - char timestr[64]; + char timestr[GF_TIMESTR_SIZE]; struct timeval tv = { 0, }; @@ -2285,10 +2244,9 @@ gf_cmd_log(const char *domain, const char *fmt, ...) goto out; } - gf_time_fmt(timestr, sizeof timestr, tv.tv_sec, gf_timefmt_FT); + gf_time_fmt_tv(timestr, sizeof timestr, &tv, gf_timefmt_FT); - ret = gf_asprintf(&logline, "[%s.%" GF_PRI_SUSECONDS "] %s : %s\n", timestr, - tv.tv_usec, domain, msg); + ret = gf_asprintf(&logline, "[%s] %s : %s\n", timestr, domain, msg); if (ret == -1) { goto out; } @@ -2305,20 +2263,18 @@ gf_cmd_log(const char *domain, const char *fmt, ...) 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 " - "logfile \"%s\" \n", - ctx->log.cmd_log_filename); + 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; } ctx->log.cmdlogfile = fdopen(fd, "a"); if (!ctx->log.cmdlogfile) { - gf_msg(THIS->name, GF_LOG_CRITICAL, errno, LG_MSG_FILE_OP_FAILED, - "failed to open logfile \"%s\"" - " \n", - ctx->log.cmd_log_filename); + 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; @@ -2337,7 +2293,7 @@ out: } static int -_do_slog_format(const char *event, va_list inp, char **msg) +_do_slog_format(int errnum, const char *event, va_list inp, char **msg) { va_list valist_tmp; int i = 0; @@ -2350,10 +2306,13 @@ _do_slog_format(const char *event, va_list inp, char **msg) char format_char = '%'; char *tmp1 = NULL; char *tmp2 = NULL; + char temp_sep[3] = ""; - ret = gf_asprintf(&tmp2, "%s", event); - if (ret == -1) + tmp2 = gf_strdup(""); + if (!tmp2) { + ret = -1; goto out; + } /* Hardcoded value for max key value pairs, exits early */ /* from loop if found NULL */ @@ -2401,22 +2360,45 @@ _do_slog_format(const char *event, va_list inp, char **msg) (void)va_arg(inp, void *); } - ret = gf_asprintf(&tmp2, "%s\t%s", tmp1, buffer); + ret = gf_asprintf(&tmp2, "%s%s{%s}", tmp1, temp_sep, buffer); if (ret < 0) goto out; GF_FREE(buffer); buffer = NULL; } else { - ret = gf_asprintf(&tmp2, "%s\t%s", tmp1, fmt); + ret = gf_asprintf(&tmp2, "%s%s{%s}", tmp1, temp_sep, fmt); if (ret < 0) goto out; } + /* Set seperator for next iteration */ + temp_sep[0] = ','; + temp_sep[1] = ' '; + temp_sep[2] = 0; + 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); + } + + if (ret == -1) + goto out; + *msg = gf_strdup(tmp2); if (!*msg) ret = -1; @@ -2442,36 +2424,19 @@ _gf_smsg(const char *domain, const char *file, const char *function, va_list valist; char *msg = NULL; int ret = 0; + xlator_t *this = THIS; - va_start(valist, event); - ret = _do_slog_format(event, valist, &msg); - if (ret == -1) - goto out; - - ret = _gf_msg(domain, file, function, line, level, errnum, trace, msgid, - "%s", msg); - -out: - va_end(valist); - if (msg) - GF_FREE(msg); - return ret; -} - -int -_gf_slog(const char *domain, const char *file, const char *function, int line, - gf_loglevel_t level, const char *event, ...) -{ - va_list valist; - char *msg = NULL; - int ret = 0; + if (skip_logging(this, level)) + return ret; va_start(valist, event); - ret = _do_slog_format(event, valist, &msg); + ret = _do_slog_format(errnum, event, valist, &msg); if (ret == -1) goto out; - ret = _gf_log(domain, file, function, line, level, "%s", msg); + /* 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); diff --git a/libglusterfs/src/mem-pool.c b/libglusterfs/src/mem-pool.c index d0f8a64d2f7..2d5a12b0a00 100644 --- a/libglusterfs/src/mem-pool.c +++ b/libglusterfs/src/mem-pool.c @@ -123,6 +123,15 @@ gf_mem_update_acct_info(struct mem_acct *mem_acct, struct mem_header *header, 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) { @@ -131,7 +140,7 @@ __gf_calloc(size_t nmemb, size_t size, uint32_t type, const char *typestr) void *ptr = NULL; xlator_t *xl = NULL; - if (!THIS->ctx->mem_acct_enable) + if (!gf_mem_acct_enabled()) return CALLOC(nmemb, size); xl = THIS; @@ -156,7 +165,7 @@ __gf_malloc(size_t size, uint32_t type, const char *typestr) void *ptr = NULL; xlator_t *xl = NULL; - if (!THIS->ctx->mem_acct_enable) + if (!gf_mem_acct_enabled()) return MALLOC(size); xl = THIS; @@ -178,7 +187,7 @@ __gf_realloc(void *ptr, size_t size) size_t tot_size = 0; struct mem_header *header = NULL; - if (!THIS->ctx->mem_acct_enable) + if (!gf_mem_acct_enabled()) return REALLOC(ptr, size); REQUIRE(NULL != ptr); @@ -301,7 +310,7 @@ __gf_free(void *free_ptr) struct mem_header *header = NULL; bool last_ref = false; - if (!THIS->ctx->mem_acct_enable) { + if (!gf_mem_acct_enabled()) { FREE(free_ptr); return; } @@ -353,6 +362,30 @@ free: FREE(ptr); } +#if defined(GF_DISABLE_MEMPOOL) + +struct mem_pool * +mem_pool_new_fn(glusterfs_ctx_t *ctx, unsigned long sizeof_type, + unsigned long count, char *name) +{ + struct mem_pool *new; + + new = GF_MALLOC(sizeof(struct mem_pool), gf_common_mt_mem_pool); + if (!new) + return NULL; + + new->sizeof_type = sizeof_type; + return new; +} + +void +mem_pool_destroy(struct mem_pool *pool) +{ + GF_FREE(pool); +} + +#else /* !GF_DISABLE_MEMPOOL */ + 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; @@ -362,12 +395,10 @@ static size_t pool_list_size; static __thread per_thread_pool_list_t *thread_pool_list = NULL; -#if !defined(GF_DISABLE_MEMPOOL) #define N_COLD_LISTS 1024 #define POOL_SWEEP_SECS 30 typedef struct { - struct list_head death_row; pooled_obj_hdr_t *cold_lists[N_COLD_LISTS]; unsigned int n_cold_lists; } sweep_state_t; @@ -384,36 +415,33 @@ static pthread_mutex_t init_mutex = PTHREAD_MUTEX_INITIALIZER; static unsigned int init_count = 0; static pthread_t sweeper_tid; -gf_boolean_t +static bool collect_garbage(sweep_state_t *state, per_thread_pool_list_t *pool_list) { unsigned int i; per_thread_pool_t *pt_pool; - gf_boolean_t poisoned; (void)pthread_spin_lock(&pool_list->lock); - poisoned = pool_list->poison != 0; - if (!poisoned) { - 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) { - break; - } - state->cold_lists[state->n_cold_lists++] = pt_pool->cold_list; + 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; } - pt_pool->cold_list = pt_pool->hot_list; - pt_pool->hot_list = NULL; + state->cold_lists[state->n_cold_lists++] = pt_pool->cold_list; } + pt_pool->cold_list = pt_pool->hot_list; + pt_pool->hot_list = NULL; } (void)pthread_spin_unlock(&pool_list->lock); - return poisoned; + return false; } -void +static void free_obj_list(pooled_obj_hdr_t *victim) { pooled_obj_hdr_t *next; @@ -425,82 +453,96 @@ free_obj_list(pooled_obj_hdr_t *victim) } } -void * +static void * pool_sweeper(void *arg) { sweep_state_t state; per_thread_pool_list_t *pool_list; - per_thread_pool_list_t *next_pl; - per_thread_pool_t *pt_pool; - unsigned int i; - gf_boolean_t poisoned; + 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 three passes, with + * global lock. Thus, we split each iteration into two passes, with * only the first and fastest holding the lock. */ + pending = true; + for (;;) { - sleep(POOL_SWEEP_SECS); + /* 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); - INIT_LIST_HEAD(&state.death_row); 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_safe(pool_list, next_pl, &pool_threads, thr_list) + list_for_each_entry(pool_list, &pool_threads, thr_list) { - (void)pthread_mutex_unlock(&pool_lock); - poisoned = collect_garbage(&state, pool_list); - (void)pthread_mutex_lock(&pool_lock); - - if (poisoned) { - list_move(&pool_list->thr_list, &state.death_row); + if (collect_garbage(&state, pool_list)) { + pending = true; } } (void)pthread_mutex_unlock(&pool_lock); - /* Second pass: free dead pools. */ - (void)pthread_mutex_lock(&pool_free_lock); - list_for_each_entry_safe(pool_list, next_pl, &state.death_row, thr_list) - { - for (i = 0; i < NPOOLS; ++i) { - pt_pool = &pool_list->pools[i]; - free_obj_list(pt_pool->cold_list); - free_obj_list(pt_pool->hot_list); - pt_pool->hot_list = pt_pool->cold_list = NULL; - } - list_del(&pool_list->thr_list); - list_add(&pool_list->thr_list, &pool_free_threads); - } - (void)pthread_mutex_unlock(&pool_free_lock); - - /* Third pass: free cold objects from live pools. */ + /* Second pass: free cold objects from live pools. */ for (i = 0; i < state.n_cold_lists; ++i) { free_obj_list(state.cold_lists[i]); } (void)pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); } + + return NULL; } void -mem_pool_thread_destructor(void) +mem_pool_thread_destructor(per_thread_pool_list_t *pool_list) { - per_thread_pool_list_t *pool_list = thread_pool_list; + per_thread_pool_t *pt_pool; + uint32_t i; - /* The pool-sweeper thread will take it from here. - * - * We can change 'poison' here without taking locks because the change - * itself doesn't interact with other parts of the code and a simple write - * is already atomic from the point of view of the processor. - * - * This change can modify what mem_put() does, but both possibilities are - * fine until the sweeper thread kicks in. The real synchronization must be - * between mem_put() and the sweeper thread. */ + 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) { - pool_list->poison = 1; + /* 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; + } + + 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; } } @@ -528,6 +570,22 @@ mem_pools_preinit(void) init_done = GF_MEMPOOL_INIT_EARLY; } +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. */ @@ -560,10 +618,6 @@ mem_pools_fini(void) */ break; case 1: { - per_thread_pool_list_t *pool_list; - per_thread_pool_list_t *next_pl; - unsigned int i; - /* 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 @@ -571,32 +625,11 @@ mem_pools_fini(void) (void)pthread_cancel(sweeper_tid); (void)pthread_join(sweeper_tid, NULL); - /* At this point all threads should have already terminated, so - * it should be safe to destroy all pending per_thread_pool_list_t - * structures that are stored for each thread. */ - mem_pool_thread_destructor(); - - /* free all objects from all pools */ - list_for_each_entry_safe(pool_list, next_pl, &pool_threads, - thr_list) - { - for (i = 0; i < NPOOLS; ++i) { - free_obj_list(pool_list->pools[i].hot_list); - free_obj_list(pool_list->pools[i].cold_list); - pool_list->pools[i].hot_list = NULL; - pool_list->pools[i].cold_list = NULL; - } - - list_del(&pool_list->thr_list); - FREE(pool_list); - } - - list_for_each_entry_safe(pool_list, next_pl, &pool_free_threads, - thr_list) - { - list_del(&pool_list->thr_list); - FREE(pool_list); - } + /* 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. */ @@ -607,21 +640,29 @@ mem_pools_fini(void) pthread_mutex_unlock(&init_mutex); } -#else void -mem_pools_init(void) -{ -} -void -mem_pools_fini(void) -{ -} -void -mem_pool_thread_destructor(void) +mem_pool_destroy(struct mem_pool *pool) { -} + if (!pool) + return; -#endif + /* 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, @@ -672,6 +713,7 @@ mem_pool_new_fn(glusterfs_ctx_t *ctx, unsigned long sizeof_type, 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 @@ -689,21 +731,6 @@ mem_pool_new_fn(glusterfs_ctx_t *ctx, unsigned long sizeof_type, return new; } -void * -mem_get0(struct mem_pool *mem_pool) -{ - 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 - } - - return ptr; -} - per_thread_pool_list_t * mem_get_pool_list(void) { @@ -738,13 +765,21 @@ mem_get_pool_list(void) } } + /* 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); - pool_list->poison = 0; 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; } @@ -804,6 +839,23 @@ mem_get_from_pool(struct mem_pool *mem_pool) return retval; } +#endif /* GF_DISABLE_MEMPOOL */ + +void * +mem_get0(struct mem_pool *mem_pool) +{ + 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 + } + + return ptr; +} + void * mem_get(struct mem_pool *mem_pool) { @@ -848,6 +900,14 @@ mem_put(void *ptr) /* 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]; @@ -870,27 +930,3 @@ mem_put(void *ptr) } #endif /* GF_DISABLE_MEMPOOL */ } - -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. - */ -} diff --git a/libglusterfs/src/monitoring.c b/libglusterfs/src/monitoring.c index 45e3d776903..fbb68dc8622 100644 --- a/libglusterfs/src/monitoring.c +++ b/libglusterfs/src/monitoring.c @@ -113,15 +113,15 @@ dump_latency_and_count(xlator_t *xl, int fd) dprintf(fd, "%s.interval.%s.fail_count %" PRIu64 "\n", xl->name, gf_fop_list[index], cbk); } - if (xl->stats.interval.latencies[index].count != 0.0) { + if (xl->stats.interval.latencies[index].count != 0) { dprintf(fd, "%s.interval.%s.latency %lf\n", xl->name, gf_fop_list[index], - (xl->stats.interval.latencies[index].total / + (((double)xl->stats.interval.latencies[index].total) / xl->stats.interval.latencies[index].count)); - dprintf(fd, "%s.interval.%s.max %lf\n", xl->name, + 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 %lf\n", xl->name, + dprintf(fd, "%s.interval.%s.min %" PRIu64 "\n", xl->name, gf_fop_list[index], xl->stats.interval.latencies[index].min); } diff --git a/libglusterfs/src/options.c b/libglusterfs/src/options.c index 400a3901689..f6b5aa0ea23 100644 --- a/libglusterfs/src/options.c +++ b/libglusterfs/src/options.c @@ -25,7 +25,8 @@ xlator_option_validate_path(xlator_t *xl, const char *key, const char *value, 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); + gf_smsg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "error=%s", + errstr, NULL); goto out; } @@ -35,7 +36,8 @@ xlator_option_validate_path(xlator_t *xl, const char *key, const char *value, "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); + gf_smsg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "error=%s", + errstr, NULL); goto out; } @@ -59,7 +61,8 @@ xlator_option_validate_int(xlator_t *xl, const char *key, const char *value, 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); + gf_smsg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "error=%s", + errstr, NULL); goto out; } @@ -67,7 +70,8 @@ xlator_option_validate_int(xlator_t *xl, const char *key, const char *value, 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); + gf_smsg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "error=%s", + errstr, NULL); goto out; } @@ -87,8 +91,8 @@ xlator_option_validate_int(xlator_t *xl, const char *key, const char *value, "'%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); + gf_smsg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "error=%s", + errstr, NULL); goto out; } } else if (opt->validate == GF_OPT_VALIDATE_MAX) { @@ -97,8 +101,8 @@ xlator_option_validate_int(xlator_t *xl, const char *key, const char *value, "'%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); + gf_smsg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "error=%s", + errstr, NULL); goto out; } } else if ((inputll < opt->min) || (inputll > opt->max)) { @@ -106,7 +110,8 @@ xlator_option_validate_int(xlator_t *xl, const char *key, const char *value, "'%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); + gf_smsg(xl->name, GF_LOG_ERROR, 0, LG_MSG_OUT_OF_RANGE, "error=%s", + errstr, NULL); goto out; } @@ -129,7 +134,8 @@ xlator_option_validate_sizet(xlator_t *xl, const char *key, const char *value, if (gf_string2bytesize_uint64(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); + gf_smsg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "error=%s", + errstr, NULL); ret = -1; goto out; } @@ -147,7 +153,8 @@ xlator_option_validate_sizet(xlator_t *xl, const char *key, const char *value, "'%" PRIu64 "' 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); + gf_smsg(xl->name, GF_LOG_ERROR, 0, LG_MSG_OUT_OF_RANGE, "error=%s", + errstr, NULL); ret = -1; } @@ -171,7 +178,8 @@ xlator_option_validate_bool(xlator_t *xl, const char *key, const char *value, 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); + gf_smsg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "error=%s", + errstr, NULL); goto out; } @@ -206,7 +214,8 @@ xlator_option_validate_xlator(xlator_t *xl, const char *key, const char *value, 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); + gf_smsg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "error=%s", + errstr, NULL); goto out; } @@ -305,7 +314,8 @@ out: char errstr[4096]; set_error_str(errstr, sizeof(errstr), opt, key, value); - gf_msg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "%s", errstr); + gf_smsg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "error=%s", + errstr, NULL); if (op_errstr) *op_errstr = gf_strdup(errstr); } @@ -324,7 +334,8 @@ xlator_option_validate_percent(xlator_t *xl, const char *key, const char *value, 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); + gf_smsg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "error=%s", + errstr, NULL); goto out; } @@ -332,7 +343,8 @@ xlator_option_validate_percent(xlator_t *xl, const char *key, const char *value, 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); + gf_smsg(xl->name, GF_LOG_ERROR, 0, LG_MSG_OUT_OF_RANGE, "error=%s", + errstr, NULL); goto out; } @@ -378,8 +390,8 @@ xlator_option_validate_percent_or_sizet(xlator_t *xl, const char *key, "'%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); + gf_smsg(xl->name, GF_LOG_ERROR, 0, LG_MSG_OUT_OF_RANGE, + "error=%s", errstr, NULL); goto out; } ret = 0; @@ -394,8 +406,8 @@ xlator_option_validate_percent_or_sizet(xlator_t *xl, const char *key, " %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); + gf_smsg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "error=%s", + errstr, NULL); goto out; } @@ -413,8 +425,8 @@ xlator_option_validate_percent_or_sizet(xlator_t *xl, const char *key, "'%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); + gf_smsg(xl->name, GF_LOG_ERROR, 0, LG_MSG_OUT_OF_RANGE, "error=%s", + errstr, NULL); goto out; } ret = 0; @@ -425,7 +437,8 @@ xlator_option_validate_percent_or_sizet(xlator_t *xl, const char *key, 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); + gf_smsg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "error=%s", errstr, + NULL); out: if (ret && op_errstr) @@ -447,7 +460,8 @@ xlator_option_validate_time(xlator_t *xl, const char *key, const char *value, "invalid time format \"%s\" in " "\"option %s\"", value, key); - gf_msg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "%s", errstr); + gf_smsg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "error=%s", + errstr, NULL); goto out; } @@ -466,7 +480,8 @@ xlator_option_validate_time(xlator_t *xl, const char *key, const char *value, "' 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); + gf_smsg(xl->name, GF_LOG_ERROR, 0, LG_MSG_OUT_OF_RANGE, "error=%s", + errstr, NULL); goto out; } @@ -489,7 +504,8 @@ xlator_option_validate_double(xlator_t *xl, const char *key, const char *value, 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); + gf_smsg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "error=%s", + errstr, NULL); goto out; } @@ -509,8 +525,8 @@ xlator_option_validate_double(xlator_t *xl, const char *key, const char *value, "'%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); + gf_smsg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "error=%s", + errstr, NULL); goto out; } } else if (opt->validate == GF_OPT_VALIDATE_MAX) { @@ -519,8 +535,8 @@ xlator_option_validate_double(xlator_t *xl, const char *key, const char *value, "'%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); + gf_smsg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "error=%s", + errstr, NULL); goto out; } } else if ((input < opt->min) || (input > opt->max)) { @@ -528,7 +544,8 @@ xlator_option_validate_double(xlator_t *xl, const char *key, const char *value, "'%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); + gf_smsg(xl->name, GF_LOG_ERROR, 0, LG_MSG_OUT_OF_RANGE, "error=%s", + errstr, NULL); goto out; } @@ -549,7 +566,8 @@ xlator_option_validate_addr(xlator_t *xl, const char *key, const char *value, 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_msg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "%s", errstr); + gf_smsg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "error=%s", + errstr, NULL); if (op_errstr) *op_errstr = gf_strdup(errstr); } @@ -640,7 +658,8 @@ out: "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); + gf_smsg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "error=%s", + errstr, NULL); if (op_errstr) *op_errstr = gf_strdup(errstr); } @@ -681,7 +700,8 @@ out: "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); + gf_smsg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "error=%s", + errstr, NULL); if (op_errstr) *op_errstr = gf_strdup(errstr); } @@ -747,20 +767,16 @@ validate_list_elements(const char *string, volume_option_t *opt, 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 ? key : ""); + gf_smsg(THIS->name, GF_LOG_WARNING, 0, LG_MSG_INVALID_ENTRY, + "list=%s", string, "key=%s", key ? key : "", NULL); 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); + gf_smsg(THIS->name, GF_LOG_WARNING, 0, LG_MSG_INVALID_ENTRY, + "list=%s", string, "value=%s", key, NULL); goto out; } @@ -865,8 +881,8 @@ xlator_option_validate(xlator_t *xl, char *key, char *value, }; 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); + gf_smsg(xl->name, GF_LOG_ERROR, 0, LG_MSG_UNKNOWN_OPTION_TYPE, + "type=%d", opt->type, NULL); goto out; } @@ -947,18 +963,16 @@ xl_opt_validate(dict_t *dict, char *key, data_t *value, void *data) 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); + 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_msg(xl->name, GF_LOG_DEBUG, 0, LG_MSG_INVALID_ENTRY, - "option '%s' is deprecated, preferred is '%s', " - "continuing with correction", - key, opt->key[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); } @@ -1026,9 +1040,8 @@ xlator_validate_rec(xlator_t *xlator, char **op_errstr) 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"); + gf_smsg("xlator", GF_LOG_WARNING, 0, LG_MSG_VALIDATE_REC_FAILED, + NULL); goto out; } @@ -1052,8 +1065,8 @@ xlator_validate_rec(xlator_t *xlator, char **op_errstr) THIS = old_THIS; if (ret) { - gf_msg(xlator->name, GF_LOG_INFO, 0, LG_MSG_INVALID_ENTRY, "%s", - *op_errstr); + gf_smsg(xlator->name, GF_LOG_INFO, 0, LG_MSG_INVALID_ENTRY, "%s", + *op_errstr, NULL); goto out; } diff --git a/libglusterfs/src/rbthash.c b/libglusterfs/src/rbthash.c index ae2e158d61e..c90b5a21f44 100644 --- a/libglusterfs/src/rbthash.c +++ b/libglusterfs/src/rbthash.c @@ -56,9 +56,8 @@ __rbthash_init_buckets(rbthash_table_t *tbl, int buckets) 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"); + gf_smsg(GF_RBTHASH, GF_LOG_ERROR, 0, LG_MSG_RB_TABLE_CREATE_FAILED, + NULL); ret = -1; goto err; } @@ -88,20 +87,17 @@ rbthash_table_init(glusterfs_ctx_t *ctx, int buckets, rbt_hasher_t hfunc, int ret = -1; if (!hfunc) { - gf_msg(GF_RBTHASH, GF_LOG_ERROR, 0, LG_MSG_HASH_FUNC_ERROR, - "Hash function not given"); + gf_smsg(GF_RBTHASH, GF_LOG_ERROR, 0, LG_MSG_HASH_FUNC_ERROR, NULL); return NULL; } if (!entrypool && !expected_entries) { - gf_msg(GF_RBTHASH, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, - "Both mem-pool and expected entries not provided"); + gf_smsg(GF_RBTHASH, GF_LOG_ERROR, 0, LG_MSG_ENTRIES_NOT_PROVIDED, NULL); 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"); + gf_smsg(GF_RBTHASH, GF_LOG_ERROR, 0, LG_MSG_ENTRIES_PROVIDED, NULL); return NULL; } @@ -132,8 +128,8 @@ rbthash_table_init(glusterfs_ctx_t *ctx, int buckets, rbt_hasher_t hfunc, 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"); + 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 { @@ -170,8 +166,8 @@ rbthash_init_entry(rbthash_table_t *tbl, void *data, void *key, int keylen) 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"); + gf_smsg(GF_RBTHASH, GF_LOG_ERROR, 0, LG_MSG_RBTHASH_GET_ENTRY_FAILED, + NULL); goto ret; } @@ -243,8 +239,8 @@ rbthash_insert_entry(rbthash_table_t *tbl, rbthash_entry_t *entry) 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"); + gf_smsg(GF_RBTHASH, GF_LOG_ERROR, 0, LG_MSG_RBTHASH_GET_BUCKET_FAILED, + NULL); goto err; } @@ -253,8 +249,8 @@ rbthash_insert_entry(rbthash_table_t *tbl, rbthash_entry_t *entry) { if (!rb_probe(bucket->bucket, (void *)entry)) { UNLOCK(&bucket->bucketlock); - gf_msg(GF_RBTHASH, GF_LOG_ERROR, 0, LG_MSG_RBTHASH_INSERT_FAILED, - "Failed to insert entry"); + gf_smsg(GF_RBTHASH, GF_LOG_ERROR, 0, LG_MSG_RBTHASH_INSERT_FAILED, + NULL); ret = -1; goto err; } @@ -276,16 +272,16 @@ rbthash_insert(rbthash_table_t *tbl, void *data, void *key, int keylen) 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"); + 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_msg(GF_RBTHASH, GF_LOG_ERROR, 0, LG_MSG_RBTHASH_INSERT_FAILED, - "Failed to insert entry"); + gf_smsg(GF_RBTHASH, GF_LOG_ERROR, 0, LG_MSG_RBTHASH_INSERT_FAILED, + NULL); rbthash_deinit_entry(tbl, entry); goto err; } @@ -331,8 +327,8 @@ rbthash_get(rbthash_table_t *tbl, void *key, int keylen) 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"); + gf_smsg(GF_RBTHASH, GF_LOG_ERROR, 0, LG_MSG_RBTHASH_GET_BUCKET_FAILED, + NULL); return NULL; } @@ -365,8 +361,8 @@ rbthash_remove(rbthash_table_t *tbl, void *key, int keylen) 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"); + gf_smsg(GF_RBTHASH, GF_LOG_ERROR, 0, LG_MSG_RBTHASH_GET_BUCKET_FAILED, + NULL); return NULL; } diff --git a/libglusterfs/src/stack.c b/libglusterfs/src/stack.c index 371f60c4436..1531f0da43f 100644 --- a/libglusterfs/src/stack.c +++ b/libglusterfs/src/stack.c @@ -92,7 +92,7 @@ gf_proc_dump_call_frame(call_frame_t *call_frame, const char *key_buf, ...) }; int ret = -1; - char timestr[256] = { + char timestr[GF_TIMESTR_SIZE] = { 0, }; int len; @@ -162,7 +162,7 @@ gf_proc_dump_call_stack(call_stack_t *call_stack, const char *key_buf, ...) va_list ap; call_frame_t *trav; int32_t i = 1, cnt = 0; - char timestr[256] = { + char timestr[GF_TIMESTR_SIZE] = { 0, }; int len; diff --git a/libglusterfs/src/statedump.c b/libglusterfs/src/statedump.c index 5e0f04f3217..65f0eb5c7f3 100644 --- a/libglusterfs/src/statedump.c +++ b/libglusterfs/src/statedump.c @@ -199,6 +199,40 @@ gf_proc_dump_write(char *key, char *value, ...) 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); +} + +void +gf_proc_dump_xl_latency_info(xlator_t *xl) +{ + 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("%s", key_prefix); + + 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) { @@ -270,7 +304,7 @@ gf_proc_dump_xlator_mem_info_only_in_use(xlator_t *xl) void gf_proc_dump_mem_info() { -#ifdef HAVE_MALLOC_STATS +#ifdef HAVE_MALLINFO struct mallinfo info; memset(&info, 0, sizeof(struct mallinfo)); @@ -296,7 +330,7 @@ gf_proc_dump_mem_info_to_dict(dict_t *dict) { if (!dict) return; -#ifdef HAVE_MALLOC_STATS +#ifdef HAVE_MALLINFO struct mallinfo info; int ret = -1; @@ -349,26 +383,13 @@ gf_proc_dump_mem_info_to_dict(dict_t *dict) 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"); -#if defined(OLD_MEM_POOLS) - list_for_each_entry(pool, &ctx->mempool_list, global_list) - { - gf_proc_dump_write("-----", "-----"); - gf_proc_dump_write("pool-name", "%s", pool->name); - gf_proc_dump_write("hot-count", "%d", pool->hot_count); - gf_proc_dump_write("cold-count", "%d", pool->cold_count); - gf_proc_dump_write("padded_sizeof", "%lu", pool->padded_sizeof_type); - gf_proc_dump_write("alloc-count", "%" PRIu64, pool->alloc_count); - gf_proc_dump_write("max-alloc", "%d", pool->max_alloc); - - gf_proc_dump_write("pool-misses", "%" PRIu64, pool->pool_misses); - gf_proc_dump_write("cur-stdalloc", "%d", pool->curr_stdalloc); - gf_proc_dump_write("max-stdalloc", "%d", pool->max_stdalloc); - } -#else LOCK(&ctx->lock); { list_for_each_entry(pool, &ctx->mempool_list, owner) @@ -377,6 +398,7 @@ gf_proc_dump_mempool_info(glusterfs_ctx_t *ctx) 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", @@ -387,15 +409,13 @@ gf_proc_dump_mempool_info(glusterfs_ctx_t *ctx) } } UNLOCK(&ctx->lock); - - /* TODO: details of (struct mem_pool_shared) pool->pool */ -#endif +#endif /* GF_DISABLE_MEMPOOL */ } void gf_proc_dump_mempool_info_to_dict(glusterfs_ctx_t *ctx, dict_t *dict) { -#if defined(OLD_MEM_POOLS) +#ifndef GF_DISABLE_MEMPOOL struct mem_pool *pool = NULL; char key[GF_DUMP_MAX_BUF_LEN] = { 0, @@ -406,51 +426,47 @@ gf_proc_dump_mempool_info_to_dict(glusterfs_ctx_t *ctx, dict_t *dict) if (!ctx || !dict) return; - list_for_each_entry(pool, &ctx->mempool_list, global_list) + LOCK(&ctx->lock); { - snprintf(key, sizeof(key), "pool%d.name", count); - ret = dict_set_str(dict, key, pool->name); - if (ret) - return; - - snprintf(key, sizeof(key), "pool%d.hotcount", count); - ret = dict_set_int32(dict, key, pool->hot_count); - if (ret) - return; - - snprintf(key, sizeof(key), "pool%d.coldcount", count); - ret = dict_set_int32(dict, key, pool->cold_count); - if (ret) - return; - - snprintf(key, sizeof(key), "pool%d.paddedsizeof", count); - ret = dict_set_uint64(dict, key, pool->padded_sizeof_type); - if (ret) - return; - - snprintf(key, sizeof(key), "pool%d.alloccount", count); - ret = dict_set_uint64(dict, key, pool->alloc_count); - if (ret) - return; - - snprintf(key, sizeof(key), "pool%d.max_alloc", count); - ret = dict_set_int32(dict, key, pool->max_alloc); - if (ret) - return; - - snprintf(key, sizeof(key), "pool%d.max-stdalloc", count); - ret = dict_set_int32(dict, key, pool->max_stdalloc); - if (ret) - return; - - snprintf(key, sizeof(key), "pool%d.pool-misses", count); - ret = dict_set_uint64(dict, key, pool->pool_misses); - if (ret) - return; - count++; + 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; + + snprintf(key, sizeof(key), "pool%d.sizeof-type", count); + ret = dict_set_uint64(dict, key, pool->sizeof_type); + if (ret) + goto out; + + 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; + + snprintf(key, sizeof(key), "pool%d.shared-pool", count); + ret = dict_set_static_ptr(dict, key, pool->pool); + if (ret) + goto out; + } } - ret = dict_set_int32(dict, "mempool-count", count); -#endif +out: + UNLOCK(&ctx->lock); +#endif /* !GF_DISABLE_MEMPOOL */ } void @@ -485,7 +501,7 @@ gf_proc_dump_single_xlator_info(xlator_t *trav) return; if (ctx->measure_latency) - gf_proc_dump_latency_info(trav); + gf_proc_dump_xl_latency_info(trav); gf_proc_dump_xlator_mem_info(trav); @@ -782,7 +798,7 @@ gf_proc_dump_info(int signum, glusterfs_ctx_t *ctx) char brick_name[PATH_MAX] = { 0, }; - char timestr[256] = { + char timestr[GF_TIMESTR_SIZE] = { 0, }; char sign_string[512] = { @@ -842,7 +858,7 @@ gf_proc_dump_info(int signum, glusterfs_ctx_t *ctx) ? dump_options.dump_path : ((ctx->statedump_path != NULL) ? ctx->statedump_path : DEFAULT_VAR_RUN_DIRECTORY)), - brick_name, getpid(), (uint64_t)time(NULL)); + brick_name, getpid(), (uint64_t)gf_time()); if ((ret < 0) || (ret >= sizeof(path))) { goto out; } @@ -861,10 +877,7 @@ gf_proc_dump_info(int signum, glusterfs_ctx_t *ctx) // 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); - len = strlen(timestr); - snprintf(timestr + len, sizeof timestr - len, ".%" GF_PRI_SUSECONDS, - tv.tv_usec); + gf_time_fmt_tv(timestr, sizeof timestr, &tv, gf_timefmt_FT); } len = snprintf(sign_string, sizeof(sign_string), "DUMP-START-TIME: %s\n", @@ -913,10 +926,7 @@ gf_proc_dump_info(int signum, glusterfs_ctx_t *ctx) ret = gettimeofday(&tv, NULL); if (0 == ret) { - gf_time_fmt(timestr, sizeof timestr, tv.tv_sec, gf_timefmt_FT); - len = strlen(timestr); - snprintf(timestr + len, sizeof timestr - len, ".%" GF_PRI_SUSECONDS, - tv.tv_usec); + gf_time_fmt_tv(timestr, sizeof timestr, &tv, gf_timefmt_FT); } len = snprintf(sign_string, sizeof(sign_string), "\nDUMP-END-TIME: %s", @@ -1035,7 +1045,7 @@ gf_proc_dump_xlator_profile(xlator_t *this, strfd_t *strfd) { gf_dump_strfd = strfd; - gf_proc_dump_latency_info(this); + gf_proc_dump_xl_latency_info(this); gf_dump_strfd = NULL; } diff --git a/libglusterfs/src/store.c b/libglusterfs/src/store.c index 06ef75e3d35..5c316b9291a 100644 --- a/libglusterfs/src/store.c +++ b/libglusterfs/src/store.c @@ -22,7 +22,7 @@ gf_store_mkdir(char *path) { int32_t ret = -1; - ret = mkdir_p(path, 0777, _gf_true); + ret = mkdir_p(path, 0755, _gf_true); if ((-1 == ret) && (EEXIST != errno)) { gf_msg("", GF_LOG_ERROR, errno, LG_MSG_DIR_OP_FAILED, @@ -183,8 +183,8 @@ out: } int -gf_store_read_and_tokenize(FILE *file, char *str, int size, 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; @@ -192,15 +192,15 @@ gf_store_read_and_tokenize(FILE *file, char *str, int size, char **iter_key, char *value = NULL; char *temp = NULL; size_t str_len = 0; + char str[8192]; GF_ASSERT(file); - GF_ASSERT(str); GF_ASSERT(iter_key); GF_ASSERT(iter_val); GF_ASSERT(store_errno); retry: - temp = fgets(str, size, file); + temp = fgets(str, 8192, file); if (temp == NULL || feof(file)) { ret = -1; *store_errno = GD_STORE_EOF; @@ -240,13 +240,8 @@ int32_t 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); @@ -278,32 +273,9 @@ gf_store_retrieve_value(gf_store_handle_t *handle, char *key, char **value) } else { fseek(handle->read, 0, SEEK_SET); } - ret = sys_fstat(handle->fd, &st); - 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; - } - - free_str = scan_str; - do { - ret = gf_store_read_and_tokenize(handle->read, scan_str, st.st_size + 1, - &iter_key, &iter_val, &store_errno); + ret = gf_store_read_and_tokenize(handle->read, &iter_key, &iter_val, + &store_errno); if (ret < 0) { gf_msg_trace("", 0, "error while reading key '%s': " @@ -333,8 +305,6 @@ out: sys_close(handle->fd); } - GF_FREE(free_str); - return ret; } @@ -607,40 +577,16 @@ 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 = sys_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, st.st_size + 1, - &iter_key, &iter_val, &store_errno); + ret = gf_store_read_and_tokenize(iter->file, &iter_key, &iter_val, + &store_errno); if (ret < 0) { goto out; } @@ -665,7 +611,6 @@ gf_store_iter_get_next(gf_store_iter_t *iter, char **key, char **value, ret = 0; out: - GF_FREE(scan_str); if (ret) { GF_FREE(*key); GF_FREE(*value); @@ -704,23 +649,25 @@ out: } int32_t -gf_store_iter_destroy(gf_store_iter_t *iter) +gf_store_iter_destroy(gf_store_iter_t **iter) { int32_t ret = -1; - if (!iter) + if (!(*iter)) return 0; /* gf_store_iter_new will not return a valid iter object with iter->file * being NULL*/ - ret = fclose(iter->file); + 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); + (*iter)->filepath, ret); + + GF_FREE(*iter); + *iter = NULL; - GF_FREE(iter); return ret; } diff --git a/libglusterfs/src/syncop-utils.c b/libglusterfs/src/syncop-utils.c index 4167db465f4..d9f1723856d 100644 --- a/libglusterfs/src/syncop-utils.c +++ b/libglusterfs/src/syncop-utils.c @@ -345,10 +345,8 @@ syncop_mt_dir_scan(call_frame_t *frame, xlator_t *subvol, loc_t *loc, int pid, gf_dirent_t *tmp = NULL; uint32_t jobs_running = 0; uint32_t qlen = 0; - pthread_cond_t cond; - pthread_mutex_t mut; - gf_boolean_t cond_init = _gf_false; - gf_boolean_t mut_init = _gf_false; + pthread_cond_t cond = PTHREAD_COND_INITIALIZER; + pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER; gf_dirent_t entries; xlator_t *this = NULL; @@ -378,15 +376,6 @@ syncop_mt_dir_scan(call_frame_t *frame, xlator_t *subvol, loc_t *loc, int pid, INIT_LIST_HEAD(&entries.list); INIT_LIST_HEAD(&q.list); - ret = pthread_mutex_init(&mut, NULL); - if (ret) - goto out; - mut_init = _gf_true; - - ret = pthread_cond_init(&cond, NULL); - if (ret) - goto out; - cond_init = _gf_true; while ((ret = syncop_readdir(subvol, fd, 131072, offset, &entries, xdata, NULL))) { @@ -452,21 +441,17 @@ syncop_mt_dir_scan(call_frame_t *frame, xlator_t *subvol, loc_t *loc, int pid, out: if (fd) fd_unref(fd); - if (mut_init && cond_init) { - pthread_mutex_lock(&mut); - { - while (jobs_running) - pthread_cond_wait(&cond, &mut); - } - pthread_mutex_unlock(&mut); - gf_dirent_free(&q); - gf_dirent_free(&entries); + + pthread_mutex_lock(&mut); + { + while (jobs_running) + pthread_cond_wait(&cond, &mut); } + pthread_mutex_unlock(&mut); + + gf_dirent_free(&q); + gf_dirent_free(&entries); - if (mut_init) - pthread_mutex_destroy(&mut); - if (cond_init) - pthread_cond_destroy(&cond); return ret | retval; } diff --git a/libglusterfs/src/syncop.c b/libglusterfs/src/syncop.c index 2eb7b49fc4c..df20cec559f 100644 --- a/libglusterfs/src/syncop.c +++ b/libglusterfs/src/syncop.c @@ -11,6 +11,10 @@ #include "glusterfs/syncop.h" #include "glusterfs/libglusterfs-messages.h" +#ifdef HAVE_TSAN_API +#include <sanitizer/tsan_interface.h> +#endif + int syncopctx_setfsuid(void *uid) { @@ -97,6 +101,13 @@ syncopctx_setfsgroups(int count, const void *groups) /* 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: @@ -147,10 +158,14 @@ out: return ret; } +void * +syncenv_processor(void *thdata); + static void __run(struct synctask *task) { struct syncenv *env = NULL; + int32_t total, ret, i; env = task->env; @@ -166,7 +181,6 @@ __run(struct synctask *task) env->runcount--; break; case SYNCTASK_WAIT: - env->waitcount--; break; case SYNCTASK_DONE: gf_msg(task->xl->name, GF_LOG_WARNING, 0, LG_MSG_COMPLETED_TASK, @@ -180,8 +194,27 @@ __run(struct synctask *task) } list_add_tail(&task->all_tasks, &env->runq); - env->runcount++; 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; + } + } + } + } } static void @@ -203,7 +236,6 @@ __wait(struct synctask *task) gf_msg(task->xl->name, GF_LOG_WARNING, 0, LG_MSG_REWAITING_TASK, "re-waiting already waiting " "task"); - env->waitcount--; break; case SYNCTASK_DONE: gf_msg(task->xl->name, GF_LOG_WARNING, 0, LG_MSG_COMPLETED_TASK, @@ -216,12 +248,11 @@ __wait(struct synctask *task) } list_add_tail(&task->all_tasks, &env->waitq); - env->waitcount++; task->state = SYNCTASK_WAIT; } void -synctask_yield(struct synctask *task) +synctask_yield(struct synctask *task, struct timespec *delta) { xlator_t *oldTHIS = THIS; @@ -230,9 +261,16 @@ synctask_yield(struct synctask *task) task->proc->sched.uc_flags &= ~_UC_TLSBASE; #endif + task->delta = delta; + 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"); @@ -242,6 +280,35 @@ synctask_yield(struct synctask *task) } void +synctask_sleep(int32_t secs) +{ + struct timespec delta; + struct synctask *task; + + task = synctask_get(); + + if (task == NULL) { + sleep(secs); + } else { + delta.tv_sec = secs; + delta.tv_nsec = 0; + + synctask_yield(task, &delta); + } +} + +static void +__synctask_wake(struct synctask *task) +{ + task->woken = 1; + + if (task->slept) + __run(task); + + pthread_cond_broadcast(&task->env->cond); +} + +void synctask_wake(struct synctask *task) { struct syncenv *env = NULL; @@ -250,13 +317,18 @@ synctask_wake(struct synctask *task) pthread_mutex_lock(&env->mutex); { - task->woken = 1; + if (task->timer != NULL) { + if (gf_timer_call_cancel(task->xl->ctx, task->timer) != 0) { + goto unlock; + } - if (task->slept) - __run(task); + task->timer = NULL; + task->synccond = NULL; + } - pthread_cond_broadcast(&env->cond); + __synctask_wake(task); } +unlock: pthread_mutex_unlock(&env->mutex); } @@ -275,7 +347,7 @@ synctask_wrap(void) task->state = SYNCTASK_DONE; - synctask_yield(task); + synctask_yield(task, NULL); } void @@ -294,6 +366,10 @@ synctask_destroy(struct synctask *task) pthread_cond_destroy(&task->cond); } +#ifdef HAVE_TSAN_API + __tsan_destroy_fiber(task->tsan.fiber); +#endif + GF_FREE(task); } @@ -404,6 +480,13 @@ synctask_create(struct syncenv *env, size_t stacksize, synctask_fn_t fn, 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->slept = 1; @@ -415,11 +498,6 @@ synctask_create(struct syncenv *env, size_t stacksize, synctask_fn_t fn, } synctask_wake(newtask); - /* - * Make sure someone's there to execute anything we just put on the - * run queue. - */ - syncenv_scale(env); return newtask; err: @@ -513,8 +591,12 @@ syncenv_task(struct syncproc *proc) goto unlock; } - sleep_till.tv_sec = time(NULL) + SYNCPROC_IDLE_TIME; + 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); @@ -533,6 +615,34 @@ unlock: return task; } +static void +synctask_timer(void *data) +{ + struct synctask *task = data; + struct synccond *cond; + + cond = task->synccond; + if (cond != NULL) { + pthread_mutex_lock(&cond->pmutex); + + list_del_init(&task->waitq); + task->synccond = NULL; + + pthread_mutex_unlock(&cond->pmutex); + + task->ret = -ETIMEDOUT; + } + + pthread_mutex_lock(&task->env->mutex); + + gf_timer_call_cancel(task->xl->ctx, task->timer); + task->timer = NULL; + + __synctask_wake(task); + + pthread_mutex_unlock(&task->env->mutex); +} + void synctask_switchto(struct synctask *task) { @@ -548,6 +658,10 @@ synctask_switchto(struct synctask *task) task->ctx.uc_flags &= ~_UC_TLSBASE; #endif +#ifdef HAVE_TSAN_API + __tsan_switch_to_fiber(task->tsan.fiber, 0); +#endif + if (swapcontext(&task->proc->sched, &task->ctx) < 0) { gf_msg("syncop", GF_LOG_ERROR, errno, LG_MSG_SWAPCONTEXT_FAILED, "swapcontext failed"); @@ -565,7 +679,14 @@ synctask_switchto(struct synctask *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); + } } + + task->delta = NULL; } pthread_mutex_unlock(&env->mutex); } @@ -573,63 +694,27 @@ synctask_switchto(struct synctask *task) void * syncenv_processor(void *thdata) { - struct syncenv *env = NULL; struct syncproc *proc = NULL; struct synctask *task = NULL; proc = thdata; - env = proc->env; - 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 + while ((task = syncenv_task(proc)) != NULL) { synctask_switchto(task); - - syncenv_scale(env); } - return NULL; -} - -void -syncenv_scale(struct syncenv *env) -{ - int diff = 0; - int scale = 0; - int i = 0; - int ret = 0; - - 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; - } +#ifdef HAVE_TSAN_API + __tsan_destroy_fiber(proc->tsan.fiber); +#endif - env->proc[i].env = env; - ret = gf_thread_create(&env->proc[i].processor, NULL, - syncenv_processor, &env->proc[i], - "sproc%03hx", env->procs & 0x3ff); - if (ret) - break; - env->procs++; - i++; - } - } -unlock: - pthread_mutex_unlock(&env->mutex); + return NULL; } /* The syncenv threads are cleaned up in this routine. @@ -708,12 +793,13 @@ syncenv_new(size_t stacksize, int procmin, int procmax) 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], "sproc%d", - newenv->procs); + i); if (ret) break; newenv->procs++; @@ -803,7 +889,7 @@ __synclock_lock(struct synclock *lock) task->woken = 0; list_add_tail(&task->waitq, &lock->waitq); pthread_mutex_unlock(&lock->guard); - synctask_yield(task); + synctask_yield(task, NULL); /* task is removed from waitq in unlock, * under lock->guard.*/ pthread_mutex_lock(&lock->guard); @@ -956,6 +1042,136 @@ synclock_unlock(synclock_t *lock) return ret; } +/* Condition variables */ + +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); +} + +int +synccond_timedwait(synccond_t *cond, synclock_t *lock, struct timespec *delta) +{ + struct timespec now; + struct synctask *task = NULL; + int ret; + + task = synctask_get(); + + if (task == NULL) { + if (delta != NULL) { + timespec_now_realtime(&now); + timespec_adjust_delta(&now, *delta); + } + + pthread_mutex_lock(&cond->pmutex); + + 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); + + 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; + } + + list_del_init(&task->waitq); + } + + pthread_mutex_unlock(&cond->pmutex); + + return ret; +} + +int +synccond_wait(synccond_t *cond, synclock_t *lock) +{ + return synccond_timedwait(cond, lock, NULL); +} + +void +synccond_signal(synccond_t *cond) +{ + struct synctask *task; + + pthread_mutex_lock(&cond->pmutex); + + if (!list_empty(&cond->waitq)) { + task = list_first_entry(&cond->waitq, struct synctask, waitq); + list_del_init(&task->waitq); + + 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 @@ -1025,7 +1241,7 @@ __syncbarrier_wait(struct syncbarrier *barrier, int waitfor) /* called within a synctask */ list_add_tail(&task->waitq, &barrier->waitq); pthread_mutex_unlock(&barrier->guard); - synctask_yield(task); + synctask_yield(task, NULL); pthread_mutex_lock(&barrier->guard); } else { /* called by a non-synctask */ @@ -2874,12 +3090,13 @@ syncop_seek(xlator_t *subvol, fd_t *fd, off_t offset, gf_seek_what_t what, SYNCOP(subvol, (&args), syncop_seek_cbk, subvol->fops->seek, fd, offset, what, xdata_in); - if (*off) - *off = args.offset; - - if (args.op_ret == -1) + if (args.op_ret < 0) { return -args.op_errno; - return args.op_ret; + } else { + if (off) + *off = args.offset; + return args.op_ret; + } } int diff --git a/libglusterfs/src/syscall.c b/libglusterfs/src/syscall.c index 1d88c8adac1..04400f98b6c 100644 --- a/libglusterfs/src/syscall.c +++ b/libglusterfs/src/syscall.c @@ -13,6 +13,10 @@ #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> @@ -214,6 +218,15 @@ sys_unlink(const char *pathname) } int +sys_unlinkat(int dfd, const char *pathname) +{ +#ifdef GF_SOLARIS_HOST_OS + return FS_RET_CHECK0(solaris_unlinkat(dfd, pathname, 0), errno); +#endif + return FS_RET_CHECK0(unlinkat(dfd, pathname, 0), errno); +} + +int sys_rmdir(const char *pathname) { return FS_RET_CHECK0(rmdir(pathname), errno); @@ -226,6 +239,12 @@ sys_symlink(const char *oldpath, const char *newpath) } int +sys_symlinkat(const char *oldpath, int dirfd, const char *newpath) +{ + return FS_RET_CHECK0(symlinkat(oldpath, dirfd, newpath), errno); +} + +int sys_rename(const char *oldpath, const char *newpath) { #ifdef GF_SOLARIS_HOST_OS @@ -253,6 +272,12 @@ sys_link(const char *oldpath, const char *newpath) } int +sys_linkat(int oldfd, const char *oldpath, int newfd, const char *newpath) +{ + return FS_RET_CHECK0(linkat(oldfd, oldpath, newfd, newpath, 0), errno); +} + +int sys_chmod(const char *path, mode_t mode) { return FS_RET_CHECK0(chmod(path, mode), errno); @@ -485,7 +510,7 @@ sys_lsetxattr(const char *path, const char *name, const void *value, #endif #ifdef GF_BSD_HOST_OS - return FS_RET_CHECK0( + return FS_RET_CHECK( extattr_set_link(path, EXTATTR_NAMESPACE_USER, name, value, size), errno); #endif @@ -603,7 +628,7 @@ sys_fsetxattr(int filedes, const char *name, const void *value, size_t size, #endif #ifdef GF_BSD_HOST_OS - return FS_RET_CHECK0( + return FS_RET_CHECK( extattr_set_fd(filedes, EXTATTR_NAMESPACE_USER, name, value, size), errno); #endif @@ -828,7 +853,24 @@ sys_copy_file_range(int fd_in, off64_t *off_in, int fd_out, off64_t *off_out, return syscall(SYS_copy_file_range, fd_in, off_in, fd_out, off_out, len, flags); #else - return -ENOSYS; + errno = ENOSYS; + return -1; #endif /* HAVE_COPY_FILE_RANGE_SYS */ #endif /* HAVE_COPY_FILE_RANGE */ } + +#ifdef __FreeBSD__ +int +sys_kill(pid_t pid, int sig) +{ + return FS_RET_CHECK0(kill(pid, sig), errno); +} + +int +sys_sysctl(const int *name, u_int namelen, void *oldp, size_t *oldlenp, + const void *newp, size_t newlen) +{ + return FS_RET_CHECK0(sysctl(name, namelen, oldp, oldlenp, newp, newlen), + errno); +} +#endif diff --git a/libglusterfs/src/throttle-tbf.c b/libglusterfs/src/throttle-tbf.c index 81efebd7efe..e11ca4f9d35 100644 --- a/libglusterfs/src/throttle-tbf.c +++ b/libglusterfs/src/throttle-tbf.c @@ -99,7 +99,7 @@ tbf_tokengenerator(void *arg) token_gen_interval = bucket->token_gen_interval; while (1) { - usleep(token_gen_interval); + gf_nanosleep(token_gen_interval * GF_US_IN_NS); LOCK(&bucket->lock); { diff --git a/libglusterfs/src/tier-ctr-interface.h b/libglusterfs/src/tier-ctr-interface.h deleted file mode 100644 index 19680aa3bea..00000000000 --- a/libglusterfs/src/tier-ctr-interface.h +++ /dev/null @@ -1,44 +0,0 @@ -#ifndef _TIER_CTR_INTERFACE_H_ -#define _TIER_CTR_INTERFACE_H_ - -#include "glusterfs/common-utils.h" -#include "gfdb_data_store_types.h" - -#define GFDB_IPC_CTR_KEY "gfdb.ipc-ctr-op" - -/* - * CTR IPC OPERATIONS - * - * - */ -#define GFDB_IPC_CTR_QUERY_OPS "gfdb.ipc-ctr-query-op" -#define GFDB_IPC_CTR_CLEAR_OPS "gfdb.ipc-ctr-clear-op" -#define GFDB_IPC_CTR_GET_DB_PARAM_OPS "gfdb.ipc-ctr-get-db-parm" -#define GFDB_IPC_CTR_GET_DB_VERSION_OPS "gfdb.ipc-ctr-get-db-version" -#define GFDB_IPC_CTR_SET_COMPACT_PRAGMA "gfdb.ipc-ctr-set-compact-pragma" -/* - * CTR IPC INPUT/OUTPUT - * - * - */ -#define GFDB_IPC_CTR_GET_QFILE_PATH "gfdb.ipc-ctr-get-qfile-path" -#define GFDB_IPC_CTR_GET_QUERY_PARAMS "gfdb.ipc-ctr-get-query-parms" -#define GFDB_IPC_CTR_RET_QUERY_COUNT "gfdb.ipc-ctr-ret-rec-count" -#define GFDB_IPC_CTR_GET_DB_KEY "gfdb.ipc-ctr-get-params-key" -#define GFDB_IPC_CTR_RET_DB_VERSION "gfdb.ipc-ctr-ret-db-version" - -/* - * gfdb ipc ctr params for query - * - * - */ -typedef struct gfdb_ipc_ctr_params { - gf_boolean_t is_promote; - int write_freq_threshold; - int read_freq_threshold; - gfdb_time_t time_stamp; - int query_limit; - gf_boolean_t emergency_demote; -} gfdb_ipc_ctr_params_t; - -#endif diff --git a/libglusterfs/src/timer.c b/libglusterfs/src/timer.c index 1e19ffdff22..66c861b04cd 100644 --- a/libglusterfs/src/timer.c +++ b/libglusterfs/src/timer.c @@ -137,7 +137,8 @@ gf_timer_proc(void *data) timespec_now(&now); event = list_first_entry(®->active, gf_timer_t, list); if (TS(now) < TS(event->at)) { - pthread_cond_timedwait(®->cond, ®->lock, &event->at); + now = event->at; + pthread_cond_timedwait(®->cond, ®->lock, &now); } else { event->fired = _gf_true; list_del_init(&event->list); diff --git a/libglusterfs/src/xlator.c b/libglusterfs/src/xlator.c index 9906809f7aa..9a2582d45d5 100644 --- a/libglusterfs/src/xlator.c +++ b/libglusterfs/src/xlator.c @@ -184,9 +184,11 @@ xlator_volopt_dynload(char *xlator_type, void **dl_handle, volume_opt_list_t *opt_list) { int ret = -1; + int flag = 0; char *name = NULL; void *handle = NULL; xlator_api_t *xlapi = NULL; + volume_option_t *opt = NULL; GF_VALIDATE_OR_GOTO("xlator", xlator_type, out); @@ -194,8 +196,10 @@ xlator_volopt_dynload(char *xlator_type, void **dl_handle, * need this check */ if (!strstr(xlator_type, "rpc-transport")) ret = gf_asprintf(&name, "%s/%s.so", XLATORDIR, xlator_type); - else + else { + flag = 1; ret = gf_asprintf(&name, "%s/%s.so", XLATORPARENTDIR, xlator_type); + } if (-1 == ret) { goto out; } @@ -206,24 +210,34 @@ xlator_volopt_dynload(char *xlator_type, void **dl_handle, handle = dlopen(name, RTLD_NOW); if (!handle) { - gf_msg("xlator", GF_LOG_WARNING, 0, LG_MSG_DLOPEN_FAILED, "%s", - dlerror()); + gf_smsg("xlator", GF_LOG_WARNING, 0, LG_MSG_DLOPEN_FAILED, "error=%s", + dlerror(), NULL); goto out; } - /* check new struct first, and then check this */ - xlapi = dlsym(handle, "xlator_api"); - if (!xlapi) { - gf_msg("xlator", GF_LOG_ERROR, 0, LG_MSG_DLSYM_ERROR, - "dlsym(xlator_api) missing: %s", dlerror()); - goto out; - } + if (flag == 0) { + /* check new struct first, and then check this */ + xlapi = dlsym(handle, "xlator_api"); + if (!xlapi) { + gf_smsg("xlator", GF_LOG_ERROR, 0, LG_MSG_DLSYM_ERROR, "error=%s", + dlerror(), NULL); + goto out; + } - opt_list->given_opt = xlapi->options; - if (!opt_list->given_opt) { - gf_msg("xlator", GF_LOG_ERROR, 0, LG_MSG_LOAD_FAILED, - "Failed to load xlator options table"); - goto out; + opt_list->given_opt = xlapi->options; + if (!opt_list->given_opt) { + gf_smsg("xlator", GF_LOG_ERROR, 0, LG_MSG_LOAD_FAILED, NULL); + goto out; + } + } else { + opt = dlsym(handle, "options"); + if (!opt) { + gf_smsg("xlator", GF_LOG_ERROR, 0, LG_MSG_DLSYM_ERROR, "error=%s", + dlerror(), NULL); + goto out; + } + + opt_list->given_opt = opt; } *dl_handle = handle; @@ -246,21 +260,22 @@ xlator_dynload_apis(xlator_t *xl) void *handle = NULL; volume_opt_list_t *vol_opt = NULL; xlator_api_t *xlapi = NULL; + int i = 0; handle = xl->dlhandle; xlapi = dlsym(handle, "xlator_api"); if (!xlapi) { - gf_msg("xlator", GF_LOG_ERROR, 0, LG_MSG_DLSYM_ERROR, - "dlsym(xlator_api) missing: %s", dlerror()); + gf_smsg("xlator", GF_LOG_ERROR, 0, LG_MSG_DLSYM_ERROR, "dlsym=%s", + dlerror(), NULL); ret = -1; goto out; } xl->fops = xlapi->fops; if (!xl->fops) { - gf_msg("xlator", GF_LOG_WARNING, 0, LG_MSG_DLSYM_ERROR, - "%s: struct missing (fops)", xl->name); + gf_smsg("xlator", GF_LOG_WARNING, 0, LG_MSG_STRUCT_MISS, "name=%s", + xl->name, NULL); goto out; } @@ -271,8 +286,8 @@ xlator_dynload_apis(xlator_t *xl) xl->init = xlapi->init; if (!xl->init) { - gf_msg("xlator", GF_LOG_WARNING, 0, LG_MSG_DLSYM_ERROR, - "%s: method missing (init)", xl->name); + gf_smsg("xlator", GF_LOG_WARNING, 0, LG_MSG_METHOD_MISS, "name=%s", + xl->name, NULL); goto out; } @@ -343,6 +358,10 @@ xlator_dynload_apis(xlator_t *xl) memcpy(xl->op_version, xlapi->op_version, sizeof(uint32_t) * GF_MAX_RELEASES); + for (i = 0; i < GF_FOP_MAXVALUE; i++) { + gf_latency_reset(&xl->stats.interval.latencies[i]); + } + ret = 0; out: return ret; @@ -370,8 +389,8 @@ xlator_dynload(xlator_t *xl) handle = dlopen(name, RTLD_NOW); if (!handle) { - gf_msg("xlator", GF_LOG_WARNING, 0, LG_MSG_DLOPEN_FAILED, "%s", - dlerror()); + gf_smsg("xlator", GF_LOG_WARNING, 0, LG_MSG_DLOPEN_FAILED, "error=%s", + dlerror(), NULL); goto out; } xl->dlhandle = handle; @@ -438,10 +457,8 @@ xlator_set_inode_lru_limit(xlator_t *this, void *data) if (this->itable) { if (!data) { - gf_msg(this->name, GF_LOG_WARNING, 0, LG_MSG_INVALID_ENTRY, - "input data is NULL. " - "Cannot update the lru limit of the inode" - " table. Continuing with older value"); + gf_smsg(this->name, GF_LOG_WARNING, 0, LG_MSG_INPUT_DATA_NULL, + NULL); goto out; } inode_lru_limit = *(int *)data; @@ -615,18 +632,15 @@ xlator_init(xlator_t *xl) xl->instance_name = NULL; GF_ATOMIC_INIT(xl->xprtrefcnt, 0); if (!xl->init) { - gf_msg(xl->name, GF_LOG_WARNING, 0, LG_MSG_INIT_FAILED, - "No init() found"); + gf_smsg(xl->name, GF_LOG_WARNING, 0, LG_MSG_INIT_FAILED, NULL); goto out; } ret = __xlator_init(xl); if (ret) { - gf_msg(xl->name, GF_LOG_ERROR, 0, LG_MSG_VOLUME_ERROR, - "Initialization of volume '%s' failed," - " review your volfile again", - xl->name); + gf_smsg(xl->name, GF_LOG_ERROR, 0, LG_MSG_VOLUME_ERROR, "name=%s", + xl->name, NULL); goto out; } @@ -812,7 +826,7 @@ xlator_members_free(xlator_t *xl) GF_FREE(xl->name); GF_FREE(xl->type); - if (!(xl->ctx && xl->ctx->cmd_args.valgrind) && xl->dlhandle) + if (!(xl->ctx && xl->ctx->cmd_args.vgtool != _gf_none) && xl->dlhandle) dlclose(xl->dlhandle); if (xl->options) dict_unref(xl->options); @@ -862,8 +876,7 @@ xlator_tree_free_members(xlator_t *tree) xlator_t *prev = tree; if (!tree) { - gf_msg("parser", GF_LOG_ERROR, 0, LG_MSG_TREE_NOT_FOUND, - "Translator tree not found"); + gf_smsg("parser", GF_LOG_ERROR, 0, LG_MSG_TREE_NOT_FOUND, NULL); return -1; } @@ -883,8 +896,7 @@ xlator_tree_free_memacct(xlator_t *tree) xlator_t *prev = tree; if (!tree) { - gf_msg("parser", GF_LOG_ERROR, 0, LG_MSG_TREE_NOT_FOUND, - "Translator tree not found"); + gf_smsg("parser", GF_LOG_ERROR, 0, LG_MSG_TREE_NOT_FOUND, NULL); return -1; } @@ -945,6 +957,8 @@ xlator_mem_cleanup(xlator_t *this) xlator_list_t **trav_p = NULL; xlator_t *top = NULL; xlator_t *victim = NULL; + glusterfs_graph_t *graph = NULL; + gf_boolean_t graph_cleanup = _gf_false; if (this->call_cleanup || !this->ctx) return; @@ -952,6 +966,12 @@ xlator_mem_cleanup(xlator_t *this) this->call_cleanup = 1; ctx = this->ctx; + inode_table = this->itable; + if (inode_table) { + inode_table_destroy(inode_table); + this->itable = NULL; + } + xlator_call_fini(trav); while (prev) { @@ -960,12 +980,6 @@ xlator_mem_cleanup(xlator_t *this) prev = trav; } - inode_table = this->itable; - if (inode_table) { - inode_table_destroy(inode_table); - this->itable = NULL; - } - if (this->fini) { this->fini(this); } @@ -975,17 +989,28 @@ xlator_mem_cleanup(xlator_t *this) if (ctx->active) { top = ctx->active->first; LOCK(&ctx->volfile_lock); - /* TODO here we have leak for xlator node in a graph */ - /* Need to move only top xlator from a graph */ for (trav_p = &top->children; *trav_p; trav_p = &(*trav_p)->next) { victim = (*trav_p)->xlator; if (victim->call_cleanup && !strcmp(victim->name, this->name)) { + graph_cleanup = _gf_true; (*trav_p) = (*trav_p)->next; break; } } UNLOCK(&ctx->volfile_lock); } + + if (graph_cleanup) { + prev = this; + graph = ctx->active; + pthread_mutex_lock(&graph->mutex); + while (prev) { + trav = prev->next; + GF_FREE(prev); + prev = trav; + } + pthread_mutex_unlock(&graph->mutex); + } } void @@ -1344,9 +1369,9 @@ is_gf_log_command(xlator_t *this, const char *name, char *value, size_t size) /* Some crude way to change the log-level of process */ if (!strcmp(name, "trusted.glusterfs.set-log-level")) { - gf_msg("glusterfs", gf_log_get_loglevel(), 0, LG_MSG_SET_LOG_LEVEL, - "setting log level to %d (old-value=%d)", log_level, - gf_log_get_loglevel()); + gf_smsg("glusterfs", gf_log_get_loglevel(), 0, LG_MSG_SET_LOG_LEVEL, + "new-value=%d", log_level, "old-value=%d", + gf_log_get_loglevel(), NULL); gf_log_set_loglevel(this->ctx, log_level); ret = 0; goto out; @@ -1354,9 +1379,9 @@ is_gf_log_command(xlator_t *this, const char *name, char *value, size_t size) if (!strcmp(name, "trusted.glusterfs.fuse.set-log-level")) { /* */ - gf_msg(this->name, gf_log_get_xl_loglevel(this), 0, - LG_MSG_SET_LOG_LEVEL, "setting log level to %d (old-value=%d)", - log_level, gf_log_get_xl_loglevel(this)); + gf_smsg(this->name, gf_log_get_xl_loglevel(this), 0, + LG_MSG_SET_LOG_LEVEL, "new-value=%d", log_level, "old-value=%d", + gf_log_get_xl_loglevel(this), NULL); gf_log_set_xl_loglevel(this, log_level); ret = 0; goto out; @@ -1372,10 +1397,9 @@ is_gf_log_command(xlator_t *this, const char *name, char *value, size_t size) while (trav) { snprintf(key, 1024, "trusted.glusterfs.%s.set-log-level", trav->name); if (fnmatch(name, key, FNM_NOESCAPE) == 0) { - gf_msg(trav->name, gf_log_get_xl_loglevel(trav), 0, - LG_MSG_SET_LOG_LEVEL, - "setting log level to %d (old-value=%d)", log_level, - gf_log_get_xl_loglevel(trav)); + gf_smsg(trav->name, gf_log_get_xl_loglevel(trav), 0, + LG_MSG_SET_LOG_LEVEL, "new-value%d", log_level, + "old-value=%d", gf_log_get_xl_loglevel(trav), NULL); gf_log_set_xl_loglevel(trav, log_level); ret = 0; } @@ -1407,9 +1431,7 @@ glusterd_check_log_level(const char *value) } if (log_level == -1) - gf_msg(THIS->name, GF_LOG_ERROR, 0, LG_MSG_INIT_FAILED, - "Invalid log-level. possible values are " - "DEBUG|WARNING|ERROR|CRITICAL|NONE|TRACE"); + gf_smsg(THIS->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_INIT, NULL); return log_level; } @@ -1486,8 +1508,7 @@ gluster_graph_take_reference(xlator_t *tree) xlator_t *prev = tree; if (!tree) { - gf_msg("parser", GF_LOG_ERROR, 0, LG_MSG_TREE_NOT_FOUND, - "Translator tree not found"); + gf_smsg("parser", GF_LOG_ERROR, 0, LG_MSG_TREE_NOT_FOUND, NULL); return; } @@ -1524,15 +1545,15 @@ xlator_is_cleanup_starting(xlator_t *this) xlator_t *xl = NULL; if (!this) { - gf_msg("xlator", GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG, - "xlator object is null, returning false"); + gf_smsg("xlator", GF_LOG_WARNING, EINVAL, LG_MSG_OBJECT_NULL, "xlator", + NULL); goto out; } graph = this->graph; if (!graph) { - gf_msg("xlator", GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG, - "Graph is not set for xlator %s", this->name); + gf_smsg("xlator", GF_LOG_WARNING, EINVAL, LG_MSG_GRAPH_NOT_SET, + "name=%s", this->name, NULL); goto out; } @@ -1542,3 +1563,31 @@ xlator_is_cleanup_starting(xlator_t *this) out: return cleanup; } + +int +graph_total_client_xlator(glusterfs_graph_t *graph) +{ + xlator_t *xl = NULL; + int count = 0; + + if (!graph) { + gf_smsg("xlator", GF_LOG_WARNING, EINVAL, LG_MSG_OBJECT_NULL, "graph", + NULL); + goto out; + } + + xl = graph->first; + if (!strcmp(xl->type, "protocol/server")) { + gf_msg_debug(xl->name, 0, "Return because it is a server graph"); + return 0; + } + + while (xl) { + if (strcmp(xl->type, "protocol/client") == 0) { + count++; + } + xl = xl->next; + } +out: + return count; +} |
