diff options
Diffstat (limited to 'xlators/debug')
21 files changed, 9407 insertions, 4712 deletions
diff --git a/xlators/debug/Makefile.am b/xlators/debug/Makefile.am index b655554efec..88fac1c6d9e 100644 --- a/xlators/debug/Makefile.am +++ b/xlators/debug/Makefile.am @@ -1,3 +1,3 @@ -SUBDIRS = trace error-gen io-stats +SUBDIRS = error-gen io-stats sink trace delay-gen CLEANFILES = diff --git a/xlators/debug/delay-gen/Makefile.am b/xlators/debug/delay-gen/Makefile.am new file mode 100644 index 00000000000..a985f42a877 --- /dev/null +++ b/xlators/debug/delay-gen/Makefile.am @@ -0,0 +1,3 @@ +SUBDIRS = src + +CLEANFILES = diff --git a/xlators/debug/delay-gen/src/Makefile.am b/xlators/debug/delay-gen/src/Makefile.am new file mode 100644 index 00000000000..8f758dec199 --- /dev/null +++ b/xlators/debug/delay-gen/src/Makefile.am @@ -0,0 +1,11 @@ + +xlator_LTLIBRARIES = delay-gen.la +xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/debug +delay_gen_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) +delay_gen_la_SOURCES = delay-gen.c +delay_gen_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la +noinst_HEADERS = delay-gen.h delay-gen-mem-types.h delay-gen-messages.h +AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ + -I$(top_srcdir)/rpc/xdr/src -I$(top_builddir)/rpc/xdr/src +AM_CFLAGS = -Wall -fno-strict-aliasing $(GF_CFLAGS) +CLEANFILES = diff --git a/xlators/debug/delay-gen/src/delay-gen-mem-types.h b/xlators/debug/delay-gen/src/delay-gen-mem-types.h new file mode 100644 index 00000000000..c89a9217193 --- /dev/null +++ b/xlators/debug/delay-gen/src/delay-gen-mem-types.h @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2017 Red Hat, Inc. <http://www.redhat.com> + * This file is part of GlusterFS. + * + * This file is licensed to you under your choice of the GNU Lesser + * General Public License, version 3 or any later version (LGPLv3 or + * later), or the GNU General Public License, version 2 (GPLv2), in all + * cases as published by the Free Software Foundation. + */ + +#ifndef __DELAY_GEN_MEM_TYPES_H__ +#define __DELAY_GEN_MEM_TYPES_H__ + +#include <glusterfs/mem-types.h> + +enum gf_delay_gen_mem_types_ { + gf_delay_gen_mt_dg_t = gf_common_mt_end + 1, + gf_delay_gen_mt_end +}; + +#endif /* __DELAY_GEN_MEM_TYPES_H__ */ diff --git a/xlators/debug/delay-gen/src/delay-gen-messages.h b/xlators/debug/delay-gen/src/delay-gen-messages.h new file mode 100644 index 00000000000..bc98cec2885 --- /dev/null +++ b/xlators/debug/delay-gen/src/delay-gen-messages.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2017 Red Hat, Inc. <http://www.redhat.com> + * This file is part of GlusterFS. + * + * This file is licensed to you under your choice of the GNU Lesser + * General Public License, version 3 or any later version (LGPLv3 or + * later), or the GNU General Public License, version 2 (GPLv2), in all + * cases as published by the Free Software Foundation. + */ + +#ifndef __DELAY_GEN_MESSAGES_H__ +#define __DELAY_GEN_MESSAGES_H__ + +#include <glusterfs/glfs-message-id.h> + +/* To add new message IDs, append new identifiers at the end of the list. + * + * Never remove a message ID. If it's not used anymore, you can rename it or + * leave it as it is, but not delete it. This is to prevent reutilization of + * IDs by other messages. + * + * The component name must match one of the entries defined in + * glfs-message-id.h. + */ + +#endif /* __DELAY_GEN_MESSAGES_H__ */ diff --git a/xlators/debug/delay-gen/src/delay-gen.c b/xlators/debug/delay-gen/src/delay-gen.c new file mode 100644 index 00000000000..4698f1fd785 --- /dev/null +++ b/xlators/debug/delay-gen/src/delay-gen.c @@ -0,0 +1,697 @@ +/* + * Copyright (c) 2017 Red Hat, Inc. <http://www.redhat.com> + * This file is part of GlusterFS. + * + * This file is licensed to you under your choice of the GNU Lesser + * General Public License, version 3 or any later version (LGPLv3 or + * later), or the GNU General Public License, version 2 (GPLv2), in all + * cases as published by the Free Software Foundation. + */ + +#include "delay-gen.h" + +#define DELAY_GRANULARITY (1 << 20) + +#define DG_FOP(fop, name, frame, this, args...) \ + do { \ + delay_gen(this, fop); \ + default_##name(frame, this, args); \ + } while (0) + +int +delay_gen(xlator_t *this, int fop) +{ + dg_t *dg = this->private; + + if (!dg->enable[fop] || !dg->delay_ppm) + return 0; + + if ((rand() % DELAY_GRANULARITY) < dg->delay_ppm) + gf_nanosleep(dg->delay_duration * GF_US_IN_NS); + + return 0; +} + +int32_t +dg_rename(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, + dict_t *xdata) +{ + DG_FOP(GF_FOP_RENAME, rename, frame, this, oldloc, newloc, xdata); + return 0; +} + +int32_t +dg_ipc(call_frame_t *frame, xlator_t *this, int32_t op, dict_t *xdata) +{ + DG_FOP(GF_FOP_IPC, ipc, frame, this, op, xdata); + return 0; +} + +int32_t +dg_setactivelk(call_frame_t *frame, xlator_t *this, loc_t *loc, + lock_migration_info_t *locklist, dict_t *xdata) +{ + DG_FOP(GF_FOP_SETACTIVELK, setactivelk, frame, this, loc, locklist, xdata); + return 0; +} + +int32_t +dg_flush(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata) +{ + DG_FOP(GF_FOP_FLUSH, flush, frame, this, fd, xdata); + return 0; +} + +int32_t +dg_readdir(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, + off_t off, dict_t *xdata) +{ + DG_FOP(GF_FOP_READDIR, readdir, frame, this, fd, size, off, xdata); + return 0; +} + +int32_t +dg_setxattr(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict, + int32_t flags, dict_t *xdata) +{ + DG_FOP(GF_FOP_SETXATTR, setxattr, frame, this, loc, dict, flags, xdata); + return 0; +} + +int32_t +dg_mknod(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, + dev_t rdev, mode_t umask, dict_t *xdata) +{ + DG_FOP(GF_FOP_MKNOD, mknod, frame, this, loc, mode, rdev, umask, xdata); + return 0; +} + +int32_t +dg_fsetxattr(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *dict, + int32_t flags, dict_t *xdata) +{ + DG_FOP(GF_FOP_FSETXATTR, fsetxattr, frame, this, fd, dict, flags, xdata); + return 0; +} + +int32_t +dg_readv(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, + off_t offset, uint32_t flags, dict_t *xdata) +{ + DG_FOP(GF_FOP_READ, readv, frame, this, fd, size, offset, flags, xdata); + return 0; +} + +int32_t +dg_inodelk(call_frame_t *frame, xlator_t *this, const char *volume, loc_t *loc, + int32_t cmd, struct gf_flock *lock, dict_t *xdata) +{ + DG_FOP(GF_FOP_INODELK, inodelk, frame, this, volume, loc, cmd, lock, xdata); + return 0; +} + +int32_t +dg_fremovexattr(call_frame_t *frame, xlator_t *this, fd_t *fd, const char *name, + dict_t *xdata) +{ + DG_FOP(GF_FOP_FREMOVEXATTR, fremovexattr, frame, this, fd, name, xdata); + return 0; +} + +int32_t +dg_open(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, + fd_t *fd, dict_t *xdata) +{ + DG_FOP(GF_FOP_OPEN, open, frame, this, loc, flags, fd, xdata); + return 0; +} + +int32_t +dg_xattrop(call_frame_t *frame, xlator_t *this, loc_t *loc, + gf_xattrop_flags_t flags, dict_t *dict, dict_t *xdata) +{ + DG_FOP(GF_FOP_XATTROP, xattrop, frame, this, loc, flags, dict, xdata); + return 0; +} + +int32_t +dg_entrylk(call_frame_t *frame, xlator_t *this, const char *volume, loc_t *loc, + const char *basename, entrylk_cmd cmd, entrylk_type type, + dict_t *xdata) +{ + DG_FOP(GF_FOP_ENTRYLK, entrylk, frame, this, volume, loc, basename, cmd, + type, xdata); + return 0; +} + +int32_t +dg_getactivelk(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) +{ + DG_FOP(GF_FOP_GETACTIVELK, getactivelk, frame, this, loc, xdata); + return 0; +} + +int32_t +dg_finodelk(call_frame_t *frame, xlator_t *this, const char *volume, fd_t *fd, + int32_t cmd, struct gf_flock *lock, dict_t *xdata) +{ + DG_FOP(GF_FOP_FINODELK, finodelk, frame, this, volume, fd, cmd, lock, + xdata); + return 0; +} + +int32_t +dg_create(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, + mode_t mode, mode_t umask, fd_t *fd, dict_t *xdata) +{ + DG_FOP(GF_FOP_CREATE, create, frame, this, loc, flags, mode, umask, fd, + xdata); + return 0; +} + +int32_t +dg_discard(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, + size_t len, dict_t *xdata) +{ + DG_FOP(GF_FOP_DISCARD, discard, frame, this, fd, offset, len, xdata); + return 0; +} + +int32_t +dg_mkdir(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, + mode_t umask, dict_t *xdata) +{ + DG_FOP(GF_FOP_MKDIR, mkdir, frame, this, loc, mode, umask, xdata); + return 0; +} + +int32_t +dg_lk(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t cmd, + struct gf_flock *lock, dict_t *xdata) +{ + DG_FOP(GF_FOP_LK, lk, frame, this, fd, cmd, lock, xdata); + return 0; +} + +int32_t +dg_writev(call_frame_t *frame, xlator_t *this, fd_t *fd, struct iovec *vector, + int32_t count, off_t off, uint32_t flags, struct iobref *iobref, + dict_t *xdata) +{ + DG_FOP(GF_FOP_WRITE, writev, frame, this, fd, vector, count, off, flags, + iobref, xdata); + return 0; +} + +int32_t +dg_access(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t mask, + dict_t *xdata) +{ + DG_FOP(GF_FOP_ACCESS, access, frame, this, loc, mask, xdata); + return 0; +} + +int32_t +dg_lookup(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) +{ + DG_FOP(GF_FOP_LOOKUP, lookup, frame, this, loc, xdata); + return 0; +} + +int32_t +dg_rmdir(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, + dict_t *xdata) +{ + DG_FOP(GF_FOP_RMDIR, rmdir, frame, this, loc, flags, xdata); + return 0; +} + +int32_t +dg_fallocate(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t keep_size, + off_t offset, size_t len, dict_t *xdata) +{ + DG_FOP(GF_FOP_FALLOCATE, fallocate, frame, this, fd, keep_size, offset, len, + xdata); + return 0; +} + +int32_t +dg_fstat(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata) +{ + DG_FOP(GF_FOP_FSTAT, fstat, frame, this, fd, xdata); + return 0; +} + +int32_t +dg_lease(call_frame_t *frame, xlator_t *this, loc_t *loc, + struct gf_lease *lease, dict_t *xdata) +{ + DG_FOP(GF_FOP_LEASE, lease, frame, this, loc, lease, xdata); + return 0; +} + +int32_t +dg_stat(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) +{ + DG_FOP(GF_FOP_STAT, stat, frame, this, loc, xdata); + return 0; +} + +int32_t +dg_truncate(call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset, + dict_t *xdata) +{ + DG_FOP(GF_FOP_TRUNCATE, truncate, frame, this, loc, offset, xdata); + return 0; +} + +int32_t +dg_getxattr(call_frame_t *frame, xlator_t *this, loc_t *loc, const char *name, + dict_t *xdata) +{ + DG_FOP(GF_FOP_GETXATTR, getxattr, frame, this, loc, name, xdata); + return 0; +} + +int32_t +dg_symlink(call_frame_t *frame, xlator_t *this, const char *linkpath, + loc_t *loc, mode_t umask, dict_t *xdata) +{ + DG_FOP(GF_FOP_SYMLINK, symlink, frame, this, linkpath, loc, umask, xdata); + return 0; +} + +int32_t +dg_zerofill(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, + off_t len, dict_t *xdata) +{ + DG_FOP(GF_FOP_ZEROFILL, zerofill, frame, this, fd, offset, len, xdata); + return 0; +} + +int32_t +dg_fsyncdir(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags, + dict_t *xdata) +{ + DG_FOP(GF_FOP_FSYNCDIR, fsyncdir, frame, this, fd, flags, xdata); + return 0; +} + +int32_t +dg_fgetxattr(call_frame_t *frame, xlator_t *this, fd_t *fd, const char *name, + dict_t *xdata) +{ + DG_FOP(GF_FOP_FGETXATTR, fgetxattr, frame, this, fd, name, xdata); + return 0; +} + +int32_t +dg_readdirp(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, + off_t off, dict_t *xdata) +{ + DG_FOP(GF_FOP_READDIRP, readdirp, frame, this, fd, size, off, xdata); + return 0; +} + +int32_t +dg_link(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, + dict_t *xdata) +{ + DG_FOP(GF_FOP_LINK, link, frame, this, oldloc, newloc, xdata); + return 0; +} + +int32_t +dg_fxattrop(call_frame_t *frame, xlator_t *this, fd_t *fd, + gf_xattrop_flags_t flags, dict_t *dict, dict_t *xdata) +{ + DG_FOP(GF_FOP_FXATTROP, fxattrop, frame, this, fd, flags, dict, xdata); + return 0; +} + +int32_t +dg_ftruncate(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, + dict_t *xdata) +{ + DG_FOP(GF_FOP_FTRUNCATE, ftruncate, frame, this, fd, offset, xdata); + return 0; +} + +int32_t +dg_rchecksum(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, + int32_t len, dict_t *xdata) +{ + DG_FOP(GF_FOP_RCHECKSUM, rchecksum, frame, this, fd, offset, len, xdata); + return 0; +} + +int32_t +dg_unlink(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, + dict_t *xdata) +{ + DG_FOP(GF_FOP_UNLINK, unlink, frame, this, loc, flags, xdata); + return 0; +} + +int32_t +dg_fentrylk(call_frame_t *frame, xlator_t *this, const char *volume, fd_t *fd, + const char *basename, entrylk_cmd cmd, entrylk_type type, + dict_t *xdata) +{ + DG_FOP(GF_FOP_FENTRYLK, fentrylk, frame, this, volume, fd, basename, cmd, + type, xdata); + return 0; +} + +int32_t +dg_getspec(call_frame_t *frame, xlator_t *this, const char *key, int32_t flags) +{ + DG_FOP(GF_FOP_GETSPEC, getspec, frame, this, key, flags); + return 0; +} + +int32_t +dg_setattr(call_frame_t *frame, xlator_t *this, loc_t *loc, struct iatt *stbuf, + int32_t valid, dict_t *xdata) +{ + DG_FOP(GF_FOP_SETATTR, setattr, frame, this, loc, stbuf, valid, xdata); + return 0; +} + +int32_t +dg_fsync(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags, + dict_t *xdata) +{ + DG_FOP(GF_FOP_FSYNC, fsync, frame, this, fd, flags, xdata); + return 0; +} + +int32_t +dg_statfs(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) +{ + DG_FOP(GF_FOP_STATFS, statfs, frame, this, loc, xdata); + return 0; +} + +int32_t +dg_seek(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, + gf_seek_what_t what, dict_t *xdata) +{ + DG_FOP(GF_FOP_SEEK, seek, frame, this, fd, offset, what, xdata); + return 0; +} + +int32_t +dg_fsetattr(call_frame_t *frame, xlator_t *this, fd_t *fd, struct iatt *stbuf, + int32_t valid, dict_t *xdata) +{ + DG_FOP(GF_FOP_FSETATTR, fsetattr, frame, this, fd, stbuf, valid, xdata); + return 0; +} + +int32_t +dg_opendir(call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd, + dict_t *xdata) +{ + DG_FOP(GF_FOP_OPENDIR, opendir, frame, this, loc, fd, xdata); + return 0; +} + +int32_t +dg_readlink(call_frame_t *frame, xlator_t *this, loc_t *loc, size_t size, + dict_t *xdata) +{ + DG_FOP(GF_FOP_READLINK, readlink, frame, this, loc, size, xdata); + return 0; +} + +int32_t +dg_removexattr(call_frame_t *frame, xlator_t *this, loc_t *loc, + const char *name, dict_t *xdata) +{ + DG_FOP(GF_FOP_REMOVEXATTR, removexattr, frame, this, loc, name, xdata); + return 0; +} + +int32_t +dg_forget(xlator_t *this, inode_t *inode) +{ + return 0; +} + +int32_t +dg_release(xlator_t *this, fd_t *fd) +{ + return 0; +} + +int32_t +dg_releasedir(xlator_t *this, fd_t *fd) +{ + return 0; +} + +static int +delay_gen_parse_fill_fops(dg_t *dg, char *enable_fops) +{ + char *op_no_str = NULL; + int op_no = -1; + int i = 0; + int ret = 0; + xlator_t *this = THIS; + char *saveptr = NULL; + char *dup_enable_fops = NULL; + + if (strlen(enable_fops) == 0) { + for (i = GF_FOP_NULL + 1; i < GF_FOP_MAXVALUE; i++) + dg->enable[i] = 1; + } else { + dup_enable_fops = gf_strdup(enable_fops); + if (!dup_enable_fops) { + ret = -1; + goto out; + } + op_no_str = strtok_r(dup_enable_fops, ",", &saveptr); + while (op_no_str) { + op_no = gf_fop_int(op_no_str); + if (op_no == -1) { + gf_log(this->name, GF_LOG_WARNING, "Wrong option value %s", + op_no_str); + ret = -1; + goto out; + } else { + dg->enable[op_no] = 1; + } + + op_no_str = strtok_r(NULL, ",", &saveptr); + } + } +out: + GF_FREE(dup_enable_fops); + return ret; +} + +void +delay_gen_set_delay_ppm(dg_t *dg, double percent) +{ + double ppm; + + ppm = (percent / 100.0) * (double)DELAY_GRANULARITY; + dg->delay_ppm = ppm; +} + +int32_t +init(xlator_t *this) +{ + dg_t *dg = NULL; + int32_t ret = 0; + double delay_percent = 0; + char *delay_enable_fops = NULL; + + if (!this->children || this->children->next) { + gf_log(this->name, GF_LOG_ERROR, + "delay-gen not configured with one subvolume"); + ret = -1; + goto out; + } + + if (!this->parents) { + gf_log(this->name, GF_LOG_WARNING, "dangling volume. check volfile "); + } + + dg = GF_CALLOC(1, sizeof(*dg), gf_delay_gen_mt_dg_t); + + if (!dg) { + ret = -1; + goto out; + } + + ret = -1; + + GF_OPTION_INIT("delay-percentage", delay_percent, percent, out); + GF_OPTION_INIT("enable", delay_enable_fops, str, out); + GF_OPTION_INIT("delay-duration", dg->delay_duration, int32, out); + + delay_gen_set_delay_ppm(dg, delay_percent); + + ret = delay_gen_parse_fill_fops(dg, delay_enable_fops); + if (ret) + goto out; + + this->private = dg; + + ret = 0; +out: + if (ret) + GF_FREE(dg); + return ret; +} + +void +fini(xlator_t *this) +{ + GF_FREE(this->private); +} + +int32_t +mem_acct_init(xlator_t *this) +{ + int ret = -1; + + if (!this) + return ret; + + ret = xlator_mem_acct_init(this, gf_delay_gen_mt_end + 1); + + if (ret != 0) { + gf_log(this->name, GF_LOG_ERROR, + "Memory accounting init" + " failed"); + return ret; + } + + return ret; +} + +int32_t +reconfigure(xlator_t *this, dict_t *dict) +{ + /*At the moment I don't see any need to implement this. In future + *if this is needed we can add code here. + */ + return 0; +} + +int +notify(xlator_t *this, int event, void *data, ...) +{ + return default_notify(this, event, data); +} + +struct xlator_fops fops = { + .rename = dg_rename, + .ipc = dg_ipc, + .setactivelk = dg_setactivelk, + .flush = dg_flush, + .readdir = dg_readdir, + .setxattr = dg_setxattr, + .mknod = dg_mknod, + .fsetxattr = dg_fsetxattr, + .readv = dg_readv, + .inodelk = dg_inodelk, + .fremovexattr = dg_fremovexattr, + .open = dg_open, + .xattrop = dg_xattrop, + .entrylk = dg_entrylk, + .getactivelk = dg_getactivelk, + .finodelk = dg_finodelk, + .create = dg_create, + .discard = dg_discard, + .mkdir = dg_mkdir, + .lk = dg_lk, + .writev = dg_writev, + .access = dg_access, + .lookup = dg_lookup, + .rmdir = dg_rmdir, + .fallocate = dg_fallocate, + .fstat = dg_fstat, + .lease = dg_lease, + .stat = dg_stat, + .truncate = dg_truncate, + .getxattr = dg_getxattr, + .symlink = dg_symlink, + .zerofill = dg_zerofill, + .fsyncdir = dg_fsyncdir, + .fgetxattr = dg_fgetxattr, + .readdirp = dg_readdirp, + .link = dg_link, + .fxattrop = dg_fxattrop, + .ftruncate = dg_ftruncate, + .rchecksum = dg_rchecksum, + .unlink = dg_unlink, + .fentrylk = dg_fentrylk, + .getspec = dg_getspec, + .setattr = dg_setattr, + .fsync = dg_fsync, + .statfs = dg_statfs, + .seek = dg_seek, + .fsetattr = dg_fsetattr, + .opendir = dg_opendir, + .readlink = dg_readlink, + .removexattr = dg_removexattr, +}; + +struct xlator_cbks cbks = { + .forget = dg_forget, + .release = dg_release, + .releasedir = dg_releasedir, +}; + +struct volume_options options[] = { + { + .key = {"delay-percentage"}, + .type = GF_OPTION_TYPE_PERCENT, + .default_value = "10%", + .description = "Percentage delay of operations when enabled.", + .op_version = {GD_OP_VERSION_3_13_0}, + .flags = OPT_FLAG_SETTABLE, + .tags = {"delay-gen"}, + }, + + { + .key = {"delay-duration"}, + .type = GF_OPTION_TYPE_INT, + .description = "Delay duration in micro seconds", + .default_value = "100000", + .op_version = {GD_OP_VERSION_3_13_0}, + .flags = OPT_FLAG_SETTABLE, + .tags = {"delay-gen"}, + }, + + { + .key = {"enable"}, + .type = GF_OPTION_TYPE_STR, + .description = "Accepts a string which takes ',' separated fop " + "strings to denote which fops are enabled for delay", + .op_version = {GD_OP_VERSION_3_13_0}, + .flags = OPT_FLAG_SETTABLE, + .tags = {"delay-gen"}, + .default_value = "", + }, + + {.key = {NULL}}, +}; + +xlator_api_t xlator_api = { + .init = init, + .fini = fini, + .notify = notify, + .reconfigure = reconfigure, + .mem_acct_init = mem_acct_init, + .op_version = {GD_OP_VERSION_3_12_0}, + .fops = &fops, + .cbks = &cbks, + .options = options, + .identifier = "delay-gen", + .category = GF_TECH_PREVIEW, +}; diff --git a/xlators/debug/delay-gen/src/delay-gen.h b/xlators/debug/delay-gen/src/delay-gen.h new file mode 100644 index 00000000000..afa95e5eb2d --- /dev/null +++ b/xlators/debug/delay-gen/src/delay-gen.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2017 Red Hat, Inc. <http://www.redhat.com> + * This file is part of GlusterFS. + * + * This file is licensed to you under your choice of the GNU Lesser + * General Public License, version 3 or any later version (LGPLv3 or + * later), or the GNU General Public License, version 2 (GPLv2), in all + * cases as published by the Free Software Foundation. + */ + +#ifndef __DELAY_GEN_H__ +#define __DELAY_GEN_H__ + +#include "delay-gen-mem-types.h" +#include "delay-gen-messages.h" +#include <glusterfs/glusterfs.h> +#include <glusterfs/xlator.h> +#include <glusterfs/defaults.h> + +typedef struct { + int enable[GF_FOP_MAXVALUE]; + int op_count; + int delay_ppm; + int delay_duration; +} dg_t; + +#endif /* __DELAY_GEN_H__ */ diff --git a/xlators/debug/error-gen/src/Makefile.am b/xlators/debug/error-gen/src/Makefile.am index f353b61e69c..038d2e8e66d 100644 --- a/xlators/debug/error-gen/src/Makefile.am +++ b/xlators/debug/error-gen/src/Makefile.am @@ -2,15 +2,17 @@ xlator_LTLIBRARIES = error-gen.la xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/debug -error_gen_la_LDFLAGS = -module -avoidversion +error_gen_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) error_gen_la_SOURCES = error-gen.c error_gen_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la -noinst_HEADERS = error-gen.h +noinst_HEADERS = error-gen.h error-gen-mem-types.h -AM_CFLAGS = -fPIC -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -Wall -D$(GF_HOST_OS)\ - -I$(top_srcdir)/libglusterfs/src -shared -nostartfiles $(GF_CFLAGS) +AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ + -I$(top_srcdir)/rpc/xdr/src -I$(top_builddir)/rpc/xdr/src + +AM_CFLAGS = -Wall $(GF_CFLAGS) CLEANFILES = diff --git a/xlators/debug/error-gen/src/error-gen-mem-types.h b/xlators/debug/error-gen/src/error-gen-mem-types.h new file mode 100644 index 00000000000..b9b713af8fc --- /dev/null +++ b/xlators/debug/error-gen/src/error-gen-mem-types.h @@ -0,0 +1,20 @@ +/* + Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com> + This file is part of GlusterFS. + + This file is licensed to you under your choice of the GNU Lesser + General Public License, version 3 or any later version (LGPLv3 or + later), or the GNU General Public License, version 2 (GPLv2), in all + cases as published by the Free Software Foundation. +*/ + +#ifndef __ERROR_GEN_MEM_TYPES_H__ +#define __ERROR_GEN_MEM_TYPES_H__ + +#include <glusterfs/mem-types.h> + +enum gf_error_gen_mem_types_ { + gf_error_gen_mt_eg_t = gf_common_mt_end + 1, + gf_error_gen_mt_end +}; +#endif diff --git a/xlators/debug/error-gen/src/error-gen.c b/xlators/debug/error-gen/src/error-gen.c index e6a5967cceb..d45655ef4c3 100644 --- a/xlators/debug/error-gen/src/error-gen.c +++ b/xlators/debug/error-gen/src/error-gen.c @@ -1,2199 +1,1663 @@ /* - Copyright (c) 2008-2009 Gluster, Inc. <http://www.gluster.com> - This file is part of GlusterFS. - - GlusterFS is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3 of the License, - or (at your option) any later version. - - GlusterFS is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see - <http://www.gnu.org/licenses/>. -*/ - -#ifndef _CONFIG_H -#define _CONFIG_H -#include "config.h" -#endif + Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com> + This file is part of GlusterFS. -#include "xlator.h" + This file is licensed to you under your choice of the GNU Lesser + General Public License, version 3 or any later version (LGPLv3 or + later), or the GNU General Public License, version 2 (GPLv2), in all + cases as published by the Free Software Foundation. +*/ +#include <glusterfs/xlator.h> #include "error-gen.h" +#include <glusterfs/statedump.h> +#include <glusterfs/defaults.h> + +/* + * The user can specify an error probability as a float percentage, but we + * store it internally as a numerator with this as the denominator. When it's + * used, it's like this: + * + * (rand() % FAILURE_GRANULARITY) < error_rate + * + * To minimize rounding errors from the modulo operation, it's good for this to + * be a power of two. + * + * (BTW this is just the normal case. If "random-failure" is set, that does + * something completely different and this number is irrelevant. See error_gen + * for the legacy code.) + */ +#define FAILURE_GRANULARITY (1 << 20) sys_error_t error_no_list[] = { - [ERR_LOOKUP] = { .error_no_count = 4, - .error_no = {ENOENT,ENOTDIR, - ENAMETOOLONG,EAGAIN}}, - [ERR_STAT] = { .error_no_count = 7, - .error_no = {EACCES,EBADF,EFAULT, - ENAMETOOLONG,ENOENT, - ENOMEM,ENOTDIR}}, - [ERR_READLINK] = { .error_no_count = 8, - .error_no = {EACCES,EFAULT,EINVAL,EIO, - ENAMETOOLONG,ENOENT,ENOMEM, - ENOTDIR}}, - [ERR_MKNOD] = { .error_no_count = 11, - .error_no = {EACCES,EEXIST,EFAULT, - EINVAL,ENAMETOOLONG, - ENOENT,ENOMEM,ENOSPC, - ENOTDIR,EPERM,EROFS}}, - [ERR_MKDIR] = { .error_no_count = 10, - .error_no = {EACCES,EEXIST,EFAULT, - ENAMETOOLONG,ENOENT, - ENOMEM,ENOSPC,ENOTDIR, - EPERM,EROFS}}, - [ERR_UNLINK] = { .error_no_count = 10, - .error_no = {EACCES,EBUSY,EFAULT,EIO, - EISDIR,ENAMETOOLONG, - ENOENT,ENOMEM,ENOTDIR, - EPERM,EROFS}}, - [ERR_RMDIR] = { .error_no_count = 8, - .error_no = {EACCES,EBUSY,EFAULT, - ENOMEM,ENOTDIR,ENOTEMPTY, - EPERM,EROFS}}, - [ERR_SYMLINK] = { .error_no_count = 11, - .error_no = {EACCES,EEXIST,EFAULT,EIO, - ENAMETOOLONG,ENOENT,ENOMEM, - ENOSPC,ENOTDIR,EPERM, - EROFS}}, - [ERR_RENAME] = { .error_no_count = 13, - .error_no = {EACCES,EBUSY,EFAULT, - EINVAL,EISDIR,EMLINK, - ENAMETOOLONG,ENOENT,ENOMEM, - ENOSPC,ENOTDIR,EEXIST, - EXDEV}}, - [ERR_LINK] = { .error_no_count = 13, - .error_no = {EACCES,EFAULT,EEXIST,EIO, - EMLINK,ENAMETOOLONG, - ENOENT,ENOMEM,ENOSPC, - ENOTDIR,EPERM,EROFS, - EXDEV}}, - [ERR_TRUNCATE] = { .error_no_count = 10, - .error_no = {EACCES,EFAULT,EFBIG, - EINTR,EINVAL,EIO,EISDIR, - ENAMETOOLONG,ENOENT, - EISDIR}}, - [ERR_CREATE] = {.error_no_count = 10, - .error_no = {EACCES,EEXIST,EFAULT, - EISDIR,EMFILE,ENAMETOOLONG, - ENFILE,ENODEV,ENOENT, - ENODEV}}, - [ERR_OPEN] = { .error_no_count = 10, - .error_no = {EACCES,EEXIST,EFAULT, - EISDIR,EMFILE, - ENAMETOOLONG,ENFILE, - ENODEV,ENOENT,ENOMEM}}, - [ERR_READV] = { .error_no_count = 5, - .error_no = {EINVAL,EBADF,EFAULT,EISDIR, - ENAMETOOLONG}}, - [ERR_WRITEV] = { .error_no_count = 5, - .error_no = {EINVAL,EBADF,EFAULT,EISDIR, - ENAMETOOLONG}}, - [ERR_STATFS] = {.error_no_count = 10, - .error_no = {EACCES,EBADF,EFAULT,EINTR, - EIO,ENAMETOOLONG,ENOENT, - ENOMEM,ENOSYS,ENOTDIR}}, - [ERR_FLUSH] = { .error_no_count = 5, - .error_no = {EACCES,EFAULT, - ENAMETOOLONG,ENOSYS, - ENOENT}}, - [ERR_FSYNC] = { .error_no_count = 4, - .error_no = {EBADF,EIO,EROFS,EINVAL}}, - [ERR_SETXATTR] = { .error_no_count = 4, - .error_no = {EACCES,EBADF,EINTR, - ENAMETOOLONG}}, - [ERR_GETXATTR] = { .error_no_count = 4, - .error_no = {EACCES,EBADF,ENAMETOOLONG, - EINTR}}, - [ERR_REMOVEXATTR] = { .error_no_count = 4, - .error_no = {EACCES,EBADF,ENAMETOOLONG, - EINTR}}, - [ERR_OPENDIR] = { .error_no_count = 8, - .error_no = {EACCES,EEXIST,EFAULT, - EISDIR,EMFILE, - ENAMETOOLONG,ENFILE, - ENODEV}}, - [ERR_READDIR] = { .error_no_count = 5, - .error_no = {EINVAL,EACCES,EBADF, - EMFILE,ENOENT}}, - [ERR_READDIRP] = { .error_no_count = 5, - .error_no = {EINVAL,EACCES,EBADF, - EMFILE,ENOENT}}, - [ERR_GETDENTS] = { .error_no_count = 5, - .error_no = {EBADF,EFAULT,EINVAL, - ENOENT,ENOTDIR}}, - [ERR_FSYNCDIR] = { .error_no_count = 4, - .error_no = {EBADF,EIO,EROFS,EINVAL}}, - [ERR_ACCESS] = { .error_no_count = 8, - .error_no = {EACCES,ENAMETOOLONG, - ENOENT,ENOTDIR,EROFS, - EFAULT,EINVAL,EIO}}, - [ERR_FTRUNCATE] = { .error_no_count = 9, - .error_no = {EACCES,EFAULT,EFBIG, - EINTR,EINVAL,EIO,EISDIR, - ENAMETOOLONG,ENOENT}}, - [ERR_FSTAT] = { .error_no_count = 7, - .error_no = {EACCES,EBADF,EFAULT, - ENAMETOOLONG,ENOENT, - ENOMEM,ENOTDIR}}, - [ERR_LK] = { .error_no_count = 4, - .error_no = {EACCES,EFAULT,ENOENT, - EINTR}}, - [ERR_SETDENTS] = { .error_no_count = 4, - .error_no = {EACCES,EBADF,EINTR, - ENAMETOOLONG}}, - [ERR_CHECKSUM] = { .error_no_count = 4, - .error_no = {EACCES,EBADF, - ENAMETOOLONG,EINTR}}, - [ERR_XATTROP] = { .error_no_count = 5, - .error_no = {EACCES,EFAULT, - ENAMETOOLONG,ENOSYS, - ENOENT}}, - [ERR_FXATTROP] = { .error_no_count = 4, - .error_no = {EBADF,EIO,EROFS,EINVAL}}, - [ERR_INODELK] = { .error_no_count = 4, - .error_no = {EACCES,EBADF,EINTR, - ENAMETOOLONG}}, - [ERR_FINODELK] = { .error_no_count = 4, - .error_no = {EACCES,EBADF,EINTR, - ENAMETOOLONG}}, - [ERR_ENTRYLK] = { .error_no_count = 4, - .error_no = {EACCES,EBADF, - ENAMETOOLONG,EINTR}}, - [ERR_FENTRYLK] = { .error_no_count = 10, - .error_no = {EACCES,EEXIST,EFAULT, - EISDIR,EMFILE, - ENAMETOOLONG,ENFILE, - ENODEV,ENOENT,ENOMEM}}, - [ERR_SETATTR] = {.error_no_count = 11, - .error_no = {EACCES,EFAULT,EIO, - ENAMETOOLONG,ENOENT, - ENOMEM,ENOTDIR,EPERM, - EROFS,EBADF,EIO}}, - [ERR_FSETATTR] = { .error_no_count = 11, - .error_no = {EACCES,EFAULT,EIO, - ENAMETOOLONG,ENOENT, - ENOMEM,ENOTDIR,EPERM, - EROFS,EBADF,EIO}}, - [ERR_STATS] = { .error_no_count = 4, - .error_no = {EACCES,EBADF,ENAMETOOLONG, - EINTR}}, - [ERR_GETSPEC] = { .error_no_count = 4, - .error_no = {EACCES,EBADF,ENAMETOOLONG, - EINTR}} -}; + [GF_FOP_LOOKUP] = {.error_no_count = 4, + .error_no = {ENOENT, ENOTDIR, ENAMETOOLONG, EAGAIN}}, + [GF_FOP_STAT] = {.error_no_count = 6, + .error_no = {EACCES, EFAULT, ENAMETOOLONG, ENOENT, ENOMEM, + ENOTDIR}}, + [GF_FOP_READLINK] = {.error_no_count = 8, + .error_no = {EACCES, EFAULT, EINVAL, EIO, ENAMETOOLONG, + ENOENT, ENOMEM, ENOTDIR}}, + [GF_FOP_MKNOD] = {.error_no_count = 11, + .error_no = {EACCES, EEXIST, EFAULT, EINVAL, ENAMETOOLONG, + ENOENT, ENOMEM, ENOSPC, ENOTDIR, EPERM, + EROFS}}, + [GF_FOP_MKDIR] = {.error_no_count = 10, + .error_no = {EACCES, EEXIST, EFAULT, ENAMETOOLONG, ENOENT, + ENOMEM, ENOSPC, ENOTDIR, EPERM, EROFS}}, + [GF_FOP_UNLINK] = {.error_no_count = 10, + .error_no = {EACCES, EBUSY, EFAULT, EIO, EISDIR, + ENAMETOOLONG, ENOENT, ENOMEM, ENOTDIR, + EPERM, EROFS}}, + [GF_FOP_RMDIR] = {.error_no_count = 8, + .error_no = {EACCES, EBUSY, EFAULT, ENOMEM, ENOTDIR, + ENOTEMPTY, EPERM, EROFS}}, + [GF_FOP_SYMLINK] = {.error_no_count = 11, + .error_no = {EACCES, EEXIST, EFAULT, EIO, ENAMETOOLONG, + ENOENT, ENOMEM, ENOSPC, ENOTDIR, EPERM, + EROFS}}, + [GF_FOP_RENAME] = {.error_no_count = 13, + .error_no = {EACCES, EBUSY, EFAULT, EINVAL, EISDIR, + EMLINK, ENAMETOOLONG, ENOENT, ENOMEM, + ENOSPC, ENOTDIR, EEXIST, EXDEV}}, + [GF_FOP_LINK] = {.error_no_count = 13, + .error_no = {EACCES, EFAULT, EEXIST, EIO, EMLINK, + ENAMETOOLONG, ENOENT, ENOMEM, ENOSPC, ENOTDIR, + EPERM, EROFS, EXDEV}}, + [GF_FOP_TRUNCATE] = {.error_no_count = 10, + .error_no = {EACCES, EFAULT, EFBIG, EINTR, EINVAL, EIO, + EISDIR, ENAMETOOLONG, ENOENT, EISDIR}}, + [GF_FOP_CREATE] = {.error_no_count = 10, + .error_no = {EACCES, EEXIST, EFAULT, EISDIR, EMFILE, + ENAMETOOLONG, ENFILE, ENODEV, ENOENT, + ENODEV}}, + [GF_FOP_OPEN] = {.error_no_count = 10, + .error_no = {EACCES, EEXIST, EFAULT, EISDIR, EMFILE, + ENAMETOOLONG, ENFILE, ENODEV, ENOENT, + ENOMEM}}, + [GF_FOP_READ] = {.error_no_count = 5, + .error_no = {EINVAL, EBADF, EFAULT, EISDIR, ENAMETOOLONG}}, + [GF_FOP_WRITE] = {.error_no_count = 7, + .error_no = {EINVAL, EBADF, EFAULT, EISDIR, ENAMETOOLONG, + ENOSPC, GF_ERROR_SHORT_WRITE}}, + [GF_FOP_STATFS] = {.error_no_count = 9, + .error_no = {EACCES, EFAULT, EINTR, EIO, ENAMETOOLONG, + ENOENT, ENOMEM, ENOSYS, ENOTDIR}}, + [GF_FOP_FLUSH] = {.error_no_count = 5, + .error_no = {EACCES, EFAULT, ENAMETOOLONG, ENOSYS, + ENOENT}}, + [GF_FOP_FSYNC] = {.error_no_count = 4, + .error_no = {EBADF, EIO, EROFS, EINVAL}}, + [GF_FOP_SETXATTR] = {.error_no_count = 3, + .error_no = {EACCES, EINTR, ENAMETOOLONG}}, + [GF_FOP_GETXATTR] = {.error_no_count = 3, + .error_no = {EACCES, ENAMETOOLONG, EINTR}}, + [GF_FOP_REMOVEXATTR] = {.error_no_count = 3, + .error_no = {EACCES, ENAMETOOLONG, EINTR}}, + [GF_FOP_FSETXATTR] = {.error_no_count = 4, + .error_no = {EACCES, EBADF, EINTR, ENAMETOOLONG}}, + [GF_FOP_FGETXATTR] = {.error_no_count = 4, + .error_no = {EACCES, EBADF, ENAMETOOLONG, EINTR}}, + [GF_FOP_FREMOVEXATTR] = {.error_no_count = 4, + .error_no = {EACCES, EBADF, ENAMETOOLONG, EINTR}}, + [GF_FOP_OPENDIR] = {.error_no_count = 8, + .error_no = {EACCES, EEXIST, EFAULT, EISDIR, EMFILE, + ENAMETOOLONG, ENFILE, ENODEV}}, + [GF_FOP_READDIR] = {.error_no_count = 5, + .error_no = {EINVAL, EACCES, EBADF, EMFILE, ENOENT}}, + [GF_FOP_READDIRP] = {.error_no_count = 5, + .error_no = {EINVAL, EACCES, EBADF, EMFILE, ENOENT}}, + [GF_FOP_FSYNCDIR] = {.error_no_count = 4, + .error_no = {EBADF, EIO, EROFS, EINVAL}}, + [GF_FOP_ACCESS] = {.error_no_count = 8, + .error_no = {EACCES, ENAMETOOLONG, ENOENT, ENOTDIR, + EROFS, EFAULT, EINVAL, EIO}}, + [GF_FOP_FTRUNCATE] = {.error_no_count = 9, + .error_no = {EACCES, EFAULT, EFBIG, EINTR, EINVAL, + EIO, EISDIR, ENAMETOOLONG, ENOENT}}, + [GF_FOP_FSTAT] = {.error_no_count = 7, + .error_no = {EACCES, EBADF, EFAULT, ENAMETOOLONG, ENOENT, + ENOMEM, ENOTDIR}}, + [GF_FOP_LK] = {.error_no_count = 4, + .error_no = {EACCES, EFAULT, ENOENT, EINTR}}, + [GF_FOP_XATTROP] = {.error_no_count = 5, + .error_no = {EACCES, EFAULT, ENAMETOOLONG, ENOSYS, + ENOENT}}, + [GF_FOP_FXATTROP] = {.error_no_count = 4, + .error_no = {EBADF, EIO, EROFS, EINVAL}}, + [GF_FOP_INODELK] = {.error_no_count = 3, + .error_no = {EACCES, EINTR, ENAMETOOLONG}}, + [GF_FOP_FINODELK] = {.error_no_count = 4, + .error_no = {EACCES, EBADF, EINTR, ENAMETOOLONG}}, + [GF_FOP_ENTRYLK] = {.error_no_count = 3, + .error_no = {EACCES, ENAMETOOLONG, EINTR}}, + [GF_FOP_FENTRYLK] = {.error_no_count = 10, + .error_no = {EACCES, EEXIST, EFAULT, EISDIR, EMFILE, + ENAMETOOLONG, ENFILE, ENODEV, ENOENT, + ENOMEM}}, + [GF_FOP_SETATTR] = {.error_no_count = 10, + .error_no = {EACCES, EFAULT, EIO, ENAMETOOLONG, ENOENT, + ENOMEM, ENOTDIR, EPERM, EROFS, EIO}}, + [GF_FOP_FSETATTR] = {.error_no_count = 11, + .error_no = {EACCES, EFAULT, EIO, ENAMETOOLONG, ENOENT, + ENOMEM, ENOTDIR, EPERM, EROFS, EBADF, + EIO}}, + [GF_FOP_GETSPEC] = {.error_no_count = 3, + .error_no = {EACCES, ENAMETOOLONG, EINTR}}}; + +int +generate_rand_no(int op_no) +{ + int rand_no = 0; + int error_no_list_size = 0; + + error_no_list_size = sizeof(error_no_list) / sizeof(error_no_list[0]); + + if (op_no < error_no_list_size) + /* coverity[DC.WEAK_CRYPTO] */ + rand_no = rand() % error_no_list[op_no].error_no_count; + return rand_no; +} + +int +conv_errno_to_int(char **error_no) +{ + if (!strcmp((*error_no), "ENOENT")) + return ENOENT; + else if (!strcmp((*error_no), "ENOTDIR")) + return ENOTDIR; + else if (!strcmp((*error_no), "ENAMETOOLONG")) + return ENAMETOOLONG; + else if (!strcmp((*error_no), "EACCES")) + return EACCES; + else if (!strcmp((*error_no), "EBADF")) + return EBADF; + else if (!strcmp((*error_no), "EFAULT")) + return EFAULT; + else if (!strcmp((*error_no), "ENOMEM")) + return ENOMEM; + else if (!strcmp((*error_no), "EINVAL")) + return EINVAL; + else if (!strcmp((*error_no), "EIO")) + return EIO; + else if (!strcmp((*error_no), "EEXIST")) + return EEXIST; + else if (!strcmp((*error_no), "ENOSPC")) + return ENOSPC; + else if (!strcmp((*error_no), "EPERM")) + return EPERM; + else if (!strcmp((*error_no), "EROFS")) + return EROFS; + else if (!strcmp((*error_no), "EBUSY")) + return EBUSY; + else if (!strcmp((*error_no), "EISDIR")) + return EISDIR; + else if (!strcmp((*error_no), "ENOTEMPTY")) + return ENOTEMPTY; + else if (!strcmp((*error_no), "EMLINK")) + return EMLINK; + else if (!strcmp((*error_no), "ENODEV")) + return ENODEV; + else if (!strcmp((*error_no), "EXDEV")) + return EXDEV; + else if (!strcmp((*error_no), "EMFILE")) + return EMFILE; + else if (!strcmp((*error_no), "ENFILE")) + return ENFILE; + else if (!strcmp((*error_no), "ENOSYS")) + return ENOSYS; + else if (!strcmp((*error_no), "EINTR")) + return EINTR; + else if (!strcmp((*error_no), "EFBIG")) + return EFBIG; + else if (!strcmp((*error_no), "GF_ERROR_SHORT_WRITE")) + return GF_ERROR_SHORT_WRITE; + else + return EAGAIN; +} + +int +error_gen(xlator_t *this, int op_no) +{ + eg_t *egp = NULL; + int count = 0; + int error_no_int = 0; + int rand_no = 0; + int ret = 0; + gf_boolean_t should_err = _gf_false; + int error_no_list_size = 0; + + egp = this->private; + + if (egp->random_failure) { + /* + * I honestly don't know why anyone would use this "feature" + * but I'll try to preserve its functionality anyway. Without + * locking twice to update failure_iter_no and egp->op_count + * separately, then not locking at all to update + * egp->failure_iter_no. That's not needed for compatibility, + * and it's abhorrently wrong. I have *some* standards. + */ + LOCK(&egp->lock); + { + count = ++(egp->op_count); + error_no_int = egp->error_no_int; + if ((count % egp->failure_iter_no) == 0) { + egp->op_count = 0; + /* coverity[DC.WEAK_CRYPTO] */ + egp->failure_iter_no = 3 + (rand() % GF_UNIVERSAL_ANSWER); + should_err = _gf_true; + } + } + UNLOCK(&egp->lock); + } else { + /* + * It turns out that rand() is almost universally implemented + * as a linear congruential PRNG, which is about as cheap as + * it gets. This gets us real random behavior, including + * phenomena like streaks and dry spells, with controllable + * long-term probability, cheaply. + */ + if ((rand() % FAILURE_GRANULARITY) < egp->failure_iter_no) { + should_err = _gf_true; + } + } + + error_no_list_size = sizeof(error_no_list) / sizeof(error_no_list[0]); + if (should_err) { + if (error_no_int) + ret = error_no_int; + else { + rand_no = generate_rand_no(op_no); + if (op_no >= error_no_list_size) + op_no = 0; + if (rand_no >= error_no_list[op_no].error_no_count) + rand_no = 0; + ret = error_no_list[op_no].error_no[rand_no]; + } + } + + return ret; +} int -generate_rand_no (int op_no) +error_gen_lookup(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { - int rand_no = 0; + int op_errno = 0; + eg_t *egp = NULL; + int enable = 1; + + egp = this->private; + enable = egp->enable[GF_FOP_LOOKUP]; + + if (enable) + op_errno = error_gen(this, GF_FOP_LOOKUP); + + if (op_errno) { + GF_ERROR(this, "unwind(-1, %s)", strerror(op_errno)); + STACK_UNWIND_STRICT(lookup, frame, -1, op_errno, NULL, NULL, NULL, + NULL); + return 0; + } - if (op_no < NO_OF_FOPS) - rand_no = rand () % error_no_list[op_no].error_no_count; - return rand_no; + STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->lookup, + loc, xdata); + return 0; } int -conv_errno_to_int (char **error_no) +error_gen_stat(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { - if (!strcmp ((*error_no), "ENOENT")) - return ENOENT; - else if (!strcmp ((*error_no), "ENOTDIR")) - return ENOTDIR; - else if (!strcmp ((*error_no), "ENAMETOOLONG")) - return ENAMETOOLONG; - else if (!strcmp ((*error_no), "EACCES")) - return EACCES; - else if (!strcmp ((*error_no), "EBADF")) - return EBADF; - else if (!strcmp ((*error_no), "EFAULT")) - return EFAULT; - else if (!strcmp ((*error_no), "ENOMEM")) - return ENOMEM; - else if (!strcmp ((*error_no), "EINVAL")) - return EINVAL; - else if (!strcmp ((*error_no), "EIO")) - return EIO; - else if (!strcmp ((*error_no), "EEXIST")) - return EEXIST; - else if (!strcmp ((*error_no), "ENOSPC")) - return ENOSPC; - else if (!strcmp ((*error_no), "EPERM")) - return EPERM; - else if (!strcmp ((*error_no), "EROFS")) - return EROFS; - else if (!strcmp ((*error_no), "EBUSY")) - return EBUSY; - else if (!strcmp ((*error_no), "EISDIR")) - return EISDIR; - else if (!strcmp ((*error_no), "ENOTEMPTY")) - return ENOTEMPTY; - else if (!strcmp ((*error_no), "EMLINK")) - return EMLINK; - else if (!strcmp ((*error_no), "ENODEV")) - return ENODEV; - else if (!strcmp ((*error_no), "EXDEV")) - return EXDEV; - else if (!strcmp ((*error_no), "EMFILE")) - return EMFILE; - else if (!strcmp ((*error_no), "ENFILE")) - return ENFILE; - else if (!strcmp ((*error_no), "ENOSYS")) - return ENOSYS; - else if (!strcmp ((*error_no), "EINTR")) - return EINTR; - else if (!strcmp ((*error_no), "EFBIG")) - return EFBIG; - else - return EAGAIN; + int op_errno = 0; + eg_t *egp = NULL; + int enable = 1; + + egp = this->private; + enable = egp->enable[GF_FOP_STAT]; + + if (enable) + op_errno = error_gen(this, GF_FOP_STAT); + + if (op_errno) { + GF_ERROR(this, "unwind(-1, %s)", strerror(op_errno)); + STACK_UNWIND_STRICT(stat, frame, -1, op_errno, NULL, xdata); + return 0; + } + + STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->stat, + loc, xdata); + return 0; } int -get_fop_int (char **op_no_str) +error_gen_setattr(call_frame_t *frame, xlator_t *this, loc_t *loc, + struct iatt *stbuf, int32_t valid, dict_t *xdata) { - if (!strcmp ((*op_no_str), "lookup")) - return ERR_LOOKUP; - else if (!strcmp ((*op_no_str), "stat")) - return ERR_STAT; - else if (!strcmp ((*op_no_str), "readlink")) - return ERR_READLINK; - else if (!strcmp ((*op_no_str), "mknod")) - return ERR_MKNOD; - else if (!strcmp ((*op_no_str), "mkdir")) - return ERR_MKDIR; - else if (!strcmp ((*op_no_str), "unlink")) - return ERR_UNLINK; - else if (!strcmp ((*op_no_str), "rmdir")) - return ERR_RMDIR; - else if (!strcmp ((*op_no_str), "symlink")) - return ERR_SYMLINK; - else if (!strcmp ((*op_no_str), "rename")) - return ERR_RENAME; - else if (!strcmp ((*op_no_str), "link")) - return ERR_LINK; - else if (!strcmp ((*op_no_str), "truncate")) - return ERR_TRUNCATE; - else if (!strcmp ((*op_no_str), "create")) - return ERR_CREATE; - else if (!strcmp ((*op_no_str), "open")) - return ERR_OPEN; - else if (!strcmp ((*op_no_str), "readv")) - return ERR_READV; - else if (!strcmp ((*op_no_str), "writev")) - return ERR_WRITEV; - else if (!strcmp ((*op_no_str), "statfs")) - return ERR_STATFS; - else if (!strcmp ((*op_no_str), "flush")) - return ERR_FLUSH; - else if (!strcmp ((*op_no_str), "fsync")) - return ERR_FSYNC; - else if (!strcmp ((*op_no_str), "setxattr")) - return ERR_SETXATTR; - else if (!strcmp ((*op_no_str), "getxattr")) - return ERR_GETXATTR; - else if (!strcmp ((*op_no_str), "removexattr")) - return ERR_REMOVEXATTR; - else if (!strcmp ((*op_no_str), "opendir")) - return ERR_OPENDIR; - else if (!strcmp ((*op_no_str), "readdir")) - return ERR_READDIR; - else if (!strcmp ((*op_no_str), "readdirp")) - return ERR_READDIRP; - else if (!strcmp ((*op_no_str), "getdents")) - return ERR_GETDENTS; - else if (!strcmp ((*op_no_str), "fsyncdir")) - return ERR_FSYNCDIR; - else if (!strcmp ((*op_no_str), "access")) - return ERR_ACCESS; - else if (!strcmp ((*op_no_str), "ftruncate")) - return ERR_FTRUNCATE; - else if (!strcmp ((*op_no_str), "fstat")) - return ERR_FSTAT; - else if (!strcmp ((*op_no_str), "lk")) - return ERR_LK; - else if (!strcmp ((*op_no_str), "setdents")) - return ERR_SETDENTS; - else if (!strcmp ((*op_no_str), "checksum")) - return ERR_CHECKSUM; - else if (!strcmp ((*op_no_str), "xattrop")) - return ERR_XATTROP; - else if (!strcmp ((*op_no_str), "fxattrop")) - return ERR_FXATTROP; - else if (!strcmp ((*op_no_str), "inodelk")) - return ERR_INODELK; - else if (!strcmp ((*op_no_str), "finodelk")) - return ERR_FINODELK; - else if (!strcmp ((*op_no_str), "etrylk")) - return ERR_ENTRYLK; - else if (!strcmp ((*op_no_str), "fentrylk")) - return ERR_FENTRYLK; - else if (!strcmp ((*op_no_str), "setattr")) - return ERR_SETATTR; - else if (!strcmp ((*op_no_str), "fsetattr")) - return ERR_FSETATTR; - else if (!strcmp ((*op_no_str), "stats")) - return ERR_STATS; - else if (!strcmp ((*op_no_str), "getspec")) - return ERR_GETSPEC; - else - return -1; + int op_errno = 0; + eg_t *egp = NULL; + int enable = 1; + + egp = this->private; + enable = egp->enable[GF_FOP_SETATTR]; + + if (enable) + op_errno = error_gen(this, GF_FOP_SETATTR); + + if (op_errno) { + GF_ERROR(this, "unwind(-1, %s)", strerror(op_errno)); + STACK_UNWIND_STRICT(setattr, frame, -1, op_errno, NULL, NULL, xdata); + return 0; + } + + STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->setattr, + loc, stbuf, valid, xdata); + return 0; } int -error_gen (xlator_t *this, int op_no) +error_gen_fsetattr(call_frame_t *frame, xlator_t *this, fd_t *fd, + struct iatt *stbuf, int32_t valid, dict_t *xdata) { - eg_t *egp = NULL; - int count = 0; - int failure_iter_no = GF_FAILURE_DEFAULT; - char *error_no = NULL; - int rand_no = 0; - int ret = 0; + int op_errno = 0; + eg_t *egp = NULL; + int enable = 1; - egp = this->private; + egp = this->private; + enable = egp->enable[GF_FOP_FSETATTR]; - LOCK (&egp->lock); - { - count = ++egp->op_count; - failure_iter_no = egp->failure_iter_no; - error_no = egp->error_no; - } - UNLOCK (&egp->lock); - - if((count % failure_iter_no) == 0) { - LOCK (&egp->lock); - { - egp->op_count = 0; - } - UNLOCK (&egp->lock); - - if (error_no) - ret = conv_errno_to_int (&error_no); - else { - - rand_no = generate_rand_no (op_no); - if (op_no >= NO_OF_FOPS) - op_no = 0; - if (rand_no >= error_no_list[op_no].error_no_count) - rand_no = 0; - ret = error_no_list[op_no].error_no[rand_no]; - } - } - return ret; -} + if (enable) + op_errno = error_gen(this, GF_FOP_FSETATTR); + if (op_errno) { + GF_ERROR(this, "unwind(-1, %s)", strerror(op_errno)); + STACK_UNWIND_STRICT(fsetattr, frame, -1, op_errno, NULL, NULL, xdata); + return 0; + } -int -error_gen_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, inode_t *inode, - struct stat *buf, dict_t *dict, struct stat *postparent) -{ - STACK_UNWIND_STRICT (lookup, frame, op_ret, op_errno, inode, - buf, dict, postparent); - return 0; + STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fsetattr, + fd, stbuf, valid, xdata); + return 0; } - int -error_gen_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc, - dict_t *xattr_req) +error_gen_truncate(call_frame_t *frame, xlator_t *this, loc_t *loc, + off_t offset, dict_t *xdata) { - int op_errno = 0; - eg_t *egp = NULL; - int enable = 1; - - egp = this->private; - enable = egp->enable[ERR_LOOKUP]; - - if (enable) - op_errno = error_gen (this, ERR_LOOKUP); - - if (op_errno) { - GF_ERROR(this, "unwind(-1, %s)", strerror (op_errno)); - STACK_UNWIND (frame, -1, op_errno, NULL, NULL, NULL, - NULL); - return 0; - } - - STACK_WIND (frame, error_gen_lookup_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->lookup, - loc, xattr_req); - return 0; -} + int op_errno = 0; + eg_t *egp = NULL; + int enable = 1; + egp = this->private; + enable = egp->enable[GF_FOP_TRUNCATE]; -int -error_gen_forget (xlator_t *this, inode_t *inode) -{ - return 0; -} + if (enable) + op_errno = error_gen(this, GF_FOP_TRUNCATE); + + if (op_errno) { + GF_ERROR(this, "unwind(-1, %s)", strerror(op_errno)); + STACK_UNWIND_STRICT(truncate, frame, -1, op_errno, NULL, NULL, xdata); + return 0; + } + STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->truncate, + loc, offset, xdata); + return 0; +} int -error_gen_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, struct stat *buf) +error_gen_ftruncate(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, + dict_t *xdata) { - STACK_UNWIND_STRICT (stat, frame, op_ret, op_errno, buf); + int op_errno = 0; + eg_t *egp = NULL; + int enable = 1; + + egp = this->private; + enable = egp->enable[GF_FOP_FTRUNCATE]; - return 0; + if (enable) + op_errno = error_gen(this, GF_FOP_FTRUNCATE); + + if (op_errno) { + GF_ERROR(this, "unwind(-1, %s)", strerror(op_errno)); + STACK_UNWIND_STRICT(ftruncate, frame, -1, op_errno, NULL, NULL, xdata); + return 0; + } + + STACK_WIND_TAIL(frame, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->ftruncate, fd, offset, xdata); + return 0; } int -error_gen_stat (call_frame_t *frame, xlator_t *this, loc_t *loc) +error_gen_access(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t mask, + dict_t *xdata) { - int op_errno = 0; - eg_t *egp = NULL; - int enable = 1; - - egp = this->private; - enable = egp->enable[ERR_STAT]; - - if (enable) - op_errno = error_gen (this, ERR_STAT); - - if (op_errno) { - GF_ERROR(this, "unwind(-1, %s)", strerror (op_errno)); - STACK_UNWIND (frame, -1, op_errno, NULL); - return 0; - } - - STACK_WIND (frame, error_gen_stat_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->stat, - loc); - return 0; -} + int op_errno = 0; + eg_t *egp = NULL; + int enable = 1; + egp = this->private; + enable = egp->enable[GF_FOP_ACCESS]; -int -error_gen_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, - struct stat *preop, struct stat *postop) -{ - STACK_UNWIND_STRICT (setattr, frame, op_ret, op_errno, preop, postop); + if (enable) + op_errno = error_gen(this, GF_FOP_ACCESS); - return 0; -} + if (op_errno) { + GF_ERROR(this, "unwind(-1, %s)", strerror(op_errno)); + STACK_UNWIND_STRICT(access, frame, -1, op_errno, xdata); + return 0; + } + STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->access, + loc, mask, xdata); + return 0; +} int -error_gen_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc, - struct stat *stbuf, int32_t valid) +error_gen_readlink(call_frame_t *frame, xlator_t *this, loc_t *loc, size_t size, + dict_t *xdata) { - int op_errno = 0; - eg_t *egp = NULL; - int enable = 1; - - egp = this->private; - enable = egp->enable[ERR_SETATTR]; - - if (enable) - op_errno = error_gen (this, ERR_SETATTR); - - if (op_errno) { - GF_ERROR(this, "unwind(-1, %s)", strerror (op_errno)); - STACK_UNWIND_STRICT (setattr, frame, -1, op_errno, NULL, NULL); - return 0; - } - - STACK_WIND (frame, error_gen_setattr_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->setattr, - loc, stbuf, valid); - return 0; -} + int op_errno = 0; + eg_t *egp = NULL; + int enable = 1; + egp = this->private; + enable = egp->enable[GF_FOP_READLINK]; -int -error_gen_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd, - struct stat *stbuf, int32_t valid) -{ - int op_errno = 0; - eg_t *egp = NULL; - int enable = 1; - - egp = this->private; - enable = egp->enable[ERR_FSETATTR]; - - if (enable) - op_errno = error_gen (this, ERR_FSETATTR); - - if (op_errno) { - GF_ERROR(this, "unwind(-1, %s)", strerror (op_errno)); - STACK_UNWIND_STRICT (fsetattr, frame, -1, op_errno, NULL, NULL); - return 0; - } - - STACK_WIND (frame, error_gen_setattr_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->fsetattr, - fd, stbuf, valid); - return 0; -} + if (enable) + op_errno = error_gen(this, GF_FOP_READLINK); + if (op_errno) { + GF_ERROR(this, "unwind(-1, %s)", strerror(op_errno)); + STACK_UNWIND_STRICT(readlink, frame, -1, op_errno, NULL, NULL, xdata); + return 0; + } -int -error_gen_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, - struct stat *prebuf, struct stat *postbuf) -{ - STACK_UNWIND_STRICT (truncate, frame, op_ret, op_errno, - prebuf, postbuf); - return 0; + STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->readlink, + loc, size, xdata); + return 0; } - int -error_gen_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, - off_t offset) +error_gen_mknod(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, + dev_t rdev, mode_t umask, dict_t *xdata) { - int op_errno = 0; - eg_t *egp = NULL; - int enable = 1; - - egp = this->private; - enable = egp->enable[ERR_TRUNCATE]; - - if (enable) - op_errno = error_gen (this, ERR_TRUNCATE); - - if (op_errno) { - GF_ERROR(this, "unwind(-1, %s)", strerror (op_errno)); - STACK_UNWIND_STRICT (truncate, frame, -1, op_errno, - NULL, NULL); - return 0; - } - - STACK_WIND (frame, error_gen_truncate_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->truncate, - loc, offset); - return 0; -} + int op_errno = 0; + eg_t *egp = NULL; + int enable = 1; + egp = this->private; + enable = egp->enable[GF_FOP_MKNOD]; -int -error_gen_ftruncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, struct stat *prebuf, - struct stat *postbuf) -{ - STACK_UNWIND_STRICT (ftruncate, frame, op_ret, op_errno, - prebuf, postbuf); - return 0; -} + if (enable) + op_errno = error_gen(this, GF_FOP_MKNOD); + if (op_errno) { + GF_ERROR(this, "unwind(-1, %s)", strerror(op_errno)); + STACK_UNWIND_STRICT(mknod, frame, -1, op_errno, NULL, NULL, NULL, NULL, + xdata); + return 0; + } -int -error_gen_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, - off_t offset) -{ - int op_errno = 0; - eg_t *egp =NULL; - int enable = 1; - - egp = this->private; - enable = egp->enable[ERR_FTRUNCATE]; - - if (enable) - op_errno = error_gen (this, ERR_FTRUNCATE); - - if (op_errno) { - GF_ERROR(this, "unwind(-1, %s)", strerror (op_errno)); - STACK_UNWIND_STRICT (ftruncate, frame, -1, op_errno, - NULL, NULL); - return 0; - } - - STACK_WIND (frame, error_gen_ftruncate_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->ftruncate, - fd, offset); - return 0; + STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->mknod, + loc, mode, rdev, umask, xdata); + return 0; } - int -error_gen_access_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno) +error_gen_mkdir(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, + mode_t umask, dict_t *xdata) { - STACK_UNWIND_STRICT (access, frame, op_ret, op_errno); + int op_errno = 0; + eg_t *egp = NULL; + int enable = 1; - return 0; -} + egp = this->private; + enable = egp->enable[GF_FOP_MKDIR]; + if (enable) + op_errno = error_gen(this, GF_FOP_MKDIR); -int -error_gen_access (call_frame_t *frame, xlator_t *this, loc_t *loc, - int32_t mask) -{ - int op_errno = 0; - eg_t *egp = NULL; - int enable = 1; - - egp = this->private; - enable = egp->enable[ERR_ACCESS]; - - if (enable) - op_errno = error_gen (this, ERR_ACCESS); - - if (op_errno) { - GF_ERROR(this, "unwind(-1, %s)", strerror (op_errno)); - STACK_UNWIND_STRICT (access, frame, -1, op_errno); - return 0; - } - - STACK_WIND (frame, error_gen_access_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->access, - loc, mask); - return 0; -} + if (op_errno) { + GF_ERROR(this, "unwind(-1, %s)", strerror(op_errno)); + STACK_UNWIND_STRICT(mkdir, frame, -1, op_errno, NULL, NULL, NULL, NULL, + xdata); + return 0; + } + STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->mkdir, + loc, mode, umask, xdata); + return 0; +} int -error_gen_readlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, - const char *path, struct stat *sbuf) +error_gen_unlink(call_frame_t *frame, xlator_t *this, loc_t *loc, int xflag, + dict_t *xdata) { - STACK_UNWIND_STRICT (readlink, frame, op_ret, op_errno, path, sbuf); - return 0; -} + int op_errno = 0; + eg_t *egp = NULL; + int enable = 1; + egp = this->private; + enable = egp->enable[GF_FOP_UNLINK]; -int -error_gen_readlink (call_frame_t *frame, xlator_t *this, loc_t *loc, - size_t size) -{ - int op_errno = 0; - eg_t *egp = NULL; - int enable = 1; - - egp = this->private; - enable = egp->enable[ERR_READLINK]; - - if (enable) - op_errno = error_gen (this, ERR_READLINK); - - if (op_errno) { - GF_ERROR(this, "unwind(-1, %s)", strerror (op_errno)); - STACK_UNWIND_STRICT (readlink, frame, -1, op_errno, NULL, NULL); - return 0; - } - - STACK_WIND (frame, error_gen_readlink_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->readlink, - loc, size); - return 0; -} + if (enable) + op_errno = error_gen(this, GF_FOP_UNLINK); + if (op_errno) { + GF_ERROR(this, "unwind(-1, %s)", strerror(op_errno)); + STACK_UNWIND_STRICT(unlink, frame, -1, op_errno, NULL, NULL, xdata); + return 0; + } -int -error_gen_mknod_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, inode_t *inode, - struct stat *buf, struct stat *preparent, - struct stat *postparent) -{ - STACK_UNWIND_STRICT (mknod, frame, op_ret, op_errno, - inode, buf, - preparent, postparent); - return 0; + STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->unlink, + loc, xflag, xdata); + return 0; } - int -error_gen_mknod (call_frame_t *frame, xlator_t *this, loc_t *loc, - mode_t mode, dev_t rdev) +error_gen_rmdir(call_frame_t *frame, xlator_t *this, loc_t *loc, int flags, + dict_t *xdata) { - int op_errno = 0; - eg_t *egp = NULL; - int enable = 1; - - egp = this->private; - enable = egp->enable[ERR_MKNOD]; - - if (enable) - op_errno = error_gen (this, ERR_MKNOD); - - if (op_errno) { - GF_ERROR(this, "unwind(-1, %s)", strerror (op_errno)); - STACK_UNWIND_STRICT (mknod, frame, -1, op_errno, NULL, NULL, - NULL, NULL); - return 0; - } - - STACK_WIND (frame, error_gen_mknod_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->mknod, - loc, mode, rdev); - return 0; -} + int op_errno = 0; + eg_t *egp = NULL; + int enable = 1; + egp = this->private; + enable = egp->enable[GF_FOP_RMDIR]; -int -error_gen_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, inode_t *inode, - struct stat *buf, struct stat *preparent, - struct stat *postparent) -{ - STACK_UNWIND_STRICT (mkdir, frame, op_ret, op_errno, - inode, buf, - preparent, postparent); - return 0; + if (enable) + op_errno = error_gen(this, GF_FOP_RMDIR); + + if (op_errno) { + GF_ERROR(this, "unwind(-1, %s)", strerror(op_errno)); + STACK_UNWIND_STRICT(rmdir, frame, -1, op_errno, NULL, NULL, xdata); + return 0; + } + + STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->rmdir, + loc, flags, xdata); + return 0; } int -error_gen_mkdir (call_frame_t *frame, xlator_t *this, - loc_t *loc, mode_t mode) +error_gen_symlink(call_frame_t *frame, xlator_t *this, const char *linkpath, + loc_t *loc, mode_t umask, dict_t *xdata) { - int op_errno = 0; - eg_t *egp = NULL; - int enable = 1; - - egp = this->private; - enable = egp->enable[ERR_MKDIR]; - - if (enable) - op_errno = error_gen (this, ERR_MKDIR); - - if (op_errno) { - GF_ERROR(this, "unwind(-1, %s)", strerror (op_errno)); - STACK_UNWIND_STRICT (mkdir, frame, -1, op_errno, NULL, NULL, - NULL, NULL); - return 0; - } - - STACK_WIND (frame, error_gen_mkdir_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->mkdir, - loc, mode); - return 0; -} + int op_errno = 0; + eg_t *egp = NULL; + int enable = 1; + egp = this->private; + enable = egp->enable[GF_FOP_SYMLINK]; -int -error_gen_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, - struct stat *preparent, struct stat *postparent) -{ - STACK_UNWIND_STRICT (unlink, frame, op_ret, op_errno, - preparent, postparent); - return 0; -} + if (enable) + op_errno = error_gen(this, GF_FOP_SYMLINK); + if (op_errno) { + GF_ERROR(this, "unwind(-1, %s)", strerror(op_errno)); + STACK_UNWIND_STRICT(symlink, frame, -1, op_errno, NULL, NULL, NULL, + NULL, NULL); /* pre & post parent attr */ + return 0; + } -int -error_gen_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc) -{ - int op_errno = 0; - eg_t *egp = NULL; - int enable = 1; - - egp = this->private; - enable = egp->enable[ERR_UNLINK]; - - if (enable) - op_errno = error_gen (this, ERR_UNLINK); - - if (op_errno) { - GF_ERROR(this, "unwind(-1, %s)", strerror (op_errno)); - STACK_UNWIND_STRICT (unlink, frame, -1, op_errno, NULL, NULL); - return 0; - } - - STACK_WIND (frame, error_gen_unlink_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->unlink, - loc); - return 0; + STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->symlink, + linkpath, loc, umask, xdata); + return 0; } - int -error_gen_rmdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, - struct stat *preparent, struct stat *postparent) +error_gen_rename(call_frame_t *frame, xlator_t *this, loc_t *oldloc, + loc_t *newloc, dict_t *xdata) { - STACK_UNWIND_STRICT (rmdir, frame, op_ret, op_errno, - preparent, postparent); - return 0; -} + int op_errno = 0; + eg_t *egp = NULL; + int enable = 1; + egp = this->private; + enable = egp->enable[GF_FOP_RENAME]; -int -error_gen_rmdir (call_frame_t *frame, xlator_t *this, loc_t *loc) -{ - int op_errno = 0; - eg_t *egp = NULL; - int enable = 1; - - egp = this->private; - enable = egp->enable[ERR_RMDIR]; - - if (enable) - op_errno = error_gen (this, ERR_RMDIR); - - if (op_errno) { - GF_ERROR(this, "unwind(-1, %s)", strerror (op_errno)); - STACK_UNWIND_STRICT (rmdir, frame, -1, op_errno, NULL, NULL); - return 0; - } - - STACK_WIND (frame, error_gen_rmdir_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->rmdir, - loc); - return 0; -} + if (enable) + op_errno = error_gen(this, GF_FOP_RENAME); + if (op_errno) { + GF_ERROR(this, "unwind(-1, %s)", strerror(op_errno)); + STACK_UNWIND_STRICT(rename, frame, -1, op_errno, NULL, NULL, NULL, NULL, + NULL, NULL); + return 0; + } -int -error_gen_symlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, inode_t *inode, - struct stat *buf, struct stat *preparent, - struct stat *postparent) -{ - STACK_UNWIND_STRICT (symlink, frame, op_ret, op_errno, inode, buf, - preparent, postparent); - return 0; + STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->rename, + oldloc, newloc, xdata); + return 0; } - int -error_gen_symlink (call_frame_t *frame, xlator_t *this, const char *linkpath, - loc_t *loc) +error_gen_link(call_frame_t *frame, xlator_t *this, loc_t *oldloc, + loc_t *newloc, dict_t *xdata) { - int op_errno = 0; - eg_t *egp = NULL; - int enable = 1; - - egp = this->private; - enable = egp->enable[ERR_SYMLINK]; - - if (enable) - op_errno = error_gen (this, ERR_SYMLINK); - - if (op_errno) { - GF_ERROR(this, "unwind(-1, %s)", strerror (op_errno)); - STACK_UNWIND_STRICT (symlink, frame, -1, op_errno, NULL, NULL, - NULL, NULL); /* pre & post parent attr */ - return 0; - } - - STACK_WIND (frame, error_gen_symlink_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->symlink, - linkpath, loc); - return 0; -} + int op_errno = 0; + eg_t *egp = NULL; + int enable = 1; + egp = this->private; + enable = egp->enable[GF_FOP_LINK]; -int -error_gen_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, struct stat *buf, - struct stat *preoldparent, struct stat *postoldparent, - struct stat *prenewparent, struct stat *postnewparent) -{ - STACK_UNWIND_STRICT (rename, frame, op_ret, op_errno, buf, - preoldparent, postoldparent, - prenewparent, postnewparent); - return 0; -} + if (enable) + op_errno = error_gen(this, GF_FOP_LINK); + if (op_errno) { + GF_ERROR(this, "unwind(-1, %s)", strerror(op_errno)); + STACK_UNWIND_STRICT(link, frame, -1, op_errno, NULL, NULL, NULL, NULL, + NULL); + return 0; + } -int -error_gen_rename (call_frame_t *frame, xlator_t *this, - loc_t *oldloc, loc_t *newloc) -{ - int op_errno = 0; - eg_t *egp = NULL; - int enable = 1; - - egp = this->private; - enable = egp->enable[ERR_RENAME]; - - if (enable) - op_errno = error_gen (this, ERR_RENAME); - - if (op_errno) { - GF_ERROR(this, "unwind(-1, %s)", strerror (op_errno)); - STACK_UNWIND_STRICT (rename, frame, -1, op_errno, NULL, - NULL, NULL, NULL, NULL); /* pre & post parent attr */ - return 0; - } - - STACK_WIND (frame, error_gen_rename_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->rename, - oldloc, newloc); - return 0; + STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->link, + oldloc, newloc, xdata); + return 0; } - int -error_gen_link_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, inode_t *inode, - struct stat *buf, struct stat *preparent, - struct stat *postparent) +error_gen_create(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, + mode_t mode, mode_t umask, fd_t *fd, dict_t *xdata) { - STACK_UNWIND_STRICT (link, frame, op_ret, op_errno, inode, buf, - preparent, postparent); - return 0; -} + int op_errno = 0; + eg_t *egp = NULL; + int enable = 1; + egp = this->private; + enable = egp->enable[GF_FOP_CREATE]; -int -error_gen_link (call_frame_t *frame, xlator_t *this, - loc_t *oldloc, loc_t *newloc) -{ - int op_errno = 0; - eg_t *egp = NULL; - int enable = 1; - - egp = this->private; - enable = egp->enable[ERR_LINK]; - - if (enable) - op_errno = error_gen (this, ERR_LINK); - - if (op_errno) { - GF_ERROR(this, "unwind(-1, %s)", strerror (op_errno)); - STACK_UNWIND_STRICT (link, frame, -1, op_errno, NULL, NULL, - NULL, NULL); /* pre & post parent attr */ - return 0; - } - - STACK_WIND (frame, error_gen_link_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->link, - oldloc, newloc); - return 0; -} + if (enable) + op_errno = error_gen(this, GF_FOP_CREATE); + if (op_errno) { + GF_ERROR(this, "unwind(-1, %s)", strerror(op_errno)); + STACK_UNWIND_STRICT(create, frame, -1, op_errno, NULL, NULL, NULL, NULL, + NULL, NULL); + return 0; + } -int -error_gen_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, - fd_t *fd, inode_t *inode, struct stat *buf, - struct stat *preparent, struct stat *postparent) -{ - STACK_UNWIND_STRICT (create, frame, op_ret, op_errno, fd, inode, buf, - preparent, postparent); - return 0; + STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->create, + loc, flags, mode, umask, fd, xdata); + return 0; } - int -error_gen_create (call_frame_t *frame, xlator_t *this, loc_t *loc, - int32_t flags, mode_t mode, fd_t *fd) +error_gen_open(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, + fd_t *fd, dict_t *xdata) { - int op_errno = 0; - eg_t *egp = NULL; - int enable = 1; - - egp = this->private; - enable = egp->enable[ERR_CREATE]; - - if (enable) - op_errno = error_gen (this, ERR_CREATE); - - if (op_errno) { - GF_ERROR(this, "unwind(-1, %s)", strerror (op_errno)); - STACK_UNWIND_STRICT (create, frame, -1, op_errno, NULL, NULL, - NULL, NULL, NULL); /* pre & post attr */ - return 0; - } - - STACK_WIND (frame, error_gen_create_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->create, - loc, flags, mode, fd); - return 0; -} + int op_errno = 0; + eg_t *egp = NULL; + int enable = 1; + egp = this->private; + enable = egp->enable[GF_FOP_OPEN]; -int -error_gen_open_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, fd_t *fd) -{ - STACK_UNWIND_STRICT (open, frame, op_ret, op_errno, fd); - return 0; -} + if (enable) + op_errno = error_gen(this, GF_FOP_OPEN); + if (op_errno) { + GF_ERROR(this, "unwind(-1, %s)", strerror(op_errno)); + STACK_UNWIND_STRICT(open, frame, -1, op_errno, NULL, xdata); + return 0; + } -int -error_gen_open (call_frame_t *frame, xlator_t *this, loc_t *loc, - int32_t flags, fd_t *fd, int32_t wbflags) -{ - int op_errno = 0; - eg_t *egp = NULL; - int enable = 1; - - egp = this->private; - enable = egp->enable[ERR_OPEN]; - - if (enable) - op_errno = error_gen (this, ERR_OPEN); - - if (op_errno) { - GF_ERROR(this, "unwind(-1, %s)", strerror (op_errno)); - STACK_UNWIND_STRICT (open, frame, -1, op_errno, NULL); - return 0; - } - - STACK_WIND (frame, error_gen_open_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->open, - loc, flags, fd, wbflags); - return 0; + STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->open, + loc, flags, fd, xdata); + return 0; } - int -error_gen_readv_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, - struct iovec *vector, int32_t count, - struct stat *stbuf, struct iobref *iobref) +error_gen_readv(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, + off_t offset, uint32_t flags, dict_t *xdata) { - STACK_UNWIND_STRICT (readv, frame, op_ret, op_errno, - vector, count, stbuf, iobref); - return 0; -} + int op_errno = 0; + eg_t *egp = NULL; + int enable = 1; + + egp = this->private; + enable = egp->enable[GF_FOP_READ]; + + if (enable) + op_errno = error_gen(this, GF_FOP_READ); + if (op_errno) { + GF_ERROR(this, "unwind(-1, %s)", strerror(op_errno)); + STACK_UNWIND_STRICT(readv, frame, -1, op_errno, NULL, 0, NULL, NULL, + xdata); + return 0; + } + + STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->readv, + fd, size, offset, flags, xdata); + return 0; +} int -error_gen_readv (call_frame_t *frame, xlator_t *this, - fd_t *fd, size_t size, off_t offset) +error_gen_writev(call_frame_t *frame, xlator_t *this, fd_t *fd, + struct iovec *vector, int32_t count, off_t off, uint32_t flags, + struct iobref *iobref, dict_t *xdata) { - int op_errno = 0; - eg_t *egp = NULL; - int enable = 1; - - egp = this->private; - enable = egp->enable[ERR_READV]; + int op_errno = 0; + eg_t *egp = NULL; + int enable = 1; + struct iovec *shortvec = NULL; - if (enable) - op_errno = error_gen (this, ERR_READV); + egp = this->private; + enable = egp->enable[GF_FOP_WRITE]; - if (op_errno) { - GF_ERROR(this, "unwind(-1, %s)", strerror (op_errno)); - STACK_UNWIND_STRICT (readv, frame, -1, op_errno, NULL, 0, - NULL, NULL); - return 0; - } + if (enable) + op_errno = error_gen(this, GF_FOP_WRITE); + if (op_errno == GF_ERROR_SHORT_WRITE) { + /* + * A short write error returns some value less than what was + * requested from a write. To simulate this, replace the vector + * with one half the size; + */ + shortvec = iov_dup(vector, 1); + shortvec->iov_len /= 2; + count = 1; + goto wind; + } else if (op_errno) { + GF_ERROR(this, "unwind(-1, %s)", strerror(op_errno)); + STACK_UNWIND_STRICT(writev, frame, -1, op_errno, NULL, NULL, xdata); + return 0; + } +wind: + STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->writev, + fd, shortvec ? shortvec : vector, count, off, flags, iobref, + xdata); - STACK_WIND (frame, error_gen_readv_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->readv, - fd, size, offset); - return 0; + if (shortvec) + GF_FREE(shortvec); + return 0; } - int -error_gen_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, - struct stat *prebuf, struct stat *postbuf) +error_gen_flush(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata) { - STACK_UNWIND_STRICT (writev, frame, op_ret, op_errno, prebuf, postbuf); - return 0; -} + int op_errno = 0; + eg_t *egp = NULL; + int enable = 1; + egp = this->private; + enable = egp->enable[GF_FOP_FLUSH]; -int -error_gen_writev (call_frame_t *frame, xlator_t *this, fd_t *fd, - struct iovec *vector, int32_t count, - off_t off, struct iobref *iobref) -{ - int op_errno = 0; - eg_t *egp = NULL; - int enable = 1; - - egp = this->private; - enable = egp->enable[ERR_WRITEV]; - - if (enable) - op_errno = error_gen (this, ERR_WRITEV); - - if (op_errno) { - GF_ERROR(this, "unwind(-1, %s)", strerror (op_errno)); - STACK_UNWIND_STRICT (writev, frame, -1, op_errno, NULL, NULL); - return 0; - } - - STACK_WIND (frame, error_gen_writev_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->writev, - fd, vector, count, off, iobref); - return 0; -} + if (enable) + op_errno = error_gen(this, GF_FOP_FLUSH); + if (op_errno) { + GF_ERROR(this, "unwind(-1, %s)", strerror(op_errno)); + STACK_UNWIND_STRICT(flush, frame, -1, op_errno, xdata); + return 0; + } -int -error_gen_flush_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno) -{ - STACK_UNWIND_STRICT (flush, frame, op_ret, op_errno); - return 0; + STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->flush, + fd, xdata); + return 0; } - int -error_gen_flush (call_frame_t *frame, xlator_t *this, fd_t *fd) +error_gen_fsync(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags, + dict_t *xdata) { - int op_errno = 0; - eg_t *egp = NULL; - int enable = 1; - - egp = this->private; - enable = egp->enable[ERR_FLUSH]; - - if (enable) - op_errno = error_gen (this, ERR_FLUSH); - - if (op_errno) { - GF_ERROR(this, "unwind(-1, %s)", strerror (op_errno)); - STACK_UNWIND_STRICT (flush, frame, -1, op_errno); - return 0; - } - - STACK_WIND (frame, error_gen_flush_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->flush, - fd); - return 0; -} + int op_errno = 0; + eg_t *egp = NULL; + int enable = 1; + egp = this->private; + enable = egp->enable[GF_FOP_FSYNC]; -int -error_gen_fsync_cbk (call_frame_t *frame, void *cookie, - xlator_t *this, int32_t op_ret, - int32_t op_errno, struct stat *prebuf, - struct stat *postbuf) -{ - STACK_UNWIND_STRICT (fsync, frame, op_ret, op_errno, prebuf, postbuf); - return 0; -} + if (enable) + op_errno = error_gen(this, GF_FOP_FSYNC); + if (op_errno) { + GF_ERROR(this, "unwind(-1, %s)", strerror(op_errno)); + STACK_UNWIND_STRICT(fsync, frame, -1, op_errno, NULL, NULL, xdata); + return 0; + } -int -error_gen_fsync (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags) -{ - int op_errno = 0; - eg_t *egp = NULL; - int enable = 1; - - egp = this->private; - enable = egp->enable[ERR_FSYNC]; - - if (enable) - op_errno = error_gen (this, ERR_FSYNC); - - if (op_errno) { - GF_ERROR(this, "unwind(-1, %s)", strerror (op_errno)); - STACK_UNWIND_STRICT (fsync, frame, -1, op_errno, NULL, NULL); - return 0; - } - - STACK_WIND (frame, error_gen_fsync_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->fsync, - fd, flags); - return 0; + STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fsync, + fd, flags, xdata); + return 0; } - int -error_gen_fstat_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, struct stat *buf) +error_gen_fstat(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata) { - STACK_UNWIND_STRICT (fstat, frame, op_ret, op_errno, buf); - return 0; -} + int op_errno = 0; + eg_t *egp = NULL; + int enable = 1; + egp = this->private; + enable = egp->enable[GF_FOP_FSTAT]; -int -error_gen_fstat (call_frame_t *frame, xlator_t *this, fd_t *fd) -{ - int op_errno = 0; - eg_t *egp = NULL; - int enable = 1; - - egp = this->private; - enable = egp->enable[ERR_FSTAT]; - - if (enable) - op_errno = error_gen (this, ERR_FSTAT); - - if (op_errno) { - GF_ERROR(this, "unwind(-1, %s)", strerror (op_errno)); - STACK_UNWIND_STRICT (fstat, frame, -1, op_errno, NULL); - return 0; - } - - STACK_WIND (frame, error_gen_fstat_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->fstat, - fd); - return 0; -} + if (enable) + op_errno = error_gen(this, GF_FOP_FSTAT); + if (op_errno) { + GF_ERROR(this, "unwind(-1, %s)", strerror(op_errno)); + STACK_UNWIND_STRICT(fstat, frame, -1, op_errno, NULL, xdata); + return 0; + } -int -error_gen_opendir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, fd_t *fd) -{ - STACK_UNWIND_STRICT (opendir, frame, op_ret, op_errno, fd); - return 0; + STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fstat, + fd, xdata); + return 0; } - int -error_gen_opendir (call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd) +error_gen_opendir(call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd, + dict_t *xdata) { - int op_errno = 0; - eg_t *egp = NULL; - int enable = 1; - - egp = this->private; - enable = egp->enable[ERR_OPENDIR]; - - if (enable) - op_errno = error_gen (this, ERR_OPENDIR); - - if (op_errno) { - GF_ERROR(this, "unwind(-1, %s)", strerror (op_errno)); - STACK_UNWIND_STRICT (opendir, frame, -1, op_errno, NULL); - return 0; - } - - STACK_WIND (frame, error_gen_opendir_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->opendir, - loc, fd); - return 0; -} + int op_errno = 0; + eg_t *egp = NULL; + int enable = 1; + egp = this->private; + enable = egp->enable[GF_FOP_OPENDIR]; -int -error_gen_getdents_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, dir_entry_t *entries, - int32_t count) -{ - STACK_UNWIND_STRICT (getdents, frame, op_ret, op_errno, entries, - count); - return 0; -} + if (enable) + op_errno = error_gen(this, GF_FOP_OPENDIR); + if (op_errno) { + GF_ERROR(this, "unwind(-1, %s)", strerror(op_errno)); + STACK_UNWIND_STRICT(opendir, frame, -1, op_errno, NULL, xdata); + return 0; + } -int -error_gen_getdents (call_frame_t *frame, xlator_t *this, fd_t *fd, - size_t size, off_t offset, int32_t flag) -{ - int op_errno = 0; - eg_t *egp = NULL; - int enable = 1; - - egp = this->private; - enable = egp->enable[ERR_GETDENTS]; - - if (enable) - op_errno = error_gen (this, ERR_GETDENTS); - - if (op_errno) { - GF_ERROR(this, "unwind(-1, %s)", strerror (op_errno)); - STACK_UNWIND_STRICT (getdents, frame, -1, op_errno, NULL, 0); - return 0; - } - - STACK_WIND (frame, error_gen_getdents_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->getdents, - fd, size, offset, flag); - return 0; + STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->opendir, + loc, fd, xdata); + return 0; } - int -error_gen_setdents_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno) +error_gen_fsyncdir(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags, + dict_t *xdata) { - STACK_UNWIND_STRICT (setdents, frame, op_ret, op_errno); - return 0; -} + int op_errno = 0; + eg_t *egp = NULL; + int enable = 1; + egp = this->private; + enable = egp->enable[GF_FOP_FSYNCDIR]; -int -error_gen_setdents (call_frame_t *frame, xlator_t *this, fd_t *fd, - int32_t flags, dir_entry_t *entries, int32_t count) -{ - int op_errno = 0; - eg_t *egp = NULL; - int enable = 1; - - egp = this->private; - enable = egp->enable[ERR_SETDENTS]; - - if (enable) - op_errno = error_gen (this, ERR_SETDENTS); - - if (op_errno) { - GF_ERROR(this, "unwind(-1, %s)", strerror (op_errno)); - STACK_UNWIND_STRICT (setdents, frame, -1, op_errno); - return 0; - } - - STACK_WIND (frame, error_gen_setdents_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->setdents, - fd, flags, entries, count); - return 0; -} + if (enable) + op_errno = error_gen(this, GF_FOP_FSYNCDIR); + if (op_errno) { + GF_ERROR(this, "unwind(-1, %s)", strerror(op_errno)); + STACK_UNWIND_STRICT(fsyncdir, frame, -1, op_errno, xdata); + return 0; + } -int -error_gen_fsyncdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno) -{ - STACK_UNWIND_STRICT (fsyncdir, frame, op_ret, op_errno); - return 0; + STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fsyncdir, + fd, flags, xdata); + return 0; } - int -error_gen_fsyncdir (call_frame_t *frame, xlator_t *this, fd_t *fd, - int32_t flags) +error_gen_statfs(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { - int op_errno = 0; - eg_t *egp = NULL; - int enable = 1; - - egp = this->private; - enable = egp->enable[ERR_FSYNCDIR]; - - if (enable) - op_errno = error_gen (this, ERR_FSYNCDIR); - - if (op_errno) { - GF_ERROR(this, "unwind(-1, %s)", strerror (op_errno)); - STACK_UNWIND_STRICT (fsyncdir, frame, -1, op_errno); - return 0; - } - - STACK_WIND (frame, error_gen_fsyncdir_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->fsyncdir, - fd, flags); - return 0; -} + int op_errno = 0; + eg_t *egp = NULL; + int enable = 1; + egp = this->private; + enable = egp->enable[GF_FOP_STATFS]; -int -error_gen_statfs_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, struct statvfs *buf) -{ - STACK_UNWIND_STRICT (statfs, frame, op_ret, op_errno, buf); + if (enable) + op_errno = error_gen(this, GF_FOP_STATFS); - return 0; -} + if (op_errno) { + GF_ERROR(this, "unwind(-1, %s)", strerror(op_errno)); + STACK_UNWIND_STRICT(statfs, frame, -1, op_errno, NULL, xdata); + return 0; + } + STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->statfs, + loc, xdata); + return 0; +} int -error_gen_statfs (call_frame_t *frame, xlator_t *this, loc_t *loc) +error_gen_setxattr(call_frame_t *frame, xlator_t *this, loc_t *loc, + dict_t *dict, int32_t flags, dict_t *xdata) { - int op_errno = 0; - eg_t *egp = NULL; - int enable = 1; - - egp = this->private; - enable = egp->enable[ERR_STATFS]; - - if (enable) - op_errno = error_gen (this, ERR_STATFS); - - if (op_errno) { - GF_ERROR(this, "unwind(-1, %s)", strerror (op_errno)); - STACK_UNWIND_STRICT (statfs, frame, -1, op_errno, NULL); - return 0; - } - - STACK_WIND (frame, error_gen_statfs_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->statfs, - loc); - return 0; -} + int op_errno = 0; + eg_t *egp = NULL; + int enable = 1; + egp = this->private; + enable = egp->enable[GF_FOP_SETXATTR]; -int -error_gen_setxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno) -{ - STACK_UNWIND_STRICT (setxattr, frame, op_ret, op_errno); + if (enable) + op_errno = error_gen(this, GF_FOP_SETXATTR); - return 0; -} + if (op_errno) { + GF_ERROR(this, "unwind(-1, %s)", strerror(op_errno)); + STACK_UNWIND_STRICT(setxattr, frame, -1, op_errno, xdata); + return 0; + } + STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->setxattr, + loc, dict, flags, xdata); + return 0; +} int -error_gen_setxattr (call_frame_t *frame, xlator_t *this, loc_t *loc, - dict_t *dict, int32_t flags) +error_gen_getxattr(call_frame_t *frame, xlator_t *this, loc_t *loc, + const char *name, dict_t *xdata) { - int op_errno = 0; - eg_t *egp = NULL; - int enable = 1; - - egp = this->private; - enable = egp->enable[ERR_SETXATTR]; - - if (enable) - op_errno = error_gen (this, ERR_SETXATTR); - - if (op_errno) { - GF_ERROR(this, "unwind(-1, %s)", strerror (op_errno)); - STACK_UNWIND_STRICT (setxattr, frame, -1, op_errno); - return 0; - } - - STACK_WIND (frame, error_gen_setxattr_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->setxattr, - loc, dict, flags); - return 0; -} + int op_errno = 0; + eg_t *egp = NULL; + int enable = 1; + egp = this->private; + enable = egp->enable[GF_FOP_GETXATTR]; -int -error_gen_getxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, dict_t *dict) -{ - STACK_UNWIND_STRICT (getxattr, frame, op_ret, op_errno, dict); - return 0; -} + if (enable) + op_errno = error_gen(this, GF_FOP_GETXATTR); + if (op_errno) { + GF_ERROR(this, "unwind(-1, %s)", strerror(op_errno)); + STACK_UNWIND_STRICT(getxattr, frame, -1, op_errno, NULL, xdata); + return 0; + } -int -error_gen_getxattr (call_frame_t *frame, xlator_t *this, loc_t *loc, - const char *name) -{ - int op_errno = 0; - eg_t *egp = NULL; - int enable = 1; - - egp = this->private; - enable = egp->enable[ERR_GETXATTR]; - - if (enable) - op_errno = error_gen (this, ERR_GETXATTR); - - if (op_errno) { - GF_ERROR(this, "unwind(-1, %s)", strerror (op_errno)); - STACK_UNWIND_STRICT (getxattr, frame, -1, op_errno, NULL); - return 0; - } - - STACK_WIND (frame, error_gen_getxattr_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->getxattr, - loc, name); - return 0; + STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->getxattr, + loc, name, xdata); + return 0; } - int -error_gen_xattrop_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, dict_t *dict) +error_gen_fsetxattr(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *dict, + int32_t flags, dict_t *xdata) { - STACK_UNWIND_STRICT (xattrop, frame, op_ret, op_errno, dict); + int op_errno = 0; + eg_t *egp = NULL; + int enable = 1; - return 0; -} + egp = this->private; + enable = egp->enable[GF_FOP_FSETXATTR]; + if (enable) + op_errno = error_gen(this, GF_FOP_FSETXATTR); -int -error_gen_xattrop (call_frame_t *frame, xlator_t *this, loc_t *loc, - gf_xattrop_flags_t flags, dict_t *dict) -{ - int op_errno = 0; - eg_t *egp = NULL; - int enable = 1; - - egp = this->private; - enable = egp->enable[ERR_XATTROP]; - - if (enable) - op_errno = error_gen (this, ERR_XATTROP); - - if (op_errno) { - GF_ERROR(this, "unwind(-1, %s)", strerror (op_errno)); - STACK_UNWIND_STRICT (xattrop, frame, -1, op_errno, NULL); - return 0; - } - - STACK_WIND (frame, error_gen_xattrop_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->xattrop, - loc, flags, dict); - return 0; -} + if (op_errno) { + GF_ERROR(this, "unwind(-1, %s)", strerror(op_errno)); + STACK_UNWIND_STRICT(fsetxattr, frame, -1, op_errno, xdata); + return 0; + } + STACK_WIND_TAIL(frame, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->fsetxattr, fd, dict, flags, xdata); + return 0; +} int -error_gen_fxattrop_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, dict_t *dict) +error_gen_fgetxattr(call_frame_t *frame, xlator_t *this, fd_t *fd, + const char *name, dict_t *xdata) { - STACK_UNWIND_STRICT (fxattrop, frame, op_ret, op_errno, dict); + int op_errno = 0; + eg_t *egp = NULL; + int enable = 1; - return 0; -} + egp = this->private; + enable = egp->enable[GF_FOP_FGETXATTR]; + if (enable) + op_errno = error_gen(this, GF_FOP_FGETXATTR); -int -error_gen_fxattrop (call_frame_t *frame, xlator_t *this, fd_t *fd, - gf_xattrop_flags_t flags, dict_t *dict) -{ - int op_errno = 0; - eg_t *egp = NULL; - int enable = 1; - - egp = this->private; - enable = egp->enable[ERR_FXATTROP]; - - if (enable) - op_errno = error_gen (this, ERR_FXATTROP); - - if (op_errno) { - GF_ERROR(this, "unwind(-1, %s)", strerror (op_errno)); - STACK_UNWIND_STRICT (fxattrop, frame, -1, op_errno, NULL); - return 0; - } - - STACK_WIND (frame, error_gen_fxattrop_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->fxattrop, - fd, flags, dict); - return 0; -} + if (op_errno) { + GF_ERROR(this, "unwind(-1, %s)", strerror(op_errno)); + STACK_UNWIND_STRICT(fgetxattr, frame, -1, op_errno, NULL, xdata); + return 0; + } + STACK_WIND_TAIL(frame, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->fgetxattr, fd, name, xdata); + return 0; +} int -error_gen_removexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno) +error_gen_xattrop(call_frame_t *frame, xlator_t *this, loc_t *loc, + gf_xattrop_flags_t flags, dict_t *dict, dict_t *xdata) { - STACK_UNWIND_STRICT (removexattr, frame, op_ret, op_errno); + int op_errno = 0; + eg_t *egp = NULL; + int enable = 1; - return 0; -} + egp = this->private; + enable = egp->enable[GF_FOP_XATTROP]; + if (enable) + op_errno = error_gen(this, GF_FOP_XATTROP); -int -error_gen_removexattr (call_frame_t *frame, xlator_t *this, loc_t *loc, - const char *name) -{ - int op_errno = 0; - eg_t *egp = NULL; - int enable = 1; - - egp = this->private; - enable = egp->enable[ERR_REMOVEXATTR]; - - if (enable) - op_errno = error_gen (this, ERR_REMOVEXATTR); - - if (op_errno) { - GF_ERROR(this, "unwind(-1, %s)", strerror (op_errno)); - STACK_UNWIND_STRICT (removexattr, frame, -1, op_errno); - return 0; - } - - STACK_WIND (frame, error_gen_removexattr_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->removexattr, - loc, name); - return 0; -} + if (op_errno) { + GF_ERROR(this, "unwind(-1, %s)", strerror(op_errno)); + STACK_UNWIND_STRICT(xattrop, frame, -1, op_errno, NULL, xdata); + return 0; + } + STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->xattrop, + loc, flags, dict, xdata); + return 0; +} int -error_gen_lk_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, struct flock *lock) +error_gen_fxattrop(call_frame_t *frame, xlator_t *this, fd_t *fd, + gf_xattrop_flags_t flags, dict_t *dict, dict_t *xdata) { - STACK_UNWIND_STRICT (lk, frame, op_ret, op_errno, lock); - return 0; -} + int op_errno = 0; + eg_t *egp = NULL; + int enable = 1; + egp = this->private; + enable = egp->enable[GF_FOP_FXATTROP]; + + if (enable) + op_errno = error_gen(this, GF_FOP_FXATTROP); + + if (op_errno) { + GF_ERROR(this, "unwind(-1, %s)", strerror(op_errno)); + STACK_UNWIND_STRICT(fxattrop, frame, -1, op_errno, NULL, xdata); + return 0; + } + + STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fxattrop, + fd, flags, dict, xdata); + return 0; +} int -error_gen_lk (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t cmd, - struct flock *lock) +error_gen_removexattr(call_frame_t *frame, xlator_t *this, loc_t *loc, + const char *name, dict_t *xdata) { - int op_errno = 0; - eg_t *egp = NULL; - int enable = 1; - - egp = this->private; - enable = egp->enable[ERR_LK]; - - if (enable) - op_errno = error_gen (this, ERR_LK); - - if (op_errno) { - GF_ERROR(this, "unwind(-1, %s)", strerror (op_errno)); - STACK_UNWIND_STRICT (lk, frame, -1, op_errno, NULL); - return 0; - } - - STACK_WIND (frame, error_gen_lk_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->lk, - fd, cmd, lock); - return 0; -} + int op_errno = 0; + eg_t *egp = NULL; + int enable = 1; + egp = this->private; + enable = egp->enable[GF_FOP_REMOVEXATTR]; -int -error_gen_inodelk_cbk (call_frame_t *frame, void *cookie, - xlator_t *this, int32_t op_ret, int32_t op_errno) + if (enable) + op_errno = error_gen(this, GF_FOP_REMOVEXATTR); -{ - STACK_UNWIND_STRICT (inodelk, frame, op_ret, op_errno); - return 0; -} + if (op_errno) { + GF_ERROR(this, "unwind(-1, %s)", strerror(op_errno)); + STACK_UNWIND_STRICT(removexattr, frame, -1, op_errno, xdata); + return 0; + } + STACK_WIND_TAIL(frame, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->removexattr, loc, name, xdata); + return 0; +} int -error_gen_inodelk (call_frame_t *frame, xlator_t *this, - const char *volume, loc_t *loc, int32_t cmd, - struct flock *lock) +error_gen_fremovexattr(call_frame_t *frame, xlator_t *this, fd_t *fd, + const char *name, dict_t *xdata) { - int op_errno = 0; - eg_t *egp = NULL; - int enable = 1; - - egp = this->private; - enable = egp->enable[ERR_INODELK]; - - if (enable) - op_errno = error_gen (this, ERR_INODELK); - - if (op_errno) { - GF_ERROR(this, "unwind(-1, %s)", strerror (op_errno)); - STACK_UNWIND_STRICT (inodelk, frame, -1, op_errno); - return 0; - } - - STACK_WIND (frame, error_gen_inodelk_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->inodelk, - volume, loc, cmd, lock); - return 0; -} + int op_errno = 0; + eg_t *egp = NULL; + int enable = 1; + egp = this->private; + enable = egp->enable[GF_FOP_FREMOVEXATTR]; -int -error_gen_finodelk_cbk (call_frame_t *frame, void *cookie, - xlator_t *this, int32_t op_ret, int32_t op_errno) + if (enable) + op_errno = error_gen(this, GF_FOP_FREMOVEXATTR); -{ - STACK_UNWIND_STRICT (finodelk, frame, op_ret, op_errno); - return 0; -} + if (op_errno) { + GF_ERROR(this, "unwind(-1, %s)", strerror(op_errno)); + STACK_UNWIND_STRICT(fremovexattr, frame, -1, op_errno, xdata); + return 0; + } + STACK_WIND_TAIL(frame, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->fremovexattr, fd, name, xdata); + return 0; +} int -error_gen_finodelk (call_frame_t *frame, xlator_t *this, - const char *volume, fd_t *fd, int32_t cmd, - struct flock *lock) +error_gen_lk(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t cmd, + struct gf_flock *lock, dict_t *xdata) { - int op_errno = 0; - eg_t *egp = NULL; - int enable = 1; - - egp = this->private; - enable = egp->enable[ERR_FINODELK]; - - if (enable) - op_errno = error_gen (this, ERR_FINODELK); - - if (op_errno) { - GF_ERROR(this, "unwind(-1, %s)", strerror (op_errno)); - STACK_UNWIND_STRICT (finodelk, frame, -1, op_errno); - return 0; - } - - STACK_WIND (frame, error_gen_finodelk_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->finodelk, - volume, fd, cmd, lock); - return 0; -} + int op_errno = 0; + eg_t *egp = NULL; + int enable = 1; + egp = this->private; + enable = egp->enable[GF_FOP_LK]; -int -error_gen_entrylk_cbk (call_frame_t *frame, void *cookie, - xlator_t *this, int32_t op_ret, int32_t op_errno) + if (enable) + op_errno = error_gen(this, GF_FOP_LK); -{ - STACK_UNWIND_STRICT (entrylk, frame, op_ret, op_errno); - return 0; -} + if (op_errno) { + GF_ERROR(this, "unwind(-1, %s)", strerror(op_errno)); + STACK_UNWIND_STRICT(lk, frame, -1, op_errno, NULL, xdata); + return 0; + } + STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->lk, fd, + cmd, lock, xdata); + return 0; +} int -error_gen_entrylk (call_frame_t *frame, xlator_t *this, - const char *volume, loc_t *loc, const char *basename, - entrylk_cmd cmd, entrylk_type type) +error_gen_inodelk(call_frame_t *frame, xlator_t *this, const char *volume, + loc_t *loc, int32_t cmd, struct gf_flock *lock, dict_t *xdata) { - int op_errno = 0; - eg_t *egp = NULL; - int enable = 1; - - egp = this->private; - enable = egp->enable[ERR_ENTRYLK]; - - if (enable) - op_errno = error_gen (this, ERR_ENTRYLK); - - if (op_errno) { - GF_ERROR(this, "unwind(-1, %s)", strerror (op_errno)); - STACK_UNWIND_STRICT (entrylk, frame, -1, op_errno); - return 0; - } - - STACK_WIND (frame, error_gen_entrylk_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->entrylk, - volume, loc, basename, cmd, type); - return 0; -} + int op_errno = 0; + eg_t *egp = NULL; + int enable = 1; + egp = this->private; + enable = egp->enable[GF_FOP_INODELK]; -int -error_gen_fentrylk_cbk (call_frame_t *frame, void *cookie, - xlator_t *this, int32_t op_ret, int32_t op_errno) + if (enable) + op_errno = error_gen(this, GF_FOP_INODELK); -{ - STACK_UNWIND_STRICT (fentrylk, frame, op_ret, op_errno); - return 0; -} + if (op_errno) { + GF_ERROR(this, "unwind(-1, %s)", strerror(op_errno)); + STACK_UNWIND_STRICT(inodelk, frame, -1, op_errno, xdata); + return 0; + } + STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->inodelk, + volume, loc, cmd, lock, xdata); + return 0; +} int -error_gen_fentrylk (call_frame_t *frame, xlator_t *this, - const char *volume, fd_t *fd, const char *basename, - entrylk_cmd cmd, entrylk_type type) +error_gen_finodelk(call_frame_t *frame, xlator_t *this, const char *volume, + fd_t *fd, int32_t cmd, struct gf_flock *lock, dict_t *xdata) { - int op_errno = 0; - eg_t *egp = NULL; - int enable = 1; - - egp = this->private; - enable = egp->enable[ERR_FENTRYLK]; - - if (enable) - op_errno = error_gen (this, ERR_FENTRYLK); - - if (op_errno) { - GF_ERROR(this, "unwind(-1, %s)", strerror (op_errno)); - STACK_UNWIND_STRICT (fentrylk, frame, -1, op_errno); - return 0; - } - - STACK_WIND (frame, error_gen_fentrylk_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->fentrylk, - volume, fd, basename, cmd, type); - return 0; -} + int op_errno = 0; + eg_t *egp = NULL; + int enable = 1; + egp = this->private; + enable = egp->enable[GF_FOP_FINODELK]; -/* Management operations */ + if (enable) + op_errno = error_gen(this, GF_FOP_FINODELK); -int -error_gen_stats_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, - struct xlator_stats *stats) -{ - STACK_UNWIND (frame, op_ret, op_errno, stats); - return 0; -} + if (op_errno) { + GF_ERROR(this, "unwind(-1, %s)", strerror(op_errno)); + STACK_UNWIND_STRICT(finodelk, frame, -1, op_errno, xdata); + return 0; + } + STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->finodelk, + volume, fd, cmd, lock, xdata); + return 0; +} int -error_gen_stats (call_frame_t *frame, xlator_t *this, int32_t flags) +error_gen_entrylk(call_frame_t *frame, xlator_t *this, const char *volume, + loc_t *loc, const char *basename, entrylk_cmd cmd, + entrylk_type type, dict_t *xdata) { - int op_errno = 0; - eg_t *egp = NULL; - int enable = 1; - - egp = this->private; - enable = egp->enable[ERR_STATS]; - - if (enable) - op_errno = error_gen (this, ERR_STATS); - - if (op_errno) { - GF_ERROR(this, "unwind(-1, %s)", strerror (op_errno)); - STACK_UNWIND (frame, -1, op_errno, NULL); - return 0; - } - - STACK_WIND (frame, error_gen_stats_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->mops->stats, - flags); - return 0; -} + int op_errno = 0; + eg_t *egp = NULL; + int enable = 1; + egp = this->private; + enable = egp->enable[GF_FOP_ENTRYLK]; -int -error_gen_getspec_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, char *spec_data) -{ - STACK_UNWIND (frame, op_ret, op_errno, spec_data); + if (enable) + op_errno = error_gen(this, GF_FOP_ENTRYLK); - return 0; -} + if (op_errno) { + GF_ERROR(this, "unwind(-1, %s)", strerror(op_errno)); + STACK_UNWIND_STRICT(entrylk, frame, -1, op_errno, xdata); + return 0; + } + STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->entrylk, + volume, loc, basename, cmd, type, xdata); + return 0; +} int -error_gen_getspec (call_frame_t *frame, xlator_t *this, const char *key, - int32_t flags) +error_gen_fentrylk(call_frame_t *frame, xlator_t *this, const char *volume, + fd_t *fd, const char *basename, entrylk_cmd cmd, + entrylk_type type, dict_t *xdata) { - int op_errno = 0; - eg_t *egp = NULL; - int enable = 1; - - egp = this->private; - enable = egp->enable[ERR_GETSPEC]; - - if (enable) - op_errno = error_gen (this, ERR_GETSPEC); - - if (op_errno) { - GF_ERROR(this, "unwind(-1, %s)", strerror (op_errno)); - STACK_UNWIND (frame, -1, op_errno, NULL); - return 0; - } - - STACK_WIND (frame, error_gen_getspec_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->mops->getspec, - key, flags); - return 0; -} + int op_errno = 0; + eg_t *egp = NULL; + int enable = 1; + egp = this->private; + enable = egp->enable[GF_FOP_FENTRYLK]; -int -error_gen_checksum_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, - uint8_t *file_checksum, uint8_t *dir_checksum) -{ - STACK_UNWIND (frame, op_ret, op_errno, - file_checksum, dir_checksum); - return 0; -} + if (enable) + op_errno = error_gen(this, GF_FOP_FENTRYLK); + if (op_errno) { + GF_ERROR(this, "unwind(-1, %s)", strerror(op_errno)); + STACK_UNWIND_STRICT(fentrylk, frame, -1, op_errno, xdata); + return 0; + } -int -error_gen_checksum (call_frame_t *frame, xlator_t *this, loc_t *loc, - int32_t flag) -{ - int op_errno = 0; - eg_t *egp = NULL; - int enable = 1; - - egp = this->private; - enable = egp->enable[ERR_CHECKSUM]; - - if (enable) - op_errno = error_gen (this, ERR_CHECKSUM); - - if (op_errno) { - GF_ERROR(this, "unwind(-1, %s)", strerror (op_errno)); - STACK_UNWIND (frame, -1, op_errno, NULL, NULL); - return 0; - } - - STACK_WIND (frame, error_gen_checksum_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->checksum, - loc, flag); - return 0; + STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->fentrylk, + volume, fd, basename, cmd, type, xdata); + return 0; } - int -error_gen_readdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, gf_dirent_t *entries) +error_gen_getspec(call_frame_t *frame, xlator_t *this, const char *key, + int32_t flags) { - STACK_UNWIND_STRICT (readdir, frame, op_ret, op_errno, entries); - return 0; -} + int op_errno = 0; + eg_t *egp = NULL; + int enable = 1; + egp = this->private; + enable = egp->enable[GF_FOP_GETSPEC]; + + if (enable) + op_errno = error_gen(this, GF_FOP_GETSPEC); + + if (op_errno) { + GF_ERROR(this, "unwind(-1, %s)", strerror(op_errno)); + STACK_UNWIND_STRICT(getspec, frame, -1, op_errno, NULL); + return 0; + } + + STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->getspec, + key, flags); + return 0; +} int -error_gen_readdir (call_frame_t *frame, xlator_t *this, fd_t *fd, - size_t size, off_t off) +error_gen_readdir(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, + off_t off, dict_t *xdata) { - int op_errno = 0; - eg_t *egp = NULL; - int enable = 1; - - egp = this->private; - enable = egp->enable[ERR_READDIR]; - - if (enable) - op_errno = error_gen (this, ERR_READDIR); - - if (op_errno) { - GF_ERROR(this, "unwind(-1, %s)", strerror (op_errno)); - STACK_UNWIND_STRICT (readdir, frame, -1, op_errno, NULL); - return 0; - } - - STACK_WIND (frame, error_gen_readdir_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->readdir, - fd, size, off); - return 0; -} + int op_errno = 0; + eg_t *egp = NULL; + int enable = 1; + egp = this->private; + enable = egp->enable[GF_FOP_READDIR]; + + if (enable) + op_errno = error_gen(this, GF_FOP_READDIR); + + if (op_errno) { + GF_ERROR(this, "unwind(-1, %s)", strerror(op_errno)); + STACK_UNWIND_STRICT(readdir, frame, -1, op_errno, NULL, xdata); + return 0; + } + + STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->readdir, + fd, size, off, xdata); + return 0; +} int -error_gen_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, gf_dirent_t *entries) +error_gen_readdirp(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, + off_t off, dict_t *dict) { - STACK_UNWIND_STRICT (readdirp, frame, op_ret, op_errno, entries); - return 0; -} + int op_errno = 0; + eg_t *egp = NULL; + int enable = 1; + egp = this->private; + enable = egp->enable[GF_FOP_READDIRP]; -int -error_gen_readdirp (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, - off_t off) + if (enable) + op_errno = error_gen(this, GF_FOP_READDIRP); + + if (op_errno) { + GF_ERROR(this, "unwind(-1, %s)", strerror(op_errno)); + STACK_UNWIND_STRICT(readdirp, frame, -1, op_errno, NULL, NULL); + return 0; + } + + STACK_WIND_TAIL(frame, FIRST_CHILD(this), FIRST_CHILD(this)->fops->readdirp, + fd, size, off, dict); + return 0; +} + +static void +error_gen_set_failure(eg_t *pvt, double percent) { - int op_errno = 0; - eg_t *egp = NULL; - int enable = 1; - - egp = this->private; - enable = egp->enable[ERR_READDIRP]; - - if (enable) - op_errno = error_gen (this, ERR_READDIRP); - - if (op_errno) { - GF_ERROR(this, "unwind(-1, %s)", strerror (op_errno)); - STACK_UNWIND_STRICT (readdirp, frame, -1, op_errno, NULL); - return 0; - } - - STACK_WIND (frame, error_gen_readdirp_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->readdirp, - fd, size, off); - return 0; + double ppm; + + GF_ASSERT(pvt); + + ppm = (percent / 100.0) * (double)FAILURE_GRANULARITY; + pvt->failure_iter_no = (int)ppm; } +static void +error_gen_parse_fill_fops(eg_t *pvt, char *enable_fops) +{ + char *op_no_str = NULL; + int op_no = -1; + int i = 0; + xlator_t *this = THIS; + char *saveptr = NULL; -int -error_gen_closedir (xlator_t *this, fd_t *fd) + GF_ASSERT(pvt); + GF_ASSERT(this); + + for (i = 0; i < GF_FOP_MAXVALUE; i++) + pvt->enable[i] = 0; + + if (!enable_fops) { + gf_log(this->name, GF_LOG_WARNING, "All fops are enabled."); + for (i = 0; i < GF_FOP_MAXVALUE; i++) + pvt->enable[i] = 1; + } else { + op_no_str = strtok_r(enable_fops, ",", &saveptr); + while (op_no_str) { + op_no = gf_fop_int(op_no_str); + if (op_no == -1) { + gf_log(this->name, GF_LOG_WARNING, "Wrong option value %s", + op_no_str); + } else + pvt->enable[op_no] = 1; + + op_no_str = strtok_r(NULL, ",", &saveptr); + } + } +} + +int32_t +error_gen_priv_dump(xlator_t *this) { - return 0; + char key_prefix[GF_DUMP_MAX_BUF_LEN]; + int ret = -1; + eg_t *conf = NULL; + + if (!this) + goto out; + + conf = this->private; + if (!conf) + goto out; + + ret = TRY_LOCK(&conf->lock); + if (ret != 0) { + return ret; + } + + gf_proc_dump_add_section("xlator.debug.error-gen.%s.priv", this->name); + gf_proc_dump_build_key(key_prefix, "xlator.debug.error-gen", "%s.priv", + this->name); + + gf_proc_dump_write("op_count", "%d", conf->op_count); + gf_proc_dump_write("failure_iter_no", "%d", conf->failure_iter_no); + gf_proc_dump_write("error_no", "%d", conf->error_no_int); + gf_proc_dump_write("random_failure", "%d", conf->random_failure); + + UNLOCK(&conf->lock); +out: + return ret; } +int32_t +mem_acct_init(xlator_t *this) +{ + int ret = -1; + + if (!this) + return ret; + + ret = xlator_mem_acct_init(this, gf_error_gen_mt_end + 1); + + if (ret != 0) { + gf_log(this->name, GF_LOG_ERROR, + "Memory accounting init" + " failed"); + return ret; + } + + return ret; +} int -error_gen_close (xlator_t *this, fd_t *fd) +reconfigure(xlator_t *this, dict_t *options) { - return 0; -} + eg_t *pvt = NULL; + int32_t ret = 0; + char *error_enable_fops = NULL; + char *error_no = NULL; + double failure_percent_dbl = 0.0; + + if (!this || !this->private) + goto out; + + pvt = this->private; + + ret = -1; + + GF_OPTION_RECONF("error-no", error_no, options, str, out); + + if (error_no) + pvt->error_no_int = conv_errno_to_int(&error_no); + + GF_OPTION_RECONF("failure", failure_percent_dbl, options, percent, out); + GF_OPTION_RECONF("enable", error_enable_fops, options, str, out); + + GF_OPTION_RECONF("random-failure", pvt->random_failure, options, bool, out); + + error_gen_parse_fill_fops(pvt, error_enable_fops); + error_gen_set_failure(pvt, failure_percent_dbl); + + ret = 0; +out: + gf_log(this ? this->name : "error-gen", GF_LOG_DEBUG, + "reconfigure returning %d", ret); + return ret; +} int -init (xlator_t *this) +init(xlator_t *this) { - eg_t *pvt = NULL; - data_t *error_no = NULL; - data_t *failure_percent = NULL; - data_t *enable = NULL; - int32_t ret = 0; - char *error_enable_fops = NULL; - char *op_no_str = NULL; - int op_no = -1; - int i = 0; - int32_t failure_percent_int = 0; - - if (!this->children || this->children->next) { - gf_log (this->name, GF_LOG_ERROR, - "error-gen not configured with one subvolume"); - ret = -1; - goto out; - } + eg_t *pvt = NULL; + int32_t ret = 0; + char *error_enable_fops = NULL; + char *error_no = NULL; + double failure_percent_dbl = 0.0; - if (!this->parents) { - gf_log (this->name, GF_LOG_WARNING, - "dangling volume. check volfile "); - } + if (!this->children || this->children->next) { + gf_log(this->name, GF_LOG_ERROR, + "error-gen not configured with one subvolume"); + ret = -1; + goto out; + } - error_no = dict_get (this->options, "error-no"); - failure_percent = dict_get (this->options, "failure"); - enable = dict_get (this->options, "enable"); + if (!this->parents) { + gf_log(this->name, GF_LOG_WARNING, "dangling volume. check volfile "); + } - pvt = CALLOC (1, sizeof (eg_t)); + pvt = GF_CALLOC(1, sizeof(eg_t), gf_error_gen_mt_eg_t); - if (!pvt) { - gf_log (this->name, GF_LOG_ERROR, - "out of memory."); - ret = -1; - goto out; - } + if (!pvt) { + ret = -1; + goto out; + } - LOCK_INIT (&pvt->lock); + LOCK_INIT(&pvt->lock); - for (i = 0; i < NO_OF_FOPS; i++) - pvt->enable[i] = 0; - if (!error_no) { - gf_log (this->name, GF_LOG_DEBUG, - "error-no not specified."); - } else { - pvt->error_no = data_to_str (error_no); - } + ret = -1; - if (!failure_percent) { - gf_log (this->name, GF_LOG_DEBUG, - "failure percent not specified."); - pvt->failure_iter_no = 100/GF_FAILURE_DEFAULT; - } else { - failure_percent_int = data_to_int32 (failure_percent); - if (failure_percent_int) - pvt->failure_iter_no = 100/failure_percent_int; - else - pvt->failure_iter_no = 100/GF_FAILURE_DEFAULT; - } + GF_OPTION_INIT("error-no", error_no, str, out); - if (!enable) { - gf_log (this->name, GF_LOG_WARNING, - "All fops are enabled."); - for (i = 0; i < NO_OF_FOPS; i++) - pvt->enable[i] = 1; - } else { - error_enable_fops = data_to_str (enable); - op_no_str = error_enable_fops; - while ((*error_enable_fops) != '\0') { - error_enable_fops++; - if (((*error_enable_fops) == ',') || - ((*error_enable_fops) == '\0')) { - if ((*error_enable_fops) != '\0') { - (*error_enable_fops) = '\0'; - error_enable_fops++; - } - op_no = get_fop_int (&op_no_str); - if (op_no == -1) { - gf_log (this->name, GF_LOG_WARNING, - "Wrong option value %s", - op_no_str); - } else - pvt->enable[op_no] = 1; - op_no_str = error_enable_fops; - } - } - } - this->private = pvt; + if (error_no) + pvt->error_no_int = conv_errno_to_int(&error_no); + + GF_OPTION_INIT("failure", failure_percent_dbl, percent, out); + + GF_OPTION_INIT("enable", error_enable_fops, str, out); + + GF_OPTION_INIT("random-failure", pvt->random_failure, bool, out); + + error_gen_parse_fill_fops(pvt, error_enable_fops); + error_gen_set_failure(pvt, failure_percent_dbl); + + this->private = pvt; + + /* Give some seed value here. */ + srand(gf_time()); + + ret = 0; out: - return ret; + if (ret) + GF_FREE(pvt); + return ret; } - void -fini (xlator_t *this) +fini(xlator_t *this) { - eg_t *pvt = NULL; - - if (!this) - return; - pvt = this->private; + eg_t *pvt = NULL; - if (pvt) { - LOCK_DESTROY (&pvt->lock); - FREE (pvt); - gf_log (this->name, GF_LOG_DEBUG, "fini called"); - } + if (!this) return; + pvt = this->private; + + if (pvt) { + LOCK_DESTROY(&pvt->lock); + GF_FREE(pvt); + gf_log(this->name, GF_LOG_DEBUG, "fini called"); + } + return; } -struct xlator_fops fops = { - .lookup = error_gen_lookup, - .stat = error_gen_stat, - .readlink = error_gen_readlink, - .mknod = error_gen_mknod, - .mkdir = error_gen_mkdir, - .unlink = error_gen_unlink, - .rmdir = error_gen_rmdir, - .symlink = error_gen_symlink, - .rename = error_gen_rename, - .link = error_gen_link, - .truncate = error_gen_truncate, - .create = error_gen_create, - .open = error_gen_open, - .readv = error_gen_readv, - .writev = error_gen_writev, - .statfs = error_gen_statfs, - .flush = error_gen_flush, - .fsync = error_gen_fsync, - .setxattr = error_gen_setxattr, - .getxattr = error_gen_getxattr, - .removexattr = error_gen_removexattr, - .opendir = error_gen_opendir, - .readdir = error_gen_readdir, - .readdirp = error_gen_readdirp, - .getdents = error_gen_getdents, - .fsyncdir = error_gen_fsyncdir, - .access = error_gen_access, - .ftruncate = error_gen_ftruncate, - .fstat = error_gen_fstat, - .lk = error_gen_lk, - .setdents = error_gen_setdents, - .lookup_cbk = error_gen_lookup_cbk, - .checksum = error_gen_checksum, - .xattrop = error_gen_xattrop, - .fxattrop = error_gen_fxattrop, - .inodelk = error_gen_inodelk, - .finodelk = error_gen_finodelk, - .entrylk = error_gen_entrylk, - .fentrylk = error_gen_fentrylk, - .setattr = error_gen_setattr, - .fsetattr = error_gen_fsetattr, +struct xlator_dumpops dumpops = { + .priv = error_gen_priv_dump, }; -struct xlator_mops mops = { - .stats = error_gen_stats, - .getspec = error_gen_getspec, -}; +struct xlator_cbks cbks; -struct xlator_cbks cbks = { - .release = error_gen_close, - .releasedir = error_gen_closedir, +struct xlator_fops fops = { + .lookup = error_gen_lookup, + .stat = error_gen_stat, + .readlink = error_gen_readlink, + .mknod = error_gen_mknod, + .mkdir = error_gen_mkdir, + .unlink = error_gen_unlink, + .rmdir = error_gen_rmdir, + .symlink = error_gen_symlink, + .rename = error_gen_rename, + .link = error_gen_link, + .truncate = error_gen_truncate, + .create = error_gen_create, + .open = error_gen_open, + .readv = error_gen_readv, + .writev = error_gen_writev, + .statfs = error_gen_statfs, + .flush = error_gen_flush, + .fsync = error_gen_fsync, + .setxattr = error_gen_setxattr, + .getxattr = error_gen_getxattr, + .removexattr = error_gen_removexattr, + .fsetxattr = error_gen_fsetxattr, + .fgetxattr = error_gen_fgetxattr, + .fremovexattr = error_gen_fremovexattr, + .opendir = error_gen_opendir, + .readdir = error_gen_readdir, + .readdirp = error_gen_readdirp, + .fsyncdir = error_gen_fsyncdir, + .access = error_gen_access, + .ftruncate = error_gen_ftruncate, + .fstat = error_gen_fstat, + .lk = error_gen_lk, + .xattrop = error_gen_xattrop, + .fxattrop = error_gen_fxattrop, + .inodelk = error_gen_inodelk, + .finodelk = error_gen_finodelk, + .entrylk = error_gen_entrylk, + .fentrylk = error_gen_fentrylk, + .setattr = error_gen_setattr, + .fsetattr = error_gen_fsetattr, + .getspec = error_gen_getspec, }; struct volume_options options[] = { - { .key = {"failure"}, - .type = GF_OPTION_TYPE_INT }, - { .key = {"error-no"}, - .value = {"ENOENT","ENOTDIR","ENAMETOOLONG","EACCES","EBADF", - "EFAULT","ENOMEM","EINVAL","EIO","EEXIST","ENOSPC", - "EPERM","EROFS","EBUSY","EISDIR","ENOTEMPTY","EMLINK" - "ENODEV","EXDEV","EMFILE","ENFILE","ENOSYS","EINTR", - "EFBIG","EAGAIN"}, - .type = GF_OPTION_TYPE_STR }, - { .key = {"enable"}, - .type = GF_OPTION_TYPE_STR }, - { .key = {NULL} } + { + .key = {"failure"}, + .type = GF_OPTION_TYPE_PERCENT, + .description = "Percentage failure of operations when enabled.", + }, + + { + .key = {"error-no"}, + .value = {"ENOENT", + "ENOTDIR", + "ENAMETOOLONG", + "EACCES", + "EBADF", + "EFAULT", + "ENOMEM", + "EINVAL", + "EIO", + "EEXIST", + "ENOSPC", + "EPERM", + "EROFS", + "EBUSY", + "EISDIR", + "ENOTEMPTY", + "EMLINK" + "ENODEV", + "EXDEV", + "EMFILE", + "ENFILE", + "ENOSYS", + "EINTR", + "EFBIG", + "EAGAIN", + "GF_ERROR_SHORT_WRITE"}, + .type = GF_OPTION_TYPE_STR, + .op_version = {3}, + .tags = {"error-gen"}, + .flags = OPT_FLAG_SETTABLE, + + }, + + { + .key = {"random-failure"}, + .type = GF_OPTION_TYPE_BOOL, + .default_value = "off", + .op_version = {3}, + .tags = {"error-gen"}, + .flags = OPT_FLAG_SETTABLE, + }, + + { + .key = {"enable", "error-fops"}, + .type = GF_OPTION_TYPE_STR, + .description = "Accepts a string which takes ',' separated fop " + "strings to denote which fops are enabled for error", + .op_version = {3}, + .tags = {"error-gen"}, + .flags = OPT_FLAG_SETTABLE, + }, + + {.key = {NULL}}, +}; + +xlator_api_t xlator_api = { + .init = init, + .fini = fini, + .reconfigure = reconfigure, + .mem_acct_init = mem_acct_init, + .op_version = {1}, + .dumpops = &dumpops, + .fops = &fops, + .cbks = &cbks, + .options = options, + .identifier = "error-gen", + .category = GF_TECH_PREVIEW, }; diff --git a/xlators/debug/error-gen/src/error-gen.h b/xlators/debug/error-gen/src/error-gen.h index 7fb5fdfb56c..2478cd5b21c 100644 --- a/xlators/debug/error-gen/src/error-gen.h +++ b/xlators/debug/error-gen/src/error-gen.h @@ -1,89 +1,49 @@ /* - Copyright (c) 2008-2009 Gluster, Inc. <http://www.gluster.com> - This file is part of GlusterFS. + Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com> + This file is part of GlusterFS. - GlusterFS is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3 of the License, - or (at your option) any later version. - - GlusterFS is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see - <http://www.gnu.org/licenses/>. + This file is licensed to you under your choice of the GNU Lesser + General Public License, version 3 or any 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 _ERROR_GEN_H #define _ERROR_GEN_H -#ifndef _CONFIG_H -#define _CONFIG_H -#include "config.h" -#endif +#include "error-gen-mem-types.h" #define GF_FAILURE_DEFAULT 10 -#define NO_OF_FOPS 42 -enum { - ERR_LOOKUP, - ERR_STAT, - ERR_READLINK, - ERR_MKNOD, - ERR_MKDIR, - ERR_UNLINK, - ERR_RMDIR, - ERR_SYMLINK, - ERR_RENAME, - ERR_LINK, - ERR_TRUNCATE, - ERR_CREATE, - ERR_OPEN, - ERR_READV, - ERR_WRITEV, - ERR_STATFS, - ERR_FLUSH, - ERR_FSYNC, - ERR_SETXATTR, - ERR_GETXATTR, - ERR_REMOVEXATTR, - ERR_OPENDIR, - ERR_READDIR, - ERR_READDIRP, - ERR_GETDENTS, - ERR_FSYNCDIR, - ERR_ACCESS, - ERR_FTRUNCATE, - ERR_FSTAT, - ERR_LK, - ERR_SETDENTS, - ERR_CHECKSUM, - ERR_XATTROP, - ERR_FXATTROP, - ERR_INODELK, - ERR_FINODELK, - ERR_ENTRYLK, - ERR_FENTRYLK, - ERR_SETATTR, - ERR_FSETATTR, - ERR_STATS, - ERR_GETSPEC +/* + * Pseudo-errors refer to errors beyond the scope of traditional <-1, op_errno> + * returns. This facilitates the ability to return unexpected, but not -1 values + * and/or to inject operations that lead to implicit error conditions. The range + * for pseudo errors resides at a high value to avoid conflicts with the errno + * range. + */ +enum GF_PSEUDO_ERRORS { + GF_ERROR_SHORT_WRITE = 1000, /* short writev return value */ + GF_ERROR_MAX }; typedef struct { - int enable[NO_OF_FOPS]; - int op_count; - int failure_iter_no; - char *error_no; - gf_lock_t lock; + int enable[GF_FOP_MAXVALUE]; + int op_count; + /* + * This is only an iteration number in the random-failure case. For + * the normal controlled-probability case, it's actually a numerator + * for the failure probability (see FAILURE_GRANULARITY declaration). + * It's just not worth blowing up the diff by changing it. + */ + int failure_iter_no; + int error_no_int; + gf_boolean_t random_failure; + gf_lock_t lock; } eg_t; typedef struct { - int error_no_count; - int error_no[20]; + int error_no_count; + int error_no[20]; } sys_error_t; #endif diff --git a/xlators/debug/io-stats/src/Makefile.am b/xlators/debug/io-stats/src/Makefile.am index 91aea6ebbc2..c69f3caf0fe 100644 --- a/xlators/debug/io-stats/src/Makefile.am +++ b/xlators/debug/io-stats/src/Makefile.am @@ -2,12 +2,18 @@ xlator_LTLIBRARIES = io-stats.la xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/debug -io_stats_la_LDFLAGS = -module -avoidversion +io_stats_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) io_stats_la_SOURCES = io-stats.c io_stats_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la -AM_CFLAGS = -fPIC -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -Wall -D$(GF_HOST_OS)\ - -I$(top_srcdir)/libglusterfs/src -shared -nostartfiles $(GF_CFLAGS) +noinst_HEADERS = io-stats-mem-types.h + +AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ + -I$(top_srcdir)/rpc/xdr/src -I$(top_builddir)/rpc/xdr/src \ + -I$(top_srcdir)/rpc/rpc-lib/src \ + -DDATADIR=\"$(localstatedir)\" + +AM_CFLAGS = -Wall $(GF_CFLAGS) CLEANFILES = diff --git a/xlators/debug/io-stats/src/io-stats-mem-types.h b/xlators/debug/io-stats/src/io-stats-mem-types.h new file mode 100644 index 00000000000..51d38d8b97c --- /dev/null +++ b/xlators/debug/io-stats/src/io-stats-mem-types.h @@ -0,0 +1,27 @@ +/* + Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com> + This file is part of GlusterFS. + + This file is licensed to you under your choice of the GNU Lesser + General Public License, version 3 or any later version (LGPLv3 or + later), or the GNU General Public License, version 2 (GPLv2), in all + cases as published by the Free Software Foundation. +*/ + +#ifndef __IO_STATS_MEM_TYPES_H__ +#define __IO_STATS_MEM_TYPES_H__ + +#include <glusterfs/mem-types.h> + +extern const char *__progname; + +enum gf_io_stats_mem_types_ { + gf_io_stats_mt_ios_conf = gf_common_mt_end + 1, + gf_io_stats_mt_ios_fd, + gf_io_stats_mt_ios_stat, + gf_io_stats_mt_ios_stat_list, + gf_io_stats_mt_ios_sample_buf, + gf_io_stats_mt_ios_sample, + gf_io_stats_mt_end +}; +#endif diff --git a/xlators/debug/io-stats/src/io-stats.c b/xlators/debug/io-stats/src/io-stats.c index b3cfbeb4ffc..aa00c446e5a 100644 --- a/xlators/debug/io-stats/src/io-stats.c +++ b/xlators/debug/io-stats/src/io-stats.c @@ -1,26 +1,14 @@ /* - Copyright (c) 2006-2009 Gluster, Inc. <http://www.gluster.com> - This file is part of GlusterFS. - - GlusterFS is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3 of the License, - or (at your option) any later version. - - GlusterFS is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see - <http://www.gnu.org/licenses/>. -*/ + Copyright (c) 2006-2012 Red Hat, Inc. <http://www.redhat.com> + This file is part of GlusterFS. -#ifndef _CONFIG_H -#define _CONFIG_H -#include "config.h" -#endif + This file is licensed to you under your choice of the GNU Lesser + General Public License, version 3 or any later version (LGPLv3 or + later), or the GNU General Public License, version 2 (GPLv2), in all + cases as published by the Free Software Foundation. +*/ +#include <glusterfs/xlator.h> +#include <glusterfs/syscall.h> /** * xlators/debug/io_stats : @@ -29,1574 +17,4464 @@ * * a) total read data - since process start, last interval and per fd * b) total write data - since process start, last interval and per fd - * c) counts of read IO block size - since process start, last interval and per fd - * d) counts of write IO block size - since process start, last interval and per fd - * e) counts of all FOP types passing through it + * c) counts of read IO block size - since process start, last interval and per + * fd d) counts of write IO block size - since process start, last interval and + * per fd e) counts of all FOP types passing through it * - * Usage: setfattr -n io-stats-dump /tmp/filename /mnt/gluster + * Usage: setfattr -n trusted.io-stats-dump /tmp/filename /mnt/gluster + * output is written to /tmp/filename.<iostats xlator instance name> * */ #include <fnmatch.h> #include <errno.h> -#include "glusterfs.h" -#include "xlator.h" +#include <glusterfs/glusterfs.h> +#include <glusterfs/xlator.h> +#include "io-stats-mem-types.h" +#include <stdarg.h> +#include <glusterfs/defaults.h> +#include <glusterfs/logging.h> +#include <glusterfs/statedump.h> +#include <glusterfs/syncop.h> +#include <pwd.h> +#include <grp.h> +#include <glusterfs/upcall-utils.h> +#include <glusterfs/async.h> + +#define MAX_LIST_MEMBERS 100 +#define DEFAULT_PWD_BUF_SZ 16384 +#define DEFAULT_GRP_BUF_SZ 16384 +#define IOS_BLOCK_COUNT_SIZE 32 + +#define IOS_STATS_DUMP_DIR DEFAULT_VAR_RUN_DIRECTORY + +typedef enum { + IOS_STATS_TYPE_NONE, + IOS_STATS_TYPE_OPEN, + IOS_STATS_TYPE_READ, + IOS_STATS_TYPE_WRITE, + IOS_STATS_TYPE_OPENDIR, + IOS_STATS_TYPE_READDIRP, + IOS_STATS_TYPE_READ_THROUGHPUT, + IOS_STATS_TYPE_WRITE_THROUGHPUT, + IOS_STATS_TYPE_MAX +} ios_stats_type_t; + +typedef enum { + IOS_STATS_THRU_READ, + IOS_STATS_THRU_WRITE, + IOS_STATS_THRU_MAX, +} ios_stats_thru_t; + +/* This is same as gf1_cli_info_op */ +/* had to be defined here again, so we have modularity between + xdr, xlator, and library functions */ +typedef enum ios_info_op { + GF_IOS_INFO_NONE = 0, + GF_IOS_INFO_ALL = 1, + GF_IOS_INFO_INCREMENTAL = 2, + GF_IOS_INFO_CUMULATIVE = 3, + GF_IOS_INFO_CLEAR = 4, +} ios_info_op_t; + +struct ios_stat_lat { + struct timeval time; + double throughput; +}; +struct ios_stat { + gf_lock_t lock; + uuid_t gfid; + char *filename; + gf_atomic_t counters[IOS_STATS_TYPE_MAX]; + struct ios_stat_lat thru_counters[IOS_STATS_THRU_MAX]; + gf_atomic_t refcnt; +}; + +struct ios_stat_list { + struct list_head list; + struct ios_stat *iosstat; + double value; +}; + +struct ios_stat_head { + gf_lock_t lock; + double min_cnt; + uint64_t members; + struct ios_stat_list *iosstats; +}; + +typedef struct _ios_sample_t { + uid_t uid; + gid_t gid; + char identifier[UNIX_PATH_MAX]; + glusterfs_fop_t fop_type; + struct timeval timestamp; + double elapsed; +} ios_sample_t; + +typedef struct _ios_sample_buf_t { + uint64_t pos; /* Position in write buffer */ + uint64_t size; /* Size of ring buffer */ + uint64_t collected; /* Number of samples we've collected */ + uint64_t observed; /* Number of FOPs we've observed */ + ios_sample_t *ios_samples; /* Our list of samples */ +} ios_sample_buf_t; + +struct ios_lat { + double min; + double max; + double avg; + uint64_t total; +}; struct ios_global_stats { - uint64_t data_written; - uint64_t data_read; - uint64_t block_count_write[32]; - uint64_t block_count_read[32]; - uint64_t fop_hits[GF_FOP_MAXVALUE]; - uint64_t cbk_hits[GF_CBK_MAXVALUE]; - struct timeval started_at; + gf_atomic_t data_written; + gf_atomic_t data_read; + gf_atomic_t block_count_write[IOS_BLOCK_COUNT_SIZE]; + gf_atomic_t block_count_read[IOS_BLOCK_COUNT_SIZE]; + gf_atomic_t fop_hits[GF_FOP_MAXVALUE]; + gf_atomic_t upcall_hits[GF_UPCALL_FLAGS_MAXVALUE]; + time_t started_at; + struct ios_lat latency[GF_FOP_MAXVALUE]; + uint64_t nr_opens; + uint64_t max_nr_opens; + struct timeval max_openfd_time; }; +typedef enum { + IOS_DUMP_TYPE_NONE = 0, + IOS_DUMP_TYPE_FILE = 1, + IOS_DUMP_TYPE_DICT = 2, + IOS_DUMP_TYPE_JSON_FILE = 3, + IOS_DUMP_TYPE_SAMPLES = 4, + IOS_DUMP_TYPE_MAX = 5 +} ios_dump_type_t; struct ios_conf { - gf_lock_t lock; - struct ios_global_stats cumulative; - uint64_t increment; - struct ios_global_stats incremental; - gf_boolean_t dump_fd_stats; + gf_lock_t lock; + struct ios_global_stats cumulative; + uint64_t increment; + struct ios_global_stats incremental; + gf_boolean_t dump_fd_stats; + gf_boolean_t count_fop_hits; + gf_boolean_t measure_latency; + struct ios_stat_head list[IOS_STATS_TYPE_MAX]; + struct ios_stat_head thru_list[IOS_STATS_THRU_MAX]; + int32_t ios_dump_interval; + pthread_t dump_thread; + gf_boolean_t dump_thread_should_die; + gf_boolean_t dump_thread_running; + gf_lock_t ios_sampling_lock; + int32_t ios_sample_interval; + int32_t ios_sample_buf_size; + ios_sample_buf_t *ios_sample_buf; + struct dnscache *dnscache; + int32_t ios_dnscache_ttl_sec; + /* + * What we really need here is just a unique value to keep files + * created by this instance distinct from those created by any other. + * On the client side this isn't a problem, so we just use the + * translator name. On the server side conflicts can occur, so the + * volfile-generation code automatically sets this (via an option) + * to be the brick path. + * + * NB While the *field* name has changed, it didn't seem worth changing + * all of the cases where "xlator_name" is used as a *variable* name. + */ + char *unique_id; + ios_dump_type_t dump_format; }; - struct ios_fd { - char *filename; - uint64_t data_written; - uint64_t data_read; - uint64_t block_count_write[32]; - uint64_t block_count_read[32]; - struct timeval opened_at; + char *filename; + gf_atomic_t data_written; + gf_atomic_t data_read; + gf_atomic_t block_count_write[IOS_BLOCK_COUNT_SIZE]; + gf_atomic_t block_count_read[IOS_BLOCK_COUNT_SIZE]; + struct timeval opened_at; +}; + +struct ios_dump_args { + ios_dump_type_t type; + union { + FILE *logfp; + dict_t *dict; + } u; }; +typedef int (*block_dump_func)(xlator_t *, struct ios_dump_args *, int, int, + uint64_t); struct ios_local { - struct timeval wind_at; - struct timeval unwind_at; + struct timeval wind_at; + struct timeval unwind_at; }; +struct volume_options options[]; -#define BUMP_FOP(op) \ - do { \ - struct ios_conf *conf = NULL; \ - \ - conf = this->private; \ - LOCK (&conf->lock); \ - { \ - conf->cumulative.fop_hits[GF_FOP_##op]++; \ - conf->incremental.fop_hits[GF_FOP_##op]++; \ - } \ - UNLOCK (&conf->lock); \ - } while (0) - - -#define BUMP_CBK(op) \ - do { \ - struct ios_conf *conf = NULL; \ - \ - conf = this->private; \ - LOCK (&conf->lock); \ - { \ - conf->cumulative.cbk_hits[GF_CBK_##op]++; \ - conf->incremental.cbk_hits[GF_CBK_##op]++; \ - } \ - UNLOCK (&conf->lock); \ - } while (0) - - -#define BUMP_READ(fd, len) \ - do { \ - struct ios_conf *conf = NULL; \ - struct ios_fd *iosfd = NULL; \ - int lb2 = 0; \ - \ - conf = this->private; \ - lb2 = log_base2 (len); \ - ios_fd_ctx_get (fd, this, &iosfd); \ - \ - LOCK (&conf->lock); \ - { \ - conf->cumulative.data_read += len; \ - conf->incremental.data_read += len; \ - conf->cumulative.block_count_read[lb2]++; \ - conf->incremental.block_count_read[lb2]++; \ - \ - if (iosfd) { \ - iosfd->data_read += len; \ - iosfd->block_count_read[lb2]++; \ - } \ - } \ - UNLOCK (&conf->lock); \ - } while (0) - - -#define BUMP_WRITE(fd, len) \ - do { \ - struct ios_conf *conf = NULL; \ - struct ios_fd *iosfd = NULL; \ - int lb2 = 0; \ - \ - conf = this->private; \ - lb2 = log_base2 (len); \ - ios_fd_ctx_get (fd, this, &iosfd); \ - \ - LOCK (&conf->lock); \ - { \ - conf->cumulative.data_written += len; \ - conf->incremental.data_written += len; \ - conf->cumulative.block_count_write[lb2]++; \ - conf->incremental.block_count_write[lb2]++; \ - \ - if (iosfd) { \ - iosfd->data_written += len; \ - iosfd->block_count_write[lb2]++; \ - } \ - } \ - UNLOCK (&conf->lock); \ - } while (0) - - -int -ios_fd_ctx_get (fd_t *fd, xlator_t *this, struct ios_fd **iosfd) -{ - uint64_t iosfd64 = 0; - unsigned long iosfdlong = 0; - int ret = 0; - - ret = fd_ctx_get (fd, this, &iosfd64); - iosfdlong = iosfd64; - if (ret != -1) - *iosfd = (void *) iosfdlong; - - return ret; +static int +is_fop_latency_started(call_frame_t *frame) +{ + GF_ASSERT(frame); + struct timeval epoch = { + 0, + }; + return memcmp(&frame->begin, &epoch, sizeof(epoch)); } +#define _IOS_SAMP_DIR DEFAULT_LOG_FILE_DIRECTORY "/samples" +#ifdef GF_LINUX_HOST_OS +#define _IOS_DUMP_DIR DATADIR "/lib/glusterd/stats" +#else +#define _IOS_DUMP_DIR DATADIR "/db/glusterd/stats" +#endif - -int -ios_fd_ctx_set (fd_t *fd, xlator_t *this, struct ios_fd *iosfd) +#define END_FOP_LATENCY(frame, op) \ + do { \ + struct ios_conf *conf = NULL; \ + \ + conf = this->private; \ + if (conf && conf->measure_latency) { \ + timespec_now(&frame->end); \ + update_ios_latency(conf, frame, GF_FOP_##op); \ + } \ + } while (0) + +#define START_FOP_LATENCY(frame) \ + do { \ + struct ios_conf *conf = NULL; \ + \ + conf = this->private; \ + if (conf && conf->measure_latency) { \ + timespec_now(&frame->begin); \ + } else { \ + memset(&frame->begin, 0, sizeof(frame->begin)); \ + } \ + } while (0) + +#define BUMP_FOP(op) \ + do { \ + struct ios_conf *conf = NULL; \ + \ + conf = this->private; \ + if (!conf) \ + break; \ + GF_ATOMIC_INC(conf->cumulative.fop_hits[GF_FOP_##op]); \ + GF_ATOMIC_INC(conf->incremental.fop_hits[GF_FOP_##op]); \ + } while (0) + +#define UPDATE_PROFILE_STATS(frame, op) \ + do { \ + struct ios_conf *conf = NULL; \ + \ + if (!is_fop_latency_started(frame)) \ + break; \ + conf = this->private; \ + if (conf && conf->measure_latency && conf->count_fop_hits) { \ + BUMP_FOP(op); \ + timespec_now(&frame->end); \ + update_ios_latency(conf, frame, GF_FOP_##op); \ + } \ + } while (0) + +#define BUMP_THROUGHPUT(iosstat, type) \ + do { \ + struct ios_conf *conf = NULL; \ + double elapsed; \ + struct timespec *begin, *end; \ + double throughput; \ + int flag = 0; \ + struct timeval tv = { \ + 0, \ + }; \ + \ + begin = &frame->begin; \ + end = &frame->end; \ + \ + elapsed = gf_tsdiff(begin, end) / 1000.0; \ + throughput = op_ret / elapsed; \ + \ + conf = this->private; \ + gettimeofday(&tv, NULL); \ + LOCK(&iosstat->lock); \ + { \ + if (iosstat->thru_counters[type].throughput <= throughput) { \ + iosstat->thru_counters[type].throughput = throughput; \ + memcpy(&iosstat->thru_counters[type].time, &tv, \ + sizeof(struct timeval)); \ + flag = 1; \ + } \ + } \ + UNLOCK(&iosstat->lock); \ + if (flag) \ + ios_stat_add_to_list(&conf->thru_list[type], throughput, iosstat); \ + } while (0) + +static int +ios_fd_ctx_get(fd_t *fd, xlator_t *this, struct ios_fd **iosfd) { - uint64_t iosfd64 = 0; - int ret = 0; + uint64_t iosfd64 = 0; + unsigned long iosfdlong = 0; + int ret = 0; - iosfd64 = (unsigned long) iosfd; - ret = fd_ctx_set (fd, this, iosfd64); + ret = fd_ctx_get(fd, this, &iosfd64); + iosfdlong = iosfd64; + if (ret != -1) + *iosfd = (void *)iosfdlong; - return ret; + return ret; } +static int +ios_fd_ctx_set(fd_t *fd, xlator_t *this, struct ios_fd *iosfd) +{ + uint64_t iosfd64 = 0; + int ret = 0; -#define ios_log(this, logfp, fmt ...) \ - do { \ - if (logfp) { \ - fprintf (logfp, fmt); \ - fprintf (logfp, "\n"); \ - } \ - gf_log (this->name, GF_LOG_NORMAL, fmt); \ - } while (0) + iosfd64 = (unsigned long)iosfd; + ret = fd_ctx_set(fd, this, iosfd64); + return ret; +} -int -io_stats_dump_global (xlator_t *this, struct ios_global_stats *stats, - struct timeval *now, int interval, FILE *logfp) +static int +ios_stat_ref(struct ios_stat *iosstat) { - int i = 0; + uint64_t refcnt = 0; + refcnt = GF_ATOMIC_INC(iosstat->refcnt); - if (interval == -1) - ios_log (this, logfp, "=== Cumulative stats ==="); - else - ios_log (this, logfp, "=== Interval %d stats ===", - interval); - ios_log (this, logfp, " Duration : %"PRId64"secs", - (uint64_t) (now->tv_sec - stats->started_at.tv_sec)); - ios_log (this, logfp, " BytesRead : %"PRId64, - stats->data_read); - ios_log (this, logfp, " BytesWritten : %"PRId64, - stats->data_written); - - for (i = 0; i < 32; i++) { - if (stats->block_count_read[i]) - ios_log (this, logfp, " Read %06db+ : %"PRId64, - (1 << i), stats->block_count_read[i]); - } + return refcnt; +} - for (i = 0; i < 32; i++) { - if (stats->block_count_write[i]) - ios_log (this, logfp, "Write %06db+ : %"PRId64, - (1 << i), stats->block_count_write[i]); +static int +ios_stat_unref(struct ios_stat *iosstat) +{ + int cleanup = 0; + uint64_t refcnt = 0; + + refcnt = GF_ATOMIC_DEC(iosstat->refcnt); + if (refcnt == 0) { + if (iosstat->filename) { + GF_FREE(iosstat->filename); + iosstat->filename = NULL; } + cleanup = 1; + } - for (i = 0; i < GF_FOP_MAXVALUE; i++) - if (stats->fop_hits[i]) - ios_log (this, logfp, "%14s : %"PRId64, - gf_fop_list[i], stats->fop_hits[i]); + if (cleanup) { + LOCK_DESTROY(&iosstat->lock); + GF_FREE(iosstat); + iosstat = NULL; + } - for (i = 0; i < GF_CBK_MAXVALUE; i++) - if (stats->cbk_hits[i]) - ios_log (this, logfp, "%14s : %"PRId64, - gf_fop_list[i], stats->cbk_hits[i]); - return 0; + return 0; } +static int +ios_stat_add_to_list(struct ios_stat_head *list_head, uint64_t value, + struct ios_stat *iosstat) +{ + struct ios_stat_list *new = NULL; + struct ios_stat_list *entry = NULL; + struct ios_stat_list *t = NULL; + struct ios_stat_list *list_entry = NULL; + struct ios_stat_list *tmp = NULL; + struct ios_stat_list *last = NULL; + struct ios_stat *stat = NULL; + int cnt = 0; + int found = 0; + int reposition = 0; + double min_count = 0; + + LOCK(&list_head->lock); + { + if (list_head->min_cnt == 0) + list_head->min_cnt = value; + if ((list_head->members == MAX_LIST_MEMBERS) && + (list_head->min_cnt > value)) + goto out; + + list_for_each_entry_safe(entry, t, &list_head->iosstats->list, list) + { + cnt++; + if (cnt == list_head->members) + last = entry; + + if (!gf_uuid_compare(iosstat->gfid, entry->iosstat->gfid)) { + list_entry = entry; + found = cnt; + entry->value = value; + if (!reposition) { + if (cnt == list_head->members) + list_head->min_cnt = value; + goto out; + } + break; + } else if (entry->value <= value && !reposition) { + reposition = cnt; + tmp = entry; + if (cnt == list_head->members - 1) + min_count = entry->value; + } + } + if (found) { + list_del(&list_entry->list); + list_add_tail(&list_entry->list, &tmp->list); + if (min_count) + list_head->min_cnt = min_count; + goto out; + } else if (list_head->members == MAX_LIST_MEMBERS && reposition) { + new = GF_CALLOC(1, sizeof(*new), gf_io_stats_mt_ios_stat_list); + new->iosstat = iosstat; + new->value = value; + ios_stat_ref(iosstat); + list_add_tail(&new->list, &tmp->list); + if (last) { + stat = last->iosstat; + last->iosstat = NULL; + ios_stat_unref(stat); + list_del(&last->list); + GF_FREE(last); + } + if (reposition == MAX_LIST_MEMBERS) + list_head->min_cnt = value; + else if (min_count) { + list_head->min_cnt = min_count; + } + } else if (list_head->members < MAX_LIST_MEMBERS) { + new = GF_CALLOC(1, sizeof(*new), gf_io_stats_mt_ios_stat_list); + new->iosstat = iosstat; + new->value = value; + ios_stat_ref(iosstat); + if (reposition) { + list_add_tail(&new->list, &tmp->list); + } else { + list_add_tail(&new->list, &entry->list); + } + list_head->members++; + if (list_head->min_cnt > value) + list_head->min_cnt = value; + } + } +out: + UNLOCK(&list_head->lock); + return 0; +} -int -io_stats_dump (xlator_t *this, char *filename, inode_t *inode, - const char *path) +static void +ios_bump_read(xlator_t *this, fd_t *fd, size_t len) { - struct ios_conf *conf = NULL; - struct ios_global_stats cumulative = {0, }; - struct ios_global_stats incremental = {0, }; - int increment = 0; - struct timeval now; - FILE *logfp = NULL; + struct ios_conf *conf = NULL; + struct ios_fd *iosfd = NULL; + int lb2 = 0; + + conf = this->private; + lb2 = log_base2(len); + ios_fd_ctx_get(fd, this, &iosfd); + if (!conf) + return; - conf = this->private; + GF_ATOMIC_ADD(conf->cumulative.data_read, len); + GF_ATOMIC_ADD(conf->incremental.data_read, len); + GF_ATOMIC_INC(conf->cumulative.block_count_read[lb2]); + GF_ATOMIC_INC(conf->incremental.block_count_read[lb2]); - gettimeofday (&now, NULL); - LOCK (&conf->lock); - { - cumulative = conf->cumulative; - incremental = conf->incremental; + if (iosfd) { + GF_ATOMIC_ADD(iosfd->data_read, len); + GF_ATOMIC_INC(iosfd->block_count_read[lb2]); + } +} - increment = conf->increment++; +static void +ios_bump_write(xlator_t *this, fd_t *fd, size_t len) +{ + struct ios_conf *conf = NULL; + struct ios_fd *iosfd = NULL; + int lb2 = 0; + + conf = this->private; + lb2 = log_base2(len); + ios_fd_ctx_get(fd, this, &iosfd); + if (!conf) + return; - memset (&conf->incremental, 0, sizeof (conf->incremental)); - conf->incremental.started_at = now; - } - UNLOCK (&conf->lock); + GF_ATOMIC_ADD(conf->cumulative.data_written, len); + GF_ATOMIC_ADD(conf->incremental.data_written, len); + GF_ATOMIC_INC(conf->cumulative.block_count_write[lb2]); + GF_ATOMIC_INC(conf->incremental.block_count_write[lb2]); - logfp = fopen (filename, "w+"); - io_stats_dump_global (this, &cumulative, &now, -1, logfp); - io_stats_dump_global (this, &incremental, &now, increment, logfp); + if (iosfd) { + GF_ATOMIC_ADD(iosfd->data_written, len); + GF_ATOMIC_INC(iosfd->block_count_write[lb2]); + } +} - if (logfp) - fclose (logfp); - return 0; +static void +ios_bump_upcall(xlator_t *this, gf_upcall_flags_t event) +{ + struct ios_conf *conf = NULL; + + conf = this->private; + if (!conf) + return; + if (conf->count_fop_hits) { + GF_ATOMIC_INC(conf->cumulative.upcall_hits[event]); + GF_ATOMIC_INC(conf->incremental.upcall_hits[event]); + } } +static void +ios_bump_stats(xlator_t *this, struct ios_stat *iosstat, ios_stats_type_t type) +{ + struct ios_conf *conf = NULL; + uint64_t value = 0; + + conf = this->private; + + value = GF_ATOMIC_INC(iosstat->counters[type]); + ios_stat_add_to_list(&conf->list[type], value, iosstat); +} int -io_stats_dump_fd (xlator_t *this, struct ios_fd *iosfd) +ios_inode_ctx_set(inode_t *inode, xlator_t *this, struct ios_stat *iosstat) { - struct ios_conf *conf = NULL; - struct timeval now; - uint64_t sec = 0; - uint64_t usec = 0; - int i = 0; + uint64_t iosstat64 = 0; + int ret = 0; - conf = this->private; + ios_stat_ref(iosstat); + iosstat64 = (unsigned long)iosstat; + ret = inode_ctx_put(inode, this, iosstat64); + return ret; +} - if (!conf->dump_fd_stats) - return 0; +int +ios_inode_ctx_get(inode_t *inode, xlator_t *this, struct ios_stat **iosstat) +{ + uint64_t iosstat64 = 0; + unsigned long iosstatlong = 0; + int ret = 0; - if (!iosfd) - return 0; + ret = inode_ctx_get(inode, this, &iosstat64); + iosstatlong = iosstat64; + if (ret != -1) + *iosstat = (void *)iosstatlong; - gettimeofday (&now, NULL); + return ret; +} - if (iosfd->opened_at.tv_usec > now.tv_usec) { - now.tv_usec += 1000000; - now.tv_usec--; - } +/* + * So why goto all this trouble? Why not just queue up some samples in + * a big list and malloc away? Well malloc is expensive relative + * to what we are measuring, so cannot have any malloc's (or worse + * callocs) in our measurement code paths. Instead, we are going to + * pre-allocate a circular buffer and collect a maximum number of samples. + * Prior to dumping them all we'll create a new buffer and swap the + * old buffer with the new, and then proceed to dump the statistics + * in our dump thread. + * + */ +ios_sample_buf_t * +ios_create_sample_buf(size_t buf_size) +{ + ios_sample_buf_t *ios_sample_buf = NULL; + ios_sample_t *ios_samples = NULL; + + ios_sample_buf = GF_CALLOC(1, sizeof(*ios_sample_buf), + gf_io_stats_mt_ios_sample_buf); + if (!ios_sample_buf) + goto err; + + ios_samples = GF_CALLOC(buf_size, sizeof(*ios_samples), + gf_io_stats_mt_ios_sample); + + if (!ios_samples) + goto err; + + ios_sample_buf->ios_samples = ios_samples; + ios_sample_buf->size = buf_size; + ios_sample_buf->pos = 0; + ios_sample_buf->observed = 0; + ios_sample_buf->collected = 0; + + return ios_sample_buf; +err: + GF_FREE(ios_sample_buf); + return NULL; +} - sec = now.tv_sec - iosfd->opened_at.tv_sec; - usec = now.tv_usec - iosfd->opened_at.tv_usec; - - gf_log (this->name, GF_LOG_NORMAL, - "--- fd stats ---"); - - if (iosfd->filename) - gf_log (this->name, GF_LOG_NORMAL, - " Filename : %s", - iosfd->filename); - - if (sec) - gf_log (this->name, GF_LOG_NORMAL, - " Lifetime : %"PRId64"secs, %"PRId64"usecs", - sec, usec); - - if (iosfd->data_read) - gf_log (this->name, GF_LOG_NORMAL, - " BytesRead : %"PRId64" bytes", - iosfd->data_read); - - if (iosfd->data_written) - gf_log (this->name, GF_LOG_NORMAL, - " BytesWritten : %"PRId64" bytes", - iosfd->data_written); - - for (i = 0; i < 32; i++) { - if (iosfd->block_count_read[i]) - gf_log (this->name, GF_LOG_NORMAL, - " Read %06db+ : %"PRId64, - (1 << i), iosfd->block_count_read[i]); - } - for (i = 0; i < 32; i++) { - if (iosfd->block_count_write[i]) - gf_log (this->name, GF_LOG_NORMAL, - "Write %06db+ : %"PRId64, - (1 << i), iosfd->block_count_write[i]); - } +void +ios_destroy_sample_buf(ios_sample_buf_t *ios_sample_buf) +{ + GF_FREE(ios_sample_buf->ios_samples); + GF_FREE(ios_sample_buf); +} + +static int +ios_init_sample_buf(struct ios_conf *conf) +{ + int32_t ret = -1; + + GF_ASSERT(conf); + LOCK(&conf->lock); + conf->ios_sample_buf = ios_create_sample_buf(conf->ios_sample_buf_size); + if (!conf->ios_sample_buf) + goto out; + ret = 0; +out: + UNLOCK(&conf->lock); + return ret; +} + +static int +ios_stats_cleanup(xlator_t *this, inode_t *inode) +{ + struct ios_stat *iosstat = NULL; + uint64_t iosstat64 = 0; + + inode_ctx_del(inode, this, &iosstat64); + if (!iosstat64) { + gf_log(this->name, GF_LOG_WARNING, "could not get inode ctx"); return 0; + } + iosstat = (void *)(long)iosstat64; + if (iosstat) { + ios_stat_unref(iosstat); + } + return 0; } +#define ios_log(this, logfp, fmt...) \ + do { \ + if (logfp) { \ + fprintf(logfp, fmt); \ + fprintf(logfp, "\n"); \ + } \ + gf_log(this->name, GF_LOG_DEBUG, fmt); \ + } while (0) int -io_stats_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, fd_t *fd, - inode_t *inode, struct stat *buf, - struct stat *preparent, struct stat *postparent) +ios_dump_file_stats(struct ios_stat_head *list_head, xlator_t *this, + FILE *logfp) { - struct ios_fd *iosfd = NULL; - char *path = NULL; + struct ios_stat_list *entry = NULL; - path = frame->local; - frame->local = NULL; + LOCK(&list_head->lock); + { + list_for_each_entry(entry, &list_head->iosstats->list, list) + { + ios_log(this, logfp, "%-12.0f %s", entry->value, + entry->iosstat->filename); + } + } + UNLOCK(&list_head->lock); + return 0; +} - if (!path) - goto unwind; +int +ios_dump_throughput_stats(struct ios_stat_head *list_head, xlator_t *this, + FILE *logfp, ios_stats_thru_t type) +{ + struct ios_stat_list *entry = NULL; + char timestr[GF_TIMESTR_SIZE] = { + 0, + }; + + LOCK(&list_head->lock); + { + list_for_each_entry(entry, &list_head->iosstats->list, list) + { + gf_time_fmt_tv(timestr, sizeof timestr, + &entry->iosstat->thru_counters[type].time, + gf_timefmt_FT); + + ios_log(this, logfp, "%s \t %-10.2f \t %s", timestr, entry->value, + entry->iosstat->filename); + } + } + UNLOCK(&list_head->lock); + return 0; +} + +int +_io_stats_get_key_prefix(xlator_t *this, char **key_prefix) +{ + char *key_root = "gluster"; + char *xlator_name = NULL; + char *instance_name = NULL; + size_t key_len = 0; + int bytes_written = 0; + int i = 0; + int ret = 0; + struct ios_conf *conf = this->private; + + xlator_name = strdupa(conf->unique_id); + for (i = 0; i < strlen(xlator_name); i++) { + if (xlator_name[i] == '/') + xlator_name[i] = '_'; + } + + instance_name = this->instance_name; + if (this->name && strcmp(this->name, "glustershd") == 0) { + xlator_name = "shd"; + } else if (this->prev && strcmp(this->prev->name, "nfs-server") == 0) { + xlator_name = "nfsd"; + if (this->prev->instance_name) + instance_name = strdupa(this->prev->instance_name); + } + + if (strcmp(__progname, "glusterfsd") == 0) + key_root = "gluster.brick"; + + if (instance_name) { + /* +3 for 2 x "." + NULL */ + key_len = strlen(key_root) + strlen(xlator_name) + + strlen(instance_name) + 3; + *key_prefix = GF_CALLOC(key_len, sizeof(char), gf_common_mt_char); + if (!*key_prefix) { + ret = -ENOMEM; + goto err; + } + bytes_written = snprintf(*key_prefix, key_len, "%s.%s.%s", key_root, + xlator_name, instance_name); + if (bytes_written != key_len - 1) { + ret = -EINVAL; + goto err; + } + } else { + /* +2 for 1 x "." + NULL */ + key_len = strlen(key_root) + strlen(xlator_name) + 2; + *key_prefix = GF_CALLOC(key_len, sizeof(char), gf_common_mt_char); + if (!*key_prefix) { + ret = -ENOMEM; + goto err; + } + bytes_written = snprintf(*key_prefix, key_len, "%s.%s", key_root, + xlator_name); + if (bytes_written != key_len - 1) { + ret = -EINVAL; + goto err; + } + } + return 0; +err: + GF_FREE(*key_prefix); + *key_prefix = NULL; + return ret; +} - if (op_ret < 0) { - FREE (path); - goto unwind; +int +io_stats_dump_global_to_json_logfp(xlator_t *this, + struct ios_global_stats *stats, time_t now, + int interval, FILE *logfp) +{ + int i = 0; + int j = 0; + struct ios_conf *conf = NULL; + char *key_prefix = NULL; + char *str_prefix = NULL; + char *lc_fop_name = NULL; + int ret = 1; /* Default to error */ + int rw_size; + char *rw_unit = NULL; + uint64_t fop_hits; + float fop_lat_ave; + float fop_lat_min; + float fop_lat_max; + double interval_sec; + double fop_ave_usec = 0.0; + double fop_ave_usec_sum = 0.0; + double weighted_fop_ave_usec = 0.0; + double weighted_fop_ave_usec_sum = 0.0; + long total_fop_hits = 0; + loc_t unused_loc = { + 0, + }; + dict_t *xattr = NULL; + + interval_sec = (double)(now - stats->started_at); + + conf = this->private; + + ret = _io_stats_get_key_prefix(this, &key_prefix); + if (ret) { + goto out; + } + + if (interval == -1) { + str_prefix = "aggr"; + + } else { + str_prefix = "inter"; + } + ios_log(this, logfp, "{"); + + for (i = 0; i < 31; i++) { + rw_size = (1 << i); + if (rw_size >= 1024 * 1024) { + rw_size = rw_size / (1024 * 1024); + rw_unit = "mb"; + } else if (rw_size >= 1024) { + rw_size = rw_size / 1024; + rw_unit = "kb"; + } else { + rw_unit = "b"; } - iosfd = CALLOC (1, sizeof (*iosfd)); - if (!iosfd) { - FREE (path); - goto unwind; + if (interval == -1) { + ios_log(this, logfp, "\"%s.%s.read_%d%s\": %" GF_PRI_ATOMIC ",", + key_prefix, str_prefix, rw_size, rw_unit, + GF_ATOMIC_GET(stats->block_count_read[i])); + ios_log(this, logfp, "\"%s.%s.write_%d%s\": %" GF_PRI_ATOMIC ",", + key_prefix, str_prefix, rw_size, rw_unit, + GF_ATOMIC_GET(stats->block_count_write[i])); + } else { + ios_log(this, logfp, "\"%s.%s.read_%d%s_per_sec\": %0.2lf,", + key_prefix, str_prefix, rw_size, rw_unit, + (double)(GF_ATOMIC_GET(stats->block_count_read[i]) / + interval_sec)); + ios_log(this, logfp, "\"%s.%s.write_%d%s_per_sec\": %0.2lf,", + key_prefix, str_prefix, rw_size, rw_unit, + (double)(GF_ATOMIC_GET(stats->block_count_write[i]) / + interval_sec)); + } + } + + if (interval == -1) { + ios_log(this, logfp, "\"%s.%s.fds.open_count\": %" PRId64 ",", + key_prefix, str_prefix, conf->cumulative.nr_opens); + ios_log(this, logfp, "\"%s.%s.fds.max_open_count\": %" PRId64 ",", + key_prefix, str_prefix, conf->cumulative.max_nr_opens); + } + + for (i = 0; i < GF_FOP_MAXVALUE; i++) { + lc_fop_name = strdupa(gf_fop_list[i]); + for (j = 0; lc_fop_name[j]; j++) { + lc_fop_name[j] = tolower(lc_fop_name[j]); } - iosfd->filename = path; - gettimeofday (&iosfd->opened_at, NULL); + fop_hits = GF_ATOMIC_GET(stats->fop_hits[i]); + fop_lat_ave = 0.0; + fop_lat_min = 0.0; + fop_lat_max = 0.0; + if (fop_hits) { + if (stats->latency[i].avg) { + fop_lat_ave = stats->latency[i].avg; + fop_lat_min = stats->latency[i].min; + fop_lat_max = stats->latency[i].max; + } + } + if (interval == -1) { + ios_log(this, logfp, "\"%s.%s.fop.%s.count\": %" GF_PRI_ATOMIC ",", + key_prefix, str_prefix, lc_fop_name, fop_hits); + } else { + ios_log(this, logfp, "\"%s.%s.fop.%s.per_sec\": %0.2lf,", + key_prefix, str_prefix, lc_fop_name, + (double)(fop_hits / interval_sec)); + } - ios_fd_ctx_set (fd, this, iosfd); + ios_log(this, logfp, "\"%s.%s.fop.%s.latency_ave_usec\": %0.2lf,", + key_prefix, str_prefix, lc_fop_name, fop_lat_ave); + ios_log(this, logfp, "\"%s.%s.fop.%s.latency_min_usec\": %0.2lf,", + key_prefix, str_prefix, lc_fop_name, fop_lat_min); + ios_log(this, logfp, "\"%s.%s.fop.%s.latency_max_usec\": %0.2lf,", + key_prefix, str_prefix, lc_fop_name, fop_lat_max); + + fop_ave_usec_sum += fop_lat_ave; + weighted_fop_ave_usec_sum += fop_hits * fop_lat_ave; + total_fop_hits += fop_hits; + } + + if (total_fop_hits) { + weighted_fop_ave_usec = weighted_fop_ave_usec_sum / total_fop_hits; + /* Extra key that does not print out an entry w/ 0.00 for + * intervals with no data + */ + ios_log(this, logfp, + "\"%s.%s.fop.weighted_latency_ave_usec_nozerofill\": " + "%0.4lf,", + key_prefix, str_prefix, weighted_fop_ave_usec); + } + ios_log(this, logfp, "\"%s.%s.fop.weighted_latency_ave_usec\": %0.4lf,", + key_prefix, str_prefix, weighted_fop_ave_usec); + ios_log(this, logfp, "\"%s.%s.fop.weighted_fop_count\": %ld,", key_prefix, + str_prefix, total_fop_hits); + + fop_ave_usec = fop_ave_usec_sum / GF_FOP_MAXVALUE; + ios_log(this, logfp, "\"%s.%s.fop.unweighted_latency_ave_usec\":%0.4lf,", + key_prefix, str_prefix, fop_ave_usec); + + for (i = 0; i < GF_UPCALL_FLAGS_MAXVALUE; i++) { + lc_fop_name = strdupa(gf_upcall_list[i]); + for (j = 0; lc_fop_name[j]; j++) { + lc_fop_name[j] = tolower(lc_fop_name[j]); + } + fop_hits = GF_ATOMIC_GET(stats->upcall_hits[i]); + if (interval == -1) { + ios_log(this, logfp, "\"%s.%s.fop.%s.count\": %" GF_PRI_ATOMIC ",", + key_prefix, str_prefix, lc_fop_name, fop_hits); + } else { + ios_log(this, logfp, "\"%s.%s.fop.%s.per_sec\": %0.2lf,", + key_prefix, str_prefix, lc_fop_name, + (double)(fop_hits / interval_sec)); + } + } + + ret = syncop_getxattr(this, &unused_loc, &xattr, IO_THREADS_QUEUE_SIZE_KEY, + NULL, NULL); + if (xattr) { + /* + * Iterate over the dictionary returned to us by io-threads and + * dump the results to the stats file. + */ + data_pair_t *curr = NULL; + + dict_foreach_inline(xattr, curr) + { + ios_log(this, logfp, "\"%s.%s.%s.queue_size\": %d,", key_prefix, + str_prefix, curr->key, data_to_int32(curr->value)); + } -unwind: - STACK_UNWIND_STRICT (create, frame, op_ret, op_errno, fd, inode, buf, - preparent, postparent); - return 0; + /* Free the dictionary */ + dict_unref(xattr); + } else { + gf_log(this->name, GF_LOG_WARNING, + "Unable to get queue size counts from " + "the io-threads translator!"); + } + + if (interval == -1) { + ios_log(this, logfp, "\"%s.%s.uptime\": %" PRIu64 ",", key_prefix, + str_prefix, (uint64_t)(now - stats->started_at)); + ios_log(this, logfp, + "\"%s.%s.bytes_read\": " + "%" GF_PRI_ATOMIC ",", + key_prefix, str_prefix, GF_ATOMIC_GET(stats->data_read)); + ios_log(this, logfp, + "\"%s.%s.bytes_written\": " + "%" GF_PRI_ATOMIC "", + key_prefix, str_prefix, GF_ATOMIC_GET(stats->data_written)); + } else { + ios_log(this, logfp, "\"%s.%s.sample_interval_sec\": %0.2lf,", + key_prefix, str_prefix, interval_sec); + ios_log(this, logfp, "\"%s.%s.bytes_read_per_sec\": %0.2lf,", + key_prefix, str_prefix, + (double)(GF_ATOMIC_GET(stats->data_read) / interval_sec)); + ios_log(this, logfp, "\"%s.%s.bytes_written_per_sec\": %0.2lf", + key_prefix, str_prefix, + (double)(GF_ATOMIC_GET(stats->data_written) / interval_sec)); + } + + ios_log(this, logfp, "}"); + ret = 0; +out: + GF_FREE(key_prefix); + return ret; } +char * +_resolve_username(xlator_t *this, uid_t uid) +{ + struct passwd pwd; + struct passwd *pwd_result = NULL; + size_t pwd_buf_len; + char *pwd_buf = NULL; + char *ret = NULL; + + /* Prepare our buffer for the uid->username translation */ +#ifdef _SC_GETGR_R_SIZE_MAX + pwd_buf_len = sysconf(_SC_GETGR_R_SIZE_MAX); +#else + pwd_buf_len = -1; +#endif + if (pwd_buf_len == -1) { + pwd_buf_len = DEFAULT_PWD_BUF_SZ; /* per the man page */ + } -int -io_stats_open_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, fd_t *fd) + pwd_buf = alloca(pwd_buf_len); + if (!pwd_buf) + goto err; + + getpwuid_r(uid, &pwd, pwd_buf, pwd_buf_len, &pwd_result); + if (!pwd_result) + goto err; + + ret = gf_strdup(pwd.pw_name); + if (ret) + return ret; + else + gf_log(this->name, GF_LOG_ERROR, + "gf_strdup failed, failing username " + "resolution."); +err: + return ret; +} + +char * +_resolve_group_name(xlator_t *this, gid_t gid) { - struct ios_fd *iosfd = NULL; - char *path = NULL; + struct group grp; + struct group *grp_result = NULL; + size_t grp_buf_len; + char *grp_buf = NULL; + char *ret = NULL; + + /* Prepare our buffer for the gid->group name translation */ +#ifdef _SC_GETGR_R_SIZE_MAX + grp_buf_len = sysconf(_SC_GETGR_R_SIZE_MAX); +#else + grp_buf_len = -1; +#endif + if (grp_buf_len == -1) { + grp_buf_len = DEFAULT_GRP_BUF_SZ; /* per the man page */ + } - path = frame->local; - frame->local = NULL; + grp_buf = alloca(grp_buf_len); + if (!grp_buf) { + goto err; + } - if (!path) - goto unwind; + if (getgrgid_r(gid, &grp, grp_buf, grp_buf_len, &grp_result) != 0) + goto err; - if (op_ret < 0) { - FREE (path); - goto unwind; - } + if (!grp_result) + goto err; + + ret = gf_strdup(grp.gr_name); + if (ret) + return ret; + else + gf_log(this->name, GF_LOG_ERROR, + "gf_strdup failed, failing username " + "resolution."); +err: + return ret; +} - iosfd = CALLOC (1, sizeof (*iosfd)); - if (!iosfd) { - FREE (path); - goto unwind; +/* + * This function writes out a latency sample to a given file descriptor + * and beautifies the output in the process. + */ +void +_io_stats_write_latency_sample(xlator_t *this, ios_sample_t *sample, + FILE *logfp) +{ + double epoch_time = 0.00; + char *xlator_name = NULL; + char *instance_name = NULL; + char *hostname = NULL; + char *identifier = NULL; + char *port = NULL; + char *port_pos = NULL; + char *group_name = NULL; + char *username = NULL; + struct ios_conf *conf = NULL; + + conf = this->private; + + epoch_time = (sample->timestamp).tv_sec + + ((sample->timestamp).tv_usec / 1000000.0); + + if (strlen(sample->identifier) == 0) { + hostname = "Unknown"; + port = "Unknown"; + } else { + identifier = strdupa(sample->identifier); + port_pos = strrchr(identifier, ':'); + if (!port_pos || strlen(port_pos) < 2) + goto err; + port = strdupa(port_pos + 1); + if (!port) + goto err; + *port_pos = '\0'; + hostname = gf_rev_dns_lookup_cached(identifier, conf->dnscache); + if (!hostname) + hostname = "Unknown"; + } + + xlator_name = conf->unique_id; + if (!xlator_name || strlen(xlator_name) == 0) + xlator_name = "Unknown"; + + instance_name = this->instance_name; + if (!instance_name || strlen(instance_name) == 0) + instance_name = "N/A"; + + /* Resolve the UID to a string username */ + username = _resolve_username(this, sample->uid); + if (!username) { + username = GF_MALLOC(30, gf_common_mt_char); + if (!username) { + goto out; + } + sprintf(username, "%d", (int32_t)sample->uid); + } + + /* Resolve the GID to a string group name */ + group_name = _resolve_group_name(this, sample->gid); + if (!group_name) { + group_name = GF_MALLOC(30, gf_common_mt_char); + if (!group_name) { + goto out; } + sprintf(group_name, "%d", (int32_t)sample->gid); + } + + ios_log(this, logfp, "%0.6lf,%s,%s,%0.4lf,%s,%s,%s,%s,%s,%s", epoch_time, + fop_enum_to_pri_string(sample->fop_type), + gf_fop_string(sample->fop_type), sample->elapsed, xlator_name, + instance_name, username, group_name, hostname, port); + goto out; +err: + gf_log(this->name, GF_LOG_ERROR, "Error parsing socket identifier"); +out: + GF_FREE(group_name); + GF_FREE(username); +} - iosfd->filename = path; - gettimeofday (&iosfd->opened_at, NULL); +/* + * Takes our current sample buffer in conf->io_sample_buf, and saves + * a reference to this, init's a new buffer, and then dumps out the + * contents of the saved reference. + */ +int +io_stats_dump_latency_samples_logfp(xlator_t *this, FILE *logfp) +{ + uint64_t i = 0; + struct ios_conf *conf = NULL; + ios_sample_buf_t *sample_buf = NULL; + int ret = 1; /* Default to error */ + + conf = this->private; + + /* Save pointer to old buffer; the CS equivalent of + * Indiana Jones: https://www.youtube.com/watch?v=Pr-8AP0To4k, + * though ours will end better I hope! + */ + sample_buf = conf->ios_sample_buf; + if (!sample_buf) { + gf_log(this->name, GF_LOG_WARNING, "Sampling buffer is null, bailing!"); + goto out; + } + + /* Empty case, nothing to do, exit. */ + if (sample_buf->collected == 0) { + gf_log(this->name, GF_LOG_DEBUG, "No samples, dump not required."); + ret = 0; + goto out; + } + + /* Init a new buffer, so we are free to work on the one we saved a + * reference to above. + */ + if (ios_init_sample_buf(conf) != 0) { + gf_log(this->name, GF_LOG_WARNING, + "Failed to init new sampling buffer, out of memory?"); + goto out; + } + + /* Wrap-around case, dump from pos to sample_buf->size -1 + * and then from 0 to sample_buf->pos (covered off by + * "simple case") + */ + if (sample_buf->collected > sample_buf->pos + 1) { + for (i = sample_buf->pos; i < sample_buf->size; i++) { + _io_stats_write_latency_sample(this, &(sample_buf->ios_samples[i]), + logfp); + } + } - ios_fd_ctx_set (fd, this, iosfd); + /* Simple case: Dump from 0 to sample_buf->pos */ + for (i = 0; i < sample_buf->pos; i++) { + _io_stats_write_latency_sample(this, &(sample_buf->ios_samples[i]), + logfp); + } + ios_destroy_sample_buf(sample_buf); -unwind: - STACK_UNWIND_STRICT (open, frame, op_ret, op_errno, fd); - return 0; +out: + return ret; } +int +io_stats_dump_global_to_logfp(xlator_t *this, struct ios_global_stats *stats, + time_t now, int interval, FILE *logfp) +{ + int i = 0; + int per_line = 0; + int index = 0; + struct ios_stat_head *list_head = NULL; + struct ios_conf *conf = NULL; + char timestr[GF_TIMESTR_SIZE] = { + 0, + }; + char str_header[128] = {0}; + char str_read[128] = {0}; + char str_write[128] = {0}; + uint64_t fop_hits = 0; + uint64_t block_count_read = 0; + uint64_t block_count_write = 0; + + conf = this->private; + + if (interval == -1) + ios_log(this, logfp, "\n=== Cumulative stats ==="); + else + ios_log(this, logfp, "\n=== Interval %d stats ===", interval); + ios_log(this, logfp, " Duration : %" PRIu64 " secs", + (uint64_t)(now - stats->started_at)); + ios_log(this, logfp, " BytesRead : %" GF_PRI_ATOMIC, + GF_ATOMIC_GET(stats->data_read)); + ios_log(this, logfp, " BytesWritten : %" GF_PRI_ATOMIC "\n", + GF_ATOMIC_GET(stats->data_written)); + + snprintf(str_header, sizeof(str_header), "%-12s %c", "Block Size", ':'); + snprintf(str_read, sizeof(str_read), "%-12s %c", "Read Count", ':'); + snprintf(str_write, sizeof(str_write), "%-12s %c", "Write Count", ':'); + index = 14; + for (i = 0; i < IOS_BLOCK_COUNT_SIZE; i++) { + block_count_read = GF_ATOMIC_GET(stats->block_count_read[i]); + block_count_write = GF_ATOMIC_GET(stats->block_count_write[i]); + if ((block_count_read == 0) && (block_count_write == 0)) + continue; + per_line++; + + snprintf(str_header + index, sizeof(str_header) - index, "%16dB+", + (1 << i)); + if (block_count_read) + snprintf(str_read + index, sizeof(str_read) - index, "%18" PRId64, + block_count_read); + else + snprintf(str_read + index, sizeof(str_read) - index, "%18s", "0"); + if (block_count_write) + snprintf(str_write + index, sizeof(str_write) - index, + "%18" GF_PRI_ATOMIC, block_count_write); + else + snprintf(str_write + index, sizeof(str_write) - index, "%18s", "0"); + + index += 18; + if (per_line == 3) { + ios_log(this, logfp, "%s", str_header); + ios_log(this, logfp, "%s", str_read); + ios_log(this, logfp, "%s\n", str_write); + + snprintf(str_header, sizeof(str_header), "%-12s %c", "Block Size", + ':'); + snprintf(str_read, sizeof(str_read), "%-12s %c", "Read Count", ':'); + snprintf(str_write, sizeof(str_write), "%-12s %c", "Write Count", + ':'); + + index = 14; + per_line = 0; + } + } + + if (per_line != 0) { + ios_log(this, logfp, "%s", str_header); + ios_log(this, logfp, "%s", str_read); + ios_log(this, logfp, "%s\n", str_write); + } + + ios_log(this, logfp, "%-13s %10s %14s %14s %14s", "Fop", "Call Count", + "Avg-Latency", "Min-Latency", "Max-Latency"); + ios_log(this, logfp, "%-13s %10s %14s %14s %14s", "---", "----------", + "-----------", "-----------", "-----------"); + + for (i = 0; i < GF_FOP_MAXVALUE; i++) { + fop_hits = GF_ATOMIC_GET(stats->fop_hits[i]); + if (fop_hits && !stats->latency[i].avg) + ios_log(this, logfp, + "%-13s %10" GF_PRI_ATOMIC + " %11s " + "us %11s us %11s us", + gf_fop_list[i], fop_hits, "0", "0", "0"); + else if (fop_hits && stats->latency[i].avg) + ios_log(this, logfp, + "%-13s %10" GF_PRI_ATOMIC + " " + "%11.2lf us %11.2lf us %11.2lf us", + gf_fop_list[i], fop_hits, stats->latency[i].avg, + stats->latency[i].min, stats->latency[i].max); + } + + for (i = 0; i < GF_UPCALL_FLAGS_MAXVALUE; i++) { + fop_hits = GF_ATOMIC_GET(stats->upcall_hits[i]); + if (fop_hits) + ios_log(this, logfp, + "%-13s %10" PRId64 + " %11s " + "us %11s us %11s us", + gf_upcall_list[i], fop_hits, "0", "0", "0"); + } + + ios_log(this, logfp, + "------ ----- ----- ----- ----- ----- ----- ----- " + " ----- ----- ----- -----\n"); + + if (interval == -1) { + LOCK(&conf->lock); + { + gf_time_fmt_tv(timestr, sizeof timestr, + &conf->cumulative.max_openfd_time, gf_timefmt_FT); + ios_log(this, logfp, + "Current open fd's: %" PRId64 " Max open fd's: %" PRId64 + " time %s", + conf->cumulative.nr_opens, conf->cumulative.max_nr_opens, + timestr); + } + UNLOCK(&conf->lock); + ios_log(this, logfp, "\n==========Open File Stats========"); + ios_log(this, logfp, "\nCOUNT: \t FILE NAME"); + list_head = &conf->list[IOS_STATS_TYPE_OPEN]; + ios_dump_file_stats(list_head, this, logfp); + + ios_log(this, logfp, "\n==========Read File Stats========"); + ios_log(this, logfp, "\nCOUNT: \t FILE NAME"); + list_head = &conf->list[IOS_STATS_TYPE_READ]; + ios_dump_file_stats(list_head, this, logfp); + + ios_log(this, logfp, "\n==========Write File Stats========"); + ios_log(this, logfp, "\nCOUNT: \t FILE NAME"); + list_head = &conf->list[IOS_STATS_TYPE_WRITE]; + ios_dump_file_stats(list_head, this, logfp); + + ios_log(this, logfp, "\n==========Directory open stats========"); + ios_log(this, logfp, "\nCOUNT: \t DIRECTORY NAME"); + list_head = &conf->list[IOS_STATS_TYPE_OPENDIR]; + ios_dump_file_stats(list_head, this, logfp); + + ios_log(this, logfp, "\n========Directory readdirp Stats======="); + ios_log(this, logfp, "\nCOUNT: \t DIRECTORY NAME"); + list_head = &conf->list[IOS_STATS_TYPE_READDIRP]; + ios_dump_file_stats(list_head, this, logfp); + + ios_log(this, logfp, "\n========Read Throughput File Stats====="); + ios_log(this, logfp, + "\nTIMESTAMP \t\t\t THROUGHPUT(KBPS)" + "\tFILE NAME"); + list_head = &conf->thru_list[IOS_STATS_THRU_READ]; + ios_dump_throughput_stats(list_head, this, logfp, IOS_STATS_THRU_READ); + + ios_log(this, logfp, "\n======Write Throughput File Stats======"); + ios_log(this, logfp, + "\nTIMESTAMP \t\t\t THROUGHPUT(KBPS)" + "\tFILE NAME"); + list_head = &conf->thru_list[IOS_STATS_THRU_WRITE]; + ios_dump_throughput_stats(list_head, this, logfp, IOS_STATS_THRU_WRITE); + } + return 0; +} int -io_stats_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, struct stat *buf) +io_stats_dump_global_to_dict(xlator_t *this, struct ios_global_stats *stats, + time_t now, int interval, dict_t *dict) { - STACK_UNWIND_STRICT (stat, frame, op_ret, op_errno, buf); - return 0; + int ret = 0; + char key[64] = {0}; + uint64_t sec = 0; + int i = 0; + uint64_t count = 0; + uint64_t fop_hits = 0; + + GF_ASSERT(stats); + GF_ASSERT(now); + GF_ASSERT(dict); + GF_ASSERT(this); + + if (interval == -1) + snprintf(key, sizeof(key), "cumulative"); + else + snprintf(key, sizeof(key), "interval"); + ret = dict_set_int32(dict, key, interval); + if (ret) + gf_log(this->name, GF_LOG_ERROR, + "failed to set " + "interval %d", + interval); + + snprintf(key, sizeof(key), "%d-duration", interval); + sec = now - stats->started_at; + ret = dict_set_uint64(dict, key, sec); + if (ret) { + gf_log(this->name, GF_LOG_ERROR, + "failed to set " + "duration(%d) - %" PRId64, + interval, sec); + goto out; + } + + snprintf(key, sizeof(key), "%d-total-read", interval); + ret = dict_set_uint64(dict, key, GF_ATOMIC_GET(stats->data_read)); + if (ret) { + gf_log(this->name, GF_LOG_ERROR, + "failed to set total " + "read(%d) - %" GF_PRI_ATOMIC, + interval, GF_ATOMIC_GET(stats->data_read)); + goto out; + } + + snprintf(key, sizeof(key), "%d-total-write", interval); + ret = dict_set_uint64(dict, key, GF_ATOMIC_GET(stats->data_written)); + if (ret) { + gf_log(this->name, GF_LOG_ERROR, + "failed to set total " + "write(%d) - %" GF_PRI_ATOMIC, + interval, GF_ATOMIC_GET(stats->data_written)); + goto out; + } + for (i = 0; i < 32; i++) { + count = GF_ATOMIC_GET(stats->block_count_read[i]); + if (count) { + snprintf(key, sizeof(key), "%d-read-%d", interval, (1 << i)); + ret = dict_set_uint64(dict, key, count); + if (ret) { + gf_log(this->name, GF_LOG_ERROR, + "failed to " + "set read-%db+, with: %" PRId64, + (1 << i), count); + goto out; + } + } + } + + for (i = 0; i < IOS_BLOCK_COUNT_SIZE; i++) { + count = GF_ATOMIC_GET(stats->block_count_write[i]); + if (count) { + snprintf(key, sizeof(key), "%d-write-%d", interval, (1 << i)); + ret = dict_set_uint64(dict, key, count); + if (ret) { + gf_log(this->name, GF_LOG_ERROR, + "failed to " + "set write-%db+, with: %" PRId64, + (1 << i), count); + goto out; + } + } + } + + for (i = 0; i < GF_FOP_MAXVALUE; i++) { + fop_hits = GF_ATOMIC_GET(stats->fop_hits[i]); + if (fop_hits == 0) + continue; + snprintf(key, sizeof(key), "%d-%d-hits", interval, i); + ret = dict_set_uint64(dict, key, fop_hits); + if (ret) { + gf_log(this->name, GF_LOG_ERROR, + "failed to set " + "%s-fop-hits: %" GF_PRI_ATOMIC, + gf_fop_list[i], fop_hits); + goto out; + } + + if (stats->latency[i].avg == 0) + continue; + snprintf(key, sizeof(key), "%d-%d-avglatency", interval, i); + ret = dict_set_double(dict, key, stats->latency[i].avg); + if (ret) { + gf_log(this->name, GF_LOG_ERROR, + "failed to set %s " + "avglatency(%d) with %f", + gf_fop_list[i], interval, stats->latency[i].avg); + goto out; + } + snprintf(key, sizeof(key), "%d-%d-minlatency", interval, i); + ret = dict_set_double(dict, key, stats->latency[i].min); + if (ret) { + gf_log(this->name, GF_LOG_ERROR, + "failed to set %s " + "minlatency(%d) with %f", + gf_fop_list[i], interval, stats->latency[i].min); + goto out; + } + snprintf(key, sizeof(key), "%d-%d-maxlatency", interval, i); + ret = dict_set_double(dict, key, stats->latency[i].max); + if (ret) { + gf_log(this->name, GF_LOG_ERROR, + "failed to set %s " + "maxlatency(%d) with %f", + gf_fop_list[i], interval, stats->latency[i].max); + goto out; + } + } + for (i = 0; i < GF_UPCALL_FLAGS_MAXVALUE; i++) { + fop_hits = GF_ATOMIC_GET(stats->upcall_hits[i]); + if (fop_hits == 0) + continue; + snprintf(key, sizeof(key), "%d-%d-upcall-hits", interval, i); + ret = dict_set_uint64(dict, key, fop_hits); + if (ret) { + gf_log(this->name, GF_LOG_ERROR, + "failed to " + "set %s-upcall-hits: %" PRIu64, + gf_upcall_list[i], fop_hits); + goto out; + } + } +out: + gf_log(this->name, GF_LOG_DEBUG, "returning %d", ret); + return ret; } +int +io_stats_dump_global(xlator_t *this, struct ios_global_stats *stats, time_t now, + int interval, struct ios_dump_args *args) +{ + int ret = -1; + + GF_ASSERT(args); + GF_ASSERT(now); + GF_ASSERT(stats); + GF_ASSERT(this); + + switch (args->type) { + case IOS_DUMP_TYPE_JSON_FILE: + ret = io_stats_dump_global_to_json_logfp(this, stats, now, interval, + args->u.logfp); + break; + case IOS_DUMP_TYPE_FILE: + ret = io_stats_dump_global_to_logfp(this, stats, now, interval, + args->u.logfp); + break; + case IOS_DUMP_TYPE_DICT: + ret = io_stats_dump_global_to_dict(this, stats, now, interval, + args->u.dict); + break; + default: + GF_ASSERT(0); + ret = -1; + break; + } + return ret; +} int -io_stats_readv_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, - struct iovec *vector, int32_t count, - struct stat *buf, struct iobref *iobref) +ios_dump_args_init(struct ios_dump_args *args, ios_dump_type_t type, + void *output) { - struct ios_conf *conf = NULL; - int len = 0; - fd_t *fd = NULL; + int ret = 0; + + GF_ASSERT(args); + GF_ASSERT(type > IOS_DUMP_TYPE_NONE && type < IOS_DUMP_TYPE_MAX); + GF_ASSERT(output); + + args->type = type; + switch (args->type) { + case IOS_DUMP_TYPE_JSON_FILE: + case IOS_DUMP_TYPE_FILE: + args->u.logfp = output; + break; + case IOS_DUMP_TYPE_DICT: + args->u.dict = output; + break; + default: + GF_ASSERT(0); + ret = -1; + } + + return ret; +} - conf = this->private; +static void +ios_global_stats_clear(struct ios_global_stats *stats, time_t now) +{ + GF_ASSERT(stats); + GF_ASSERT(now); - fd = frame->local; - frame->local = NULL; + memset(stats, 0, sizeof(*stats)); + stats->started_at = now; +} + +int +io_stats_dump(xlator_t *this, struct ios_dump_args *args, ios_info_op_t op, + gf_boolean_t is_peek) +{ + struct ios_conf *conf = NULL; + struct ios_global_stats cumulative = {}; + struct ios_global_stats incremental = {}; + int increment = 0; + time_t now = 0; + + GF_ASSERT(this); + GF_ASSERT(args); + GF_ASSERT(args->type > IOS_DUMP_TYPE_NONE); + GF_ASSERT(args->type < IOS_DUMP_TYPE_MAX); + + conf = this->private; + now = gf_time(); + + LOCK(&conf->lock); + { + if (op == GF_IOS_INFO_ALL || op == GF_IOS_INFO_CUMULATIVE) + cumulative = conf->cumulative; + + if (op == GF_IOS_INFO_ALL || op == GF_IOS_INFO_INCREMENTAL) { + incremental = conf->incremental; + increment = conf->increment; + + if (!is_peek) { + increment = conf->increment++; - if (op_ret > 0) { - len = iov_length (vector, count); - BUMP_READ (fd, len); + ios_global_stats_clear(&conf->incremental, now); + } } + } + UNLOCK(&conf->lock); - STACK_UNWIND_STRICT (readv, frame, op_ret, op_errno, - vector, count, buf, iobref); - return 0; -} + if (op == GF_IOS_INFO_ALL || op == GF_IOS_INFO_CUMULATIVE) + io_stats_dump_global(this, &cumulative, now, -1, args); + if (op == GF_IOS_INFO_ALL || op == GF_IOS_INFO_INCREMENTAL) + io_stats_dump_global(this, &incremental, now, increment, args); + + return 0; +} int -io_stats_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, - struct stat *prebuf, struct stat *postbuf) +io_stats_dump_fd(xlator_t *this, struct ios_fd *iosfd) { - STACK_UNWIND_STRICT (writev, frame, op_ret, op_errno, prebuf, postbuf); + struct ios_conf *conf = NULL; + struct timeval now; + int i = 0; + double usecs = 0; + uint64_t data_read = 0; + uint64_t data_written = 0; + uint64_t block_count_read = 0; + uint64_t block_count_write = 0; + + conf = this->private; + + if (!conf->dump_fd_stats) return 0; -} + if (!iosfd) + return 0; -int -io_stats_getdents_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, - dir_entry_t *entries, int32_t count) + gettimeofday(&now, NULL); + usecs = gf_tvdiff(&iosfd->opened_at, &now); + + gf_log(this->name, GF_LOG_INFO, "--- fd stats ---"); + + if (iosfd->filename) + gf_log(this->name, GF_LOG_INFO, " Filename : %s", iosfd->filename); + + if (usecs) + gf_log(this->name, GF_LOG_INFO, " Lifetime : %lf secs", usecs); + + data_read = GF_ATOMIC_GET(iosfd->data_read); + if (data_read) + gf_log(this->name, GF_LOG_INFO, " BytesRead : %" PRId64 " bytes", + data_read); + + data_written = GF_ATOMIC_GET(iosfd->data_written); + if (data_written) + gf_log(this->name, GF_LOG_INFO, " BytesWritten : %" PRId64 " bytes", + data_written); + + for (i = 0; i < 32; i++) { + block_count_read = GF_ATOMIC_GET(iosfd->block_count_read[i]); + if (block_count_read) + gf_log(this->name, GF_LOG_INFO, + " Read %06db+ :" + "%" PRId64, + (1 << i), block_count_read); + } + for (i = 0; i < IOS_BLOCK_COUNT_SIZE; i++) { + block_count_write = GF_ATOMIC_GET(iosfd->block_count_write[i]); + if (block_count_write) + gf_log(this->name, GF_LOG_INFO, "Write %06db+ : %" PRId64, (1 << i), + block_count_write); + } + return 0; +} + +void +collect_ios_latency_sample(struct ios_conf *conf, glusterfs_fop_t fop_type, + double elapsed, call_frame_t *frame) { - STACK_UNWIND_STRICT (getdents, frame, op_ret, op_errno, entries, count); - return 0; + ios_sample_buf_t *ios_sample_buf = NULL; + ios_sample_t *ios_sample = NULL; + struct timespec *timestamp = NULL; + call_stack_t *root = NULL; + + ios_sample_buf = conf->ios_sample_buf; + LOCK(&conf->ios_sampling_lock); + if (conf->ios_sample_interval == 0 || + ios_sample_buf->observed % conf->ios_sample_interval != 0) + goto out; + + timestamp = &frame->begin; + root = frame->root; + + ios_sample = &(ios_sample_buf->ios_samples[ios_sample_buf->pos]); + ios_sample->elapsed = elapsed; + ios_sample->fop_type = fop_type; + ios_sample->uid = root->uid; + ios_sample->gid = root->gid; + (ios_sample->timestamp).tv_sec = timestamp->tv_sec; + (ios_sample->timestamp).tv_usec = timestamp->tv_nsec / 1000; + memcpy(&ios_sample->identifier, &root->identifier, + sizeof(root->identifier)); + + /* We've reached the end of the circular buffer, start from the + * beginning. */ + if (ios_sample_buf->pos == (ios_sample_buf->size - 1)) + ios_sample_buf->pos = 0; + else + ios_sample_buf->pos++; + ios_sample_buf->collected++; +out: + ios_sample_buf->observed++; + UNLOCK(&conf->ios_sampling_lock); + return; } +static void +update_ios_latency_stats(struct ios_global_stats *stats, double elapsed, + glusterfs_fop_t op) +{ + double avg; + + GF_ASSERT(stats); + + stats->latency[op].total += elapsed; + + if (!stats->latency[op].min) + stats->latency[op].min = elapsed; + if (stats->latency[op].min > elapsed) + stats->latency[op].min = elapsed; + if (stats->latency[op].max < elapsed) + stats->latency[op].max = elapsed; + + avg = stats->latency[op].avg; + + stats->latency[op].avg = avg + (elapsed - avg) / + GF_ATOMIC_GET(stats->fop_hits[op]); +} int -io_stats_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, gf_dirent_t *buf) +update_ios_latency(struct ios_conf *conf, call_frame_t *frame, + glusterfs_fop_t op) { - STACK_UNWIND_STRICT (readdirp, frame, op_ret, op_errno, buf); - return 0; -} + double elapsed; + struct timespec *begin, *end; + begin = &frame->begin; + end = &frame->end; -int -io_stats_readdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, gf_dirent_t *buf) + elapsed = gf_tsdiff(begin, end) / 1000.0; + + update_ios_latency_stats(&conf->cumulative, elapsed, op); + update_ios_latency_stats(&conf->incremental, elapsed, op); + collect_ios_latency_sample(conf, op, elapsed, frame); + + return 0; +} + +int32_t +io_stats_dump_stats_to_dict(xlator_t *this, dict_t *resp, + ios_stats_type_t flags, int32_t list_cnt) { - STACK_UNWIND_STRICT (readdir, frame, op_ret, op_errno, buf); - return 0; + struct ios_conf *conf = NULL; + int cnt = 0; + char key[32]; + int keylen; + struct ios_stat_head *list_head = NULL; + struct ios_stat_list *entry = NULL; + int ret = -1; + ios_stats_thru_t index = IOS_STATS_THRU_MAX; + char timestr[GF_TIMESTR_SIZE] = { + 0, + }; + char *dict_timestr = NULL; + + conf = this->private; + + switch (flags) { + case IOS_STATS_TYPE_OPEN: + list_head = &conf->list[IOS_STATS_TYPE_OPEN]; + LOCK(&conf->lock); + { + ret = dict_set_uint64(resp, "current-open", + conf->cumulative.nr_opens); + if (ret) + goto unlock; + ret = dict_set_uint64(resp, "max-open", + conf->cumulative.max_nr_opens); + + gf_time_fmt_tv(timestr, sizeof timestr, + &conf->cumulative.max_openfd_time, + gf_timefmt_FT); + + dict_timestr = gf_strdup(timestr); + if (!dict_timestr) + goto unlock; + ret = dict_set_dynstr(resp, "max-openfd-time", dict_timestr); + if (ret) + goto unlock; + } + unlock: + UNLOCK(&conf->lock); + /* Do not proceed if we came here because of some error + * during the dict operation */ + if (ret) + goto out; + break; + case IOS_STATS_TYPE_READ: + list_head = &conf->list[IOS_STATS_TYPE_READ]; + break; + case IOS_STATS_TYPE_WRITE: + list_head = &conf->list[IOS_STATS_TYPE_WRITE]; + break; + case IOS_STATS_TYPE_OPENDIR: + list_head = &conf->list[IOS_STATS_TYPE_OPENDIR]; + break; + case IOS_STATS_TYPE_READDIRP: + list_head = &conf->list[IOS_STATS_TYPE_READDIRP]; + break; + case IOS_STATS_TYPE_READ_THROUGHPUT: + list_head = &conf->thru_list[IOS_STATS_THRU_READ]; + index = IOS_STATS_THRU_READ; + break; + case IOS_STATS_TYPE_WRITE_THROUGHPUT: + list_head = &conf->thru_list[IOS_STATS_THRU_WRITE]; + index = IOS_STATS_THRU_WRITE; + break; + + default: + goto out; + } + ret = dict_set_int32_sizen(resp, "top-op", flags); + if (!list_cnt) + goto out; + LOCK(&list_head->lock); + { + list_for_each_entry(entry, &list_head->iosstats->list, list) + { + cnt++; + keylen = snprintf(key, sizeof(key), "filename-%d", cnt); + ret = dict_set_strn(resp, key, keylen, entry->iosstat->filename); + if (ret) + goto unlock_list_head; + snprintf(key, sizeof(key), "value-%d", cnt); + ret = dict_set_uint64(resp, key, entry->value); + if (ret) + goto unlock_list_head; + if (index != IOS_STATS_THRU_MAX) { + keylen = snprintf(key, sizeof(key), "time-sec-%d", cnt); + ret = dict_set_int32n( + resp, key, keylen, + entry->iosstat->thru_counters[index].time.tv_sec); + if (ret) + goto unlock_list_head; + keylen = snprintf(key, sizeof(key), "time-usec-%d", cnt); + ret = dict_set_int32n( + resp, key, keylen, + entry->iosstat->thru_counters[index].time.tv_usec); + if (ret) + goto unlock_list_head; + } + if (cnt == list_cnt) + break; + } + } +unlock_list_head: + UNLOCK(&list_head->lock); + /* ret is !=0 if some dict operation in the above critical region + * failed. */ + if (ret) + goto out; + ret = dict_set_int32_sizen(resp, "members", cnt); +out: + return ret; } +static struct ios_stat * +ios_init_iosstat(xlator_t *this, char *path, uuid_t gfid, inode_t *inode) +{ + struct ios_stat *iosstat = NULL; + int i = 0; + + iosstat = GF_CALLOC(1, sizeof(*iosstat), gf_io_stats_mt_ios_stat); + if (!iosstat) + goto out; + + iosstat->filename = gf_strdup(path); + gf_uuid_copy(iosstat->gfid, gfid); + LOCK_INIT(&iosstat->lock); + + for (i = 0; i < IOS_STATS_TYPE_MAX; i++) + GF_ATOMIC_INIT(iosstat->counters[i], 0); + + ios_inode_ctx_set(inode, this, iosstat); + +out: + return iosstat; +} int -io_stats_fsync_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, - struct stat *prebuf, struct stat *postbuf) +io_stats_create_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, fd_t *fd, inode_t *inode, + struct iatt *buf, struct iatt *preparent, + struct iatt *postparent, dict_t *xdata) { - STACK_UNWIND_STRICT (fsync, frame, op_ret, op_errno, prebuf, postbuf); - return 0; -} + struct ios_fd *iosfd = NULL; + char *path = NULL; + struct ios_stat *iosstat = NULL; + struct ios_conf *conf = NULL; + + conf = this->private; + + path = frame->local; + frame->local = NULL; + + if (!path) + goto unwind; + + if (op_ret < 0) { + GF_FREE(path); + goto unwind; + } + + iosfd = GF_CALLOC(1, sizeof(*iosfd), gf_io_stats_mt_ios_fd); + if (!iosfd) { + GF_FREE(path); + goto unwind; + } + + iosfd->filename = path; + gettimeofday(&iosfd->opened_at, NULL); + + ios_fd_ctx_set(fd, this, iosfd); + LOCK(&conf->lock); + { + conf->cumulative.nr_opens++; + if (conf->cumulative.nr_opens > conf->cumulative.max_nr_opens) { + conf->cumulative.max_nr_opens = conf->cumulative.nr_opens; + conf->cumulative.max_openfd_time = iosfd->opened_at; + } + } + UNLOCK(&conf->lock); + iosstat = ios_init_iosstat(this, path, buf->ia_gfid, inode); + if (!iosstat) + GF_FREE(path); + +unwind: + UPDATE_PROFILE_STATS(frame, CREATE); + STACK_UNWIND_STRICT(create, frame, op_ret, op_errno, fd, inode, buf, + preparent, postparent, xdata); + return 0; +} int -io_stats_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, - struct stat *preop, struct stat *postop) +io_stats_open_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, fd_t *fd, dict_t *xdata) { - STACK_UNWIND_STRICT (setattr, frame, op_ret, op_errno, preop, postop); - return 0; -} + struct ios_fd *iosfd = NULL; + char *path = NULL; + struct ios_stat *iosstat = NULL; + struct ios_conf *conf = NULL; + int i = 0; + + conf = this->private; + path = frame->local; + frame->local = NULL; + + if (!path) + goto unwind; + + if (op_ret < 0) { + GF_FREE(path); + goto unwind; + } + + iosfd = GF_CALLOC(1, sizeof(*iosfd), gf_io_stats_mt_ios_fd); + if (!iosfd) { + GF_FREE(path); + goto unwind; + } + + iosfd->filename = path; + GF_ATOMIC_INIT(iosfd->data_read, 0); + GF_ATOMIC_INIT(iosfd->data_written, 0); + for (i = 0; i < IOS_BLOCK_COUNT_SIZE; i++) { + GF_ATOMIC_INIT(iosfd->block_count_write[i], 0); + GF_ATOMIC_INIT(iosfd->block_count_read[i], 0); + } + gettimeofday(&iosfd->opened_at, NULL); + + ios_fd_ctx_set(fd, this, iosfd); + + ios_inode_ctx_get(fd->inode, this, &iosstat); + if (!iosstat) { + iosstat = ios_init_iosstat(this, path, fd->inode->gfid, fd->inode); + } + + LOCK(&conf->lock); + { + conf->cumulative.nr_opens++; + if (conf->cumulative.nr_opens > conf->cumulative.max_nr_opens) { + conf->cumulative.max_nr_opens = conf->cumulative.nr_opens; + conf->cumulative.max_openfd_time = iosfd->opened_at; + } + } + UNLOCK(&conf->lock); + if (iosstat) { + ios_bump_stats(this, iosstat, IOS_STATS_TYPE_OPEN); + iosstat = NULL; + } +unwind: + UPDATE_PROFILE_STATS(frame, OPEN); + STACK_UNWIND_STRICT(open, frame, op_ret, op_errno, fd, xdata); + return 0; +} int -io_stats_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, - struct stat *preparent, struct stat *postparent) +io_stats_stat_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, struct iatt *buf, + dict_t *xdata) { - STACK_UNWIND_STRICT (unlink, frame, op_ret, op_errno, - preparent, postparent); - return 0; + UPDATE_PROFILE_STATS(frame, STAT); + STACK_UNWIND_STRICT(stat, frame, op_ret, op_errno, buf, xdata); + return 0; } - int -io_stats_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, struct stat *buf, - struct stat *preoldparent, struct stat *postoldparent, - struct stat *prenewparent, struct stat *postnewparent) +io_stats_readv_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, struct iovec *vector, + int32_t count, struct iatt *buf, struct iobref *iobref, + dict_t *xdata) { - STACK_UNWIND_STRICT (rename, frame, op_ret, op_errno, buf, - preoldparent, postoldparent, - prenewparent, postnewparent); - return 0; + int len = 0; + fd_t *fd = NULL; + struct ios_stat *iosstat = NULL; + + fd = frame->local; + frame->local = NULL; + + if (op_ret > 0) { + len = iov_length(vector, count); + ios_bump_read(this, fd, len); + } + + UPDATE_PROFILE_STATS(frame, READ); + ios_inode_ctx_get(fd->inode, this, &iosstat); + + if (iosstat) { + ios_bump_stats(this, iosstat, IOS_STATS_TYPE_READ); + BUMP_THROUGHPUT(iosstat, IOS_STATS_THRU_READ); + iosstat = NULL; + } + + STACK_UNWIND_STRICT(readv, frame, op_ret, op_errno, vector, count, buf, + iobref, xdata); + return 0; } - int -io_stats_readlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, const char *buf, - struct stat *sbuf) +io_stats_writev_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, struct iatt *prebuf, + struct iatt *postbuf, dict_t *xdata) { - STACK_UNWIND_STRICT (readlink, frame, op_ret, op_errno, buf, sbuf); - return 0; -} + struct ios_stat *iosstat = NULL; + inode_t *inode = NULL; + UPDATE_PROFILE_STATS(frame, WRITE); + if (frame->local) { + inode = frame->local; + frame->local = NULL; + ios_inode_ctx_get(inode, this, &iosstat); + if (iosstat) { + ios_bump_stats(this, iosstat, IOS_STATS_TYPE_WRITE); + BUMP_THROUGHPUT(iosstat, IOS_STATS_THRU_WRITE); + inode = NULL; + iosstat = NULL; + } + } + + STACK_UNWIND_STRICT(writev, frame, op_ret, op_errno, prebuf, postbuf, + xdata); + return 0; +} int -io_stats_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, - inode_t *inode, struct stat *buf, - dict_t *xattr, struct stat *postparent) +io_stats_copy_file_range_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, + struct iatt *stbuf, struct iatt *prebuf_dst, + struct iatt *postbuf_dst, dict_t *xdata) { - STACK_UNWIND_STRICT (lookup, frame, op_ret, op_errno, inode, buf, xattr, - postparent); - return 0; -} + UPDATE_PROFILE_STATS(frame, COPY_FILE_RANGE); + STACK_UNWIND_STRICT(copy_file_range, frame, op_ret, op_errno, stbuf, + prebuf_dst, postbuf_dst, xdata); + return 0; +} int -io_stats_symlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, - inode_t *inode, struct stat *buf, - struct stat *preparent, struct stat *postparent) +io_stats_readdirp_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, gf_dirent_t *buf, + dict_t *xdata) { - STACK_UNWIND_STRICT (symlink, frame, op_ret, op_errno, inode, buf, - preparent, postparent); - return 0; + struct ios_stat *iosstat = NULL; + inode_t *inode = frame->local; + + frame->local = NULL; + + UPDATE_PROFILE_STATS(frame, READDIRP); + + ios_inode_ctx_get(inode, this, &iosstat); + + if (iosstat) { + ios_bump_stats(this, iosstat, IOS_STATS_TYPE_READDIRP); + iosstat = NULL; + } + + STACK_UNWIND_STRICT(readdirp, frame, op_ret, op_errno, buf, xdata); + return 0; } +int +io_stats_readdir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, gf_dirent_t *buf, + dict_t *xdata) +{ + UPDATE_PROFILE_STATS(frame, READDIR); + STACK_UNWIND_STRICT(readdir, frame, op_ret, op_errno, buf, xdata); + return 0; +} int -io_stats_mknod_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, - inode_t *inode, struct stat *buf, - struct stat *preparent, struct stat *postparent) +io_stats_fsync_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, struct iatt *prebuf, + struct iatt *postbuf, dict_t *xdata) { - STACK_UNWIND_STRICT (mknod, frame, op_ret, op_errno, inode, buf, - preparent, postparent); - return 0; + UPDATE_PROFILE_STATS(frame, FSYNC); + STACK_UNWIND_STRICT(fsync, frame, op_ret, op_errno, prebuf, postbuf, xdata); + return 0; } +int +io_stats_setattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, struct iatt *preop, + struct iatt *postop, dict_t *xdata) +{ + UPDATE_PROFILE_STATS(frame, SETATTR); + STACK_UNWIND_STRICT(setattr, frame, op_ret, op_errno, preop, postop, xdata); + return 0; +} int -io_stats_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, - inode_t *inode, struct stat *buf, - struct stat *preparent, struct stat *postparent) +io_stats_unlink_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, struct iatt *preparent, + struct iatt *postparent, dict_t *xdata) { - STACK_UNWIND_STRICT (mkdir, frame, op_ret, op_errno, inode, buf, - preparent, postparent); - return 0; + UPDATE_PROFILE_STATS(frame, UNLINK); + STACK_UNWIND_STRICT(unlink, frame, op_ret, op_errno, preparent, postparent, + xdata); + return 0; } +int +io_stats_rename_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, struct iatt *buf, + struct iatt *preoldparent, struct iatt *postoldparent, + struct iatt *prenewparent, struct iatt *postnewparent, + dict_t *xdata) +{ + UPDATE_PROFILE_STATS(frame, RENAME); + STACK_UNWIND_STRICT(rename, frame, op_ret, op_errno, buf, preoldparent, + postoldparent, prenewparent, postnewparent, xdata); + return 0; +} int -io_stats_link_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, - inode_t *inode, struct stat *buf, - struct stat *preparent, struct stat *postparent) +io_stats_readlink_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, const char *buf, + struct iatt *sbuf, dict_t *xdata) { - STACK_UNWIND_STRICT (link, frame, op_ret, op_errno, inode, buf, - preparent, postparent); - return 0; + UPDATE_PROFILE_STATS(frame, READLINK); + STACK_UNWIND_STRICT(readlink, frame, op_ret, op_errno, buf, sbuf, xdata); + return 0; } +int +io_stats_lookup_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, inode_t *inode, + struct iatt *buf, dict_t *xdata, struct iatt *postparent) +{ + UPDATE_PROFILE_STATS(frame, LOOKUP); + STACK_UNWIND_STRICT(lookup, frame, op_ret, op_errno, inode, buf, xdata, + postparent); + return 0; +} int -io_stats_flush_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno) +io_stats_symlink_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, inode_t *inode, + struct iatt *buf, struct iatt *preparent, + struct iatt *postparent, dict_t *xdata) { - STACK_UNWIND_STRICT (flush, frame, op_ret, op_errno); - return 0; + UPDATE_PROFILE_STATS(frame, SYMLINK); + STACK_UNWIND_STRICT(symlink, frame, op_ret, op_errno, inode, buf, preparent, + postparent, xdata); + return 0; } +int +io_stats_mknod_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, inode_t *inode, + struct iatt *buf, struct iatt *preparent, + struct iatt *postparent, dict_t *xdata) +{ + UPDATE_PROFILE_STATS(frame, MKNOD); + STACK_UNWIND_STRICT(mknod, frame, op_ret, op_errno, inode, buf, preparent, + postparent, xdata); + return 0; +} int -io_stats_opendir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, fd_t *fd) +io_stats_mkdir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, inode_t *inode, + struct iatt *buf, struct iatt *preparent, + struct iatt *postparent, dict_t *xdata) { - if (op_ret >= 0) - ios_fd_ctx_set (fd, this, 0); + char *path = frame->local; - STACK_UNWIND_STRICT (opendir, frame, op_ret, op_errno, fd); - return 0; -} + if (!path) + goto unwind; + + UPDATE_PROFILE_STATS(frame, MKDIR); + if (op_ret < 0) + goto unwind; + /* allocate a struct ios_stat and set the inode ctx */ + ios_init_iosstat(this, path, buf->ia_gfid, inode); + +unwind: + /* local is assigned with path */ + GF_FREE(frame->local); + frame->local = NULL; + STACK_UNWIND_STRICT(mkdir, frame, op_ret, op_errno, inode, buf, preparent, + postparent, xdata); + return 0; +} int -io_stats_rmdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, - struct stat *preparent, struct stat *postparent) +io_stats_link_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, inode_t *inode, + struct iatt *buf, struct iatt *preparent, + struct iatt *postparent, dict_t *xdata) { - STACK_UNWIND_STRICT (rmdir, frame, op_ret, op_errno, - preparent, postparent); - return 0; + UPDATE_PROFILE_STATS(frame, LINK); + STACK_UNWIND_STRICT(link, frame, op_ret, op_errno, inode, buf, preparent, + postparent, xdata); + return 0; } +int +io_stats_flush_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, dict_t *xdata) +{ + UPDATE_PROFILE_STATS(frame, FLUSH); + STACK_UNWIND_STRICT(flush, frame, op_ret, op_errno, xdata); + return 0; +} int -io_stats_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, - struct stat *prebuf, struct stat *postbuf) +io_stats_opendir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, fd_t *fd, dict_t *xdata) { - STACK_UNWIND_STRICT (truncate, frame, op_ret, op_errno, - prebuf, postbuf); - return 0; + struct ios_stat *iosstat = NULL; + int ret = -1; + + UPDATE_PROFILE_STATS(frame, OPENDIR); + if (op_ret < 0) + goto unwind; + + ios_fd_ctx_set(fd, this, 0); + + ret = ios_inode_ctx_get(fd->inode, this, &iosstat); + if (!ret) + ios_bump_stats(this, iosstat, IOS_STATS_TYPE_OPENDIR); + +unwind: + STACK_UNWIND_STRICT(opendir, frame, op_ret, op_errno, fd, xdata); + return 0; } +int +io_stats_rmdir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, struct iatt *preparent, + struct iatt *postparent, dict_t *xdata) +{ + UPDATE_PROFILE_STATS(frame, RMDIR); + + STACK_UNWIND_STRICT(rmdir, frame, op_ret, op_errno, preparent, postparent, + xdata); + return 0; +} int -io_stats_statfs_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, struct statvfs *buf) +io_stats_truncate_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, struct iatt *prebuf, + struct iatt *postbuf, dict_t *xdata) { - STACK_UNWIND_STRICT (statfs, frame, op_ret, op_errno, buf); - return 0; + UPDATE_PROFILE_STATS(frame, TRUNCATE); + STACK_UNWIND_STRICT(truncate, frame, op_ret, op_errno, prebuf, postbuf, + xdata); + return 0; } +int +io_stats_statfs_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, struct statvfs *buf, + dict_t *xdata) +{ + UPDATE_PROFILE_STATS(frame, STATFS); + STACK_UNWIND_STRICT(statfs, frame, op_ret, op_errno, buf, xdata); + return 0; +} int -io_stats_setxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno) +io_stats_setxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, dict_t *xdata) { - STACK_UNWIND_STRICT (setxattr, frame, op_ret, op_errno); - return 0; + UPDATE_PROFILE_STATS(frame, SETXATTR); + STACK_UNWIND_STRICT(setxattr, frame, op_ret, op_errno, xdata); + return 0; } +int +io_stats_getxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, dict_t *dict, + dict_t *xdata) +{ + UPDATE_PROFILE_STATS(frame, GETXATTR); + STACK_UNWIND_STRICT(getxattr, frame, op_ret, op_errno, dict, xdata); + return 0; +} int -io_stats_getxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, dict_t *dict) +io_stats_removexattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, dict_t *xdata) { - STACK_UNWIND (frame, op_ret, op_errno, dict); - return 0; + UPDATE_PROFILE_STATS(frame, REMOVEXATTR); + STACK_UNWIND_STRICT(removexattr, frame, op_ret, op_errno, xdata); + return 0; } +int +io_stats_fsetxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, dict_t *xdata) +{ + UPDATE_PROFILE_STATS(frame, FSETXATTR); + STACK_UNWIND_STRICT(fsetxattr, frame, op_ret, op_errno, xdata); + return 0; +} int -io_stats_removexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno) +io_stats_fgetxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, dict_t *dict, + dict_t *xdata) { - STACK_UNWIND_STRICT (removexattr, frame, op_ret, op_errno); - return 0; + UPDATE_PROFILE_STATS(frame, FGETXATTR); + STACK_UNWIND_STRICT(fgetxattr, frame, op_ret, op_errno, dict, xdata); + return 0; } +int +io_stats_fremovexattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, dict_t *xdata) +{ + UPDATE_PROFILE_STATS(frame, FREMOVEXATTR); + STACK_UNWIND_STRICT(fremovexattr, frame, op_ret, op_errno, xdata); + return 0; +} int -io_stats_fsyncdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno) +io_stats_fsyncdir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, dict_t *xdata) { - STACK_UNWIND_STRICT (fsyncdir, frame, op_ret, op_errno); - return 0; + UPDATE_PROFILE_STATS(frame, FSYNCDIR); + STACK_UNWIND_STRICT(fsyncdir, frame, op_ret, op_errno, xdata); + return 0; } +int +io_stats_access_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, dict_t *xdata) +{ + UPDATE_PROFILE_STATS(frame, ACCESS); + STACK_UNWIND_STRICT(access, frame, op_ret, op_errno, xdata); + return 0; +} int -io_stats_access_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno) +io_stats_ftruncate_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, struct iatt *prebuf, + struct iatt *postbuf, dict_t *xdata) { - STACK_UNWIND_STRICT (access, frame, op_ret, op_errno); - return 0; + UPDATE_PROFILE_STATS(frame, FTRUNCATE); + STACK_UNWIND_STRICT(ftruncate, frame, op_ret, op_errno, prebuf, postbuf, + xdata); + return 0; } +int +io_stats_fstat_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, struct iatt *buf, + dict_t *xdata) +{ + UPDATE_PROFILE_STATS(frame, FSTAT); + STACK_UNWIND_STRICT(fstat, frame, op_ret, op_errno, buf, xdata); + return 0; +} int -io_stats_ftruncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, - struct stat *prebuf, struct stat *postbuf) +io_stats_fallocate_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, struct iatt *prebuf, + struct iatt *postbuf, dict_t *xdata) { - STACK_UNWIND_STRICT (ftruncate, frame, op_ret, op_errno, - prebuf, postbuf); - return 0; + UPDATE_PROFILE_STATS(frame, FALLOCATE); + STACK_UNWIND_STRICT(fallocate, frame, op_ret, op_errno, prebuf, postbuf, + xdata); + return 0; } +int +io_stats_discard_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, struct iatt *prebuf, + struct iatt *postbuf, dict_t *xdata) +{ + UPDATE_PROFILE_STATS(frame, DISCARD); + STACK_UNWIND_STRICT(discard, frame, op_ret, op_errno, prebuf, postbuf, + xdata); + return 0; +} int -io_stats_fstat_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, struct stat *buf) +io_stats_zerofill_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, struct iatt *prebuf, + struct iatt *postbuf, dict_t *xdata) { - STACK_UNWIND_STRICT (fstat, frame, op_ret, op_errno, buf); - return 0; + UPDATE_PROFILE_STATS(frame, ZEROFILL); + STACK_UNWIND_STRICT(zerofill, frame, op_ret, op_errno, prebuf, postbuf, + xdata); + return 0; } +int32_t +io_stats_ipc_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, dict_t *xdata) +{ + UPDATE_PROFILE_STATS(frame, IPC); + STACK_UNWIND_STRICT(ipc, frame, op_ret, op_errno, xdata); + return 0; +} int -io_stats_lk_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, struct flock *lock) +io_stats_lk_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, struct gf_flock *lock, + dict_t *xdata) { - STACK_UNWIND_STRICT (lk, frame, op_ret, op_errno, lock); - return 0; + UPDATE_PROFILE_STATS(frame, LK); + STACK_UNWIND_STRICT(lk, frame, op_ret, op_errno, lock, xdata); + return 0; } +int +io_stats_entrylk_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, dict_t *xdata) +{ + UPDATE_PROFILE_STATS(frame, ENTRYLK); + STACK_UNWIND_STRICT(entrylk, frame, op_ret, op_errno, xdata); + return 0; +} int -io_stats_setdents_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno) +io_stats_fentrylk_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, dict_t *xdata) { - STACK_UNWIND_STRICT (setdents, frame, op_ret, op_errno); - return 0; + UPDATE_PROFILE_STATS(frame, FENTRYLK); + STACK_UNWIND_STRICT(fentrylk, frame, op_ret, op_errno, xdata); + return 0; } +int +io_stats_rchecksum_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, uint32_t weak_checksum, + uint8_t *strong_checksum, dict_t *xdata) +{ + UPDATE_PROFILE_STATS(frame, RCHECKSUM); + STACK_UNWIND_STRICT(rchecksum, frame, op_ret, op_errno, weak_checksum, + strong_checksum, xdata); + return 0; +} int -io_stats_entrylk_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno) +io_stats_seek_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, off_t offset, dict_t *xdata) { - STACK_UNWIND_STRICT (entrylk, frame, op_ret, op_errno); - return 0; + UPDATE_PROFILE_STATS(frame, SEEK); + STACK_UNWIND_STRICT(seek, frame, op_ret, op_errno, offset, xdata); + return 0; } +int +io_stats_lease_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, struct gf_lease *lease, + dict_t *xdata) +{ + UPDATE_PROFILE_STATS(frame, LEASE); + STACK_UNWIND_STRICT(lease, frame, op_ret, op_errno, lease, xdata); + return 0; +} int -io_stats_xattrop_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, dict_t *dict) +io_stats_getactivelk_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, + lock_migration_info_t *locklist, dict_t *xdata) { - STACK_UNWIND_STRICT (xattrop, frame, op_ret, op_errno, dict); - return 0; + UPDATE_PROFILE_STATS(frame, GETACTIVELK); + STACK_UNWIND_STRICT(getactivelk, frame, op_ret, op_errno, locklist, xdata); + return 0; } +int +io_stats_setactivelk_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, dict_t *xdata) +{ + UPDATE_PROFILE_STATS(frame, SETACTIVELK); + STACK_UNWIND_STRICT(setactivelk, frame, op_ret, op_errno, xdata); + return 0; +} int -io_stats_fxattrop_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, dict_t *dict) +io_stats_compound_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, void *data, + dict_t *xdata) { - STACK_UNWIND_STRICT (fxattrop, frame, op_ret, op_errno, dict); - return 0; + UPDATE_PROFILE_STATS(frame, COMPOUND); + STACK_UNWIND_STRICT(compound, frame, op_ret, op_errno, data, xdata); + return 0; } +int +io_stats_xattrop_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, dict_t *dict, + dict_t *xdata) +{ + UPDATE_PROFILE_STATS(frame, XATTROP); + STACK_UNWIND_STRICT(xattrop, frame, op_ret, op_errno, dict, xdata); + return 0; +} int -io_stats_inodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno) +io_stats_fxattrop_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, dict_t *dict, + dict_t *xdata) { - STACK_UNWIND_STRICT (inodelk, frame, op_ret, op_errno); - return 0; + UPDATE_PROFILE_STATS(frame, FXATTROP); + STACK_UNWIND_STRICT(fxattrop, frame, op_ret, op_errno, dict, xdata); + return 0; } +int +io_stats_inodelk_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, dict_t *xdata) +{ + UPDATE_PROFILE_STATS(frame, INODELK); + STACK_UNWIND_STRICT(inodelk, frame, op_ret, op_errno, xdata); + return 0; +} int -io_stats_entrylk (call_frame_t *frame, xlator_t *this, - const char *volume, loc_t *loc, const char *basename, - entrylk_cmd cmd, entrylk_type type) +io_stats_entrylk(call_frame_t *frame, xlator_t *this, const char *volume, + loc_t *loc, const char *basename, entrylk_cmd cmd, + entrylk_type type, dict_t *xdata) { - BUMP_FOP (ENTRYLK); + START_FOP_LATENCY(frame); - STACK_WIND (frame, io_stats_entrylk_cbk, - FIRST_CHILD (this), - FIRST_CHILD (this)->fops->entrylk, - volume, loc, basename, cmd, type); - return 0; + STACK_WIND(frame, io_stats_entrylk_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->entrylk, volume, loc, basename, cmd, + type, xdata); + return 0; } - int -io_stats_inodelk (call_frame_t *frame, xlator_t *this, - const char *volume, loc_t *loc, int32_t cmd, struct flock *flock) +io_stats_fentrylk(call_frame_t *frame, xlator_t *this, const char *volume, + fd_t *fd, const char *basename, entrylk_cmd cmd, + entrylk_type type, dict_t *xdata) { + START_FOP_LATENCY(frame); - BUMP_FOP (INODELK); - - STACK_WIND (frame, io_stats_inodelk_cbk, - FIRST_CHILD (this), - FIRST_CHILD (this)->fops->inodelk, - volume, loc, cmd, flock); - return 0; + STACK_WIND(frame, io_stats_fentrylk_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->fentrylk, volume, fd, basename, cmd, + type, xdata); + return 0; } - int -io_stats_finodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno) +io_stats_inodelk(call_frame_t *frame, xlator_t *this, const char *volume, + loc_t *loc, int32_t cmd, struct gf_flock *flock, dict_t *xdata) { + START_FOP_LATENCY(frame); - STACK_UNWIND_STRICT (finodelk, frame, op_ret, op_errno); - return 0; + STACK_WIND(frame, io_stats_inodelk_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->inodelk, volume, loc, cmd, flock, + xdata); + return 0; } +int +io_stats_finodelk_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, dict_t *xdata) +{ + UPDATE_PROFILE_STATS(frame, FINODELK); + STACK_UNWIND_STRICT(finodelk, frame, op_ret, op_errno, xdata); + return 0; +} int -io_stats_finodelk (call_frame_t *frame, xlator_t *this, - const char *volume, fd_t *fd, int32_t cmd, struct flock *flock) +io_stats_finodelk(call_frame_t *frame, xlator_t *this, const char *volume, + fd_t *fd, int32_t cmd, struct gf_flock *flock, dict_t *xdata) { - BUMP_FOP (FINODELK); + START_FOP_LATENCY(frame); - STACK_WIND (frame, io_stats_finodelk_cbk, - FIRST_CHILD (this), - FIRST_CHILD (this)->fops->finodelk, - volume, fd, cmd, flock); - return 0; + STACK_WIND(frame, io_stats_finodelk_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->finodelk, volume, fd, cmd, flock, + xdata); + return 0; } - int -io_stats_xattrop (call_frame_t *frame, xlator_t *this, - loc_t *loc, gf_xattrop_flags_t flags, dict_t *dict) +io_stats_xattrop(call_frame_t *frame, xlator_t *this, loc_t *loc, + gf_xattrop_flags_t flags, dict_t *dict, dict_t *xdata) { - BUMP_FOP (XATTROP); - - STACK_WIND (frame, io_stats_xattrop_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->xattrop, - loc, flags, dict); + START_FOP_LATENCY(frame); - return 0; + STACK_WIND(frame, io_stats_xattrop_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->xattrop, loc, flags, dict, xdata); + return 0; } - int -io_stats_fxattrop (call_frame_t *frame, xlator_t *this, - fd_t *fd, gf_xattrop_flags_t flags, dict_t *dict) +io_stats_fxattrop(call_frame_t *frame, xlator_t *this, fd_t *fd, + gf_xattrop_flags_t flags, dict_t *dict, dict_t *xdata) { - BUMP_FOP (FXATTROP); + START_FOP_LATENCY(frame); - STACK_WIND (frame, io_stats_fxattrop_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->fxattrop, - fd, flags, dict); - - return 0; + STACK_WIND(frame, io_stats_fxattrop_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->fxattrop, fd, flags, dict, xdata); + return 0; } - int -io_stats_lookup (call_frame_t *frame, xlator_t *this, - loc_t *loc, dict_t *xattr_req) +io_stats_lookup(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { - BUMP_FOP (LOOKUP); - - STACK_WIND (frame, io_stats_lookup_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->lookup, - loc, xattr_req); + START_FOP_LATENCY(frame); - return 0; + STACK_WIND(frame, io_stats_lookup_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->lookup, loc, xdata); + return 0; } - int -io_stats_stat (call_frame_t *frame, xlator_t *this, loc_t *loc) +io_stats_stat(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { - BUMP_FOP (STAT); + START_FOP_LATENCY(frame); - STACK_WIND (frame, io_stats_stat_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->stat, - loc); - - return 0; + STACK_WIND(frame, io_stats_stat_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->stat, loc, xdata); + return 0; } - int -io_stats_readlink (call_frame_t *frame, xlator_t *this, - loc_t *loc, size_t size) +io_stats_readlink(call_frame_t *frame, xlator_t *this, loc_t *loc, size_t size, + dict_t *xdata) { - BUMP_FOP (READLINK); - - STACK_WIND (frame, io_stats_readlink_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->readlink, - loc, size); + START_FOP_LATENCY(frame); - return 0; + STACK_WIND(frame, io_stats_readlink_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->readlink, loc, size, xdata); + return 0; } +int +io_stats_mknod(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, + dev_t dev, mode_t umask, dict_t *xdata) +{ + START_FOP_LATENCY(frame); + + STACK_WIND(frame, io_stats_mknod_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->mknod, loc, mode, dev, umask, xdata); + return 0; +} int -io_stats_mknod (call_frame_t *frame, xlator_t *this, - loc_t *loc, mode_t mode, dev_t dev) +io_stats_mkdir(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, + mode_t umask, dict_t *xdata) { - BUMP_FOP (MKNOD); + if (loc->path) + frame->local = gf_strdup(loc->path); - STACK_WIND (frame, io_stats_mknod_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->mknod, - loc, mode, dev); + START_FOP_LATENCY(frame); - return 0; + STACK_WIND(frame, io_stats_mkdir_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->mkdir, loc, mode, umask, xdata); + return 0; } - int -io_stats_mkdir (call_frame_t *frame, xlator_t *this, - loc_t *loc, mode_t mode) +io_stats_unlink(call_frame_t *frame, xlator_t *this, loc_t *loc, int xflag, + dict_t *xdata) { - BUMP_FOP (MKDIR); + START_FOP_LATENCY(frame); - STACK_WIND (frame, io_stats_mkdir_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->mkdir, - loc, mode); - return 0; + STACK_WIND(frame, io_stats_unlink_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->unlink, loc, xflag, xdata); + return 0; } - int -io_stats_unlink (call_frame_t *frame, xlator_t *this, - loc_t *loc) +io_stats_rmdir(call_frame_t *frame, xlator_t *this, loc_t *loc, int flags, + dict_t *xdata) { - BUMP_FOP (UNLINK); + START_FOP_LATENCY(frame); - STACK_WIND (frame, io_stats_unlink_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->unlink, - loc); - return 0; + STACK_WIND(frame, io_stats_rmdir_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->rmdir, loc, flags, xdata); + return 0; } - int -io_stats_rmdir (call_frame_t *frame, xlator_t *this, - loc_t *loc) +io_stats_symlink(call_frame_t *frame, xlator_t *this, const char *linkpath, + loc_t *loc, mode_t umask, dict_t *xdata) { - BUMP_FOP (RMDIR); + START_FOP_LATENCY(frame); - STACK_WIND (frame, io_stats_rmdir_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->rmdir, - loc); - - return 0; + STACK_WIND(frame, io_stats_symlink_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->symlink, linkpath, loc, umask, xdata); + return 0; } - int -io_stats_symlink (call_frame_t *frame, xlator_t *this, - const char *linkpath, loc_t *loc) +io_stats_rename(call_frame_t *frame, xlator_t *this, loc_t *oldloc, + loc_t *newloc, dict_t *xdata) { - BUMP_FOP (SYMLINK); - - STACK_WIND (frame, io_stats_symlink_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->symlink, - linkpath, loc); + START_FOP_LATENCY(frame); - return 0; + STACK_WIND(frame, io_stats_rename_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->rename, oldloc, newloc, xdata); + return 0; } - int -io_stats_rename (call_frame_t *frame, xlator_t *this, - loc_t *oldloc, loc_t *newloc) +io_stats_link(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, + dict_t *xdata) { - BUMP_FOP (RENAME); - - STACK_WIND (frame, io_stats_rename_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->rename, - oldloc, newloc); + START_FOP_LATENCY(frame); - return 0; + STACK_WIND(frame, io_stats_link_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->link, oldloc, newloc, xdata); + return 0; } - int -io_stats_link (call_frame_t *frame, xlator_t *this, - loc_t *oldloc, loc_t *newloc) +io_stats_setattr(call_frame_t *frame, xlator_t *this, loc_t *loc, + struct iatt *stbuf, int32_t valid, dict_t *xdata) { - BUMP_FOP (LINK); + START_FOP_LATENCY(frame); - STACK_WIND (frame, io_stats_link_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->link, - oldloc, newloc); - return 0; + STACK_WIND(frame, io_stats_setattr_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->setattr, loc, stbuf, valid, xdata); + return 0; } - int -io_stats_setattr (call_frame_t *frame, xlator_t *this, - loc_t *loc, struct stat *stbuf, int32_t valid) +io_stats_truncate(call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset, + dict_t *xdata) { - BUMP_FOP (SETATTR); + START_FOP_LATENCY(frame); - STACK_WIND (frame, io_stats_setattr_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->setattr, - loc, stbuf, valid); - - return 0; + STACK_WIND(frame, io_stats_truncate_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->truncate, loc, offset, xdata); + return 0; } - int -io_stats_truncate (call_frame_t *frame, xlator_t *this, - loc_t *loc, off_t offset) +io_stats_open(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, + fd_t *fd, dict_t *xdata) { - BUMP_FOP (TRUNCATE); + if (loc->path) + frame->local = gf_strdup(loc->path); - STACK_WIND (frame, io_stats_truncate_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->truncate, - loc, offset); + START_FOP_LATENCY(frame); - return 0; + STACK_WIND(frame, io_stats_open_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->open, loc, flags, fd, xdata); + return 0; } - int -io_stats_open (call_frame_t *frame, xlator_t *this, - loc_t *loc, int32_t flags, fd_t *fd, int32_t wbflags) +io_stats_create(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, + mode_t mode, mode_t umask, fd_t *fd, dict_t *xdata) { - BUMP_FOP (OPEN); + if (loc->path) + frame->local = gf_strdup(loc->path); - frame->local = strdup (loc->path); + START_FOP_LATENCY(frame); - STACK_WIND (frame, io_stats_open_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->open, - loc, flags, fd, wbflags); - return 0; + STACK_WIND(frame, io_stats_create_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->create, loc, flags, mode, umask, fd, + xdata); + return 0; } - int -io_stats_create (call_frame_t *frame, xlator_t *this, - loc_t *loc, int32_t flags, mode_t mode, fd_t *fd) +io_stats_readv(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, + off_t offset, uint32_t flags, dict_t *xdata) { - BUMP_FOP (CREATE); + frame->local = fd; - frame->local = strdup (loc->path); + START_FOP_LATENCY(frame); - STACK_WIND (frame, io_stats_create_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->create, - loc, flags, mode, fd); - return 0; + STACK_WIND(frame, io_stats_readv_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->readv, fd, size, offset, flags, xdata); + return 0; } - int -io_stats_readv (call_frame_t *frame, xlator_t *this, - fd_t *fd, size_t size, off_t offset) +io_stats_writev(call_frame_t *frame, xlator_t *this, fd_t *fd, + struct iovec *vector, int32_t count, off_t offset, + uint32_t flags, struct iobref *iobref, dict_t *xdata) { - BUMP_FOP (READ); + int len = 0; - frame->local = fd; + if (fd->inode) + frame->local = fd->inode; + len = iov_length(vector, count); - STACK_WIND (frame, io_stats_readv_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->readv, - fd, size, offset); - return 0; -} + ios_bump_write(this, fd, len); + START_FOP_LATENCY(frame); + STACK_WIND(frame, io_stats_writev_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->writev, fd, vector, count, offset, + flags, iobref, xdata); + return 0; +} int -io_stats_writev (call_frame_t *frame, xlator_t *this, - fd_t *fd, struct iovec *vector, - int32_t count, off_t offset, - struct iobref *iobref) +io_stats_copy_file_range(call_frame_t *frame, xlator_t *this, fd_t *fd_in, + off_t off_in, fd_t *fd_out, off_t off_out, size_t len, + uint32_t flags, dict_t *xdata) { - struct ios_conf *conf = NULL; - int len = 0; - - conf = this->private; + START_FOP_LATENCY(frame); - len = iov_length (vector, count); + STACK_WIND(frame, io_stats_copy_file_range_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->copy_file_range, fd_in, off_in, fd_out, + off_out, len, flags, xdata); + return 0; +} - BUMP_FOP (WRITE); - BUMP_WRITE (fd, len); +int +io_stats_statfs(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) +{ + START_FOP_LATENCY(frame); - STACK_WIND (frame, io_stats_writev_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->writev, - fd, vector, count, offset, iobref); - return 0; + STACK_WIND(frame, io_stats_statfs_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->statfs, loc, xdata); + return 0; } - int -io_stats_statfs (call_frame_t *frame, xlator_t *this, - loc_t *loc) +io_stats_flush(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata) { - BUMP_FOP (STATFS); + START_FOP_LATENCY(frame); - STACK_WIND (frame, io_stats_statfs_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->statfs, - loc); - return 0; + STACK_WIND(frame, io_stats_flush_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->flush, fd, xdata); + return 0; } - int -io_stats_flush (call_frame_t *frame, xlator_t *this, - fd_t *fd) +io_stats_fsync(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags, + dict_t *xdata) { - BUMP_FOP (FLUSH); + START_FOP_LATENCY(frame); - STACK_WIND (frame, io_stats_flush_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->flush, - fd); - return 0; + STACK_WIND(frame, io_stats_fsync_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->fsync, fd, flags, xdata); + return 0; } - int -io_stats_fsync (call_frame_t *frame, xlator_t *this, - fd_t *fd, int32_t flags) +conditional_dump(dict_t *dict, char *key, data_t *value, void *data) { - BUMP_FOP (FSYNC); - - STACK_WIND (frame, io_stats_fsync_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->fsync, - fd, flags); - return 0; + struct { + xlator_t *this; + inode_t *inode; + const char *path; + } * stub; + xlator_t *this = NULL; + char *filename = NULL; + FILE *logfp = NULL; + struct ios_dump_args args = {0}; + int pid, namelen, dirlen; + char dump_key[100]; + char *slash_ptr = NULL; + char *path_in_value = NULL; + char *identifier = NULL; + struct ios_conf *conf = NULL; + + stub = data; + this = stub->this; + conf = this->private; + + /* Don't do this on 'brick-side', only do this on client side */ + /* Addresses CVE-2018-14659 */ + if (this->ctx->process_mode != GF_CLIENT_PROCESS) { + gf_log(this->name, GF_LOG_DEBUG, + "taking io-stats dump using setxattr not permitted on brick." + " Use 'gluster profile' instead"); + return -1; + } + + /* Create a file name that is appended with the io-stats instance + name as well. This helps when there is more than a single io-stats + instance in the graph, or the client and server processes are running + on the same node */ + /* For the sanity of where the file should be located, we should make + sure file is written only inside RUNDIR (ie, /var/run/gluster) */ + /* TODO: provide an option to dump it to different directory of + choice, based on options */ + /* name format: /var/run/gluster/<passed in path/filename>.<xlator name + * slashes to -> */ + + path_in_value = alloca0(value->len + 1); + + /* We need a memcpy here because of the way dict_unserialize works */ + + memcpy(path_in_value, data_to_str(value), value->len); + path_in_value[value->len] = '\0'; + + if (strstr(path_in_value, "../")) { + gf_log(this->name, GF_LOG_ERROR, "%s: no \"../\" allowed in path", + path_in_value); + return -1; + } + + if (path_in_value[0] == '/') { + path_in_value = path_in_value + 1; + } + + dirlen = strlen(IOS_STATS_DUMP_DIR); + if (conf->unique_id) { + /* this->name will be the same for all bricks of the volume */ + identifier = conf->unique_id; + } else { + identifier = this->name; + } + + namelen = (dirlen + value->len + strlen(identifier) + 3); + /* +3 for '/', '.' and '\0' added in snprintf below*/ + + filename = alloca0(namelen); + snprintf(filename, namelen, "%s/%s.%s", IOS_STATS_DUMP_DIR, path_in_value, + identifier); + + /* convert any slashes to '-' so that fopen works correctly */ + slash_ptr = strchr(filename + dirlen + 1, '/'); + while (slash_ptr) { + *slash_ptr = '-'; + slash_ptr = strchr(slash_ptr, '/'); + } + + pid = getpid(); + + if (!strncmp(filename, "", 1)) { + gf_log(this->name, GF_LOG_ERROR, "No filename given"); + return -1; + } + logfp = fopen(filename, "w+"); + if (!logfp) { + gf_log(this->name, GF_LOG_ERROR, + "failed to open %s " + "for writing", + filename); + return -1; + } + sprintf(dump_key, "*io*stat*%d_json_dump", pid); + if (fnmatch(dump_key, key, 0) == 0) { + (void)ios_dump_args_init(&args, IOS_DUMP_TYPE_JSON_FILE, logfp); + } else { + (void)ios_dump_args_init(&args, IOS_DUMP_TYPE_FILE, logfp); + } + io_stats_dump(this, &args, GF_IOS_INFO_ALL, _gf_false); + fclose(logfp); + return 0; } +int +_ios_destroy_dump_thread(struct ios_conf *conf) +{ + conf->dump_thread_should_die = _gf_true; + if (conf->dump_thread_running) { + (void)pthread_cancel(conf->dump_thread); + (void)pthread_join(conf->dump_thread, NULL); + } + return 0; +} -void -conditional_dump (dict_t *dict, char *key, data_t *value, void *data) -{ - struct { - xlator_t *this; - inode_t *inode; - const char *path; - } *stub; - xlator_t *this = NULL; - inode_t *inode = NULL; - const char *path = NULL; - char *filename = NULL; - - stub = data; - this = stub->this; - inode = stub->inode; - path = stub->path; - - filename = alloca (value->len + 1); - memset (filename, 0, value->len + 1); - memcpy (filename, data_to_str (value), value->len); - - if (fnmatch ("*io*stat*dump", key, 0) == 0) { - io_stats_dump (this, filename, inode, path); +void * +_ios_dump_thread(xlator_t *this) +{ + struct ios_conf *conf = NULL; + FILE *stats_logfp = NULL; + FILE *samples_logfp = NULL; + struct ios_dump_args args = {0}; + int i; + int stats_bytes_written = 0; + int samples_bytes_written = 0; + char stats_filename[PATH_MAX]; + char samples_filename[PATH_MAX]; + char *xlator_name; + char *instance_name; + gf_boolean_t log_stats_fopen_failure = _gf_true; + gf_boolean_t log_samples_fopen_failure = _gf_true; + int old_cancel_type; + + conf = this->private; + gf_log(this->name, GF_LOG_INFO, + "IO stats dump thread started, " + "polling IO stats every %d seconds", + conf->ios_dump_interval); + xlator_name = strdupa(conf->unique_id); + for (i = 0; i < strlen(xlator_name); i++) { + if (xlator_name[i] == '/') + xlator_name[i] = '_'; + } + instance_name = this->instance_name; + if (this->name && strcmp(this->name, "glustershd") == 0) { + xlator_name = "shd"; + } else if (this->prev && strcmp(this->prev->name, "nfs-server") == 0) { + xlator_name = "nfsd"; + instance_name = this->prev->instance_name; + } + if (sys_mkdir(_IOS_DUMP_DIR, S_IRWXU | S_IRWXO | S_IRWXG) == (-1)) { + if (errno != EEXIST) { + gf_log(this->name, GF_LOG_ERROR, + "could not create stats-dump directory %s", _IOS_DUMP_DIR); + goto out; + } + } + if (sys_mkdir(_IOS_SAMP_DIR, S_IRWXU | S_IRWXO | S_IRWXG) == (-1)) { + if (errno != EEXIST) { + gf_log(this->name, GF_LOG_ERROR, + "could not create stats-sample directory %s", _IOS_SAMP_DIR); + goto out; + } + } + if (instance_name) { + stats_bytes_written = snprintf(stats_filename, PATH_MAX, + "%s/%s_%s_%s.dump", _IOS_DUMP_DIR, + __progname, xlator_name, instance_name); + samples_bytes_written = snprintf( + samples_filename, PATH_MAX, "%s/%s_%s_%s.samp", _IOS_SAMP_DIR, + __progname, xlator_name, instance_name); + } else { + stats_bytes_written = snprintf(stats_filename, PATH_MAX, + "%s/%s_%s.dump", _IOS_DUMP_DIR, + __progname, xlator_name); + samples_bytes_written = snprintf(samples_filename, PATH_MAX, + "%s/%s_%s.samp", _IOS_SAMP_DIR, + __progname, xlator_name); + } + if ((stats_bytes_written >= PATH_MAX) || + (samples_bytes_written >= PATH_MAX)) { + gf_log(this->name, GF_LOG_ERROR, + "Invalid path for stats dump (%s) and/or latency " + "samples (%s)", + stats_filename, samples_filename); + goto out; + } + while (1) { + if (conf->dump_thread_should_die) + break; + (void)pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, + &old_cancel_type); + sleep(conf->ios_dump_interval); + (void)pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &old_cancel_type); + /* + * It's not clear whether we should reopen this each time, or + * just hold it open and rewind/truncate on each iteration. + * Leaving it alone for now. + */ + stats_logfp = fopen(stats_filename, "w+"); + if (stats_logfp) { + (void)ios_dump_args_init(&args, conf->dump_format, stats_logfp); + io_stats_dump(this, &args, GF_IOS_INFO_ALL, _gf_false); + fclose(stats_logfp); + log_stats_fopen_failure = _gf_true; + } else if (log_stats_fopen_failure) { + gf_log(this->name, GF_LOG_ERROR, + "could not open stats-dump file %s (%s)", stats_filename, + strerror(errno)); + log_stats_fopen_failure = _gf_false; } + samples_logfp = fopen(samples_filename, "w+"); + if (samples_logfp) { + io_stats_dump_latency_samples_logfp(this, samples_logfp); + fclose(samples_logfp); + log_samples_fopen_failure = _gf_true; + } else if (log_samples_fopen_failure) { + gf_log(this->name, GF_LOG_ERROR, + "could not open samples-dump file %s (%s)", samples_filename, + strerror(errno)); + log_samples_fopen_failure = _gf_false; + } + } +out: + conf->dump_thread_running = _gf_false; + gf_log(this->name, GF_LOG_INFO, "IO stats dump thread terminated"); + return NULL; } +static gf_boolean_t +match_special_xattr(dict_t *d, char *k, data_t *val, void *mdata) +{ + gf_boolean_t ret = _gf_false; + if (fnmatch("*io*stat*dump", k, 0) == 0) { + ret = _gf_true; + } + + return ret; +} int -io_stats_setxattr (call_frame_t *frame, xlator_t *this, - loc_t *loc, dict_t *dict, - int32_t flags) +io_stats_setxattr(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict, + int32_t flags, dict_t *xdata) { - struct { - xlator_t *this; - inode_t *inode; - const char *path; - } stub; + struct { + xlator_t *this; + inode_t *inode; + const char *path; + } stub; - BUMP_FOP (SETXATTR); + stub.this = this; + stub.inode = loc->inode; + stub.path = loc->path; - stub.this = this; - stub.inode = loc->inode; - stub.path = loc->path; + (void)dict_foreach_match(dict, match_special_xattr, NULL, conditional_dump, + &stub); - dict_foreach (dict, conditional_dump, &stub); + START_FOP_LATENCY(frame); - STACK_WIND (frame, io_stats_setxattr_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->setxattr, - loc, dict, flags); - return 0; + STACK_WIND(frame, io_stats_setxattr_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->setxattr, loc, dict, flags, xdata); + return 0; } - int -io_stats_getxattr (call_frame_t *frame, xlator_t *this, - loc_t *loc, const char *name) +io_stats_getxattr(call_frame_t *frame, xlator_t *this, loc_t *loc, + const char *name, dict_t *xdata) { - BUMP_FOP (GETXATTR); + START_FOP_LATENCY(frame); - STACK_WIND (frame, io_stats_getxattr_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->getxattr, - loc, name); - return 0; + STACK_WIND(frame, io_stats_getxattr_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->getxattr, loc, name, xdata); + return 0; } - int -io_stats_removexattr (call_frame_t *frame, xlator_t *this, - loc_t *loc, const char *name) +io_stats_removexattr(call_frame_t *frame, xlator_t *this, loc_t *loc, + const char *name, dict_t *xdata) { - BUMP_FOP (REMOVEXATTR); + START_FOP_LATENCY(frame); - STACK_WIND (frame, io_stats_removexattr_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->removexattr, - loc, name); - - return 0; + STACK_WIND(frame, io_stats_removexattr_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->removexattr, loc, name, xdata); + return 0; } - int -io_stats_opendir (call_frame_t *frame, xlator_t *this, - loc_t *loc, fd_t *fd) +io_stats_fsetxattr(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *dict, + int32_t flags, dict_t *xdata) { - BUMP_FOP (OPENDIR); + START_FOP_LATENCY(frame); - STACK_WIND (frame, io_stats_opendir_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->opendir, - loc, fd); - return 0; + STACK_WIND(frame, io_stats_fsetxattr_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->fsetxattr, fd, dict, flags, xdata); + return 0; } - int -io_stats_getdents (call_frame_t *frame, xlator_t *this, - fd_t *fd, size_t size, off_t offset, int32_t flag) +io_stats_fgetxattr(call_frame_t *frame, xlator_t *this, fd_t *fd, + const char *name, dict_t *xdata) { - BUMP_FOP (GETDENTS); + START_FOP_LATENCY(frame); - STACK_WIND (frame, io_stats_getdents_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->getdents, - fd, size, offset, flag); - return 0; + STACK_WIND(frame, io_stats_fgetxattr_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->fgetxattr, fd, name, xdata); + return 0; } - int -io_stats_readdirp (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, - off_t offset) +io_stats_fremovexattr(call_frame_t *frame, xlator_t *this, fd_t *fd, + const char *name, dict_t *xdata) { - BUMP_FOP (READDIRP); + START_FOP_LATENCY(frame); - STACK_WIND (frame, io_stats_readdirp_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->readdir, - fd, size, offset); - - return 0; + STACK_WIND(frame, io_stats_fremovexattr_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->fremovexattr, fd, name, xdata); + return 0; } +int +io_stats_opendir(call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd, + dict_t *xdata) +{ + START_FOP_LATENCY(frame); + + STACK_WIND(frame, io_stats_opendir_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->opendir, loc, fd, xdata); + return 0; +} int -io_stats_readdir (call_frame_t *frame, xlator_t *this, - fd_t *fd, size_t size, off_t offset) +io_stats_readdirp(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, + off_t offset, dict_t *dict) { - BUMP_FOP (READDIR); + frame->local = fd->inode; + START_FOP_LATENCY(frame); - STACK_WIND (frame, io_stats_readdir_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->readdir, - fd, size, offset); + STACK_WIND(frame, io_stats_readdirp_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->readdirp, fd, size, offset, dict); + return 0; +} - return 0; +int +io_stats_readdir(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, + off_t offset, dict_t *xdata) +{ + START_FOP_LATENCY(frame); + + STACK_WIND(frame, io_stats_readdir_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->readdir, fd, size, offset, xdata); + return 0; } +int +io_stats_fsyncdir(call_frame_t *frame, xlator_t *this, fd_t *fd, + int32_t datasync, dict_t *xdata) +{ + START_FOP_LATENCY(frame); + + STACK_WIND(frame, io_stats_fsyncdir_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->fsyncdir, fd, datasync, xdata); + return 0; +} int -io_stats_fsyncdir (call_frame_t *frame, xlator_t *this, - fd_t *fd, int32_t datasync) +io_stats_access(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t mask, + dict_t *xdata) { - BUMP_FOP (FSYNCDIR); + START_FOP_LATENCY(frame); - STACK_WIND (frame, io_stats_fsyncdir_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->fsyncdir, - fd, datasync); - return 0; + STACK_WIND(frame, io_stats_access_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->access, loc, mask, xdata); + return 0; } +int +io_stats_ftruncate(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, + dict_t *xdata) +{ + START_FOP_LATENCY(frame); + + STACK_WIND(frame, io_stats_ftruncate_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->ftruncate, fd, offset, xdata); + return 0; +} int -io_stats_access (call_frame_t *frame, xlator_t *this, - loc_t *loc, int32_t mask) +io_stats_fsetattr(call_frame_t *frame, xlator_t *this, fd_t *fd, + struct iatt *stbuf, int32_t valid, dict_t *xdata) { - BUMP_FOP (ACCESS); + START_FOP_LATENCY(frame); - STACK_WIND (frame, io_stats_access_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->access, - loc, mask); - return 0; + STACK_WIND(frame, io_stats_setattr_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->fsetattr, fd, stbuf, valid, xdata); + return 0; } +int +io_stats_fstat(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata) +{ + START_FOP_LATENCY(frame); + + STACK_WIND(frame, io_stats_fstat_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->fstat, fd, xdata); + return 0; +} int -io_stats_ftruncate (call_frame_t *frame, xlator_t *this, - fd_t *fd, off_t offset) +io_stats_fallocate(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t mode, + off_t offset, size_t len, dict_t *xdata) { - BUMP_FOP (FTRUNCATE); + START_FOP_LATENCY(frame); - STACK_WIND (frame, io_stats_ftruncate_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->ftruncate, - fd, offset); + STACK_WIND(frame, io_stats_fallocate_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->fallocate, fd, mode, offset, len, + xdata); - return 0; + return 0; } - int -io_stats_fsetattr (call_frame_t *frame, xlator_t *this, - fd_t *fd, struct stat *stbuf, int32_t valid) +io_stats_discard(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, + size_t len, dict_t *xdata) { - BUMP_FOP (FSETATTR); + START_FOP_LATENCY(frame); - STACK_WIND (frame, io_stats_setattr_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->fsetattr, - fd, stbuf, valid); - return 0; -} + STACK_WIND(frame, io_stats_discard_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->discard, fd, offset, len, xdata); + return 0; +} int -io_stats_fstat (call_frame_t *frame, xlator_t *this, - fd_t *fd) +io_stats_zerofill(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, + off_t len, dict_t *xdata) { - BUMP_FOP (FSTAT); + START_FOP_LATENCY(frame); - STACK_WIND (frame, io_stats_fstat_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->fstat, - fd); - return 0; + STACK_WIND(frame, io_stats_zerofill_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->zerofill, fd, offset, len, xdata); + + return 0; } +int32_t +io_stats_ipc(call_frame_t *frame, xlator_t *this, int32_t op, dict_t *xdata) +{ + START_FOP_LATENCY(frame); + + STACK_WIND(frame, io_stats_ipc_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->ipc, op, xdata); + return 0; +} int -io_stats_lk (call_frame_t *frame, xlator_t *this, - fd_t *fd, int32_t cmd, struct flock *lock) +io_stats_lk(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t cmd, + struct gf_flock *lock, dict_t *xdata) { - BUMP_FOP (LK); + START_FOP_LATENCY(frame); - STACK_WIND (frame, io_stats_lk_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->lk, - fd, cmd, lock); - return 0; + STACK_WIND(frame, io_stats_lk_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->lk, fd, cmd, lock, xdata); + return 0; } - int -io_stats_setdents (call_frame_t *frame, xlator_t *this, - fd_t *fd, int32_t flags, - dir_entry_t *entries, int32_t count) +io_stats_rchecksum(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, + int32_t len, dict_t *xdata) { - BUMP_FOP (SETDENTS); + START_FOP_LATENCY(frame); - STACK_WIND (frame, io_stats_setdents_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->setdents, - fd, flags, entries, count); - return 0; + STACK_WIND(frame, io_stats_rchecksum_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->rchecksum, fd, offset, len, xdata); + return 0; } - int -io_stats_checksum_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, - uint8_t *fchecksum, uint8_t *dchecksum) +io_stats_seek(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, + gf_seek_what_t what, dict_t *xdata) { - STACK_UNWIND_STRICT (checksum, frame, op_ret, op_errno, - fchecksum, dchecksum); + START_FOP_LATENCY(frame); - return 0; + STACK_WIND(frame, io_stats_seek_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->seek, fd, offset, what, xdata); + return 0; } - int -io_stats_checksum (call_frame_t *frame, xlator_t *this, - loc_t *loc, int32_t flag) +io_stats_lease(call_frame_t *frame, xlator_t *this, loc_t *loc, + struct gf_lease *lease, dict_t *xdata) { - STACK_WIND (frame, io_stats_checksum_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->checksum, - loc, flag); + START_FOP_LATENCY(frame); - return 0; + STACK_WIND(frame, io_stats_lease_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->lease, loc, lease, xdata); + return 0; } - int -io_stats_stats_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, struct xlator_stats *stats) +io_stats_getactivelk(call_frame_t *frame, xlator_t *this, loc_t *loc, + dict_t *xdata) { - STACK_UNWIND (frame, op_ret, op_errno, stats); - return 0; -} + START_FOP_LATENCY(frame); + STACK_WIND(frame, io_stats_getactivelk_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->getactivelk, loc, xdata); + return 0; +} int -io_stats_stats (call_frame_t *frame, xlator_t *this, int32_t flags) +io_stats_setactivelk(call_frame_t *frame, xlator_t *this, loc_t *loc, + lock_migration_info_t *locklist, dict_t *xdata) { - STACK_WIND (frame, io_stats_stats_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->mops->stats, - flags); + START_FOP_LATENCY(frame); - return 0; + STACK_WIND(frame, io_stats_setactivelk_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->setactivelk, loc, locklist, xdata); + return 0; } - int -io_stats_release (xlator_t *this, fd_t *fd) +io_stats_compound(call_frame_t *frame, xlator_t *this, void *args, + dict_t *xdata) { - struct ios_fd *iosfd = NULL; + START_FOP_LATENCY(frame); - BUMP_CBK (RELEASE); + STACK_WIND(frame, io_stats_compound_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->compound, args, xdata); + return 0; +} - ios_fd_ctx_get (fd, this, &iosfd); - if (iosfd) { - io_stats_dump_fd (this, iosfd); +int +io_stats_release(xlator_t *this, fd_t *fd) +{ + struct ios_fd *iosfd = NULL; + struct ios_conf *conf = NULL; - if (iosfd->filename) - FREE (iosfd->filename); - FREE (iosfd); + BUMP_FOP(RELEASE); + + conf = this->private; + if (conf) { + LOCK(&conf->lock); + { + conf->cumulative.nr_opens--; } + UNLOCK(&conf->lock); + } - return 0; + ios_fd_ctx_get(fd, this, &iosfd); + if (iosfd) { + io_stats_dump_fd(this, iosfd); + + GF_FREE(iosfd->filename); + GF_FREE(iosfd); + } + + return 0; } +int +io_stats_releasedir(xlator_t *this, fd_t *fd) +{ + BUMP_FOP(RELEASEDIR); + + return 0; +} int -io_stats_releasedir (xlator_t *this, fd_t *fd) +io_stats_forget(xlator_t *this, inode_t *inode) +{ + BUMP_FOP(FORGET); + ios_stats_cleanup(this, inode); + return 0; +} + +static int +ios_init_top_stats(struct ios_conf *conf) { - BUMP_CBK (RELEASEDIR); + int i = 0; - return 0; + GF_ASSERT(conf); + + for (i = 0; i < IOS_STATS_TYPE_MAX; i++) { + conf->list[i].iosstats = GF_CALLOC(1, sizeof(*conf->list[i].iosstats), + gf_io_stats_mt_ios_stat); + + if (!conf->list[i].iosstats) + return -1; + + INIT_LIST_HEAD(&conf->list[i].iosstats->list); + LOCK_INIT(&conf->list[i].lock); + } + + for (i = 0; i < IOS_STATS_THRU_MAX; i++) { + conf->thru_list[i].iosstats = GF_CALLOC( + 1, sizeof(*conf->thru_list[i].iosstats), gf_io_stats_mt_ios_stat); + + if (!conf->thru_list[i].iosstats) + return -1; + + INIT_LIST_HEAD(&conf->thru_list[i].iosstats->list); + LOCK_INIT(&conf->thru_list[i].lock); + } + + return 0; } +static void +ios_destroy_top_stats(struct ios_conf *conf) +{ + int i = 0; + struct ios_stat_head *list_head = NULL; + struct ios_stat_list *entry = NULL; + struct ios_stat_list *tmp = NULL; + struct ios_stat_list *list = NULL; + struct ios_stat *stat = NULL; + + GF_ASSERT(conf); + + LOCK(&conf->lock); + + conf->cumulative.nr_opens = 0; + conf->cumulative.max_nr_opens = 0; + conf->cumulative.max_openfd_time.tv_sec = 0; + conf->cumulative.max_openfd_time.tv_usec = 0; + + for (i = 0; i < IOS_STATS_TYPE_MAX; i++) { + list_head = &conf->list[i]; + if (!list_head) + continue; + list_for_each_entry_safe(entry, tmp, &list_head->iosstats->list, list) + { + list = entry; + stat = list->iosstat; + ios_stat_unref(stat); + list_del(&list->list); + GF_FREE(list); + list_head->members--; + } + GF_FREE(list_head->iosstats); + } + + for (i = 0; i < IOS_STATS_THRU_MAX; i++) { + list_head = &conf->thru_list[i]; + if (!list_head) + continue; + list_for_each_entry_safe(entry, tmp, &list_head->iosstats->list, list) + { + list = entry; + stat = list->iosstat; + ios_stat_unref(stat); + list_del(&list->list); + GF_FREE(list); + list_head->members--; + } + GF_FREE(list_head->iosstats); + } -int -io_stats_forget (xlator_t *this, fd_t *fd) + UNLOCK(&conf->lock); + + return; +} + +static void +io_stats_clear(struct ios_conf *conf) { - BUMP_CBK (FORGET); + time_t now = 0; + + GF_ASSERT(conf); + now = gf_time(); + + LOCK(&conf->lock); + { + ios_global_stats_clear(&conf->cumulative, now); + ios_global_stats_clear(&conf->incremental, now); + conf->increment = 0; + } + UNLOCK(&conf->lock); +} - return 0; +int32_t +io_priv(xlator_t *this) +{ + int i; + char key[GF_DUMP_MAX_BUF_LEN]; + char key_prefix_cumulative[GF_DUMP_MAX_BUF_LEN]; + char key_prefix_incremental[GF_DUMP_MAX_BUF_LEN]; + double min, max, avg; + uint64_t count, total; + struct ios_conf *conf = NULL; + + conf = this->private; + if (!conf) + return -1; + + if (!conf->count_fop_hits || !conf->measure_latency) + return -1; + + gf_proc_dump_write("cumulative.data_read", "%" GF_PRI_ATOMIC, + GF_ATOMIC_GET(conf->cumulative.data_read)); + gf_proc_dump_write("cumulative.data_written", "%" GF_PRI_ATOMIC, + GF_ATOMIC_GET(conf->cumulative.data_written)); + + gf_proc_dump_write("incremental.data_read", "%" GF_PRI_ATOMIC, + GF_ATOMIC_GET(conf->incremental.data_read)); + gf_proc_dump_write("incremental.data_written", "%" GF_PRI_ATOMIC, + GF_ATOMIC_GET(conf->incremental.data_written)); + + snprintf(key_prefix_cumulative, GF_DUMP_MAX_BUF_LEN, "%s.cumulative", + this->name); + snprintf(key_prefix_incremental, GF_DUMP_MAX_BUF_LEN, "%s.incremental", + this->name); + + for (i = 0; i < GF_FOP_MAXVALUE; i++) { + count = GF_ATOMIC_GET(conf->cumulative.fop_hits[i]); + total = conf->cumulative.latency[i].total; + min = conf->cumulative.latency[i].min; + max = conf->cumulative.latency[i].max; + avg = conf->cumulative.latency[i].avg; + + gf_proc_dump_build_key(key, key_prefix_cumulative, "%s", + (char *)gf_fop_list[i]); + + gf_proc_dump_write(key, "%" PRId64 ",%" PRId64 ",%.03f,%.03f,%.03f", + count, total, min, max, avg); + + count = GF_ATOMIC_GET(conf->incremental.fop_hits[i]); + total = conf->incremental.latency[i].total; + min = conf->incremental.latency[i].min; + max = conf->incremental.latency[i].max; + avg = conf->incremental.latency[i].avg; + + gf_proc_dump_build_key(key, key_prefix_incremental, "%s", + (char *)gf_fop_list[i]); + + gf_proc_dump_write(key, "%" PRId64 ",%" PRId64 ",%.03f,%.03f,%.03f", + count, total, min, max, avg); + } + + return 0; } +static void +ios_set_log_format_code(struct ios_conf *conf, char *dump_format_str) +{ + if (strcmp(dump_format_str, "json") == 0) + conf->dump_format = IOS_DUMP_TYPE_JSON_FILE; + else if (strcmp(dump_format_str, "text") == 0) + conf->dump_format = IOS_DUMP_TYPE_FILE; + else if (strcmp(dump_format_str, "dict") == 0) + conf->dump_format = IOS_DUMP_TYPE_DICT; + else if (strcmp(dump_format_str, "samples") == 0) + conf->dump_format = IOS_DUMP_TYPE_SAMPLES; +} -int -init (xlator_t *this) +void +xlator_set_loglevel(xlator_t *this, int log_level) { - dict_t *options = NULL; - struct ios_conf *conf = NULL; - char *str = NULL; - int ret = 0; + glusterfs_ctx_t *ctx = NULL; + glusterfs_graph_t *active = NULL; + xlator_t *top = NULL; + xlator_t *trav = this; + + ctx = this->ctx; + GF_ASSERT(ctx); + active = ctx->active; + top = active->first; + + if (log_level == -1) + return; + + if (ctx->cmd_args.brick_mux) { + /* Set log-level for all brick xlators */ + top->loglevel = log_level; - if (!this) - return -1; + /* Set log-level for parent xlator */ + if (this->parents) + this->parents->xlator->loglevel = log_level; - if (!this->children || this->children->next) { - gf_log (this->name, GF_LOG_ERROR, - "io_stats translator requires one subvolume"); - return -1; + while (trav) { + trav->loglevel = log_level; + trav = trav->next; } + } else { + gf_log_set_loglevel(this->ctx, log_level); + } +} - if (!this->parents) { - gf_log (this->name, GF_LOG_WARNING, - "dangling volume. check volfile "); +int +reconfigure(xlator_t *this, dict_t *options) +{ + struct ios_conf *conf = NULL; + int ret = -1; + char *sys_log_str = NULL; + char *log_format_str = NULL; + char *logger_str = NULL; + char *dump_format_str = NULL; + int sys_log_level = -1; + char *log_str = NULL; + int log_level = -1; + int log_format = -1; + int logger = -1; + uint32_t log_buf_size = 0; + uint32_t log_flush_timeout = 0; + int32_t old_dump_interval; + int32_t threads; + + if (!this || !this->private) + goto out; + + conf = this->private; + + GF_OPTION_RECONF("dump-fd-stats", conf->dump_fd_stats, options, bool, out); + + GF_OPTION_RECONF("count-fop-hits", conf->count_fop_hits, options, bool, + out); + + GF_OPTION_RECONF("latency-measurement", conf->measure_latency, options, + bool, out); + + old_dump_interval = conf->ios_dump_interval; + GF_OPTION_RECONF("ios-dump-interval", conf->ios_dump_interval, options, + int32, out); + if ((old_dump_interval <= 0) && (conf->ios_dump_interval > 0)) { + conf->dump_thread_running = _gf_true; + conf->dump_thread_should_die = _gf_false; + ret = gf_thread_create(&conf->dump_thread, NULL, + (void *)&_ios_dump_thread, this, "iosdump"); + if (ret) { + conf->dump_thread_running = _gf_false; + gf_log(this ? this->name : "io-stats", GF_LOG_ERROR, + "Failed to start thread" + "while reconfigure. Returning %d", + ret); + goto out; } + } else if ((old_dump_interval > 0) && (conf->ios_dump_interval == 0)) { + _ios_destroy_dump_thread(conf); + } + + GF_OPTION_RECONF("ios-sample-interval", conf->ios_sample_interval, options, + int32, out); + GF_OPTION_RECONF("ios-dump-format", dump_format_str, options, str, out); + ios_set_log_format_code(conf, dump_format_str); + GF_OPTION_RECONF("ios-sample-buf-size", conf->ios_sample_buf_size, options, + int32, out); + GF_OPTION_RECONF("sys-log-level", sys_log_str, options, str, out); + if (sys_log_str) { + sys_log_level = glusterd_check_log_level(sys_log_str); + set_sys_log_level(sys_log_level); + } + + GF_OPTION_RECONF("log-level", log_str, options, str, out); + if (log_str) { + log_level = glusterd_check_log_level(log_str); + /* Set loglevel for all children and server xlators */ + xlator_set_loglevel(this, log_level); + } + + GF_OPTION_RECONF("logger", logger_str, options, str, out); + if (logger_str) { + logger = gf_check_logger(logger_str); + gf_log_set_logger(logger); + } + + GF_OPTION_RECONF("log-format", log_format_str, options, str, out); + if (log_format_str) { + log_format = gf_check_log_format(log_format_str); + gf_log_set_logformat(log_format); + } + + GF_OPTION_RECONF("log-buf-size", log_buf_size, options, uint32, out); + gf_log_set_log_buf_size(log_buf_size); + + GF_OPTION_RECONF("log-flush-timeout", log_flush_timeout, options, time, + out); + gf_log_set_log_flush_timeout(log_flush_timeout); + + GF_OPTION_RECONF("threads", threads, options, int32, out); + gf_async_adjust_threads(threads); + + ret = 0; +out: + gf_log(this ? this->name : "io-stats", GF_LOG_DEBUG, + "reconfigure returning %d", ret); + return ret; +} - options = this->options; +int32_t +mem_acct_init(xlator_t *this) +{ + int ret = -1; - conf = CALLOC (1, sizeof(*conf)); + if (!this) + return ret; - LOCK_INIT (&conf->lock); + ret = xlator_mem_acct_init(this, gf_io_stats_mt_end + 1); - gettimeofday (&conf->cumulative.started_at, NULL); - gettimeofday (&conf->incremental.started_at, NULL); + if (ret != 0) { + gf_log(this->name, GF_LOG_ERROR, + "Memory accounting init" + " failed"); + return ret; + } - ret = dict_get_str (options, "dump-fd-stats", &str); - if (ret == 0) { - ret = gf_string2boolean (str, &conf->dump_fd_stats); - if (ret == -1) { - gf_log (this->name, GF_LOG_ERROR, - "'dump-fd-stats' takes only boolean arguments"); - return -1; - } + return ret; +} - if (conf->dump_fd_stats) { - gf_log (this->name, GF_LOG_DEBUG, - "enabling dump-fd-stats"); - } - } +void +ios_conf_destroy(struct ios_conf *conf) +{ + if (!conf) + return; - this->private = conf; + ios_destroy_top_stats(conf); + _ios_destroy_dump_thread(conf); + ios_destroy_sample_buf(conf->ios_sample_buf); + LOCK_DESTROY(&conf->lock); + gf_dnscache_deinit(conf->dnscache); + GF_FREE(conf); +} - return 0; +static void +ios_init_stats(struct ios_global_stats *stats) +{ + int i = 0; + + GF_ATOMIC_INIT(stats->data_read, 0); + GF_ATOMIC_INIT(stats->data_written, 0); + + for (i = 0; i < IOS_BLOCK_COUNT_SIZE; i++) { + GF_ATOMIC_INIT(stats->block_count_write[i], 0); + GF_ATOMIC_INIT(stats->block_count_read[i], 0); + } + + for (i = 0; i < GF_FOP_MAXVALUE; i++) + GF_ATOMIC_INIT(stats->fop_hits[i], 0); + + for (i = 0; i < GF_UPCALL_FLAGS_MAXVALUE; i++) + GF_ATOMIC_INIT(stats->upcall_hits[i], 0); + + stats->started_at = gf_time(); } +int +init(xlator_t *this) +{ + struct ios_conf *conf = NULL; + char *volume_id = NULL; + char *sys_log_str = NULL; + char *logger_str = NULL; + char *log_format_str = NULL; + char *dump_format_str = NULL; + int logger = -1; + int log_format = -1; + int sys_log_level = -1; + char *log_str = NULL; + int log_level = -1; + int ret = -1; + uint32_t log_buf_size = 0; + uint32_t log_flush_timeout = 0; + int32_t threads; + + if (!this) + return -1; + + if (!this->children) { + gf_log(this->name, GF_LOG_ERROR, + "io_stats translator requires at least one subvolume"); + return -1; + } + + if (!this->parents) { + /* This is very much valid as io-stats currently is loaded + * on top of volumes on both client and server, hence this is + * not an warning message */ + gf_log(this->name, GF_LOG_DEBUG, "dangling volume. check volfile "); + } + + conf = GF_CALLOC(1, sizeof(*conf), gf_io_stats_mt_ios_conf); + + if (!conf) + goto out; + + if (dict_get_str(this->options, "unique-id", &conf->unique_id) != 0) { + /* This is always set on servers, so we must be a client. */ + conf->unique_id = this->name; + } + + ret = dict_get_strn(this->options, "volume-id", SLEN("volume-id"), + &volume_id); + if (!ret) { + strncpy(this->graph->volume_id, volume_id, GF_UUID_BUF_SIZE); + } + /* + * Init it just after calloc, so that we are sure the lock is inited + * in case of error paths. + */ + LOCK_INIT(&conf->lock); + LOCK_INIT(&conf->ios_sampling_lock); + + ios_init_stats(&conf->cumulative); + ios_init_stats(&conf->incremental); + + ret = ios_init_top_stats(conf); + if (ret) + goto out; + + GF_OPTION_INIT("dump-fd-stats", conf->dump_fd_stats, bool, out); + + GF_OPTION_INIT("count-fop-hits", conf->count_fop_hits, bool, out); + + GF_OPTION_INIT("latency-measurement", conf->measure_latency, bool, out); + + GF_OPTION_INIT("ios-dump-interval", conf->ios_dump_interval, int32, out); + + GF_OPTION_INIT("ios-sample-interval", conf->ios_sample_interval, int32, + out); + + GF_OPTION_INIT("ios-dump-format", dump_format_str, str, out); + ios_set_log_format_code(conf, dump_format_str); + + GF_OPTION_INIT("ios-sample-buf-size", conf->ios_sample_buf_size, int32, + out); + + ret = ios_init_sample_buf(conf); + if (ret) { + gf_log(this->name, GF_LOG_ERROR, "Out of memory."); + goto out; + } + + GF_OPTION_INIT("ios-dnscache-ttl-sec", conf->ios_dnscache_ttl_sec, int32, + out); + conf->dnscache = gf_dnscache_init(conf->ios_dnscache_ttl_sec); + if (!conf->dnscache) { + ret = -1; + goto out; + } + + GF_OPTION_INIT("sys-log-level", sys_log_str, str, out); + if (sys_log_str) { + sys_log_level = glusterd_check_log_level(sys_log_str); + set_sys_log_level(sys_log_level); + } + + GF_OPTION_INIT("log-level", log_str, str, out); + if (log_str) { + log_level = glusterd_check_log_level(log_str); + if (DEFAULT_LOG_LEVEL != log_level) + gf_log_set_loglevel(this->ctx, log_level); + } + + GF_OPTION_INIT("logger", logger_str, str, out); + if (logger_str) { + logger = gf_check_logger(logger_str); + gf_log_set_logger(logger); + } + + GF_OPTION_INIT("log-format", log_format_str, str, out); + if (log_format_str) { + log_format = gf_check_log_format(log_format_str); + gf_log_set_logformat(log_format); + } + + GF_OPTION_INIT("log-buf-size", log_buf_size, uint32, out); + gf_log_set_log_buf_size(log_buf_size); + + GF_OPTION_INIT("log-flush-timeout", log_flush_timeout, time, out); + gf_log_set_log_flush_timeout(log_flush_timeout); + + GF_OPTION_INIT("threads", threads, int32, out); + gf_async_adjust_threads(threads); + + this->private = conf; + if (conf->ios_dump_interval > 0) { + conf->dump_thread_running = _gf_true; + conf->dump_thread_should_die = _gf_false; + ret = gf_thread_create(&conf->dump_thread, NULL, + (void *)&_ios_dump_thread, this, "iosdump"); + if (ret) { + conf->dump_thread_running = _gf_false; + gf_log(this ? this->name : "io-stats", GF_LOG_ERROR, + "Failed to start thread" + "in init. Returning %d", + ret); + goto out; + } + } + return 0; +out: + ios_conf_destroy(conf); + return ret; +} void -fini (xlator_t *this) +fini(xlator_t *this) { - struct ios_conf *conf = NULL; + struct ios_conf *conf = NULL; - if (!this) - return; + if (!this) + return; - conf = this->private; + conf = this->private; - gf_log (this->name, GF_LOG_NORMAL, - "io-stats translator unloaded"); - return; + ios_conf_destroy(conf); + this->private = NULL; + gf_log(this->name, GF_LOG_INFO, "io-stats translator unloaded"); + return; +} + +int +notify(xlator_t *this, int32_t event, void *data, ...) +{ + int ret = 0; + struct ios_dump_args args = {0}; + dict_t *output = NULL; + dict_t *dict = NULL; + int32_t op = 0; + int32_t list_cnt = 0; + double throughput = 0; + double time = 0; + gf_boolean_t is_peek = _gf_false; + va_list ap; + struct gf_upcall *up_data = NULL; + struct gf_upcall_cache_invalidation *up_ci = NULL; + + dict = data; + va_start(ap, data); + output = va_arg(ap, dict_t *); + va_end(ap); + switch (event) { + case GF_EVENT_TRANSLATOR_INFO: + ret = dict_get_str_boolean(dict, "clear-stats", _gf_false); + if (ret) { + ret = dict_set_int32(output, "top-op", op); + if (ret) { + gf_log(this->name, GF_LOG_ERROR, + "Failed to set top-op in dict"); + goto out; + } + ios_destroy_top_stats(this->private); + ret = ios_init_top_stats(this->private); + if (ret) + gf_log(this->name, GF_LOG_ERROR, + "Failed to reset top stats"); + ret = dict_set_int32(output, "stats-cleared", ret ? 0 : 1); + if (ret) + gf_log(this->name, GF_LOG_ERROR, + "Failed to set stats-cleared" + " in dict"); + goto out; + } + + ret = dict_get_int32(dict, "top-op", &op); + if (!ret) { + ret = dict_get_int32(dict, "list-cnt", &list_cnt); + if (op > IOS_STATS_TYPE_NONE && op < IOS_STATS_TYPE_MAX) + ret = io_stats_dump_stats_to_dict(this, output, op, + list_cnt); + if (op == IOS_STATS_TYPE_READ_THROUGHPUT || + op == IOS_STATS_TYPE_WRITE_THROUGHPUT) { + ret = dict_get_double(dict, "throughput", &throughput); + if (!ret) { + ret = dict_get_double(dict, "time", &time); + if (ret) + goto out; + ret = dict_set_double(output, "throughput", throughput); + if (ret) + goto out; + ret = dict_set_double(output, "time", time); + if (ret) + goto out; + } + ret = 0; + } + } else { + ret = dict_get_int32(dict, "info-op", &op); + if (ret || op < GF_IOS_INFO_ALL || GF_IOS_INFO_CLEAR < op) + op = GF_IOS_INFO_ALL; + + ret = dict_set_int32(output, "info-op", op); + if (ret) { + gf_log(this->name, GF_LOG_ERROR, + "Failed to set info-op in dict"); + goto out; + } + + if (GF_IOS_INFO_CLEAR == op) { + io_stats_clear(this->private); + + ret = dict_set_int32(output, "stats-cleared", 1); + if (ret) + gf_log(this->name, GF_LOG_ERROR, + "Failed to set stats-cleared" + " in dict"); + } else { + ret = dict_get_str_boolean(dict, "peek", _gf_false); + if (-1 != ret) + is_peek = ret; + + (void)ios_dump_args_init(&args, IOS_DUMP_TYPE_DICT, output); + ret = io_stats_dump(this, &args, op, is_peek); + } + } + break; + case GF_EVENT_UPCALL: + up_data = (struct gf_upcall *)data; + ios_bump_upcall(this, GF_UPCALL); + + switch (up_data->event_type) { + case GF_UPCALL_RECALL_LEASE: + ios_bump_upcall(this, GF_UPCALL_LEASE_RECALL); + break; + case GF_UPCALL_CACHE_INVALIDATION: + up_ci = (struct gf_upcall_cache_invalidation *) + up_data->data; + if (up_ci->flags & (UP_XATTR | UP_XATTR_RM)) + ios_bump_upcall(this, GF_UPCALL_CI_XATTR); + if (up_ci->flags & IATT_UPDATE_FLAGS) + ios_bump_upcall(this, GF_UPCALL_CI_STAT); + if (up_ci->flags & UP_RENAME_FLAGS) + ios_bump_upcall(this, GF_UPCALL_CI_RENAME); + if (up_ci->flags & UP_FORGET) + ios_bump_upcall(this, GF_UPCALL_CI_FORGET); + if (up_ci->flags & UP_NLINK) + ios_bump_upcall(this, GF_UPCALL_CI_NLINK); + break; + default: + gf_msg_debug(this->name, 0, + "Unknown upcall event " + "type :%d", + up_data->event_type); + break; + } + + default_notify(this, event, data); + break; + default: + default_notify(this, event, data); + break; + } +out: + return ret; } +struct xlator_dumpops dumpops = {.priv = io_priv}; struct xlator_fops fops = { - .stat = io_stats_stat, - .readlink = io_stats_readlink, - .mknod = io_stats_mknod, - .mkdir = io_stats_mkdir, - .unlink = io_stats_unlink, - .rmdir = io_stats_rmdir, - .symlink = io_stats_symlink, - .rename = io_stats_rename, - .link = io_stats_link, - .truncate = io_stats_truncate, - .open = io_stats_open, - .readv = io_stats_readv, - .writev = io_stats_writev, - .statfs = io_stats_statfs, - .flush = io_stats_flush, - .fsync = io_stats_fsync, - .setxattr = io_stats_setxattr, - .getxattr = io_stats_getxattr, - .removexattr = io_stats_removexattr, - .opendir = io_stats_opendir, - .readdir = io_stats_readdir, - .readdirp = io_stats_readdirp, - .fsyncdir = io_stats_fsyncdir, - .access = io_stats_access, - .ftruncate = io_stats_ftruncate, - .fstat = io_stats_fstat, - .create = io_stats_create, - .lk = io_stats_lk, - .inodelk = io_stats_inodelk, - .finodelk = io_stats_finodelk, - .entrylk = io_stats_entrylk, - .lookup = io_stats_lookup, - .setdents = io_stats_setdents, - .getdents = io_stats_getdents, - .checksum = io_stats_checksum, - .xattrop = io_stats_xattrop, - .fxattrop = io_stats_fxattrop, - .setattr = io_stats_setattr, - .fsetattr = io_stats_fsetattr, -}; - -struct xlator_mops mops = { - .stats = io_stats_stats, + .stat = io_stats_stat, + .readlink = io_stats_readlink, + .mknod = io_stats_mknod, + .mkdir = io_stats_mkdir, + .unlink = io_stats_unlink, + .rmdir = io_stats_rmdir, + .symlink = io_stats_symlink, + .rename = io_stats_rename, + .link = io_stats_link, + .truncate = io_stats_truncate, + .open = io_stats_open, + .readv = io_stats_readv, + .writev = io_stats_writev, + .statfs = io_stats_statfs, + .flush = io_stats_flush, + .fsync = io_stats_fsync, + .setxattr = io_stats_setxattr, + .getxattr = io_stats_getxattr, + .removexattr = io_stats_removexattr, + .fsetxattr = io_stats_fsetxattr, + .fgetxattr = io_stats_fgetxattr, + .fremovexattr = io_stats_fremovexattr, + .opendir = io_stats_opendir, + .readdir = io_stats_readdir, + .readdirp = io_stats_readdirp, + .fsyncdir = io_stats_fsyncdir, + .access = io_stats_access, + .ftruncate = io_stats_ftruncate, + .fstat = io_stats_fstat, + .create = io_stats_create, + .lk = io_stats_lk, + .inodelk = io_stats_inodelk, + .finodelk = io_stats_finodelk, + .entrylk = io_stats_entrylk, + .fentrylk = io_stats_fentrylk, + .lookup = io_stats_lookup, + .xattrop = io_stats_xattrop, + .fxattrop = io_stats_fxattrop, + .setattr = io_stats_setattr, + .fsetattr = io_stats_fsetattr, + .fallocate = io_stats_fallocate, + .discard = io_stats_discard, + .zerofill = io_stats_zerofill, + .ipc = io_stats_ipc, + .rchecksum = io_stats_rchecksum, + .seek = io_stats_seek, + .lease = io_stats_lease, + .getactivelk = io_stats_getactivelk, + .setactivelk = io_stats_setactivelk, + .compound = io_stats_compound, + .copy_file_range = io_stats_copy_file_range, }; struct xlator_cbks cbks = { - .release = io_stats_release, - .releasedir = io_stats_releasedir, + .release = io_stats_release, + .releasedir = io_stats_releasedir, + .forget = io_stats_forget, }; struct volume_options options[] = { - { .key = {"dump-fd-stats"}, - .type = GF_OPTION_TYPE_BOOL, - }, - { .key = {NULL} }, + {.key = {"dump-fd-stats"}, + .op_version = {1}, + .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC, + .tags = {"io-stats"}, + .type = GF_OPTION_TYPE_BOOL, + .default_value = "off", + .description = "If on stats related to file-operations would be " + "tracked inside GlusterFS data-structures."}, + {.key = {"ios-dump-interval"}, + .type = GF_OPTION_TYPE_INT, + .op_version = {1}, + .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC, + .tags = {"io-stats"}, + .min = 0, + .max = 3600, + .default_value = "0", + .description = "Interval (in seconds) at which to auto-dump " + "statistics. Zero disables automatic dumping."}, + {.key = {"ios-sample-interval"}, + .type = GF_OPTION_TYPE_INT, + .op_version = {1}, + .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC, + .tags = {"io-stats"}, + .min = 0, + .max = 65535, + .default_value = "0", + .description = "Interval in which we want to collect FOP latency " + "samples. 2 means collect a sample every 2nd FOP."}, + {.key = {"ios-dump-format"}, + .type = GF_OPTION_TYPE_STR, + .op_version = {GD_OP_VERSION_3_12_0}, + .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC, + .tags = {"io-stats"}, + .default_value = "json", + .description = " The dump-format option specifies the format in which" + " to dump the statistics. Select between \"text\", " + "\"json\", \"dict\" and \"samples\". Default is " + "\"json\".", + .value = {"text", "json", "dict", "samples"}}, + {.key = {"ios-sample-buf-size"}, + .type = GF_OPTION_TYPE_INT, + .op_version = {1}, + .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC, + .tags = {"io-stats"}, + .min = 1024, + .max = 1024 * 1024, + .default_value = "65535", + .description = "The maximum size of our FOP sampling ring buffer."}, + {.key = {"ios-dnscache-ttl-sec"}, + .type = GF_OPTION_TYPE_INT, + .op_version = {1}, + .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC, + .tags = {"io-stats"}, + .min = 1, + .max = 3600 * 72, + .default_value = "86400", + .description = "The interval after wish a cached DNS entry will be " + "re-validated. Default: 24 hrs"}, + {.key = {"latency-measurement"}, + .type = GF_OPTION_TYPE_BOOL, + .op_version = {1}, + .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC, + .tags = {"io-stats"}, + .default_value = "off", + .description = "If on stats related to the latency of each operation " + "would be tracked inside GlusterFS data-structures. "}, + { + .key = {"count-fop-hits"}, + .type = GF_OPTION_TYPE_BOOL, + .op_version = {1}, + .flags = OPT_FLAG_SETTABLE, + .tags = {"io-stats"}, + }, + {.key = {"log-level"}, + .type = GF_OPTION_TYPE_STR, + .value = {"DEBUG", "WARNING", "ERROR", "INFO", "CRITICAL", "NONE", + "TRACE"}}, + + /* These are synthetic entries to assist validation of CLI's * + * volume set command */ + {.key = {"client-log-level"}, + .type = GF_OPTION_TYPE_STR, + .op_version = {1}, + .flags = OPT_FLAG_SETTABLE | OPT_FLAG_CLIENT_OPT | OPT_FLAG_DOC, + .tags = {"io-stats"}, + .default_value = "INFO", + .description = "Changes the log-level of the clients", + .value = {"DEBUG", "WARNING", "ERROR", "INFO", "CRITICAL", "NONE", + "TRACE"}}, + {.key = {"sys-log-level"}, + .type = GF_OPTION_TYPE_STR, + .default_value = "CRITICAL", + .description = "Gluster's syslog log-level", + .value = {"WARNING", "ERROR", "INFO", "CRITICAL"}}, + {.key = {"brick-log-level"}, + .type = GF_OPTION_TYPE_STR, + .op_version = {1}, + .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC, + .tags = {"io-stats"}, + .default_value = "INFO", + .description = "Changes the log-level of the bricks", + .value = {"DEBUG", "WARNING", "ERROR", "INFO", "CRITICAL", "NONE", + "TRACE"}}, + {.key = {"logger"}, + .type = GF_OPTION_TYPE_STR, + .value = {GF_LOGGER_GLUSTER_LOG, GF_LOGGER_SYSLOG}}, + {.key = {"client-logger"}, + .type = GF_OPTION_TYPE_STR, + .op_version = {GD_OP_VERSION_3_6_0}, + .flags = OPT_FLAG_SETTABLE | OPT_FLAG_CLIENT_OPT | OPT_FLAG_DOC, + .tags = {"io-stats"}, + .default_value = GF_LOGGER_GLUSTER_LOG, + .description = "Changes the logging sub-system to log to, for the " + "clients", + .value = {GF_LOGGER_GLUSTER_LOG, GF_LOGGER_SYSLOG}}, + {.key = {"brick-logger"}, + .type = GF_OPTION_TYPE_STR, + .op_version = {GD_OP_VERSION_3_6_0}, + .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC, + .tags = {"io-stats"}, + .default_value = GF_LOGGER_GLUSTER_LOG, + .description = "Changes the logging sub-system to log to, for the " + "bricks", + .value = {GF_LOGGER_GLUSTER_LOG, GF_LOGGER_SYSLOG}}, + {.key = {"log-format"}, + .type = GF_OPTION_TYPE_STR, + .value = {GF_LOG_FORMAT_NO_MSG_ID, GF_LOG_FORMAT_WITH_MSG_ID}}, + {.key = {"client-log-format"}, + .type = GF_OPTION_TYPE_STR, + .op_version = {GD_OP_VERSION_3_6_0}, + .flags = OPT_FLAG_SETTABLE | OPT_FLAG_CLIENT_OPT | OPT_FLAG_DOC, + .tags = {"io-stats"}, + .default_value = GF_LOG_FORMAT_WITH_MSG_ID, + .description = "Changes log format for the clients", + .value = {GF_LOG_FORMAT_NO_MSG_ID, GF_LOG_FORMAT_WITH_MSG_ID}}, + {.key = {"brick-log-format"}, + .type = GF_OPTION_TYPE_STR, + .op_version = {GD_OP_VERSION_3_6_0}, + .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC, + .tags = {"io-stats"}, + .default_value = GF_LOG_FORMAT_WITH_MSG_ID, + .description = "Changes the log format for the bricks", + .value = {GF_LOG_FORMAT_NO_MSG_ID, GF_LOG_FORMAT_WITH_MSG_ID}}, + { + .key = {"log-buf-size"}, + .type = GF_OPTION_TYPE_INT, + .min = GF_LOG_LRU_BUFSIZE_MIN, + .max = GF_LOG_LRU_BUFSIZE_MAX, + .default_value = "5", + }, + {.key = {"client-log-buf-size"}, + .type = GF_OPTION_TYPE_INT, + .op_version = {GD_OP_VERSION_3_6_0}, + .flags = OPT_FLAG_SETTABLE | OPT_FLAG_CLIENT_OPT | OPT_FLAG_DOC, + .tags = {"io-stats"}, + .min = GF_LOG_LRU_BUFSIZE_MIN, + .max = GF_LOG_LRU_BUFSIZE_MAX, + .default_value = "5", + .description = "This option determines the maximum number of unique " + "log messages that can be buffered for a time equal to" + " the value of the option client-log-flush-timeout."}, + {.key = {"brick-log-buf-size"}, + .type = GF_OPTION_TYPE_INT, + .op_version = {GD_OP_VERSION_3_6_0}, + .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC, + .tags = {"io-stats"}, + .min = GF_LOG_LRU_BUFSIZE_MIN, + .max = GF_LOG_LRU_BUFSIZE_MAX, + .default_value = "5", + .description = "This option determines the maximum number of unique " + "log messages that can be buffered for a time equal to" + " the value of the option brick-log-flush-timeout."}, + { + .key = {"log-flush-timeout"}, + .type = GF_OPTION_TYPE_TIME, + .min = GF_LOG_FLUSH_TIMEOUT_MIN, + .max = GF_LOG_FLUSH_TIMEOUT_MAX, + .default_value = "120", + }, + {.key = {"client-log-flush-timeout"}, + .type = GF_OPTION_TYPE_TIME, + .op_version = {GD_OP_VERSION_3_6_0}, + .flags = OPT_FLAG_SETTABLE | OPT_FLAG_CLIENT_OPT | OPT_FLAG_DOC, + .tags = {"io-stats"}, + .min = GF_LOG_FLUSH_TIMEOUT_MIN, + .max = GF_LOG_FLUSH_TIMEOUT_MAX, + .default_value = "120", + .description = "This option determines the maximum number of unique " + "log messages that can be buffered for a time equal to" + " the value of the option client-log-flush-timeout."}, + {.key = {"brick-log-flush-timeout"}, + .type = GF_OPTION_TYPE_TIME, + .op_version = {GD_OP_VERSION_3_6_0}, + .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC, + .tags = {"io-stats"}, + .min = GF_LOG_FLUSH_TIMEOUT_MIN, + .max = GF_LOG_FLUSH_TIMEOUT_MAX, + .default_value = "120", + .description = "This option determines the maximum number of unique " + "log messages that can be buffered for a time equal to" + " the value of the option brick-log-flush-timeout."}, + {.key = {"unique-id"}, + .type = GF_OPTION_TYPE_STR, + .default_value = "/no/such/path", + .description = "Unique ID for our files."}, + {.key = {"global-threading"}, + .type = GF_OPTION_TYPE_BOOL, + .default_value = "off", + .op_version = {GD_OP_VERSION_6_0}, + .flags = OPT_FLAG_SETTABLE, + .tags = {"io-stats", "threading"}, + .description = "This option enables the global threading support for " + "bricks. If enabled, it's recommended to also enable " + "'performance.iot-pass-through'"}, + {.key = {"threads"}, .type = GF_OPTION_TYPE_INT}, + {.key = {"brick-threads"}, + .type = GF_OPTION_TYPE_INT, + .default_value = "16", + .min = 0, + .max = GF_ASYNC_MAX_THREADS, + .op_version = {GD_OP_VERSION_6_0}, + .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC, + .tags = {"io-stats", "threading"}, + .description = "When global threading is used, this value determines the " + "maximum amount of threads that can be created on bricks"}, + {.key = {"client-threads"}, + .type = GF_OPTION_TYPE_INT, + .default_value = "16", + .min = 0, + .max = GF_ASYNC_MAX_THREADS, + .op_version = {GD_OP_VERSION_6_0}, + .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC | OPT_FLAG_CLIENT_OPT, + .tags = {"io-stats", "threading"}, + .description = "When global threading is used, this value determines the " + "maximum amount of threads that can be created on clients"}, + {.key = {"volume-id"}, + .type = GF_OPTION_TYPE_STR, + .op_version = {GD_OP_VERSION_7_1}, + .tags = {"global", "volume-id"}, + .description = + "This option points to the 'unique' UUID particular to this " + "volume, which would be set in 'graph->volume_id'"}, + {.key = {NULL}}, +}; + +xlator_api_t xlator_api = { + .init = init, + .fini = fini, + .notify = notify, + .reconfigure = reconfigure, + .mem_acct_init = mem_acct_init, + .op_version = {1}, /* Present from the initial version */ + .dumpops = &dumpops, + .fops = &fops, + .cbks = &cbks, + .options = options, + .identifier = "io-stats", + .category = GF_MAINTAINED, }; diff --git a/xlators/debug/sink/Makefile.am b/xlators/debug/sink/Makefile.am new file mode 100644 index 00000000000..f2689244371 --- /dev/null +++ b/xlators/debug/sink/Makefile.am @@ -0,0 +1,2 @@ +SUBDIRS = src + diff --git a/xlators/debug/sink/src/Makefile.am b/xlators/debug/sink/src/Makefile.am new file mode 100644 index 00000000000..f952c2ce6bc --- /dev/null +++ b/xlators/debug/sink/src/Makefile.am @@ -0,0 +1,14 @@ +xlator_LTLIBRARIES = sink.la +xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/debug + +AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ + -I$(top_builddir)/rpc/xdr/src +AM_CFLAGS = -Wall $(GF_CFLAGS) + +sink_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) + +sink_la_SOURCES = sink.c +sink_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la + +CLEANFILES = + diff --git a/xlators/debug/sink/src/sink.c b/xlators/debug/sink/src/sink.c new file mode 100644 index 00000000000..9822bbb732e --- /dev/null +++ b/xlators/debug/sink/src/sink.c @@ -0,0 +1,94 @@ +/* + Copyright (c) 2017 Red Hat, Inc. <http://www.redhat.com> + This file is part of GlusterFS. + + This file is licensed to you under your choice of the GNU Lesser + General Public License, version 3 or any later version (LGPLv3 or + later), or the GNU General Public License, version 2 (GPLv2), in all + cases as published by the Free Software Foundation. +*/ + +#include <glusterfs/xlator.h> +#include <glusterfs/defaults.h> + +int32_t +init(xlator_t *this) +{ + return 0; +} + +void +fini(xlator_t *this) +{ + return; +} + +/* + * notify - when parent sends PARENT_UP, send CHILD_UP event from here + */ +int32_t +notify(xlator_t *this, int32_t event, void *data, ...) +{ + switch (event) { + case GF_EVENT_PARENT_UP: + /* Tell the parent that this xlator is up */ + default_notify(this, GF_EVENT_CHILD_UP, data); + break; + case GF_EVENT_PARENT_DOWN: + /* Tell the parent that this xlator is down */ + default_notify(this, GF_EVENT_CHILD_DOWN, data); + break; + default: + break; + } + + return 0; +} + +/* + * A lookup on "/" is done while mounting or glfs_init() is performed. This + * needs to return a valid directory for the root of the mountpoint. + * + * In case this xlator is used for more advanced debugging, it will need to be + * extended to support different LOOKUPs too. + */ +static int32_t +sink_lookup(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) +{ + struct iatt stbuf = { + 0, + }; + struct iatt postparent = { + 0, + }; + + /* the root of the volume always need to be a directory */ + stbuf.ia_type = IA_IFDIR; + + STACK_UNWIND_STRICT(lookup, frame, 0, 0, loc ? loc->inode : NULL, &stbuf, + xdata, &postparent); + + return 0; +} + +struct xlator_fops fops = { + .lookup = sink_lookup, +}; + +struct xlator_cbks cbks = {}; + +struct volume_options options[] = { + {.key = {NULL}}, +}; + +xlator_api_t xlator_api = { + .init = init, + .fini = fini, + .notify = notify, + .op_version = {GD_OP_VERSION_3_12_0}, + .fops = &fops, + .cbks = &cbks, + .options = options, + .identifier = "sink", + .category = GF_TECH_PREVIEW, +}; diff --git a/xlators/debug/trace/src/Makefile.am b/xlators/debug/trace/src/Makefile.am index 0f1679a049d..a37ea63af04 100644 --- a/xlators/debug/trace/src/Makefile.am +++ b/xlators/debug/trace/src/Makefile.am @@ -2,13 +2,16 @@ xlator_LTLIBRARIES = trace.la xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/debug -trace_la_LDFLAGS = -module -avoidversion +trace_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) trace_la_SOURCES = trace.c trace_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la -AM_CFLAGS = -fPIC -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -Wall -D$(GF_HOST_OS)\ - -I$(top_srcdir)/libglusterfs/src -shared -nostartfiles $(GF_CFLAGS) +noinst_HEADERS = trace.h trace-mem-types.h +AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ + -I$(top_srcdir)/rpc/xdr/src -I$(top_builddir)/rpc/xdr/src + +AM_CFLAGS = -Wall $(GF_CFLAGS) CLEANFILES = diff --git a/xlators/debug/trace/src/trace-mem-types.h b/xlators/debug/trace/src/trace-mem-types.h new file mode 100644 index 00000000000..18a7e0414a6 --- /dev/null +++ b/xlators/debug/trace/src/trace-mem-types.h @@ -0,0 +1,20 @@ +/* + Copyright (c) 2006-2012 Red Hat, Inc. <http://www.redhat.com> + This file is part of GlusterFS. + + This file is licensed to you under your choice of the GNU Lesser + General Public License, version 3 or any later version (LGPLv3 or + later), or the GNU General Public License, version 2 (GPLv2), in all + cases as published by the Free Software Foundation. +*/ + +#ifndef __TRACE_MEM_TYPES_H__ +#define __TRACE_MEM_TYPES_H__ + +#include <glusterfs/mem-types.h> + +enum gf_trace_mem_types_ { + gf_trace_mt_trace_conf_t = gf_common_mt_end + 1, + gf_trace_mt_end +}; +#endif diff --git a/xlators/debug/trace/src/trace.c b/xlators/debug/trace/src/trace.c index 67ebeb13407..6ed0ca00342 100644 --- a/xlators/debug/trace/src/trace.c +++ b/xlators/debug/trace/src/trace.c @@ -1,26 +1,15 @@ /* - Copyright (c) 2006-2009 Gluster, Inc. <http://www.gluster.com> + Copyright (c) 2006-2012 Red Hat, Inc. <http://www.redhat.com> This file is part of GlusterFS. - GlusterFS is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3 of the License, - or (at your option) any later version. - - GlusterFS is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see - <http://www.gnu.org/licenses/>. + This file is licensed to you under your choice of the GNU Lesser + General Public License, version 3 or any later version (LGPLv3 or + later), or the GNU General Public License, version 2 (GPLv2), in all + cases as published by the Free Software Foundation. */ -#ifndef _CONFIG_H -#define _CONFIG_H -#include "config.h" -#endif +#include "trace.h" +#include "trace-mem-types.h" /** * xlators/debug/trace : @@ -28,2142 +17,3518 @@ * their _cbk functions, which later passes the call to next layer. * Very helpful translator for debugging. */ +#define TRACE_STAT_TO_STR(buf, str) trace_stat_to_str(buf, str, sizeof(str)) + +static void +trace_stat_to_str(struct iatt *buf, char *str, size_t len) +{ + char atime_buf[GF_TIMESTR_SIZE] = { + 0, + }; + char mtime_buf[GF_TIMESTR_SIZE] = { + 0, + }; + char ctime_buf[GF_TIMESTR_SIZE] = { + 0, + }; + + if (!buf) + return; -#include <time.h> -#include <errno.h> -#include "glusterfs.h" -#include "xlator.h" -#include "common-utils.h" - -#define ERR_EINVAL_NORETURN(cond) \ - do \ - { \ - if ((cond)) \ - { \ - gf_log ("ERROR", GF_LOG_ERROR, \ - "%s: %s: (%s) is true", \ - __FILE__, __FUNCTION__, #cond); \ - } \ - } while (0) - - -typedef struct trace_private { - int32_t debug_flag; -} trace_private_t; - - -struct { - char *name; - int enabled; -} trace_fop_names[GF_FOP_MAXVALUE]; - - -static char * -trace_stat_to_str (struct stat *stbuf) -{ - char *statstr = NULL; - char atime_buf[256] = {0,}; - char mtime_buf[256] = {0,}; - char ctime_buf[256] = {0,}; - int asprint_ret_value = 0; - - strftime (atime_buf, 256, "[%b %d %H:%M:%S]", - localtime (&stbuf->st_atime)); - strftime (mtime_buf, 256, "[%b %d %H:%M:%S]", - localtime (&stbuf->st_mtime)); - strftime (ctime_buf, 256, "[%b %d %H:%M:%S]", - localtime (&stbuf->st_ctime)); - - asprint_ret_value = asprintf (&statstr, - "st_ino=%"PRIu64", st_mode=%o, st_nlink=%"GF_PRI_NLINK", " - "st_uid=%d, st_gid=%d, st_size=%"PRId64", st_blocks=%"PRId64 - ", st_atime=%s, st_mtime=%s, st_ctime=%s", - stbuf->st_ino, stbuf->st_mode, stbuf->st_nlink, stbuf->st_uid, - stbuf->st_gid, stbuf->st_size, stbuf->st_blocks, atime_buf, - mtime_buf, ctime_buf); - - if (asprint_ret_value < 0) - statstr = NULL; - - return statstr; -} - - -int -trace_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, fd_t *fd, - inode_t *inode, struct stat *buf, - struct stat *preparent, struct stat *postparent) -{ - char *statstr = NULL; - char *preparentstr = NULL; - char *postparentstr = NULL; - - if (trace_fop_names[GF_FOP_CREATE].enabled) { - if (op_ret >= 0) { - statstr = trace_stat_to_str (buf); - preparentstr = trace_stat_to_str (preparent); - postparentstr = trace_stat_to_str (postparent); - - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": (op_ret=%d, fd=%p, ino=%"PRIu64" " - "*stbuf {%s}, *preparent {%s}, *postparent = " - "{%s})", - frame->root->unique, op_ret, fd, inode->ino, - statstr, preparentstr, postparentstr); - - if (statstr) - FREE (statstr); - if (preparentstr) - FREE (preparentstr); - if (postparentstr) - FREE (postparentstr); - } else { - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": (op_ret=%d, op_errno=%d)", - frame->root->unique, op_ret, op_errno); - } - } + gf_time_fmt(atime_buf, sizeof atime_buf, buf->ia_atime, gf_timefmt_dirent); - STACK_UNWIND_STRICT (create, frame, op_ret, op_errno, fd, inode, buf, - preparent, postparent); - return 0; -} + gf_time_fmt(mtime_buf, sizeof mtime_buf, buf->ia_mtime, gf_timefmt_dirent); + gf_time_fmt(ctime_buf, sizeof ctime_buf, buf->ia_ctime, gf_timefmt_dirent); -int -trace_open_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, fd_t *fd) -{ + snprintf(str, len, + "gfid=%s ino=%" PRIu64 + ", mode=%o, " + "nlink=%" GF_PRI_NLINK ", uid=%u, gid=%u, size=%" PRIu64 + ", " + "blocks=%" PRIu64 + ", atime=%s mtime=%s ctime=%s " + "atime_sec=%" PRId64 ", atime_nsec=%" PRIu32 + "," + " mtime_sec=%" PRId64 ", mtime_nsec=%" PRIu32 + ", " + "ctime_sec=%" PRId64 ", ctime_nsec=%" PRIu32 "", + uuid_utoa(buf->ia_gfid), buf->ia_ino, + st_mode_from_ia(buf->ia_prot, buf->ia_type), buf->ia_nlink, + buf->ia_uid, buf->ia_gid, buf->ia_size, buf->ia_blocks, atime_buf, + mtime_buf, ctime_buf, buf->ia_atime, buf->ia_atime_nsec, + buf->ia_mtime, buf->ia_mtime_nsec, buf->ia_ctime, + buf->ia_ctime_nsec); +} + +int +dump_history_trace(circular_buffer_t *cb, void *data) +{ + char timestr[GF_TIMESTR_SIZE] = { + 0, + }; - if (trace_fop_names[GF_FOP_OPEN].enabled) { - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": (op_ret=%d, op_errno=%d, *fd=%p)", - frame->root->unique, op_ret, op_errno, fd); - } + /* Since we are continuing with adding entries to the buffer even when + gettimeofday () fails, it's safe to check tm and then dump the time + at which the entry was added to the buffer */ - STACK_UNWIND_STRICT (open, frame, op_ret, op_errno, fd); - return 0; -} + gf_time_fmt_tv(timestr, sizeof timestr, &cb->tv, gf_timefmt_Ymd_T); + gf_proc_dump_write("TIME", "%s", timestr); + + gf_proc_dump_write("FOP", "%s\n", (char *)cb->data); + return 0; +} int -trace_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, struct stat *buf) -{ - char atime_buf[256]; - char mtime_buf[256]; - char ctime_buf[256]; - - - if (trace_fop_names[GF_FOP_STAT].enabled) { - if (op_ret >= 0) { - strftime (atime_buf, 256, "[%b %d %H:%M:%S]", localtime (&buf->st_atime)); - strftime (mtime_buf, 256, "[%b %d %H:%M:%S]", localtime (&buf->st_mtime)); - strftime (ctime_buf, 256, "[%b %d %H:%M:%S]", localtime (&buf->st_ctime)); - - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": (op_ret=%d, buf {st_dev=%"GF_PRI_DEV", " - "st_ino=%"PRIu64", st_mode=%o, st_nlink=%"GF_PRI_NLINK", " - "st_uid=%d, st_gid=%d, st_rdev=%"GF_PRI_DEV", st_size=%"PRId64 - ", st_blksize=%"GF_PRI_BLKSIZE", st_blocks=%"PRId64", " - "st_atime=%s, st_mtime=%s, st_ctime=%s})", - frame->root->unique, op_ret, buf->st_dev, buf->st_ino, - buf->st_mode, buf->st_nlink, buf->st_uid, buf->st_gid, - buf->st_rdev, buf->st_size, buf->st_blksize, - buf->st_blocks, atime_buf, mtime_buf, ctime_buf); - } else { - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": (op_ret=%d, op_errno=%d)", - frame->root->unique, op_ret, op_errno); - } - } +trace_create_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, fd_t *fd, inode_t *inode, + struct iatt *buf, struct iatt *preparent, + struct iatt *postparent, dict_t *xdata) +{ + char statstr[1024] = { + 0, + }; + char preparentstr[1024] = { + 0, + }; + char postparentstr[1024] = { + 0, + }; + trace_conf_t *conf = NULL; + + conf = this->private; + + if (!conf->log_file && !conf->log_history) + goto out; + if (trace_fop_names[GF_FOP_CREATE].enabled) { + char string[4096] = { + 0, + }; + if (op_ret >= 0) { + TRACE_STAT_TO_STR(buf, statstr); + TRACE_STAT_TO_STR(preparent, preparentstr); + TRACE_STAT_TO_STR(postparent, postparentstr); + + snprintf(string, sizeof(string), + "%" PRId64 + ": gfid=%s (op_ret=%d, fd=%p" + "*stbuf {%s}, *preparent {%s}, " + "*postparent = {%s})", + frame->root->unique, uuid_utoa(inode->gfid), op_ret, fd, + statstr, preparentstr, postparentstr); + + /* for 'release' log */ + fd_ctx_set(fd, this, 0); + } else { + snprintf(string, sizeof(string), + "%" PRId64 ": (op_ret=%d, op_errno=%d)", + frame->root->unique, op_ret, op_errno); + } + LOG_ELEMENT(conf, string); + } +out: + TRACE_STACK_UNWIND(create, frame, op_ret, op_errno, fd, inode, buf, + preparent, postparent, xdata); + return 0; +} + +int +trace_open_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, fd_t *fd, dict_t *xdata) +{ + trace_conf_t *conf = NULL; + + conf = this->private; + + if (!conf->log_file && !conf->log_history) + goto out; + if (trace_fop_names[GF_FOP_OPEN].enabled) { + char string[4096] = { + 0, + }; + snprintf(string, sizeof(string), + "%" PRId64 + ": gfid=%s op_ret=%d, op_errno=%d, " + "*fd=%p", + frame->root->unique, uuid_utoa(frame->local), op_ret, op_errno, + fd); + + LOG_ELEMENT(conf, string); + } + +out: + /* for 'release' log */ + if (op_ret >= 0) + fd_ctx_set(fd, this, 0); + + TRACE_STACK_UNWIND(open, frame, op_ret, op_errno, fd, xdata); + return 0; +} + +int +trace_stat_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, struct iatt *buf, + dict_t *xdata) +{ + char statstr[1024] = { + 0, + }; + trace_conf_t *conf = NULL; + + conf = this->private; + + if (!conf->log_file && !conf->log_history) + goto out; + if (trace_fop_names[GF_FOP_STAT].enabled) { + char string[4096] = { + 0, + }; + if (op_ret == 0) { + TRACE_STAT_TO_STR(buf, statstr); + (void)snprintf( + string, sizeof(string), "%" PRId64 ": gfid=%s op_ret=%d buf=%s", + frame->root->unique, uuid_utoa(frame->local), op_ret, statstr); + } else { + (void)snprintf(string, sizeof(string), + "%" PRId64 + ": gfid=%s op_ret=%d, " + "op_errno=%d)", + frame->root->unique, uuid_utoa(frame->local), op_ret, + op_errno); + } + LOG_ELEMENT(conf, string); + } +out: + TRACE_STACK_UNWIND(stat, frame, op_ret, op_errno, buf, xdata); + return 0; +} + +int +trace_readv_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, struct iovec *vector, + int32_t count, struct iatt *buf, struct iobref *iobref, + dict_t *xdata) +{ + char statstr[1024] = { + 0, + }; + trace_conf_t *conf = NULL; + + conf = this->private; + + if (!conf->log_file && !conf->log_history) + goto out; + if (trace_fop_names[GF_FOP_READ].enabled) { + char string[4096] = { + 0, + }; + if (op_ret >= 0) { + TRACE_STAT_TO_STR(buf, statstr); + snprintf( + string, sizeof(string), "%" PRId64 ": gfid=%s op_ret=%d buf=%s", + frame->root->unique, uuid_utoa(frame->local), op_ret, statstr); + } else { + snprintf(string, sizeof(string), + "%" PRId64 + ": gfid=%s op_ret=%d, " + "op_errno=%d)", + frame->root->unique, uuid_utoa(frame->local), op_ret, + op_errno); + } + LOG_ELEMENT(conf, string); + } +out: + TRACE_STACK_UNWIND(readv, frame, op_ret, op_errno, vector, count, buf, + iobref, xdata); + return 0; +} + +int +trace_writev_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, struct iatt *prebuf, + struct iatt *postbuf, dict_t *xdata) +{ + char preopstr[1024] = { + 0, + }; + char postopstr[1024] = { + 0, + }; + trace_conf_t *conf = NULL; + + conf = this->private; + + if (!conf->log_file && !conf->log_history) + goto out; + if (trace_fop_names[GF_FOP_WRITE].enabled) { + char string[4096] = { + 0, + }; + if (op_ret >= 0) { + TRACE_STAT_TO_STR(prebuf, preopstr); + TRACE_STAT_TO_STR(postbuf, postopstr); + + snprintf(string, sizeof(string), + "%" PRId64 + ": (op_ret=%d, " + "*prebuf = {%s}, *postbuf = {%s})", + frame->root->unique, op_ret, preopstr, postopstr); + } else { + snprintf(string, sizeof(string), + "%" PRId64 + ": gfid=%s op_ret=%d, " + "op_errno=%d", + frame->root->unique, uuid_utoa(frame->local), op_ret, + op_errno); + } + LOG_ELEMENT(conf, string); + } +out: + TRACE_STACK_UNWIND(writev, frame, op_ret, op_errno, prebuf, postbuf, xdata); + return 0; +} + +int +trace_readdir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, gf_dirent_t *buf, + dict_t *xdata) +{ + trace_conf_t *conf = NULL; + + conf = this->private; + + if (!conf->log_file && !conf->log_history) + goto out; + if (trace_fop_names[GF_FOP_READDIR].enabled) { + char string[4096] = { + 0, + }; + snprintf(string, sizeof(string), + "%" PRId64 " : gfid=%s op_ret=%d, op_errno=%d", + frame->root->unique, uuid_utoa(frame->local), op_ret, + op_errno); + + LOG_ELEMENT(conf, string); + } +out: + TRACE_STACK_UNWIND(readdir, frame, op_ret, op_errno, buf, xdata); + + return 0; +} + +int +trace_readdirp_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, gf_dirent_t *buf, + dict_t *xdata) +{ + int count = 0; + char statstr[1024] = { + 0, + }; + char string[4096] = { + 0, + }; + trace_conf_t *conf = NULL; + gf_dirent_t *entry = NULL; + + conf = this->private; + + if (!conf->log_file && !conf->log_history) + goto out; + if (trace_fop_names[GF_FOP_READDIRP].enabled) { + snprintf(string, sizeof(string), + "%" PRId64 " : gfid=%s op_ret=%d, op_errno=%d", + frame->root->unique, uuid_utoa(frame->local), op_ret, + op_errno); + + LOG_ELEMENT(conf, string); + } + if (op_ret < 0) + goto out; + + list_for_each_entry(entry, &buf->list, list) + { + count++; + TRACE_STAT_TO_STR(&entry->d_stat, statstr); + snprintf(string, sizeof(string), + "entry no. %d, pargfid=%s, " + "bname=%s *buf {%s}", + count, uuid_utoa(frame->local), entry->d_name, statstr); + LOG_ELEMENT(conf, string); + } + +out: + TRACE_STACK_UNWIND(readdirp, frame, op_ret, op_errno, buf, xdata); + return 0; +} + +int +trace_fsync_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, struct iatt *prebuf, + struct iatt *postbuf, dict_t *xdata) +{ + char preopstr[1024] = { + 0, + }; + char postopstr[1024] = { + 0, + }; + trace_conf_t *conf = NULL; + + conf = this->private; + + if (!conf->log_file && !conf->log_history) + goto out; + if (trace_fop_names[GF_FOP_FSYNC].enabled) { + char string[4096] = { + 0, + }; + if (op_ret == 0) { + TRACE_STAT_TO_STR(prebuf, preopstr); + TRACE_STAT_TO_STR(postbuf, postopstr); + + snprintf(string, sizeof(string), + "%" PRId64 + ": (op_ret=%d, " + "*prebuf = {%s}, *postbuf = {%s}", + frame->root->unique, op_ret, preopstr, postopstr); + } else { + snprintf(string, sizeof(string), + "%" PRId64 + ": gfid=%s op_ret=%d, " + "op_errno=%d", + frame->root->unique, uuid_utoa(frame->local), op_ret, + op_errno); + } + LOG_ELEMENT(conf, string); + } +out: + TRACE_STACK_UNWIND(fsync, frame, op_ret, op_errno, prebuf, postbuf, xdata); + + return 0; +} + +int +trace_setattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, struct iatt *statpre, + struct iatt *statpost, dict_t *xdata) +{ + char preopstr[1024] = { + 0, + }; + char postopstr[1024] = { + 0, + }; + trace_conf_t *conf = NULL; + + conf = this->private; + + if (!conf->log_file && !conf->log_history) + goto out; + if (trace_fop_names[GF_FOP_SETATTR].enabled) { + char string[4096] = { + 0, + }; + if (op_ret == 0) { + TRACE_STAT_TO_STR(statpre, preopstr); + TRACE_STAT_TO_STR(statpost, postopstr); + + snprintf(string, sizeof(string), + "%" PRId64 + ": (op_ret=%d, " + "*prebuf = {%s}, *postbuf = {%s})", + frame->root->unique, op_ret, preopstr, postopstr); + } else { + snprintf(string, sizeof(string), + "%" PRId64 + ": gfid=%s op_ret=%d, " + "op_errno=%d)", + frame->root->unique, uuid_utoa(frame->local), op_ret, + op_errno); + } + LOG_ELEMENT(conf, string); + } +out: + TRACE_STACK_UNWIND(setattr, frame, op_ret, op_errno, statpre, statpost, + xdata); + return 0; +} + +int +trace_fsetattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, struct iatt *statpre, + struct iatt *statpost, dict_t *xdata) +{ + char preopstr[1024] = { + 0, + }; + char postopstr[1024] = { + 0, + }; + trace_conf_t *conf = NULL; + + conf = this->private; + + if (!conf->log_file && !conf->log_history) + goto out; + if (trace_fop_names[GF_FOP_FSETATTR].enabled) { + char string[4096] = { + 0, + }; + if (op_ret == 0) { + TRACE_STAT_TO_STR(statpre, preopstr); + TRACE_STAT_TO_STR(statpost, postopstr); + + snprintf(string, sizeof(string), + "%" PRId64 + ": (op_ret=%d, " + "*prebuf = {%s}, *postbuf = {%s})", + frame->root->unique, op_ret, preopstr, postopstr); + } else { + snprintf(string, sizeof(string), + "%" PRId64 ": gfid=%s op_ret=%d, op_errno=%d)", + frame->root->unique, uuid_utoa(frame->local), op_ret, + op_errno); + } + LOG_ELEMENT(conf, string); + } +out: + TRACE_STACK_UNWIND(fsetattr, frame, op_ret, op_errno, statpre, statpost, + xdata); + return 0; +} + +int +trace_unlink_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, struct iatt *preparent, + struct iatt *postparent, dict_t *xdata) +{ + char preparentstr[1024] = { + 0, + }; + char postparentstr[1024] = { + 0, + }; + trace_conf_t *conf = NULL; + + conf = this->private; + + if (!conf->log_file && !conf->log_history) + goto out; + if (trace_fop_names[GF_FOP_UNLINK].enabled) { + char string[4096] = { + 0, + }; + if (op_ret == 0) { + TRACE_STAT_TO_STR(preparent, preparentstr); + TRACE_STAT_TO_STR(postparent, postparentstr); + + snprintf(string, sizeof(string), + "%" PRId64 + ": gfid=%s op_ret=%d, " + " *preparent = {%s}, " + "*postparent = {%s})", + frame->root->unique, uuid_utoa(frame->local), op_ret, + preparentstr, postparentstr); + } else { + snprintf(string, sizeof(string), + "%" PRId64 + ": gfid=%s op_ret=%d, " + "op_errno=%d)", + frame->root->unique, uuid_utoa(frame->local), op_ret, + op_errno); + } + LOG_ELEMENT(conf, string); + } +out: + TRACE_STACK_UNWIND(unlink, frame, op_ret, op_errno, preparent, postparent, + xdata); + return 0; +} + +int +trace_rename_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, struct iatt *buf, + struct iatt *preoldparent, struct iatt *postoldparent, + struct iatt *prenewparent, struct iatt *postnewparent, + dict_t *xdata) +{ + char statstr[1024] = { + 0, + }; + char preoldparentstr[1024] = { + 0, + }; + char postoldparentstr[1024] = { + 0, + }; + char prenewparentstr[1024] = { + 0, + }; + char postnewparentstr[1024] = { + 0, + }; + trace_conf_t *conf = NULL; + + conf = this->private; + + if (!conf->log_file && !conf->log_history) + goto out; + if (trace_fop_names[GF_FOP_RENAME].enabled) { + char string[6044] = { + 0, + }; + if (op_ret == 0) { + TRACE_STAT_TO_STR(buf, statstr); + TRACE_STAT_TO_STR(preoldparent, preoldparentstr); + TRACE_STAT_TO_STR(postoldparent, postoldparentstr); + TRACE_STAT_TO_STR(prenewparent, prenewparentstr); + TRACE_STAT_TO_STR(postnewparent, postnewparentstr); + + snprintf(string, sizeof(string), + "%" PRId64 + ": (op_ret=%d, " + "*stbuf = {%s}, *preoldparent = {%s}," + " *postoldparent = {%s}" + " *prenewparent = {%s}, " + "*postnewparent = {%s})", + frame->root->unique, op_ret, statstr, preoldparentstr, + postoldparentstr, prenewparentstr, postnewparentstr); + } else { + snprintf(string, sizeof(string), + "%" PRId64 + ": gfid=%s op_ret=%d, " + "op_errno=%d", + frame->root->unique, uuid_utoa(frame->local), op_ret, + op_errno); + } + LOG_ELEMENT(conf, string); + } +out: + TRACE_STACK_UNWIND(rename, frame, op_ret, op_errno, buf, preoldparent, + postoldparent, prenewparent, postnewparent, xdata); + return 0; +} + +int +trace_readlink_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, const char *buf, + struct iatt *stbuf, dict_t *xdata) +{ + char statstr[1024] = { + 0, + }; + trace_conf_t *conf = NULL; + + conf = this->private; + + if (!conf->log_file && !conf->log_history) + goto out; + if (trace_fop_names[GF_FOP_READLINK].enabled) { + char string[4096] = { + 0, + }; + if (op_ret == 0) { + TRACE_STAT_TO_STR(stbuf, statstr); + snprintf(string, sizeof(string), + "%" PRId64 + ": (op_ret=%d, op_errno=%d," + "buf=%s, stbuf = { %s })", + frame->root->unique, op_ret, op_errno, buf, statstr); + } else { + snprintf(string, sizeof(string), + "%" PRId64 + ": gfid=%s op_ret=%d, " + "op_errno=%d", + frame->root->unique, uuid_utoa(frame->local), op_ret, + op_errno); + } + + LOG_ELEMENT(conf, string); + } +out: + TRACE_STACK_UNWIND(readlink, frame, op_ret, op_errno, buf, stbuf, xdata); + return 0; +} + +int +trace_lookup_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, inode_t *inode, + struct iatt *buf, dict_t *xdata, struct iatt *postparent) +{ + char statstr[1024] = { + 0, + }; + char postparentstr[1024] = { + 0, + }; + trace_conf_t *conf = NULL; + + conf = this->private; + + if (!conf->log_file && !conf->log_history) + goto out; + if (trace_fop_names[GF_FOP_LOOKUP].enabled) { + char string[4096] = { + 0, + }; + if (op_ret == 0) { + TRACE_STAT_TO_STR(buf, statstr); + TRACE_STAT_TO_STR(postparent, postparentstr); + /* print buf->ia_gfid instead of inode->gfid, + * since if the inode is not yet linked to the + * inode table (fresh lookup) then null gfid + * will be printed. + */ + snprintf(string, sizeof(string), + "%" PRId64 + ": gfid=%s (op_ret=%d " + "*buf {%s}, *postparent {%s}", + frame->root->unique, uuid_utoa(buf->ia_gfid), op_ret, + statstr, postparentstr); + + /* For 'forget' */ + inode_ctx_put(inode, this, 0); + } else { + snprintf(string, sizeof(string), + "%" PRId64 + ": gfid=%s op_ret=%d, " + "op_errno=%d)", + frame->root->unique, uuid_utoa(frame->local), op_ret, + op_errno); + } + LOG_ELEMENT(conf, string); + } +out: + TRACE_STACK_UNWIND(lookup, frame, op_ret, op_errno, inode, buf, xdata, + postparent); + return 0; +} + +int +trace_symlink_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, inode_t *inode, + struct iatt *buf, struct iatt *preparent, + struct iatt *postparent, dict_t *xdata) +{ + char statstr[1024] = { + 0, + }; + char preparentstr[1024] = { + 0, + }; + char postparentstr[1024] = { + 0, + }; + trace_conf_t *conf = NULL; + + conf = this->private; + + if (!conf->log_file && !conf->log_history) + goto out; + if (trace_fop_names[GF_FOP_SYMLINK].enabled) { + char string[4096] = { + 0, + }; + if (op_ret == 0) { + TRACE_STAT_TO_STR(buf, statstr); + TRACE_STAT_TO_STR(preparent, preparentstr); + TRACE_STAT_TO_STR(postparent, postparentstr); + + snprintf(string, sizeof(string), + "%" PRId64 + ": gfid=%s (op_ret=%d " + "*stbuf = {%s}, *preparent = {%s}, " + "*postparent = {%s})", + frame->root->unique, uuid_utoa(inode->gfid), op_ret, + statstr, preparentstr, postparentstr); + } else { + snprintf(string, sizeof(string), + "%" PRId64 ": op_ret=%d, op_errno=%d", frame->root->unique, + op_ret, op_errno); + } + LOG_ELEMENT(conf, string); + } +out: + TRACE_STACK_UNWIND(symlink, frame, op_ret, op_errno, inode, buf, preparent, + postparent, xdata); + return 0; +} + +int +trace_mknod_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, inode_t *inode, + struct iatt *buf, struct iatt *preparent, + struct iatt *postparent, dict_t *xdata) +{ + char statstr[1024] = { + 0, + }; + char preparentstr[1024] = { + 0, + }; + char postparentstr[1024] = { + 0, + }; + trace_conf_t *conf = NULL; + + conf = this->private; + + if (!conf->log_file && !conf->log_history) + goto out; + char string[4096] = { + 0, + }; + if (trace_fop_names[GF_FOP_MKNOD].enabled) { + if (op_ret == 0) { + TRACE_STAT_TO_STR(buf, statstr); + TRACE_STAT_TO_STR(preparent, preparentstr); + TRACE_STAT_TO_STR(postparent, postparentstr); + + snprintf(string, sizeof(string), + "%" PRId64 + ": gfid=%s (op_ret=%d " + "*stbuf = {%s}, *preparent = {%s}, " + "*postparent = {%s})", + frame->root->unique, uuid_utoa(inode->gfid), op_ret, + statstr, preparentstr, postparentstr); + } else { + snprintf(string, sizeof(string), + "%" PRId64 ": (op_ret=%d, op_errno=%d)", + frame->root->unique, op_ret, op_errno); + } + LOG_ELEMENT(conf, string); + } +out: + TRACE_STACK_UNWIND(mknod, frame, op_ret, op_errno, inode, buf, preparent, + postparent, xdata); + return 0; +} + +int +trace_mkdir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, inode_t *inode, + struct iatt *buf, struct iatt *preparent, + struct iatt *postparent, dict_t *xdata) +{ + char statstr[1024] = { + 0, + }; + char preparentstr[1024] = { + 0, + }; + char postparentstr[1024] = { + 0, + }; + trace_conf_t *conf = NULL; + + conf = this->private; + + if (!conf->log_file && !conf->log_history) + goto out; + if (trace_fop_names[GF_FOP_MKDIR].enabled) { + char string[4096] = { + 0, + }; + if (op_ret == 0) { + TRACE_STAT_TO_STR(buf, statstr); + TRACE_STAT_TO_STR(preparent, preparentstr); + TRACE_STAT_TO_STR(postparent, postparentstr); + + snprintf(string, sizeof(string), + "%" PRId64 + ": gfid=%s (op_ret=%d " + ", *stbuf = {%s}, *prebuf = {%s}, " + "*postbuf = {%s} )", + frame->root->unique, uuid_utoa(inode->gfid), op_ret, + statstr, preparentstr, postparentstr); + } else { + snprintf(string, sizeof(string), + "%" PRId64 ": (op_ret=%d, op_errno=%d)", + frame->root->unique, op_ret, op_errno); + } + LOG_ELEMENT(conf, string); + } +out: + TRACE_STACK_UNWIND(mkdir, frame, op_ret, op_errno, inode, buf, preparent, + postparent, xdata); + return 0; +} + +int +trace_link_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, inode_t *inode, + struct iatt *buf, struct iatt *preparent, + struct iatt *postparent, dict_t *xdata) +{ + char statstr[1024] = { + 0, + }; + char preparentstr[1024] = { + 0, + }; + char postparentstr[1024] = { + 0, + }; + trace_conf_t *conf = NULL; + + conf = this->private; + + if (!conf->log_file && !conf->log_history) + goto out; + char string[4096] = { + 0, + }; + if (trace_fop_names[GF_FOP_LINK].enabled) { + if (op_ret == 0) { + TRACE_STAT_TO_STR(buf, statstr); + TRACE_STAT_TO_STR(preparent, preparentstr); + TRACE_STAT_TO_STR(postparent, postparentstr); + + snprintf(string, sizeof(string), + "%" PRId64 + ": (op_ret=%d, " + "*stbuf = {%s}, *prebuf = {%s}," + " *postbuf = {%s})", + frame->root->unique, op_ret, statstr, preparentstr, + postparentstr); + } else { + snprintf(string, sizeof(string), + "%" PRId64 + ": gfid=%s op_ret=%d, " + "op_errno=%d", + frame->root->unique, uuid_utoa(frame->local), op_ret, + op_errno); + } + LOG_ELEMENT(conf, string); + } +out: + TRACE_STACK_UNWIND(link, frame, op_ret, op_errno, inode, buf, preparent, + postparent, xdata); + return 0; +} + +int +trace_flush_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, dict_t *xdata) +{ + trace_conf_t *conf = NULL; + + conf = this->private; + + if (!conf->log_file && !conf->log_history) + goto out; + char string[4096] = { + 0, + }; + if (trace_fop_names[GF_FOP_FLUSH].enabled) { + snprintf(string, sizeof(string), + "%" PRId64 ": gfid=%s op_ret=%d, op_errno=%d", + frame->root->unique, uuid_utoa(frame->local), op_ret, + op_errno); + + LOG_ELEMENT(conf, string); + } +out: + TRACE_STACK_UNWIND(flush, frame, op_ret, op_errno, xdata); + return 0; +} + +int +trace_opendir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, fd_t *fd, dict_t *xdata) +{ + trace_conf_t *conf = NULL; + + conf = this->private; + + if (!conf->log_file && !conf->log_history) + goto out; + char string[4096] = { + 0, + }; + if (trace_fop_names[GF_FOP_OPENDIR].enabled) { + snprintf(string, sizeof(string), + "%" PRId64 + ": gfid=%s op_ret=%d, op_errno=%d," + " fd=%p", + frame->root->unique, uuid_utoa(frame->local), op_ret, op_errno, + fd); + + LOG_ELEMENT(conf, string); + } +out: + /* for 'releasedir' log */ + if (op_ret >= 0) + fd_ctx_set(fd, this, 0); + + TRACE_STACK_UNWIND(opendir, frame, op_ret, op_errno, fd, xdata); + return 0; +} + +int +trace_rmdir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, struct iatt *preparent, + struct iatt *postparent, dict_t *xdata) +{ + char preparentstr[1024] = { + 0, + }; + char postparentstr[1024] = { + 0, + }; + trace_conf_t *conf = NULL; + + conf = this->private; + + if (!conf->log_file && !conf->log_history) + goto out; + if (trace_fop_names[GF_FOP_RMDIR].enabled) { + char string[4096] = { + 0, + }; + if (op_ret == 0) { + TRACE_STAT_TO_STR(preparent, preparentstr); + TRACE_STAT_TO_STR(postparent, postparentstr); + + snprintf(string, sizeof(string), + "%" PRId64 + ": gfid=%s op_ret=%d, " + "*prebuf={%s}, *postbuf={%s}", + frame->root->unique, uuid_utoa(frame->local), op_ret, + preparentstr, postparentstr); + } else { + snprintf(string, sizeof(string), + "%" PRId64 + ": gfid=%s op_ret=%d, " + "op_errno=%d", + frame->root->unique, uuid_utoa(frame->local), op_ret, + op_errno); + } + LOG_ELEMENT(conf, string); + } +out: + TRACE_STACK_UNWIND(rmdir, frame, op_ret, op_errno, preparent, postparent, + xdata); + return 0; +} + +int +trace_truncate_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, struct iatt *prebuf, + struct iatt *postbuf, dict_t *xdata) +{ + char preopstr[1024] = { + 0, + }; + char postopstr[1024] = { + 0, + }; + trace_conf_t *conf = NULL; + + conf = this->private; + + if (!conf->log_file && !conf->log_history) + goto out; + if (trace_fop_names[GF_FOP_TRUNCATE].enabled) { + char string[4096] = { + 0, + }; + if (op_ret == 0) { + TRACE_STAT_TO_STR(prebuf, preopstr); + TRACE_STAT_TO_STR(postbuf, postopstr); + + snprintf(string, sizeof(string), + "%" PRId64 + ": (op_ret=%d, " + "*prebuf = {%s}, *postbuf = {%s} )", + frame->root->unique, op_ret, preopstr, postopstr); + } else { + snprintf(string, sizeof(string), + "%" PRId64 + ": gfid=%s op_ret=%d, " + "op_errno=%d", + frame->root->unique, uuid_utoa(frame->local), op_ret, + op_errno); + } + LOG_ELEMENT(conf, string); + } +out: + TRACE_STACK_UNWIND(truncate, frame, op_ret, op_errno, prebuf, postbuf, + xdata); + return 0; +} + +int +trace_statfs_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, struct statvfs *buf, + dict_t *xdata) +{ + trace_conf_t *conf = NULL; + + conf = this->private; + + if (!conf->log_file && !conf->log_history) + goto out; + if (trace_fop_names[GF_FOP_STATFS].enabled) { + char string[4096] = { + 0, + }; + if (op_ret == 0) { + snprintf(string, sizeof(string), + "%" PRId64 + ": ({f_bsize=%lu, " + "f_frsize=%lu, " + "f_blocks=%" GF_PRI_FSBLK ", f_bfree=%" GF_PRI_FSBLK + ", " + "f_bavail=%" GF_PRI_FSBLK + ", " + "f_files=%" GF_PRI_FSBLK + ", " + "f_ffree=%" GF_PRI_FSBLK + ", " + "f_favail=%" GF_PRI_FSBLK + ", " + "f_fsid=%lu, f_flag=%lu, " + "f_namemax=%lu}) => ret=%d", + frame->root->unique, buf->f_bsize, buf->f_frsize, + buf->f_blocks, buf->f_bfree, buf->f_bavail, buf->f_files, + buf->f_ffree, buf->f_favail, buf->f_fsid, buf->f_flag, + buf->f_namemax, op_ret); + } else { + snprintf(string, sizeof(string), + "%" PRId64 + ": (op_ret=%d, " + "op_errno=%d)", + frame->root->unique, op_ret, op_errno); + } + LOG_ELEMENT(conf, string); + } +out: + TRACE_STACK_UNWIND(statfs, frame, op_ret, op_errno, buf, xdata); + return 0; +} + +int +trace_setxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, dict_t *xdata) +{ + trace_conf_t *conf = NULL; + + conf = this->private; + + if (!conf->log_file && !conf->log_history) + goto out; + if (trace_fop_names[GF_FOP_SETXATTR].enabled) { + char string[4096] = { + 0, + }; + snprintf(string, sizeof(string), + "%" PRId64 ": gfid=%s op_ret=%d, op_errno=%d", + frame->root->unique, uuid_utoa(frame->local), op_ret, + op_errno); + + LOG_ELEMENT(conf, string); + } +out: + TRACE_STACK_UNWIND(setxattr, frame, op_ret, op_errno, xdata); + return 0; +} + +int +trace_getxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, dict_t *dict, + dict_t *xdata) +{ + trace_conf_t *conf = NULL; + + conf = this->private; + + if (!conf->log_file && !conf->log_history) + goto out; + if (trace_fop_names[GF_FOP_GETXATTR].enabled) { + char string[4096] = { + 0, + }; + snprintf(string, sizeof(string), + "%" PRId64 + ": gfid=%s op_ret=%d, op_errno=%d," + " dict=%p", + frame->root->unique, uuid_utoa(frame->local), op_ret, op_errno, + dict); - STACK_UNWIND_STRICT (stat, frame, op_ret, op_errno, buf); - return 0; -} - - -int -trace_readv_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, struct iovec *vector, - int32_t count, struct stat *buf, struct iobref *iobref) -{ - char atime_buf[256]; - char mtime_buf[256]; - char ctime_buf[256]; - - if (trace_fop_names[GF_FOP_READ].enabled) { - if (op_ret >= 0) { - strftime (atime_buf, 256, "[%b %d %H:%M:%S]", localtime (&buf->st_atime)); - strftime (mtime_buf, 256, "[%b %d %H:%M:%S]", localtime (&buf->st_mtime)); - strftime (ctime_buf, 256, "[%b %d %H:%M:%S]", localtime (&buf->st_ctime)); - - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": (op_ret=%d, *buf {st_dev=%"GF_PRI_DEV", " - "st_ino=%"PRIu64", st_mode=%o, st_nlink=%"GF_PRI_NLINK", " - "st_uid=%d, st_gid=%d, st_rdev=%"GF_PRI_DEV", " - "st_size=%"PRId64", st_blksize=%"GF_PRI_BLKSIZE", " - "st_blocks=%"PRId64", st_atime=%s, st_mtime=%s, st_ctime=%s})", - frame->root->unique, op_ret, buf->st_dev, buf->st_ino, - buf->st_mode, buf->st_nlink, buf->st_uid, buf->st_gid, - buf->st_rdev, buf->st_size, buf->st_blksize, buf->st_blocks, - atime_buf, mtime_buf, ctime_buf); - } else { - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": (op_ret=%d, op_errno=%d)", - frame->root->unique, op_ret, op_errno); - } - } + LOG_ELEMENT(conf, string); + } +out: + TRACE_STACK_UNWIND(getxattr, frame, op_ret, op_errno, dict, xdata); + + return 0; +} + +int +trace_fsetxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, dict_t *xdata) +{ + trace_conf_t *conf = NULL; + + conf = this->private; + + if (!conf->log_file && !conf->log_history) + goto out; + if (trace_fop_names[GF_FOP_FSETXATTR].enabled) { + char string[4096] = { + 0, + }; + snprintf(string, sizeof(string), + "%" PRId64 ": gfid=%s op_ret=%d, op_errno=%d", + frame->root->unique, uuid_utoa(frame->local), op_ret, + op_errno); - STACK_UNWIND_STRICT (readv, frame, op_ret, op_errno, vector, count, - buf, iobref); - return 0; + LOG_ELEMENT(conf, string); + } +out: + TRACE_STACK_UNWIND(fsetxattr, frame, op_ret, op_errno, xdata); + return 0; } - int -trace_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, - struct stat *prebuf, struct stat *postbuf) +trace_fgetxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, dict_t *dict, + dict_t *xdata) { - char *preopstr = NULL; - char *postopstr = NULL; + trace_conf_t *conf = NULL; - if (trace_fop_names[GF_FOP_WRITE].enabled) { - if (op_ret >= 0) { - preopstr = trace_stat_to_str (prebuf); - preopstr = trace_stat_to_str (postbuf); + conf = this->private; - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": (op_ret=%d, ino = %"PRIu64 - ", *prebuf = {%s}, *postbuf = {%s})", - frame->root->unique, op_ret, postbuf->st_ino, - preopstr, postopstr); + if (!conf->log_file && !conf->log_history) + goto out; + if (trace_fop_names[GF_FOP_FGETXATTR].enabled) { + char string[4096] = { + 0, + }; + snprintf(string, sizeof(string), + "%" PRId64 + ": gfid=%s op_ret=%d, op_errno=%d," + " dict=%p", + frame->root->unique, uuid_utoa(frame->local), op_ret, op_errno, + dict); - if (preopstr) - FREE (preopstr); + LOG_ELEMENT(conf, string); + } +out: + TRACE_STACK_UNWIND(fgetxattr, frame, op_ret, op_errno, dict, xdata); - if (postopstr) - FREE (postopstr); - } else { - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": (op_ret=%d, op_errno=%d)", - frame->root->unique, op_ret, op_errno); - } - } - - STACK_UNWIND_STRICT (writev, frame, op_ret, op_errno, prebuf, postbuf); - return 0; + return 0; } - int -trace_getdents_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, dir_entry_t *entries, - int32_t count) +trace_removexattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, dict_t *xdata) { - if (trace_fop_names[GF_FOP_GETDENTS].enabled) { - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": (op_ret=%d, op_errno=%d, count=%d)", - frame->root->unique, op_ret, op_errno, count); - } + trace_conf_t *conf = NULL; - STACK_UNWIND_STRICT (getdents, frame, op_ret, op_errno, entries, count); - return 0; -} + conf = this->private; + if (!conf->log_file && !conf->log_history) + goto out; + if (trace_fop_names[GF_FOP_REMOVEXATTR].enabled) { + char string[4096] = { + 0, + }; + snprintf(string, sizeof(string), + "%" PRId64 ": gfid=%s op_ret=%d, op_errno=%d", + frame->root->unique, uuid_utoa(frame->local), op_ret, + op_errno); + + LOG_ELEMENT(conf, string); + } +out: + TRACE_STACK_UNWIND(removexattr, frame, op_ret, op_errno, xdata); + + return 0; +} int -trace_readdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, gf_dirent_t *buf) +trace_fsyncdir_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, dict_t *xdata) { - if (trace_fop_names[GF_FOP_READDIR].enabled) { - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64" :(op_ret=%d, op_errno=%d)", - frame->root->unique, op_ret, op_errno); - } + trace_conf_t *conf = NULL; - STACK_UNWIND_STRICT (readdir, frame, op_ret, op_errno, buf); + conf = this->private; - return 0; -} + if (!conf->log_file && !conf->log_history) + goto out; + if (trace_fop_names[GF_FOP_FSYNCDIR].enabled) { + char string[4096] = { + 0, + }; + snprintf(string, sizeof(string), + "%" PRId64 ": gfid=%s op_ret=%d, op_errno=%d", + frame->root->unique, uuid_utoa(frame->local), op_ret, + op_errno); + + LOG_ELEMENT(conf, string); + } +out: + TRACE_STACK_UNWIND(fsyncdir, frame, op_ret, op_errno, xdata); + return 0; +} + +int +trace_access_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, dict_t *xdata) +{ + trace_conf_t *conf = NULL; + + conf = this->private; + + if (!conf->log_file && !conf->log_history) + goto out; + if (trace_fop_names[GF_FOP_ACCESS].enabled) { + char string[4096] = { + 0, + }; + snprintf(string, sizeof(string), + "%" PRId64 + ": gfid=%s op_ret=%d, " + "op_errno=%d)", + frame->root->unique, uuid_utoa(frame->local), op_ret, + op_errno); + + LOG_ELEMENT(conf, string); + } +out: + TRACE_STACK_UNWIND(access, frame, op_ret, op_errno, xdata); + return 0; +} + +int +trace_ftruncate_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, struct iatt *prebuf, + struct iatt *postbuf, dict_t *xdata) +{ + char prebufstr[1024] = { + 0, + }; + char postbufstr[1024] = { + 0, + }; + trace_conf_t *conf = NULL; + + conf = this->private; + + if (!conf->log_file && !conf->log_history) + goto out; + if (trace_fop_names[GF_FOP_FTRUNCATE].enabled) { + char string[4096] = { + 0, + }; + if (op_ret == 0) { + TRACE_STAT_TO_STR(prebuf, prebufstr); + TRACE_STAT_TO_STR(postbuf, postbufstr); + + snprintf(string, sizeof(string), + "%" PRId64 + ": op_ret=%d, " + "*prebuf = {%s}, *postbuf = {%s} )", + frame->root->unique, op_ret, prebufstr, postbufstr); + } else { + snprintf(string, sizeof(string), + "%" PRId64 + ": gfid=%s op_ret=%d, " + "op_errno=%d", + frame->root->unique, uuid_utoa(frame->local), op_ret, + op_errno); + } + LOG_ELEMENT(conf, string); + } +out: + TRACE_STACK_UNWIND(ftruncate, frame, op_ret, op_errno, prebuf, postbuf, + xdata); + return 0; +} + +int +trace_fstat_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, struct iatt *buf, + dict_t *xdata) +{ + char statstr[1024] = { + 0, + }; + trace_conf_t *conf = NULL; + + conf = this->private; + + if (!conf->log_file && !conf->log_history) + goto out; + if (trace_fop_names[GF_FOP_FSTAT].enabled) { + char string[4096] = {0.}; + if (op_ret == 0) { + TRACE_STAT_TO_STR(buf, statstr); + snprintf(string, sizeof(string), + "%" PRId64 + ": gfid=%s op_ret=%d " + "buf=%s", + frame->root->unique, uuid_utoa(frame->local), op_ret, + statstr); + } else { + snprintf(string, sizeof(string), + "%" PRId64 + ": gfid=%s op_ret=%d, " + "op_errno=%d", + frame->root->unique, uuid_utoa(frame->local), op_ret, + op_errno); + } + LOG_ELEMENT(conf, string); + } +out: + TRACE_STACK_UNWIND(fstat, frame, op_ret, op_errno, buf, xdata); + return 0; +} + +int +trace_lk_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, + int32_t op_errno, struct gf_flock *lock, dict_t *xdata) +{ + trace_conf_t *conf = NULL; + + conf = this->private; + + if (!conf->log_file && !conf->log_history) + goto out; + if (trace_fop_names[GF_FOP_LK].enabled) { + char string[4096] = { + 0, + }; + if (op_ret == 0) { + snprintf(string, sizeof(string), + "%" PRId64 + ": gfid=%s op_ret=%d, " + "{l_type=%d, l_whence=%d, " + "l_start=%" PRId64 + ", " + "l_len=%" PRId64 ", l_pid=%u})", + frame->root->unique, uuid_utoa(frame->local), op_ret, + lock->l_type, lock->l_whence, lock->l_start, lock->l_len, + lock->l_pid); + } else { + snprintf(string, sizeof(string), + "%" PRId64 + ": gfid=%s op_ret=%d, " + "op_errno=%d)", + frame->root->unique, uuid_utoa(frame->local), op_ret, + op_errno); + } + + LOG_ELEMENT(conf, string); + } +out: + TRACE_STACK_UNWIND(lk, frame, op_ret, op_errno, lock, xdata); + return 0; +} + +int +trace_entrylk_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, dict_t *xdata) +{ + trace_conf_t *conf = NULL; + + conf = this->private; + + if (!conf->log_file && !conf->log_history) + goto out; + if (trace_fop_names[GF_FOP_ENTRYLK].enabled) { + char string[4096] = { + 0, + }; + snprintf(string, sizeof(string), + "%" PRId64 ": gfid=%s op_ret=%d, op_errno=%d", + frame->root->unique, uuid_utoa(frame->local), op_ret, + op_errno); + + LOG_ELEMENT(conf, string); + } +out: + TRACE_STACK_UNWIND(entrylk, frame, op_ret, op_errno, xdata); + return 0; +} + +int +trace_fentrylk_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, dict_t *xdata) +{ + trace_conf_t *conf = NULL; + + conf = this->private; + + if (!conf->log_file && !conf->log_history) + goto out; + if (trace_fop_names[GF_FOP_FENTRYLK].enabled) { + char string[4096] = { + 0, + }; + snprintf(string, sizeof(string), + "%" PRId64 ": gfid=%s op_ret=%d, op_errno=%d", + frame->root->unique, uuid_utoa(frame->local), op_ret, + op_errno); + LOG_ELEMENT(conf, string); + } +out: + TRACE_STACK_UNWIND(fentrylk, frame, op_ret, op_errno, xdata); + return 0; +} int -trace_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, gf_dirent_t *buf) +trace_xattrop_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata) { - if (trace_fop_names[GF_FOP_READDIRP].enabled) { - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64" :(op_ret=%d, op_errno=%d)", - frame->root->unique, op_ret, op_errno); - } + trace_conf_t *conf = NULL; - STACK_UNWIND_STRICT (readdirp, frame, op_ret, op_errno, buf); + conf = this->private; - return 0; -} + if (!conf->log_file && !conf->log_history) + goto out; + if (trace_fop_names[GF_FOP_XATTROP].enabled) { + char string[4096] = { + 0, + }; + snprintf(string, sizeof(string), + "%" PRId64 ": gfid=%s op_ret=%d, op_errno=%d", + frame->root->unique, uuid_utoa(frame->local), op_ret, + op_errno); + LOG_ELEMENT(conf, string); + } +out: + TRACE_STACK_UNWIND(xattrop, frame, op_ret, op_errno, dict, xdata); + return 0; +} int -trace_fsync_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, - struct stat *prebuf, struct stat *postbuf) +trace_fxattrop_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, dict_t *dict, + dict_t *xdata) { - char *preopstr = NULL; - char *postopstr = NULL; + trace_conf_t *conf = NULL; - if (trace_fop_names[GF_FOP_FSYNC].enabled) { - if (op_ret >= 0) { - preopstr = trace_stat_to_str (prebuf); - preopstr = trace_stat_to_str (postbuf); + conf = this->private; - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": (op_ret=%d, ino = %"PRIu64 - ", *prebuf = {%s}, *postbuf = {%s}", - frame->root->unique, op_ret, postbuf->st_ino, - preopstr, postopstr); + if (!conf->log_file && !conf->log_history) + goto out; + if (trace_fop_names[GF_FOP_FXATTROP].enabled) { + char string[4096] = { + 0, + }; + snprintf(string, sizeof(string), + "%" PRId64 ": gfid=%s op_ret=%d, op_errno=%d", + frame->root->unique, uuid_utoa(frame->local), op_ret, + op_errno); - if (preopstr) - FREE (preopstr); + LOG_ELEMENT(conf, string); + } +out: + TRACE_STACK_UNWIND(fxattrop, frame, op_ret, op_errno, dict, xdata); + return 0; +} - if (postopstr) - FREE (postopstr); - } else { - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": (op_ret=%d, op_errno=%d)", - frame->root->unique, op_ret, op_errno); - } - } +int +trace_inodelk_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, dict_t *xdata) +{ + trace_conf_t *conf = NULL; - STACK_UNWIND_STRICT (fsync, frame, op_ret, op_errno, prebuf, postbuf); - - return 0; -} - - -int -trace_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, - struct stat *statpre, struct stat *statpost) -{ - char atime_pre[256] = {0,}; - char mtime_pre[256] = {0,}; - char ctime_pre[256] = {0,}; - char atime_post[256] = {0,}; - char mtime_post[256] = {0,}; - char ctime_post[256] = {0,}; - - if (trace_fop_names[GF_FOP_SETATTR].enabled) { - if (op_ret >= 0) { - strftime (atime_pre, 256, "[%b %d %H:%M:%S]", - localtime (&statpre->st_atime)); - strftime (mtime_pre, 256, "[%b %d %H:%M:%S]", - localtime (&statpre->st_mtime)); - strftime (ctime_pre, 256, "[%b %d %H:%M:%S]", - localtime (&statpre->st_ctime)); - - strftime (atime_post, 256, "[%b %d %H:%M:%S]", - localtime (&statpost->st_atime)); - strftime (mtime_post, 256, "[%b %d %H:%M:%S]", - localtime (&statpost->st_mtime)); - strftime (ctime_post, 256, "[%b %d %H:%M:%S]", - localtime (&statpost->st_ctime)); - - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": (op_ret=%d, *statpre " - "{st_ino=%"PRIu64", st_mode=%o, st_uid=%d, " - "st_gid=%d, st_atime=%s, st_mtime=%s, " - "st_ctime=%s}, *statpost {st_ino=%"PRIu64", " - "st_mode=%o, st_uid=%d, st_gid=%d, st_atime=%s," - " st_mtime=%s, st_ctime=%s})", - frame->root->unique, op_ret, statpre->st_ino, - statpre->st_mode, statpre->st_uid, - statpre->st_gid, atime_pre, mtime_pre, - ctime_pre, statpost->st_ino, statpost->st_mode, - statpost->st_uid, statpost->st_gid, atime_post, - mtime_post, ctime_post); - } else { - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": (op_ret=%d, op_errno=%d)", - frame->root->unique, op_ret, op_errno); - } - } + conf = this->private; - STACK_UNWIND_STRICT (setattr, frame, op_ret, op_errno, statpre, statpost); - return 0; -} - - -int -trace_fsetattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, - struct stat *statpre, struct stat *statpost) -{ - char atime_pre[256] = {0,}; - char mtime_pre[256] = {0,}; - char ctime_pre[256] = {0,}; - char atime_post[256] = {0,}; - char mtime_post[256] = {0,}; - char ctime_post[256] = {0,}; - - if (trace_fop_names[GF_FOP_FSETATTR].enabled) { - if (op_ret >= 0) { - strftime (atime_pre, 256, "[%b %d %H:%M:%S]", - localtime (&statpre->st_atime)); - strftime (mtime_pre, 256, "[%b %d %H:%M:%S]", - localtime (&statpre->st_mtime)); - strftime (ctime_pre, 256, "[%b %d %H:%M:%S]", - localtime (&statpre->st_ctime)); - - strftime (atime_post, 256, "[%b %d %H:%M:%S]", - localtime (&statpost->st_atime)); - strftime (mtime_post, 256, "[%b %d %H:%M:%S]", - localtime (&statpost->st_mtime)); - strftime (ctime_post, 256, "[%b %d %H:%M:%S]", - localtime (&statpost->st_ctime)); - - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": (op_ret=%d, *statpre " - "{st_ino=%"PRIu64", st_mode=%o, st_uid=%d, " - "st_gid=%d, st_atime=%s, st_mtime=%s, " - "st_ctime=%s}, *statpost {st_ino=%"PRIu64", " - "st_mode=%o, st_uid=%d, st_gid=%d, st_atime=%s," - " st_mtime=%s, st_ctime=%s})", - frame->root->unique, op_ret, statpre->st_ino, - statpre->st_mode, statpre->st_uid, - statpre->st_gid, atime_pre, mtime_pre, - ctime_pre, statpost->st_ino, statpost->st_mode, - statpost->st_uid, statpost->st_gid, atime_post, - mtime_post, ctime_post); - } else { - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": (op_ret=%d, op_errno=%d)", - frame->root->unique, op_ret, op_errno); - } - } + if (!conf->log_file && !conf->log_history) + goto out; + if (trace_fop_names[GF_FOP_INODELK].enabled) { + char string[4096] = { + 0, + }; + snprintf(string, sizeof(string), + "%" PRId64 ": gfid=%s op_ret=%d, op_errno=%d", + frame->root->unique, uuid_utoa(frame->local), op_ret, + op_errno); - STACK_UNWIND_STRICT (fsetattr, frame, op_ret, op_errno, - statpre, statpost); - return 0; + LOG_ELEMENT(conf, string); + } +out: + TRACE_STACK_UNWIND(inodelk, frame, op_ret, op_errno, xdata); + return 0; } - int -trace_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, - struct stat *preparent, struct stat *postparent) +trace_finodelk_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, dict_t *xdata) { - char *preparentstr = NULL; - char *postparentstr = NULL; - - if (trace_fop_names[GF_FOP_UNLINK].enabled) { - if (op_ret >= 0) { - preparentstr = trace_stat_to_str (preparent); - postparentstr = trace_stat_to_str (postparent); + trace_conf_t *conf = NULL; - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": (op_ret=%d, *preparent = {%s}, " - "*postparent = {%s})", - frame->root->unique, op_ret, preparentstr, - postparentstr); + conf = this->private; - if (preparentstr) - FREE (preparentstr); + if (!conf->log_file && !conf->log_history) + goto out; + if (trace_fop_names[GF_FOP_FINODELK].enabled) { + char string[4096] = { + 0, + }; + snprintf(string, sizeof(string), + "%" PRId64 ": gfid=%s op_ret=%d, op_errno=%d", + frame->root->unique, uuid_utoa(frame->local), op_ret, + op_errno); - if (postparentstr) - FREE (postparentstr); - } else { - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": (op_ret=%d, op_errno=%d)", - frame->root->unique, op_ret, op_errno); - } - } - - STACK_UNWIND_STRICT (unlink, frame, op_ret, op_errno, - preparent, postparent); - return 0; -} - - -int -trace_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, struct stat *buf, - struct stat *preoldparent, struct stat *postoldparent, - struct stat *prenewparent, struct stat *postnewparent) -{ - char *statstr = NULL; - char *preoldparentstr = NULL; - char *postoldparentstr = NULL; - char *prenewparentstr = NULL; - char *postnewparentstr = NULL; - - if (trace_fop_names[GF_FOP_RENAME].enabled) { - if (op_ret >= 0) { - statstr = trace_stat_to_str (buf); - preoldparentstr = trace_stat_to_str (preoldparent); - postoldparentstr = trace_stat_to_str (postoldparent); - - prenewparentstr = trace_stat_to_str (prenewparent); - postnewparentstr = trace_stat_to_str (postnewparent); - - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": (op_ret=%d, *stbuf = {%s}, " - "*preoldparent = {%s}, *postoldparent = {%s}" - " *prenewparent = {%s}, *postnewparent = {%s})", - frame->root->unique, op_ret, statstr, - preoldparentstr, postoldparentstr, - prenewparentstr, postnewparentstr); - - if (preoldparentstr) - FREE (preoldparentstr); - - if (postoldparentstr) - FREE (postoldparentstr); - - if (prenewparentstr) - FREE (prenewparentstr); - - if (postnewparentstr) - FREE (postnewparentstr); - } else { - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": (op_ret=%d, op_errno=%d)", - frame->root->unique, op_ret, op_errno); - } - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": (op_ret=%d, op_errno=%d, buf {st_ino=%"PRIu64"})", - frame->root->unique, op_ret, op_errno, - (buf? buf->st_ino : 0)); - } - - STACK_UNWIND_STRICT (rename, frame, op_ret, op_errno, buf, - preoldparent, postoldparent, - prenewparent, postnewparent); - return 0; + LOG_ELEMENT(conf, string); + } +out: + TRACE_STACK_UNWIND(finodelk, frame, op_ret, op_errno, xdata); + return 0; } - int -trace_readlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, - const char *buf, struct stat *stbuf) +trace_rchecksum_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, uint32_t weak_checksum, + uint8_t *strong_checksum, dict_t *xdata) { - char *statstr = NULL; + trace_conf_t *conf = NULL; - if (trace_fop_names[GF_FOP_READLINK].enabled) { - statstr = trace_stat_to_str (stbuf); + conf = this->private; - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": (op_ret=%d, op_errno=%d, buf=%s, " - "stbuf = { %s })", - frame->root->unique, op_ret, op_errno, buf, statstr); + if (!conf->log_file && !conf->log_history) + goto out; + if (trace_fop_names[GF_FOP_RCHECKSUM].enabled) { + char string[4096] = { + 0, + }; + snprintf(string, sizeof(string), + "%" PRId64 ": gfid=%s op_ret=%d op_errno=%d", + frame->root->unique, uuid_utoa(frame->local), op_ret, + op_errno); - if (statstr) - FREE (statstr); - } + LOG_ELEMENT(conf, string); + } + +out: + TRACE_STACK_UNWIND(rchecksum, frame, op_ret, op_errno, weak_checksum, + strong_checksum, xdata); - STACK_UNWIND_STRICT (readlink, frame, op_ret, op_errno, buf, stbuf); - return 0; + return 0; } +/* *_cbk section over <----------> fop section start */ int -trace_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, - inode_t *inode, struct stat *buf, - dict_t *xattr, struct stat *postparent) +trace_entrylk(call_frame_t *frame, xlator_t *this, const char *volume, + loc_t *loc, const char *basename, entrylk_cmd cmd, + entrylk_type type, dict_t *xdata) { - char *statstr = NULL; - char *postparentstr = NULL; + trace_conf_t *conf = NULL; - if (trace_fop_names[GF_FOP_LOOKUP].enabled) { - if (op_ret >= 0) { - statstr = trace_stat_to_str (buf); - postparentstr = trace_stat_to_str (buf); + conf = this->private; - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": (op_ret=%d, ino=%"PRIu64", " - "*buf {%s}, *postparent {%s}", - frame->root->unique, op_ret, inode->ino, - statstr, postparentstr); + if (!conf->log_file && !conf->log_history) + goto out; + if (trace_fop_names[GF_FOP_ENTRYLK].enabled) { + char string[4096] = { + 0, + }; + snprintf(string, sizeof(string), + "%" PRId64 + ": gfid=%s volume=%s, (path=%s " + "basename=%s, cmd=%s, type=%s)", + frame->root->unique, uuid_utoa(loc->inode->gfid), volume, + loc->path, basename, + ((cmd == ENTRYLK_LOCK) ? "ENTRYLK_LOCK" : "ENTRYLK_UNLOCK"), + ((type == ENTRYLK_RDLCK) ? "ENTRYLK_RDLCK" : "ENTRYLK_WRLCK")); - if (statstr) - FREE (statstr); - if (postparentstr) - FREE (postparentstr); - } else { - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": (op_ret=%d, op_errno=%d)", - frame->root->unique, op_ret, op_errno); - } - } + frame->local = loc->inode->gfid; - STACK_UNWIND_STRICT (lookup, frame, op_ret, op_errno, inode, buf, - xattr, postparent); - return 0; -} + LOG_ELEMENT(conf, string); + } +out: + STACK_WIND(frame, trace_entrylk_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->entrylk, volume, loc, basename, cmd, + type, xdata); + return 0; +} int -trace_symlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, - inode_t *inode, struct stat *buf, - struct stat *preparent, struct stat *postparent) +trace_inodelk(call_frame_t *frame, xlator_t *this, const char *volume, + loc_t *loc, int32_t cmd, struct gf_flock *flock, dict_t *xdata) { - char *statstr = NULL; - char *preparentstr = NULL; - char *postparentstr = NULL; + char *cmd_str = NULL; + char *type_str = NULL; + trace_conf_t *conf = NULL; - if (trace_fop_names[GF_FOP_SYMLINK].enabled) { - if (op_ret >= 0) { - statstr = trace_stat_to_str (buf); - preparentstr = trace_stat_to_str (preparent); - postparentstr = trace_stat_to_str (postparent); + conf = this->private; - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": (op_ret=%d, ino=%"PRIu64", " - "*stbuf = {%s}, *preparent = {%s}, " - "*postparent = {%s})", - frame->root->unique, op_ret, inode->ino, - statstr, preparentstr, postparentstr); + if (!conf->log_file && !conf->log_history) + goto out; + if (trace_fop_names[GF_FOP_INODELK].enabled) { + char string[4096] = { + 0, + }; + switch (cmd) { +#if F_GETLK != F_GETLK64 + case F_GETLK64: +#endif + case F_GETLK: + cmd_str = "GETLK"; + break; - if (statstr) - FREE (statstr); +#if F_SETLK != F_SETLK64 + case F_SETLK64: +#endif + case F_SETLK: + cmd_str = "SETLK"; + break; - if (preparentstr) - FREE (preparentstr); +#if F_SETLKW != F_SETLKW64 + case F_SETLKW64: +#endif + case F_SETLKW: + cmd_str = "SETLKW"; + break; + + default: + cmd_str = "UNKNOWN"; + break; + } + + switch (flock->l_type) { + case F_RDLCK: + type_str = "READ"; + break; + case F_WRLCK: + type_str = "WRITE"; + break; + case F_UNLCK: + type_str = "UNLOCK"; + break; + default: + type_str = "UNKNOWN"; + break; + } + + snprintf( + string, sizeof(string), + "%" PRId64 + ": gfid=%s volume=%s, (path=%s " + "cmd=%s, type=%s, start=%llu, len=%llu, " + "pid=%llu)", + frame->root->unique, uuid_utoa(loc->inode->gfid), volume, loc->path, + cmd_str, type_str, (unsigned long long)flock->l_start, + (unsigned long long)flock->l_len, (unsigned long long)flock->l_pid); + + frame->local = loc->inode->gfid; + + LOG_ELEMENT(conf, string); + } + +out: + STACK_WIND(frame, trace_inodelk_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->inodelk, volume, loc, cmd, flock, + xdata); + return 0; +} + +int +trace_finodelk(call_frame_t *frame, xlator_t *this, const char *volume, + fd_t *fd, int32_t cmd, struct gf_flock *flock, dict_t *xdata) +{ + char *cmd_str = NULL; + char *type_str = NULL; + trace_conf_t *conf = NULL; + + conf = this->private; + + if (!conf->log_file && !conf->log_history) + goto out; + if (trace_fop_names[GF_FOP_FINODELK].enabled) { + char string[4096] = { + 0, + }; + switch (cmd) { +#if F_GETLK != F_GETLK64 + case F_GETLK64: +#endif + case F_GETLK: + cmd_str = "GETLK"; + break; - if (postparentstr) - FREE (postparentstr); +#if F_SETLK != F_SETLK64 + case F_SETLK64: +#endif + case F_SETLK: + cmd_str = "SETLK"; + break; - } else { - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": (op_ret=%d, op_errno=%d)", - frame->root->unique, op_ret, op_errno); - } +#if F_SETLKW != F_SETLKW64 + case F_SETLKW64: +#endif + case F_SETLKW: + cmd_str = "SETLKW"; + break; + + default: + cmd_str = "UNKNOWN"; + break; } - STACK_UNWIND_STRICT (symlink, frame, op_ret, op_errno, inode, buf, - preparent, postparent); - return 0; -} + switch (flock->l_type) { + case F_RDLCK: + type_str = "READ"; + break; + case F_WRLCK: + type_str = "WRITE"; + break; + case F_UNLCK: + type_str = "UNLOCK"; + break; + default: + type_str = "UNKNOWN"; + break; + } + + snprintf(string, sizeof(string), + "%" PRId64 + ": gfid=%s volume=%s, (fd =%p " + "cmd=%s, type=%s, start=%llu, len=%llu, " + "pid=%llu)", + frame->root->unique, uuid_utoa(fd->inode->gfid), volume, fd, + cmd_str, type_str, (unsigned long long)flock->l_start, + (unsigned long long)flock->l_len, + (unsigned long long)flock->l_pid); + + frame->local = fd->inode->gfid; + LOG_ELEMENT(conf, string); + } +out: + STACK_WIND(frame, trace_finodelk_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->finodelk, volume, fd, cmd, flock, + xdata); + return 0; +} int -trace_mknod_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, - inode_t *inode, struct stat *buf, - struct stat *preparent, struct stat *postparent) +trace_xattrop(call_frame_t *frame, xlator_t *this, loc_t *loc, + gf_xattrop_flags_t flags, dict_t *dict, dict_t *xdata) { - char *statstr = NULL; - char *preparentstr = NULL; - char *postparentstr = NULL; + trace_conf_t *conf = NULL; - if (trace_fop_names[GF_FOP_MKNOD].enabled) { - if (op_ret >= 0) { - statstr = trace_stat_to_str (buf); - preparentstr = trace_stat_to_str (preparent); - postparentstr = trace_stat_to_str (postparent); + conf = this->private; - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": (op_ret=%d, ino=%"PRIu64", " - "*stbuf = {%s}, *preparent = {%s}, " - "*postparent = {%s})", - frame->root->unique, op_ret, inode->ino, - statstr, preparentstr, postparentstr); + if (!conf->log_file && !conf->log_history) + goto out; + if (trace_fop_names[GF_FOP_XATTROP].enabled) { + char string[4096] = { + 0, + }; + snprintf(string, sizeof(string), + "%" PRId64 ": gfid=%s (path=%s flags=%d)", frame->root->unique, + uuid_utoa(loc->inode->gfid), loc->path, flags); - if (statstr) - FREE (statstr); + frame->local = loc->inode->gfid; - if (preparentstr) - FREE (preparentstr); + LOG_ELEMENT(conf, string); + } - if (postparentstr) - FREE (postparentstr); - } else { - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": (op_ret=%d, op_errno=%d)", - frame->root->unique, op_ret, op_errno); - } - } +out: + STACK_WIND(frame, trace_xattrop_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->xattrop, loc, flags, dict, xdata); - STACK_UNWIND_STRICT (mknod, frame, op_ret, op_errno, inode, buf, - preparent, postparent); - return 0; + return 0; } - int -trace_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, - inode_t *inode, struct stat *buf, - struct stat *preparent, struct stat *postparent) +trace_fxattrop(call_frame_t *frame, xlator_t *this, fd_t *fd, + gf_xattrop_flags_t flags, dict_t *dict, dict_t *xdata) { - char *statstr = NULL; - char *preparentstr = NULL; - char *postparentstr = NULL; + trace_conf_t *conf = NULL; - if (trace_fop_names[GF_FOP_MKDIR].enabled) { - if (op_ret >= 0) { - statstr = trace_stat_to_str (buf); - preparentstr = trace_stat_to_str (preparent); - preparentstr = trace_stat_to_str (postparent); + conf = this->private; - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": (op_ret=%d, ino = %"PRIu64 - ", *stbuf = {%s}, *prebuf = {%s}, " - "*postbuf = {%s} )", - frame->root->unique, op_ret, buf->st_ino, - statstr, preparentstr, postparentstr); + if (!conf->log_file && !conf->log_history) + goto out; + if (trace_fop_names[GF_FOP_FXATTROP].enabled) { + char string[4096] = { + 0, + }; + snprintf(string, sizeof(string), "%" PRId64 ": gfid=%s fd=%p, flags=%d", + frame->root->unique, uuid_utoa(fd->inode->gfid), fd, flags); - if (statstr) - FREE (statstr); + frame->local = fd->inode->gfid; - if (preparentstr) - FREE (preparentstr); + LOG_ELEMENT(conf, string); + } - if (postparentstr) - FREE (postparentstr); - } else { - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": (op_ret=%d, op_errno=%d)", - frame->root->unique, op_ret, op_errno); - } - } +out: + STACK_WIND(frame, trace_fxattrop_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->fxattrop, fd, flags, dict, xdata); - STACK_UNWIND_STRICT (mkdir, frame, op_ret, op_errno, inode, buf, - preparent, postparent); - return 0; + return 0; } - int -trace_link_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, - inode_t *inode, struct stat *buf, - struct stat *preparent, struct stat *postparent) +trace_lookup(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { - char *statstr = NULL; - char *preparentstr = NULL; - char *postparentstr = NULL; + trace_conf_t *conf = NULL; - if (trace_fop_names[GF_FOP_LINK].enabled) { - if (op_ret >= 0) { - statstr = trace_stat_to_str (buf); - preparentstr = trace_stat_to_str (preparent); - preparentstr = trace_stat_to_str (postparent); + conf = this->private; - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": (op_ret=%d, ino = %"PRIu64 - ", *stbuf = {%s}, *prebuf = {%s}, " - "*postbuf = {%s})", - frame->root->unique, op_ret, buf->st_ino, - statstr, preparentstr, postparentstr); + if (!conf->log_file && !conf->log_history) + goto out; + if (trace_fop_names[GF_FOP_LOOKUP].enabled) { + char string[4096] = { + 0, + }; + /* TODO: print all the keys mentioned in xattr_req */ + snprintf(string, sizeof(string), "%" PRId64 ": gfid=%s path=%s", + frame->root->unique, uuid_utoa(loc->inode->gfid), loc->path); - if (statstr) - FREE (statstr); + frame->local = loc->inode->gfid; - if (preparentstr) - FREE (preparentstr); + LOG_ELEMENT(conf, string); + } - if (postparentstr) - FREE (postparentstr); - } else { - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": (op_ret=%d, op_errno=%d)", - frame->root->unique, op_ret, op_errno); - } - } +out: + STACK_WIND(frame, trace_lookup_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->lookup, loc, xdata); - STACK_UNWIND_STRICT (link, frame, op_ret, op_errno, inode, buf, - preparent, postparent); - return 0; + return 0; } - int -trace_flush_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno) +trace_stat(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { - if (trace_fop_names[GF_FOP_FLUSH].enabled) { - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": (op_ret=%d, op_errno=%d)", - frame->root->unique, op_ret, op_errno); - } + trace_conf_t *conf = NULL; - STACK_UNWIND_STRICT (flush, frame, op_ret, op_errno); - return 0; -} + conf = this->private; + if (!conf->log_file && !conf->log_history) + goto out; + if (trace_fop_names[GF_FOP_STAT].enabled) { + char string[4096] = { + 0, + }; + snprintf(string, sizeof(string), "%" PRId64 ": gfid=%s path=%s", + frame->root->unique, uuid_utoa(loc->inode->gfid), loc->path); -int -trace_opendir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, fd_t *fd) -{ - if (trace_fop_names[GF_FOP_OPENDIR].enabled) { - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": (op_ret=%d, op_errno=%d, fd=%p)", - frame->root->unique, op_ret, op_errno, fd); - } + frame->local = loc->inode->gfid; - STACK_UNWIND_STRICT (opendir, frame, op_ret, op_errno, fd); - return 0; -} + LOG_ELEMENT(conf, string); + } +out: + STACK_WIND(frame, trace_stat_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->stat, loc, xdata); + + return 0; +} int -trace_rmdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, - struct stat *preparent, struct stat *postparent) +trace_readlink(call_frame_t *frame, xlator_t *this, loc_t *loc, size_t size, + dict_t *xdata) { - char *preparentstr = NULL; - char *postparentstr = NULL; + trace_conf_t *conf = NULL; - if (trace_fop_names[GF_FOP_RMDIR].enabled) { - if (op_ret >= 0) { - preparentstr = trace_stat_to_str (preparent); - preparentstr = trace_stat_to_str (postparent); + conf = this->private; - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": (op_ret=%d, *prebuf = {%s}, " - "*postbuf = {%s}", - frame->root->unique, op_ret, preparentstr, - postparentstr); + if (!conf->log_file && !conf->log_history) + goto out; + if (trace_fop_names[GF_FOP_READLINK].enabled) { + char string[4096] = { + 0, + }; + snprintf(string, sizeof(string), + "%" PRId64 + ": gfid=%s path=%s, " + "size=%" GF_PRI_SIZET ")", + frame->root->unique, uuid_utoa(loc->inode->gfid), loc->path, + size); - if (preparentstr) - FREE (preparentstr); + frame->local = loc->inode->gfid; - if (postparentstr) - FREE (postparentstr); - } else { - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": (op_ret=%d, op_errno=%d)", - frame->root->unique, op_ret, op_errno); - } - } + LOG_ELEMENT(conf, string); + } - STACK_UNWIND_STRICT (rmdir, frame, op_ret, op_errno, - preparent, postparent); - return 0; -} +out: + STACK_WIND(frame, trace_readlink_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->readlink, loc, size, xdata); + return 0; +} int -trace_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, - struct stat *prebuf, struct stat *postbuf) +trace_mknod(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, + dev_t dev, mode_t umask, dict_t *xdata) { - char *preopstr = NULL; - char *postopstr = NULL; + trace_conf_t *conf = NULL; - if (trace_fop_names[GF_FOP_TRUNCATE].enabled) { - if (op_ret >= 0) { - preopstr = trace_stat_to_str (prebuf); - postopstr = trace_stat_to_str (prebuf); + conf = this->private; - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": (op_ret=%d, *prebuf = {%s}, " - "*postbuf = {%s} )", - frame->root->unique, op_ret, preopstr, - postopstr); + if (!conf->log_file && !conf->log_history) + goto out; + if (trace_fop_names[GF_FOP_MKNOD].enabled) { + char string[4096] = { + 0, + }; + snprintf(string, sizeof(string), + "%" PRId64 + ": gfid=%s path=%s mode=%d " + "umask=0%o, dev=%" GF_PRI_DEV ")", + frame->root->unique, uuid_utoa(loc->inode->gfid), loc->path, + mode, umask, dev); - if (preopstr) - FREE (preopstr); + LOG_ELEMENT(conf, string); + } - if (postopstr) - FREE (postopstr); - } else { - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": (op_ret=%d, op_errno=%d)", - frame->root->unique, op_ret, op_errno); - } - } +out: + STACK_WIND(frame, trace_mknod_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->mknod, loc, mode, dev, umask, xdata); - STACK_UNWIND_STRICT (truncate, frame, op_ret, op_errno, prebuf, postbuf); - return 0; + return 0; } - int -trace_statfs_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, struct statvfs *buf) +trace_mkdir(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, + mode_t umask, dict_t *xdata) { - if (trace_fop_names[GF_FOP_STATFS].enabled) { - if (op_ret >= 0) { - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": ({f_bsize=%lu, f_frsize=%lu, f_blocks=%"GF_PRI_FSBLK - ", f_bfree=%"GF_PRI_FSBLK", f_bavail=%"GF_PRI_FSBLK", " - "f_files=%"GF_PRI_FSBLK", f_ffree=%"GF_PRI_FSBLK", f_favail=%" - GF_PRI_FSBLK", f_fsid=%lu, f_flag=%lu, f_namemax=%lu}) => ret=%d", - frame->root->unique, buf->f_bsize, buf->f_frsize, buf->f_blocks, - buf->f_bfree, buf->f_bavail, buf->f_files, buf->f_ffree, - buf->f_favail, buf->f_fsid, buf->f_flag, buf->f_namemax, op_ret); - } else { - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": (op_ret=%d, op_errno=%d)", - frame->root->unique, op_ret, op_errno); - } - } + trace_conf_t *conf = NULL; - STACK_UNWIND_STRICT (statfs, frame, op_ret, op_errno, buf); - return 0; -} + conf = this->private; + if (!conf->log_file && !conf->log_history) + goto out; + if (trace_fop_names[GF_FOP_MKDIR].enabled) { + char string[4096] = { + 0, + }; + snprintf(string, sizeof(string), + "%" PRId64 + ": gfid=%s path=%s mode=%d" + " umask=0%o", + frame->root->unique, uuid_utoa(loc->inode->gfid), loc->path, + mode, umask); -int -trace_setxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno) -{ - if (trace_fop_names[GF_FOP_SETXATTR].enabled) { - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": (op_ret=%d, op_errno=%d)", - frame->root->unique, op_ret, op_errno); - } + LOG_ELEMENT(conf, string); + } - STACK_UNWIND_STRICT (setxattr, frame, op_ret, op_errno); - return 0; +out: + STACK_WIND(frame, trace_mkdir_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->mkdir, loc, mode, umask, xdata); + return 0; } - int -trace_getxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, dict_t *dict) +trace_unlink(call_frame_t *frame, xlator_t *this, loc_t *loc, int xflag, + dict_t *xdata) { - if (trace_fop_names[GF_FOP_GETXATTR].enabled) { - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": (op_ret=%d, op_errno=%d, dict=%p)", - frame->root->unique, op_ret, op_errno, dict); - } + trace_conf_t *conf = NULL; - STACK_UNWIND_STRICT (getxattr, frame, op_ret, op_errno, dict); + conf = this->private; - return 0; -} + if (!conf->log_file && !conf->log_history) + goto out; + if (trace_fop_names[GF_FOP_UNLINK].enabled) { + char string[4096] = { + 0, + }; + snprintf(string, sizeof(string), "%" PRId64 ": gfid=%s path=%s flag=%d", + frame->root->unique, uuid_utoa(loc->inode->gfid), loc->path, + xflag); + frame->local = loc->inode->gfid; + + LOG_ELEMENT(conf, string); + } +out: + STACK_WIND(frame, trace_unlink_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->unlink, loc, xflag, xdata); + return 0; +} int -trace_removexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno) +trace_rmdir(call_frame_t *frame, xlator_t *this, loc_t *loc, int flags, + dict_t *xdata) { - if (trace_fop_names[GF_FOP_REMOVEXATTR].enabled) { - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": (op_ret=%d, op_errno=%d)", - frame->root->unique, op_ret, op_errno); - } + trace_conf_t *conf = NULL; - STACK_UNWIND_STRICT (removexattr, frame, op_ret, op_errno); + conf = this->private; - return 0; -} + if (!conf->log_file && !conf->log_history) + goto out; + if (trace_fop_names[GF_FOP_RMDIR].enabled) { + char string[4096] = { + 0, + }; + snprintf(string, sizeof(string), + "%" PRId64 ": gfid=%s path=%s flags=%d", frame->root->unique, + uuid_utoa(loc->inode->gfid), loc->path, flags); + frame->local = loc->inode->gfid; -int -trace_fsyncdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno) -{ - if (trace_fop_names[GF_FOP_FSYNCDIR].enabled) { - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": (op_ret=%d, op_errno=%d)", - frame->root->unique, op_ret, op_errno); - } + LOG_ELEMENT(conf, string); + } - STACK_UNWIND_STRICT (fsyncdir, frame, op_ret, op_errno); - return 0; -} +out: + STACK_WIND(frame, trace_rmdir_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->rmdir, loc, flags, xdata); + return 0; +} int -trace_access_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno) +trace_symlink(call_frame_t *frame, xlator_t *this, const char *linkpath, + loc_t *loc, mode_t umask, dict_t *xdata) { - if (trace_fop_names[GF_FOP_ACCESS].enabled) { - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": (op_ret=%d, op_errno=%d)", - frame->root->unique, op_ret, op_errno); - } + trace_conf_t *conf = NULL; - STACK_UNWIND_STRICT (access, frame, op_ret, op_errno); - return 0; -} + conf = this->private; + + if (!conf->log_file && !conf->log_history) + goto out; + if (trace_fop_names[GF_FOP_SYMLINK].enabled) { + char string[4096] = { + 0, + }; + snprintf(string, sizeof(string), + "%" PRId64 + ": gfid=%s linkpath=%s, path=%s" + " umask=0%o", + frame->root->unique, uuid_utoa(loc->inode->gfid), linkpath, + loc->path, umask); + + LOG_ELEMENT(conf, string); + } +out: + STACK_WIND(frame, trace_symlink_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->symlink, linkpath, loc, umask, xdata); + + return 0; +} int -trace_ftruncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, - struct stat *prebuf, struct stat *postbuf) +trace_rename(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, + dict_t *xdata) { - char *prebufstr = NULL; - char *postbufstr = NULL; + char oldgfid[50] = { + 0, + }; + char newgfid[50] = { + 0, + }; + trace_conf_t *conf = NULL; - if (trace_fop_names[GF_FOP_FTRUNCATE].enabled) { - if (op_ret >= 0) { - prebufstr = trace_stat_to_str (prebuf); - postbufstr = trace_stat_to_str (postbuf); + conf = this->private; - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": (op_ret=%d, *prebuf = {%s}, " - "*postbuf = {%s} )", - frame->root->unique, op_ret, - prebufstr, postbufstr); + if (!conf->log_file && !conf->log_history) + goto out; + if (trace_fop_names[GF_FOP_RENAME].enabled) { + char string[4096] = { + 0, + }; + if (newloc->inode) + uuid_utoa_r(newloc->inode->gfid, newgfid); + else + strcpy(newgfid, "0"); - if (prebufstr) - FREE (prebufstr); + uuid_utoa_r(oldloc->inode->gfid, oldgfid); - if (postbufstr) - FREE (postbufstr); + snprintf(string, sizeof(string), + "%" PRId64 + ": oldgfid=%s oldpath=%s --> " + "newgfid=%s newpath=%s", + frame->root->unique, oldgfid, oldloc->path, newgfid, + newloc->path); - } else { - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": (op_ret=%d, op_errno=%d)", - frame->root->unique, op_ret, op_errno); - } - } + frame->local = oldloc->inode->gfid; - STACK_UNWIND_STRICT (ftruncate, frame, op_ret, op_errno, prebuf, postbuf); - return 0; -} - - -int -trace_fstat_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, struct stat *buf) -{ - char atime_buf[256]; - char mtime_buf[256]; - char ctime_buf[256]; - - if (trace_fop_names[GF_FOP_FSTAT].enabled) { - if (op_ret >= 0) { - strftime (atime_buf, 256, "[%b %d %H:%M:%S]", - localtime (&buf->st_atime)); - strftime (mtime_buf, 256, "[%b %d %H:%M:%S]", - localtime (&buf->st_mtime)); - strftime (ctime_buf, 256, "[%b %d %H:%M:%S]", - localtime (&buf->st_ctime)); - - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": (op_ret=%d, *buf {st_dev=%"GF_PRI_DEV", " - "st_ino=%"PRIu64", st_mode=%o, st_nlink=%"GF_PRI_NLINK", " - "st_uid=%d, st_gid=%d, st_rdev=%"GF_PRI_DEV", st_size=%"PRId64", " - "st_blksize=%"GF_PRI_BLKSIZE", st_blocks=%"PRId64", st_atime=%s, " - "st_mtime=%s, st_ctime=%s})", - frame->root->unique, op_ret, buf->st_dev, buf->st_ino, - buf->st_mode, buf->st_nlink, buf->st_uid, buf->st_gid, - buf->st_rdev, buf->st_size, buf->st_blksize, - buf->st_blocks, atime_buf, mtime_buf, ctime_buf); - } else { - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": (op_ret=%d, op_errno=%d)", - frame->root->unique, op_ret, op_errno); - } - } + LOG_ELEMENT(conf, string); + } - STACK_UNWIND_STRICT (fstat, frame, op_ret, op_errno, buf); - return 0; -} +out: + STACK_WIND(frame, trace_rename_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->rename, oldloc, newloc, xdata); + return 0; +} int -trace_lk_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, struct flock *lock) +trace_link(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, + dict_t *xdata) { - if (trace_fop_names[GF_FOP_LK].enabled) { - if (op_ret >= 0) { - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": (op_ret=%d, {l_type=%d, l_whence=%d, " - "l_start=%"PRId64", l_len=%"PRId64", l_pid=%u})", - frame->root->unique, op_ret, lock->l_type, lock->l_whence, - lock->l_start, lock->l_len, lock->l_pid); - } else { - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": (op_ret=%d, op_errno=%d)", - frame->root->unique, op_ret, op_errno); - } - } + char oldgfid[50] = { + 0, + }; + char newgfid[50] = { + 0, + }; + trace_conf_t *conf = NULL; - STACK_UNWIND_STRICT (lk, frame, op_ret, op_errno, lock); - return 0; -} + conf = this->private; + if (!conf->log_file && !conf->log_history) + goto out; + if (trace_fop_names[GF_FOP_LINK].enabled) { + char string[4096] = { + 0, + }; + if (newloc->inode) + uuid_utoa_r(newloc->inode->gfid, newgfid); + else + strcpy(newgfid, "0"); -int -trace_setdents_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno) -{ - if (trace_fop_names[GF_FOP_SETDENTS].enabled) { - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": op_ret=%d, op_errno=%d", - frame->root->unique, op_ret, op_errno); - } + uuid_utoa_r(oldloc->inode->gfid, oldgfid); - STACK_UNWIND_STRICT (setdents, frame, op_ret, op_errno); - return 0; -} + snprintf(string, sizeof(string), + "%" PRId64 + ": oldgfid=%s oldpath=%s --> " + "newgfid=%s newpath=%s", + frame->root->unique, oldgfid, oldloc->path, newgfid, + newloc->path); + frame->local = oldloc->inode->gfid; -int -trace_entrylk_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno) -{ - if (trace_fop_names[GF_FOP_ENTRYLK].enabled) { - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": op_ret=%d, op_errno=%d", - frame->root->unique, op_ret, op_errno); - } + LOG_ELEMENT(conf, string); + } - STACK_UNWIND_STRICT (entrylk, frame, op_ret, op_errno); - return 0; +out: + STACK_WIND(frame, trace_link_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->link, oldloc, newloc, xdata); + return 0; } - int -trace_xattrop_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, dict_t *dict) +trace_setattr(call_frame_t *frame, xlator_t *this, loc_t *loc, + struct iatt *stbuf, int32_t valid, dict_t *xdata) { - if (trace_fop_names[GF_FOP_XATTROP].enabled) { - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": (op_ret=%d, op_errno=%d)", - frame->root->unique, op_ret, op_errno); - } + char actime_str[GF_TIMESTR_SIZE] = { + 0, + }; + char modtime_str[GF_TIMESTR_SIZE] = { + 0, + }; + trace_conf_t *conf = NULL; - STACK_UNWIND_STRICT (xattrop, frame, op_ret, op_errno, dict); - return 0; -} + conf = this->private; + + if (!conf->log_file && !conf->log_history) + goto out; + if (trace_fop_names[GF_FOP_SETATTR].enabled) { + char string[4096] = { + 0, + }; + if (valid & GF_SET_ATTR_MODE) { + snprintf( + string, sizeof(string), "%" PRId64 ": gfid=%s path=%s mode=%o)", + frame->root->unique, uuid_utoa(loc->inode->gfid), loc->path, + st_mode_from_ia(stbuf->ia_prot, stbuf->ia_type)); + LOG_ELEMENT(conf, string); + memset(string, 0, sizeof(string)); + } -int -trace_fxattrop_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, dict_t *dict) -{ - if (trace_fop_names[GF_FOP_FXATTROP].enabled) { - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": (op_ret=%d, op_errno=%d)", - frame->root->unique, op_ret, op_errno); + if (valid & (GF_SET_ATTR_UID | GF_SET_ATTR_GID)) { + snprintf(string, sizeof(string), + "%" PRId64 + ": gfid=%s path=%s uid=%o," + " gid=%o", + frame->root->unique, uuid_utoa(loc->inode->gfid), + loc->path, stbuf->ia_uid, stbuf->ia_gid); + + LOG_ELEMENT(conf, string); + memset(string, 0, sizeof(string)); } - STACK_UNWIND_STRICT (fxattrop, frame, op_ret, op_errno, dict); - return 0; -} + if (valid & (GF_SET_ATTR_ATIME | GF_SET_ATTR_MTIME)) { + gf_time_fmt(actime_str, sizeof actime_str, stbuf->ia_atime, + gf_timefmt_bdT); + gf_time_fmt(modtime_str, sizeof modtime_str, stbuf->ia_mtime, + gf_timefmt_bdT); -int -trace_inodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno) -{ - if (trace_fop_names[GF_FOP_INODELK].enabled) { - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": op_ret=%d, op_errno=%d", - frame->root->unique, op_ret, op_errno); - } + snprintf(string, sizeof(string), + "%" PRId64 + ": gfid=%s path=%s " + "ia_atime=%s, ia_mtime=%s", + frame->root->unique, uuid_utoa(loc->inode->gfid), + loc->path, actime_str, modtime_str); + + LOG_ELEMENT(conf, string); + memset(string, 0, sizeof(string)); + } + frame->local = loc->inode->gfid; + } + +out: + STACK_WIND(frame, trace_setattr_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->setattr, loc, stbuf, valid, xdata); + + return 0; +} - STACK_UNWIND_STRICT (inodelk, frame, op_ret, op_errno); - return 0; -} +int +trace_fsetattr(call_frame_t *frame, xlator_t *this, fd_t *fd, + struct iatt *stbuf, int32_t valid, dict_t *xdata) +{ + char actime_str[GF_TIMESTR_SIZE] = { + 0, + }; + char modtime_str[GF_TIMESTR_SIZE] = { + 0, + }; + trace_conf_t *conf = NULL; + + conf = this->private; + + if (!conf->log_file && !conf->log_history) + goto out; + if (trace_fop_names[GF_FOP_FSETATTR].enabled) { + char string[4096] = { + 0, + }; + if (valid & GF_SET_ATTR_MODE) { + snprintf(string, sizeof(string), + "%" PRId64 ": gfid=%s fd=%p, mode=%o", frame->root->unique, + uuid_utoa(fd->inode->gfid), fd, + st_mode_from_ia(stbuf->ia_prot, stbuf->ia_type)); + + LOG_ELEMENT(conf, string); + memset(string, 0, sizeof(string)); + } + if (valid & (GF_SET_ATTR_UID | GF_SET_ATTR_GID)) { + snprintf(string, sizeof(string), + "%" PRId64 + ": gfid=%s fd=%p, uid=%o, " + "gid=%o", + frame->root->unique, uuid_utoa(fd->inode->gfid), fd, + stbuf->ia_uid, stbuf->ia_gid); + + LOG_ELEMENT(conf, string); + memset(string, 0, sizeof(string)); + } + + if (valid & (GF_SET_ATTR_ATIME | GF_SET_ATTR_MTIME)) { + gf_time_fmt(actime_str, sizeof actime_str, stbuf->ia_atime, + gf_timefmt_bdT); + + gf_time_fmt(modtime_str, sizeof modtime_str, stbuf->ia_mtime, + gf_timefmt_bdT); + + snprintf(string, sizeof(string), + "%" PRId64 + ": gfid=%s fd=%p " + "ia_atime=%s, ia_mtime=%s", + frame->root->unique, uuid_utoa(fd->inode->gfid), fd, + actime_str, modtime_str); -int -trace_entrylk (call_frame_t *frame, xlator_t *this, - const char *volume, loc_t *loc, const char *basename, - entrylk_cmd cmd, entrylk_type type) -{ - if (trace_fop_names[GF_FOP_ENTRYLK].enabled) { - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": volume=%s, (loc= {path=%s, ino=%"PRIu64"} basename=%s, cmd=%s, type=%s)", - frame->root->unique, volume, loc->path, loc->inode->ino, basename, - ((cmd == ENTRYLK_LOCK) ? "ENTRYLK_LOCK" : "ENTRYLK_UNLOCK"), - ((type == ENTRYLK_RDLCK) ? "ENTRYLK_RDLCK" : "ENTRYLK_WRLCK")); + LOG_ELEMENT(conf, string); + memset(string, 0, sizeof(string)); } + frame->local = fd->inode->gfid; + } - STACK_WIND (frame, trace_entrylk_cbk, - FIRST_CHILD (this), - FIRST_CHILD (this)->fops->entrylk, - volume, loc, basename, cmd, type); - return 0; -} +out: + STACK_WIND(frame, trace_fsetattr_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->fsetattr, fd, stbuf, valid, xdata); + return 0; +} -int -trace_inodelk (call_frame_t *frame, xlator_t *this, const char *volume, - loc_t *loc, int32_t cmd, struct flock *flock) +static int +trace_seek_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, off_t offset, dict_t *xdata) { - if (trace_fop_names[GF_FOP_INODELK].enabled) { - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": volume=%s, (loc {path=%s, ino=%"PRIu64"}, cmd=%s)", - frame->root->unique, volume, loc->path, loc->inode->ino, - ((cmd == F_SETLK)? "F_SETLK" : "unknown")); - } + trace_conf_t *conf = this->private; - STACK_WIND (frame, trace_inodelk_cbk, - FIRST_CHILD (this), - FIRST_CHILD (this)->fops->inodelk, - volume, loc, cmd, flock); - return 0; + if (!conf->log_file && !conf->log_history) + goto out; + if (trace_fop_names[GF_FOP_SEEK].enabled) { + char string[4096] = { + 0, + }; + snprintf(string, sizeof(string), + "%" PRId64 + ": gfid=%s op_ret=%d op_errno=%d, " + "offset=%" PRId64 "", + frame->root->unique, uuid_utoa(frame->local), op_ret, op_errno, + offset); + LOG_ELEMENT(conf, string); + } +out: + TRACE_STACK_UNWIND(seek, frame, op_ret, op_errno, offset, xdata); + return 0; } - -int -trace_finodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno) +static int +trace_seek(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, + gf_seek_what_t what, dict_t *xdata) { - if (trace_fop_names[GF_FOP_FINODELK].enabled) { - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": op_ret=%d, op_errno=%d", - frame->root->unique, op_ret, op_errno); - } + trace_conf_t *conf = this->private; - STACK_UNWIND_STRICT (finodelk, frame, op_ret, op_errno); - return 0; -} + if (!conf->log_file && !conf->log_history) + goto out; + if (trace_fop_names[GF_FOP_SEEK].enabled) { + char string[4096] = { + 0, + }; + snprintf(string, sizeof(string), + "%" PRId64 + ": gfid=%s fd=%p " + "offset=%" PRId64 " what=%d", + frame->root->unique, uuid_utoa(fd->inode->gfid), fd, offset, + what); + frame->local = fd->inode->gfid; + LOG_ELEMENT(conf, string); + } +out: + STACK_WIND(frame, trace_seek_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->seek, fd, offset, what, xdata); + + return 0; +} int -trace_finodelk (call_frame_t *frame, xlator_t *this, const char *volume, - fd_t *fd, int32_t cmd, struct flock *flock) +trace_truncate(call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset, + dict_t *xdata) { - if (trace_fop_names[GF_FOP_FINODELK].enabled) { - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": volume=%s, (fd=%p, cmd=%s)", - frame->root->unique, volume, fd, - ((cmd == F_SETLK) ? "F_SETLK" : "unknown")); - } + trace_conf_t *conf = NULL; - STACK_WIND (frame, trace_finodelk_cbk, - FIRST_CHILD (this), - FIRST_CHILD (this)->fops->finodelk, - volume, fd, cmd, flock); - return 0; -} + conf = this->private; + if (!conf->log_file && !conf->log_history) + goto out; + if (trace_fop_names[GF_FOP_TRUNCATE].enabled) { + char string[4096] = { + 0, + }; + snprintf(string, sizeof(string), + "%" PRId64 + ": gfid=%s path=%s, " + "offset=%" PRId64 "", + frame->root->unique, uuid_utoa(loc->inode->gfid), loc->path, + offset); -int -trace_xattrop (call_frame_t *frame, xlator_t *this, loc_t *loc, - gf_xattrop_flags_t flags, dict_t *dict) -{ - if (trace_fop_names[GF_FOP_XATTROP].enabled) { - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": (path=%s, ino=%"PRIu64" flags=%d)", - frame->root->unique, loc->path, loc->inode->ino, flags); + frame->local = loc->inode->gfid; - } + LOG_ELEMENT(conf, string); + } - STACK_WIND (frame, trace_xattrop_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->xattrop, - loc, flags, dict); +out: + STACK_WIND(frame, trace_truncate_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->truncate, loc, offset, xdata); - return 0; + return 0; } - int -trace_fxattrop (call_frame_t *frame, xlator_t *this, fd_t *fd, - gf_xattrop_flags_t flags, dict_t *dict) +trace_open(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, + fd_t *fd, dict_t *xdata) { - if (trace_fop_names[GF_FOP_FXATTROP].enabled) { - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": (fd=%p, flags=%d)", - frame->root->unique, fd, flags); + trace_conf_t *conf = NULL; - } + conf = this->private; - STACK_WIND (frame, trace_fxattrop_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->fxattrop, - fd, flags, dict); + if (!conf->log_file && !conf->log_history) + goto out; + if (trace_fop_names[GF_FOP_OPEN].enabled) { + char string[4096] = { + 0, + }; + snprintf(string, sizeof(string), + "%" PRId64 ": gfid=%s path=%s flags=%d fd=%p", + frame->root->unique, uuid_utoa(loc->inode->gfid), loc->path, + flags, fd); - return 0; -} + frame->local = loc->inode->gfid; + LOG_ELEMENT(conf, string); + } + +out: + STACK_WIND(frame, trace_open_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->open, loc, flags, fd, xdata); + return 0; +} int -trace_lookup (call_frame_t *frame, xlator_t *this, - loc_t *loc, dict_t *xattr_req) +trace_create(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, + mode_t mode, mode_t umask, fd_t *fd, dict_t *xdata) { - if (trace_fop_names[GF_FOP_LOOKUP].enabled) { - /* TODO: print all the keys mentioned in xattr_req */ - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": (loc {path=%s, ino=%"PRIu64"})", - frame->root->unique, loc->path, - loc->inode->ino); - } + trace_conf_t *conf = NULL; - STACK_WIND (frame, trace_lookup_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->lookup, - loc, xattr_req); + conf = this->private; - return 0; -} + if (!conf->log_file && !conf->log_history) + goto out; + if (trace_fop_names[GF_FOP_CREATE].enabled) { + char string[4096] = { + 0, + }; + snprintf(string, sizeof(string), + "%" PRId64 + ": gfid=%s path=%s, fd=%p, " + "flags=0%o mode=0%o umask=0%o", + frame->root->unique, uuid_utoa(loc->inode->gfid), loc->path, + fd, flags, mode, umask); + + LOG_ELEMENT(conf, string); + } +out: + STACK_WIND(frame, trace_create_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->create, loc, flags, mode, umask, fd, + xdata); + return 0; +} int -trace_stat (call_frame_t *frame, xlator_t *this, loc_t *loc) +trace_readv(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, + off_t offset, uint32_t flags, dict_t *xdata) { - if (trace_fop_names[GF_FOP_STAT].enabled) { - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": (loc {path=%s, ino=%"PRIu64"})", - frame->root->unique, loc->path, loc->inode->ino); - } + trace_conf_t *conf = NULL; - STACK_WIND (frame, trace_stat_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->stat, - loc); + conf = this->private; - return 0; -} + if (!conf->log_file && !conf->log_history) + goto out; + if (trace_fop_names[GF_FOP_READ].enabled) { + char string[4096] = { + 0, + }; + snprintf(string, sizeof(string), + "%" PRId64 ": gfid=%s fd=%p, size=%" GF_PRI_SIZET + "offset=%" PRId64 " flags=0%x)", + frame->root->unique, uuid_utoa(fd->inode->gfid), fd, size, + offset, flags); + frame->local = fd->inode->gfid; + + LOG_ELEMENT(conf, string); + } + +out: + STACK_WIND(frame, trace_readv_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->readv, fd, size, offset, flags, xdata); + return 0; +} int -trace_readlink (call_frame_t *frame, xlator_t *this, loc_t *loc, size_t size) +trace_writev(call_frame_t *frame, xlator_t *this, fd_t *fd, + struct iovec *vector, int32_t count, off_t offset, uint32_t flags, + struct iobref *iobref, dict_t *xdata) { - if (trace_fop_names[GF_FOP_READLINK].enabled) { - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": (loc {path=%s, ino=%"PRIu64"}, size=%"GF_PRI_SIZET")", - frame->root->unique, loc->path, loc->inode->ino, size); - } + trace_conf_t *conf = NULL; + int i = 0; + size_t total_size = 0; - STACK_WIND (frame, trace_readlink_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->readlink, - loc, size); + conf = this->private; - return 0; -} + if (!conf->log_file && !conf->log_history) + goto out; + if (trace_fop_names[GF_FOP_WRITE].enabled) { + char string[4096] = { + 0, + }; + for (i = 0; i < count; i++) + total_size += vector[i].iov_len; + snprintf(string, sizeof(string), + "%" PRId64 + ": gfid=%s fd=%p, count=%d, " + " offset=%" PRId64 " flags=0%x write_size=%zu", + frame->root->unique, uuid_utoa(fd->inode->gfid), fd, count, + offset, flags, total_size); -int -trace_mknod (call_frame_t *frame, xlator_t *this, loc_t *loc, - mode_t mode, dev_t dev) -{ - if (trace_fop_names[GF_FOP_MKNOD].enabled) { - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": (loc {path=%s, ino=%"PRIu64"}, mode=%d, dev=%"GF_PRI_DEV")", - frame->root->unique, loc->path, loc->inode->ino, mode, dev); - } + frame->local = fd->inode->gfid; - STACK_WIND (frame, trace_mknod_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->mknod, - loc, mode, dev); + LOG_ELEMENT(conf, string); + } - return 0; +out: + STACK_WIND(frame, trace_writev_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->writev, fd, vector, count, offset, + flags, iobref, xdata); + return 0; } - int -trace_mkdir (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode) +trace_statfs(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) { - if (trace_fop_names[GF_FOP_MKDIR].enabled) { - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": (path=%s, ino=%"PRIu64", mode=%d)", - frame->root->unique, loc->path, - ((loc->inode)? loc->inode->ino : 0), mode); - } + trace_conf_t *conf = NULL; - STACK_WIND (frame, trace_mkdir_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->mkdir, - loc, mode); - return 0; -} + conf = this->private; + if (!conf->log_file && !conf->log_history) + goto out; + if (trace_fop_names[GF_FOP_STATFS].enabled) { + char string[4096] = { + 0, + }; + snprintf(string, sizeof(string), "%" PRId64 ": gfid=%s path=%s", + frame->root->unique, + (loc->inode) ? uuid_utoa(loc->inode->gfid) : "0", loc->path); -int -trace_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc) -{ - if (trace_fop_names[GF_FOP_UNLINK].enabled) { - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": (loc {path=%s, ino=%"PRIu64"})", - frame->root->unique, loc->path, loc->inode->ino); - } + LOG_ELEMENT(conf, string); + } - STACK_WIND (frame, trace_unlink_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->unlink, - loc); - return 0; +out: + STACK_WIND(frame, trace_statfs_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->statfs, loc, xdata); + return 0; } - int -trace_rmdir (call_frame_t *frame, xlator_t *this, loc_t *loc) +trace_flush(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata) { - if (trace_fop_names[GF_FOP_RMDIR].enabled) { - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": (loc {path=%s, ino=%"PRIu64"})", - frame->root->unique, loc->path, loc->inode->ino); - } + trace_conf_t *conf = NULL; - STACK_WIND (frame, trace_rmdir_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->rmdir, - loc); + conf = this->private; - return 0; -} + if (!conf->log_file && !conf->log_history) + goto out; + if (trace_fop_names[GF_FOP_FLUSH].enabled) { + char string[4096] = { + 0, + }; + snprintf(string, sizeof(string), "%" PRId64 ": gfid=%s fd=%p", + frame->root->unique, uuid_utoa(fd->inode->gfid), fd); + + frame->local = fd->inode->gfid; + LOG_ELEMENT(conf, string); + } + +out: + STACK_WIND(frame, trace_flush_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->flush, fd, xdata); + return 0; +} int -trace_symlink (call_frame_t *frame, xlator_t *this, const char *linkpath, - loc_t *loc) +trace_fsync(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags, + dict_t *xdata) { - if (trace_fop_names[GF_FOP_SYMLINK].enabled) { - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": (linkpath=%s, loc {path=%s, ino=%"PRIu64"})", - frame->root->unique, linkpath, loc->path, - ((loc->inode)? loc->inode->ino : 0)); - } + trace_conf_t *conf = NULL; - STACK_WIND (frame, trace_symlink_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->symlink, - linkpath, loc); + conf = this->private; - return 0; -} + if (!conf->log_file && !conf->log_history) + goto out; + if (trace_fop_names[GF_FOP_FSYNC].enabled) { + char string[4096] = { + 0, + }; + snprintf(string, sizeof(string), "%" PRId64 ": gfid=%s flags=%d fd=%p", + frame->root->unique, uuid_utoa(fd->inode->gfid), flags, fd); + + frame->local = fd->inode->gfid; + LOG_ELEMENT(conf, string); + } + +out: + STACK_WIND(frame, trace_fsync_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->fsync, fd, flags, xdata); + return 0; +} int -trace_rename (call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc) +trace_setxattr(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict, + int32_t flags, dict_t *xdata) { - if (trace_fop_names[GF_FOP_RENAME].enabled) { - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": (oldloc {path=%s, ino=%"PRIu64"}, " - "newloc{path=%s, ino=%"PRIu64"})", - frame->root->unique, oldloc->path, oldloc->ino, - newloc->path, newloc->ino); - } + trace_conf_t *conf = NULL; - STACK_WIND (frame, trace_rename_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->rename, - oldloc, newloc); + conf = this->private; - return 0; -} + if (!conf->log_file && !conf->log_history) + goto out; + if (trace_fop_names[GF_FOP_SETXATTR].enabled) { + char string[4096] = { + 0, + }; + snprintf(string, sizeof(string), + "%" PRId64 ": gfid=%s path=%s flags=%d", frame->root->unique, + uuid_utoa(loc->inode->gfid), loc->path, flags); + + frame->local = loc->inode->gfid; + LOG_ELEMENT(conf, string); + } + +out: + STACK_WIND(frame, trace_setxattr_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->setxattr, loc, dict, flags, xdata); + return 0; +} int -trace_link (call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc) +trace_getxattr(call_frame_t *frame, xlator_t *this, loc_t *loc, + const char *name, dict_t *xdata) { - if (trace_fop_names[GF_FOP_LINK].enabled) { - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": (oldloc {path=%s, ino=%"PRIu64"}, " - "newloc {path=%s, ino=%"PRIu64"})", - frame->root->unique, oldloc->path, oldloc->inode->ino, - newloc->path, newloc->inode->ino); - } + trace_conf_t *conf = NULL; - STACK_WIND (frame, trace_link_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->link, - oldloc, newloc); - return 0; -} - - -int -trace_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc, - struct stat *stbuf, int32_t valid) -{ - char actime_str[256] = {0,}; - char modtime_str[256] = {0,}; - - if (trace_fop_names[GF_FOP_SETATTR].enabled) { - if (valid & GF_SET_ATTR_MODE) { - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": (loc {path=%s, ino=%"PRIu64"}," - " mode=%o)", frame->root->unique, loc->path, - loc->inode->ino, stbuf->st_mode); - } - - if (valid & (GF_SET_ATTR_UID | GF_SET_ATTR_GID)) { - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": (loc {path=%s, ino=%"PRIu64"}," - " uid=%o, gid=%o)", - frame->root->unique, loc->path, loc->inode->ino, - stbuf->st_uid, stbuf->st_gid); - } - - if (valid & (GF_SET_ATTR_ATIME | GF_SET_ATTR_MTIME)) { - strftime (actime_str, 256, "[%b %d %H:%M:%S]", - localtime (&stbuf->st_atime)); - strftime (modtime_str, 256, "[%b %d %H:%M:%S]", - localtime (&stbuf->st_mtime)); - - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": (loc {path=%s, ino=%"PRIu64"}, " - "*stbuf=%p {st_atime=%s, st_mtime=%s})", - frame->root->unique, loc->path, loc->inode->ino, - stbuf, actime_str, modtime_str); - } - } + conf = this->private; - STACK_WIND (frame, trace_setattr_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->setattr, - loc, stbuf, valid); + if (!conf->log_file && !conf->log_history) + goto out; + if (trace_fop_names[GF_FOP_GETXATTR].enabled) { + char string[4096] = { + 0, + }; + snprintf(string, sizeof(string), "%" PRId64 ": gfid=%s path=%s name=%s", + frame->root->unique, uuid_utoa(loc->inode->gfid), loc->path, + name); - return 0; -} + frame->local = loc->inode->gfid; + LOG_ELEMENT(conf, string); + } + +out: + STACK_WIND(frame, trace_getxattr_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->getxattr, loc, name, xdata); + return 0; +} int -trace_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd, - struct stat *stbuf, int32_t valid) +trace_removexattr(call_frame_t *frame, xlator_t *this, loc_t *loc, + const char *name, dict_t *xdata) { - char actime_str[256] = {0,}; - char modtime_str[256] = {0,}; + trace_conf_t *conf = NULL; - if (trace_fop_names[GF_FOP_FSETATTR].enabled) { - if (valid & GF_SET_ATTR_MODE) { - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": (*fd=%p, mode=%o)", - frame->root->unique, fd, - stbuf->st_mode); - } + conf = this->private; - if (valid & (GF_SET_ATTR_UID | GF_SET_ATTR_GID)) { - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": (*fd=%p, uid=%o, gid=%o)", - frame->root->unique, fd, - stbuf->st_uid, stbuf->st_gid); - } + if (!conf->log_file && !conf->log_history) + goto out; + if (trace_fop_names[GF_FOP_REMOVEXATTR].enabled) { + char string[4096] = { + 0, + }; + snprintf(string, sizeof(string), "%" PRId64 ": gfid=%s path=%s name=%s", + frame->root->unique, uuid_utoa(loc->inode->gfid), loc->path, + name); - if (valid & (GF_SET_ATTR_ATIME | GF_SET_ATTR_MTIME)) { - strftime (actime_str, 256, "[%b %d %H:%M:%S]", - localtime (&stbuf->st_atime)); - strftime (modtime_str, 256, "[%b %d %H:%M:%S]", - localtime (&stbuf->st_mtime)); + frame->local = loc->inode->gfid; - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": (*fd=%p" - "*stbuf=%p {st_atime=%s, st_mtime=%s})", - frame->root->unique, fd, stbuf, actime_str, - modtime_str); - } - } + LOG_ELEMENT(conf, string); + } - STACK_WIND (frame, trace_fsetattr_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->fsetattr, - fd, stbuf, valid); +out: + STACK_WIND(frame, trace_removexattr_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->removexattr, loc, name, xdata); - return 0; + return 0; } - int -trace_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, - off_t offset) +trace_opendir(call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd, + dict_t *xdata) { - if (trace_fop_names[GF_FOP_TRUNCATE].enabled) { - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": (loc {path=%s, ino=%"PRIu64"}, offset=%"PRId64")", - frame->root->unique, loc->path, loc->inode->ino, offset); - } + trace_conf_t *conf = NULL; - STACK_WIND (frame, trace_truncate_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->truncate, - loc, offset); + conf = this->private; - return 0; -} + if (!conf->log_file && !conf->log_history) + goto out; + if (trace_fop_names[GF_FOP_OPENDIR].enabled) { + char string[4096] = { + 0, + }; + snprintf(string, sizeof(string), "%" PRId64 ": gfid=%s path=%s fd=%p", + frame->root->unique, uuid_utoa(loc->inode->gfid), loc->path, + fd); + frame->local = loc->inode->gfid; -int -trace_open (call_frame_t *frame, xlator_t *this, loc_t *loc, - int32_t flags, fd_t *fd, int32_t wbflags) -{ - if (trace_fop_names[GF_FOP_OPEN].enabled) { - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": (loc {path=%s, ino=%"PRIu64"}, flags=%d, " - "fd=%p, wbflags=%d)", - frame->root->unique, loc->path, loc->inode->ino, flags, - fd, wbflags); - } + LOG_ELEMENT(conf, string); + } - STACK_WIND (frame, trace_open_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->open, - loc, flags, fd, wbflags); - return 0; +out: + STACK_WIND(frame, trace_opendir_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->opendir, loc, fd, xdata); + return 0; } - int -trace_create (call_frame_t *frame, xlator_t *this, loc_t *loc, - int32_t flags, mode_t mode, fd_t *fd) +trace_readdirp(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, + off_t offset, dict_t *dict) { - if (trace_fop_names[GF_FOP_CREATE].enabled) { - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": (loc {path=%s, ino=%"PRIu64"}, flags=0%o mode=0%o)", - frame->root->unique, loc->path, loc->inode->ino, flags, mode); - } + trace_conf_t *conf = NULL; - STACK_WIND (frame, trace_create_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->create, - loc, flags, mode, fd); - return 0; -} + conf = this->private; + if (!conf->log_file && !conf->log_history) + goto out; + if (trace_fop_names[GF_FOP_READDIRP].enabled) { + char string[4096] = { + 0, + }; + snprintf(string, sizeof(string), + "%" PRId64 ": gfid=%s fd=%p, size=%" GF_PRI_SIZET + ", offset=%" PRId64 " dict=%p", + frame->root->unique, uuid_utoa(fd->inode->gfid), fd, size, + offset, dict); -int -trace_readv (call_frame_t *frame, xlator_t *this, fd_t *fd, - size_t size, off_t offset) -{ - if (trace_fop_names[GF_FOP_READ].enabled) { - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": (*fd=%p, size=%"GF_PRI_SIZET", offset=%"PRId64")", - frame->root->unique, fd, size, offset); - } + frame->local = fd->inode->gfid; - STACK_WIND (frame, trace_readv_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->readv, - fd, size, offset); - return 0; -} + LOG_ELEMENT(conf, string); + } +out: + STACK_WIND(frame, trace_readdirp_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->readdirp, fd, size, offset, dict); + + return 0; +} int -trace_writev (call_frame_t *frame, xlator_t *this, fd_t *fd, - struct iovec *vector, int32_t count, - off_t offset, struct iobref *iobref) +trace_readdir(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, + off_t offset, dict_t *xdata) { - if (trace_fop_names[GF_FOP_WRITE].enabled) { - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": (*fd=%p, *vector=%p, count=%d, offset=%"PRId64")", - frame->root->unique, fd, vector, count, offset); - } + trace_conf_t *conf = NULL; - STACK_WIND (frame, trace_writev_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->writev, - fd, vector, count, offset, iobref); - return 0; -} + conf = this->private; + if (!conf->log_file && !conf->log_history) + goto out; + if (trace_fop_names[GF_FOP_READDIR].enabled) { + char string[4096] = { + 0, + }; + snprintf(string, sizeof(string), + "%" PRId64 ": gfid=%s fd=%p, size=%" GF_PRI_SIZET + ", offset=%" PRId64, + frame->root->unique, uuid_utoa(fd->inode->gfid), fd, size, + offset); -int -trace_statfs (call_frame_t *frame, xlator_t *this, loc_t *loc) -{ - if (trace_fop_names[GF_FOP_STATFS].enabled) { - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": (loc {path=%s, ino=%"PRIu64"})", - frame->root->unique, loc->path, - ((loc->inode)? loc->inode->ino : 0)); - } + frame->local = fd->inode->gfid; - STACK_WIND (frame, trace_statfs_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->statfs, - loc); - return 0; -} + LOG_ELEMENT(conf, string); + } +out: + STACK_WIND(frame, trace_readdir_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->readdir, fd, size, offset, xdata); + + return 0; +} int -trace_flush (call_frame_t *frame, xlator_t *this, fd_t *fd) +trace_fsyncdir(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t datasync, + dict_t *xdata) { - if (trace_fop_names[GF_FOP_FLUSH].enabled) { - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": (*fd=%p)", - frame->root->unique, fd); - } + trace_conf_t *conf = NULL; - STACK_WIND (frame, trace_flush_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->flush, - fd); - return 0; -} + conf = this->private; + if (!conf->log_file && !conf->log_history) + goto out; + if (trace_fop_names[GF_FOP_FSYNCDIR].enabled) { + char string[4096] = { + 0, + }; + snprintf(string, sizeof(string), + "%" PRId64 ": gfid=%s datasync=%d fd=%p", frame->root->unique, + uuid_utoa(fd->inode->gfid), datasync, fd); -int -trace_fsync (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags) -{ - if (trace_fop_names[GF_FOP_FSYNC].enabled) { - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": (flags=%d, *fd=%p)", - frame->root->unique, flags, fd); - } + frame->local = fd->inode->gfid; - STACK_WIND (frame, trace_fsync_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->fsync, - fd, flags); - return 0; -} + LOG_ELEMENT(conf, string); + } +out: + STACK_WIND(frame, trace_fsyncdir_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->fsyncdir, fd, datasync, xdata); + return 0; +} int -trace_setxattr (call_frame_t *frame, xlator_t *this, - loc_t *loc, dict_t *dict, int32_t flags) +trace_access(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t mask, + dict_t *xdata) { - if (trace_fop_names[GF_FOP_SETXATTR].enabled) { - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": (loc {path=%s, ino=%"PRIu64"}, dict=%p, flags=%d)", - frame->root->unique, loc->path, - ((loc->inode)? loc->inode->ino : 0), dict, flags); - } + trace_conf_t *conf = NULL; - STACK_WIND (frame, trace_setxattr_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->setxattr, - loc, dict, flags); - return 0; -} + conf = this->private; + if (!conf->log_file && !conf->log_history) + goto out; + if (trace_fop_names[GF_FOP_ACCESS].enabled) { + char string[4096] = { + 0, + }; + snprintf(string, sizeof(string), + "%" PRId64 ": gfid=%s path=%s mask=0%o", frame->root->unique, + uuid_utoa(loc->inode->gfid), loc->path, mask); -int -trace_getxattr (call_frame_t *frame, xlator_t *this, - loc_t *loc, const char *name) -{ - if (trace_fop_names[GF_FOP_GETXATTR].enabled) { - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": (loc {path=%s, ino=%"PRIu64"}), name=%s", - frame->root->unique, loc->path, - ((loc->inode)? loc->inode->ino : 0), name); - } + frame->local = loc->inode->gfid; - STACK_WIND (frame, trace_getxattr_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->getxattr, - loc, name); - return 0; -} + LOG_ELEMENT(conf, string); + } +out: + STACK_WIND(frame, trace_access_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->access, loc, mask, xdata); + return 0; +} -int -trace_removexattr (call_frame_t *frame, xlator_t *this, - loc_t *loc, const char *name) +int32_t +trace_rchecksum(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, + int32_t len, dict_t *xdata) { - if (trace_fop_names[GF_FOP_REMOVEXATTR].enabled) { - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": (loc {path=%s, ino=%"PRIu64"}, name=%s)", - frame->root->unique, loc->path, - ((loc->inode)? loc->inode->ino : 0), name); - } + trace_conf_t *conf = NULL; - STACK_WIND (frame, trace_removexattr_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->removexattr, - loc, name); + conf = this->private; - return 0; -} + if (!conf->log_file && !conf->log_history) + goto out; + if (trace_fop_names[GF_FOP_RCHECKSUM].enabled) { + char string[4096] = { + 0, + }; + snprintf(string, sizeof(string), + "%" PRId64 ": gfid=%s offset=%" PRId64 "len=%u fd=%p", + frame->root->unique, uuid_utoa(fd->inode->gfid), offset, len, + fd); + frame->local = fd->inode->gfid; -int -trace_opendir (call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd) -{ - if (trace_fop_names[GF_FOP_OPENDIR].enabled) { - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64":( loc {path=%s, ino=%"PRIu64"}, fd=%p)", - frame->root->unique, loc->path, loc->inode->ino, fd); - } + LOG_ELEMENT(conf, string); + } - STACK_WIND (frame, trace_opendir_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->opendir, - loc, fd); - return 0; -} +out: + STACK_WIND(frame, trace_rchecksum_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->rchecksum, fd, offset, len, xdata); + return 0; +} -int -trace_getdents (call_frame_t *frame, xlator_t *this, fd_t *fd, - size_t size, off_t offset, int32_t flag) +int32_t +trace_fentrylk(call_frame_t *frame, xlator_t *this, const char *volume, + fd_t *fd, const char *basename, entrylk_cmd cmd, + entrylk_type type, dict_t *xdata) { - if (trace_fop_names[GF_FOP_GETDENTS].enabled) { - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": (fd=%p, size=%"GF_PRI_SIZET", offset=%"PRId64", flag=0x%x)", - frame->root->unique, fd, size, offset, flag); - } + trace_conf_t *conf = NULL; - STACK_WIND (frame, trace_getdents_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->getdents, - fd, size, offset, flag); - return 0; -} + conf = this->private; + if (!conf->log_file && !conf->log_history) + goto out; + if (trace_fop_names[GF_FOP_FENTRYLK].enabled) { + char string[4096] = { + 0, + }; + snprintf(string, sizeof(string), + "%" PRId64 + ": gfid=%s volume=%s, (fd=%p " + "basename=%s, cmd=%s, type=%s)", + frame->root->unique, uuid_utoa(fd->inode->gfid), volume, fd, + basename, + ((cmd == ENTRYLK_LOCK) ? "ENTRYLK_LOCK" : "ENTRYLK_UNLOCK"), + ((type == ENTRYLK_RDLCK) ? "ENTRYLK_RDLCK" : "ENTRYLK_WRLCK")); -int -trace_readdirp (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, - off_t offset) -{ - if (trace_fop_names[GF_FOP_READDIRP].enabled) { - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": (fd=%p, size=%"GF_PRI_SIZET", offset=%"PRId64")", - frame->root->unique, fd, size, offset); - } + frame->local = fd->inode->gfid; - STACK_WIND (frame, trace_readdirp_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->readdirp, - fd, size, offset); + LOG_ELEMENT(conf, string); + } - return 0; +out: + STACK_WIND(frame, trace_fentrylk_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->fentrylk, volume, fd, basename, cmd, + type, xdata); + return 0; } - -int -trace_readdir (call_frame_t *frame, xlator_t *this, fd_t *fd, - size_t size, off_t offset) +int32_t +trace_fgetxattr(call_frame_t *frame, xlator_t *this, fd_t *fd, const char *name, + dict_t *xdata) { - if (trace_fop_names[GF_FOP_READDIR].enabled) { - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": (fd=%p, size=%"GF_PRI_SIZET", offset=%"PRId64")", - frame->root->unique, fd, size, offset); - } + trace_conf_t *conf = NULL; - STACK_WIND (frame, trace_readdir_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->readdir, - fd, size, offset); + conf = this->private; - return 0; -} + if (!conf->log_file && !conf->log_history) + goto out; + if (trace_fop_names[GF_FOP_FGETXATTR].enabled) { + char string[4096] = { + 0, + }; + snprintf(string, sizeof(string), "%" PRId64 ": gfid=%s fd=%p name=%s", + frame->root->unique, uuid_utoa(fd->inode->gfid), fd, name); + frame->local = fd->inode->gfid; -int -trace_fsyncdir (call_frame_t *frame, xlator_t *this, - fd_t *fd, int32_t datasync) -{ - if (trace_fop_names[GF_FOP_FSYNCDIR].enabled) { - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": (datasync=%d, *fd=%p)", - frame->root->unique, datasync, fd); - } + LOG_ELEMENT(conf, string); + } - STACK_WIND (frame, trace_fsyncdir_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->fsyncdir, - fd, datasync); - return 0; +out: + STACK_WIND(frame, trace_fgetxattr_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->fgetxattr, fd, name, xdata); + return 0; } - -int -trace_access (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t mask) +int32_t +trace_fsetxattr(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *dict, + int32_t flags, dict_t *xdata) { - if (trace_fop_names[GF_FOP_ACCESS].enabled) { - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": (*loc {path=%s, ino=%"PRIu64"}, mask=0%o)", - frame->root->unique, loc->path, - ((loc->inode)? loc->inode->ino : 0), mask); - } + trace_conf_t *conf = NULL; - STACK_WIND (frame, trace_access_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->access, - loc, mask); - return 0; -} + conf = this->private; + if (!conf->log_file && !conf->log_history) + goto out; + if (trace_fop_names[GF_FOP_FSETXATTR].enabled) { + char string[4096] = { + 0, + }; + snprintf(string, sizeof(string), "%" PRId64 ": gfid=%s fd=%p flags=%d", + frame->root->unique, uuid_utoa(fd->inode->gfid), fd, flags); -int -trace_ftruncate (call_frame_t *frame, xlator_t *this, - fd_t *fd, off_t offset) -{ - if (trace_fop_names[GF_FOP_FTRUNCATE].enabled) { - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": (offset=%"PRId64", *fd=%p)", - frame->root->unique, offset, fd); - } + frame->local = fd->inode->gfid; - STACK_WIND (frame, trace_ftruncate_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->ftruncate, - fd, offset); + LOG_ELEMENT(conf, string); + } - return 0; +out: + STACK_WIND(frame, trace_fsetxattr_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->fsetxattr, fd, dict, flags, xdata); + return 0; } - int -trace_fstat (call_frame_t *frame, xlator_t *this, fd_t *fd) +trace_ftruncate(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, + dict_t *xdata) { - if (trace_fop_names[GF_FOP_FSTAT].enabled) { - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": (*fd=%p)", - frame->root->unique, fd); - } + trace_conf_t *conf = NULL; - STACK_WIND (frame, trace_fstat_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->fstat, - fd); - return 0; -} + conf = this->private; + if (!conf->log_file && !conf->log_history) + goto out; + if (trace_fop_names[GF_FOP_FTRUNCATE].enabled) { + char string[4096] = { + 0, + }; + snprintf(string, sizeof(string), + "%" PRId64 ": gfid=%s offset=%" PRId64 " fd=%p", + frame->root->unique, uuid_utoa(fd->inode->gfid), offset, fd); -int -trace_lk (call_frame_t *frame, xlator_t *this, fd_t *fd, - int32_t cmd, struct flock *lock) -{ - if (trace_fop_names[GF_FOP_LK].enabled) { - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": (*fd=%p, cmd=%d, lock {l_type=%d, l_whence=%d, " - "l_start=%"PRId64", l_len=%"PRId64", l_pid=%u})", - frame->root->unique, fd, cmd, lock->l_type, lock->l_whence, - lock->l_start, lock->l_len, lock->l_pid); - } + frame->local = fd->inode->gfid; - STACK_WIND (frame, trace_lk_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->lk, - fd, cmd, lock); - return 0; -} + LOG_ELEMENT(conf, string); + } +out: + STACK_WIND(frame, trace_ftruncate_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->ftruncate, fd, offset, xdata); + + return 0; +} int -trace_setdents (call_frame_t *frame, xlator_t *this, fd_t *fd, - int32_t flags, dir_entry_t *entries, int32_t count) +trace_fstat(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata) { - if (trace_fop_names[GF_FOP_SETDENTS].enabled) { - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": (*fd=%p, flags=%d, count=%d", - frame->root->unique, fd, flags, count); - } + trace_conf_t *conf = NULL; - STACK_WIND (frame, trace_setdents_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->setdents, - fd, flags, entries, count); - return 0; -} + conf = this->private; + if (!conf->log_file && !conf->log_history) + goto out; + if (trace_fop_names[GF_FOP_FSTAT].enabled) { + char string[4096] = { + 0, + }; + snprintf(string, sizeof(string), "%" PRId64 ": gfid=%s fd=%p", + frame->root->unique, uuid_utoa(fd->inode->gfid), fd); -int -trace_checksum_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, - uint8_t *fchecksum, uint8_t *dchecksum) -{ - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": op_ret (%d), op_errno(%d)", - frame->root->unique, op_ret, op_errno); + frame->local = fd->inode->gfid; - STACK_UNWIND_STRICT (checksum, frame, op_ret, op_errno, - fchecksum, dchecksum); + LOG_ELEMENT(conf, string); + } - return 0; +out: + STACK_WIND(frame, trace_fstat_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->fstat, fd, xdata); + return 0; } - int -trace_checksum (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flag) +trace_lk(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t cmd, + struct gf_flock *lock, dict_t *xdata) { - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": loc->path (%s) flag (%d)", - frame->root->unique, loc->path, flag); + trace_conf_t *conf = NULL; - STACK_WIND (frame, trace_checksum_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->fops->checksum, - loc, flag); + conf = this->private; - return 0; -} + if (!conf->log_file && !conf->log_history) + goto out; + if (trace_fop_names[GF_FOP_LK].enabled) { + char string[4096] = { + 0, + }; + snprintf(string, sizeof(string), + "%" PRId64 + ": gfid=%s fd=%p, cmd=%d, " + "lock {l_type=%d, " + "l_whence=%d, l_start=%" PRId64 + ", " + "l_len=%" PRId64 ", l_pid=%u})", + frame->root->unique, uuid_utoa(fd->inode->gfid), fd, cmd, + lock->l_type, lock->l_whence, lock->l_start, lock->l_len, + lock->l_pid); + frame->local = fd->inode->gfid; -int -trace_stats_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, - struct xlator_stats *stats) -{ - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": op_ret (%d), op_errno(%d)", - frame->root->unique, op_ret, op_errno); + LOG_ELEMENT(conf, string); + } - STACK_UNWIND (frame, op_ret, op_errno, stats); - return 0; +out: + STACK_WIND(frame, trace_lk_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->lk, fd, cmd, lock, xdata); + return 0; } +int32_t +trace_forget(xlator_t *this, inode_t *inode) +{ + trace_conf_t *conf = NULL; + + conf = this->private; + /* If user want to understand when a lookup happens, + he should know about 'forget' too */ + if (!conf->log_file && !conf->log_history) + goto out; + if (trace_fop_names[GF_FOP_LOOKUP].enabled) { + char string[4096] = { + 0, + }; + snprintf(string, sizeof(string), "gfid=%s", uuid_utoa(inode->gfid)); -int -trace_stats (call_frame_t *frame, xlator_t *this, int32_t flags) + LOG_ELEMENT(conf, string); + } + +out: + return 0; +} + +int32_t +trace_releasedir(xlator_t *this, fd_t *fd) { - gf_log (this->name, GF_LOG_NORMAL, - "%"PRId64": (flags=%d)", - frame->root->unique, flags); + trace_conf_t *conf = NULL; + + conf = this->private; - STACK_WIND (frame, trace_stats_cbk, - FIRST_CHILD(this), - FIRST_CHILD(this)->mops->stats, - flags); + if (!conf->log_file && !conf->log_history) + goto out; + if (trace_fop_names[GF_FOP_OPENDIR].enabled) { + char string[4096] = { + 0, + }; + snprintf(string, sizeof(string), "gfid=%s fd=%p", + uuid_utoa(fd->inode->gfid), fd); - return 0; + LOG_ELEMENT(conf, string); + } + +out: + return 0; } +int32_t +trace_release(xlator_t *this, fd_t *fd) +{ + trace_conf_t *conf = NULL; + + conf = this->private; + + if (!conf->log_file && !conf->log_history) + goto out; + if (trace_fop_names[GF_FOP_OPEN].enabled || + trace_fop_names[GF_FOP_CREATE].enabled) { + char string[4096] = { + 0, + }; + snprintf(string, sizeof(string), "gfid=%s fd=%p", + uuid_utoa(fd->inode->gfid), fd); + + LOG_ELEMENT(conf, string); + } + +out: + return 0; +} void -enable_all_calls (int enabled) +enable_all_calls(int enabled) { - int i; + int i; - for (i = 0; i < GF_FOP_MAXVALUE; i++) - trace_fop_names[i].enabled = enabled; + for (i = 0; i < GF_FOP_MAXVALUE; i++) + trace_fop_names[i].enabled = enabled; } - void -enable_call (const char *name, int enabled) +enable_call(const char *name, int enabled) { - int i; - for (i = 0; i < GF_FOP_MAXVALUE; i++) - if (!strcasecmp(trace_fop_names[i].name, name)) - trace_fop_names[i].enabled = enabled; + int i; + for (i = 0; i < GF_FOP_MAXVALUE; i++) + if (!strcasecmp(trace_fop_names[i].name, name)) + trace_fop_names[i].enabled = enabled; } - /* include = 1 for "include-ops" = 0 for "exclude-ops" */ void -process_call_list (const char *list, int include) +process_call_list(const char *list, int include) { - enable_all_calls (include ? 0 : 1); + enable_all_calls(include ? 0 : 1); - char *call = strsep ((char **)&list, ","); + char *call = strsep((char **)&list, ","); - while (call) { - enable_call (call, include); - call = strsep ((char **)&list, ","); - } + while (call) { + enable_call(call, include); + call = strsep((char **)&list, ","); + } } +int32_t +trace_dump_history(xlator_t *this) +{ + int ret = -1; + char key_prefix[GF_DUMP_MAX_BUF_LEN] = { + 0, + }; + trace_conf_t *conf = NULL; + + GF_VALIDATE_OR_GOTO("trace", this, out); + GF_VALIDATE_OR_GOTO(this->name, this->history, out); + + conf = this->private; + // Is it ok to return silently if log-history option his off? + if (conf && conf->log_history == _gf_true) { + gf_proc_dump_build_key(key_prefix, "xlator.debug.trace", "history"); + gf_proc_dump_add_section("%s", key_prefix); + eh_dump(this->history, NULL, dump_history_trace); + } + ret = 0; + +out: + return ret; +} int32_t -init (xlator_t *this) +mem_acct_init(xlator_t *this) { - dict_t *options = NULL; - char *includes = NULL, *excludes = NULL; + int ret = -1; - if (!this) - return -1; + if (!this) + return ret; - if (!this->children || this->children->next) { - gf_log (this->name, GF_LOG_ERROR, - "trace translator requires one subvolume"); - return -1; - } - if (!this->parents) { - gf_log (this->name, GF_LOG_WARNING, - "dangling volume. check volfile "); - } + ret = xlator_mem_acct_init(this, gf_trace_mt_end + 1); + if (ret != 0) { + gf_log(this->name, GF_LOG_ERROR, + "Memory accounting init" + " failed"); + return ret; + } - options = this->options; - includes = data_to_str (dict_get (options, "include-ops")); - excludes = data_to_str (dict_get (options, "exclude-ops")); + return ret; +} - { - int i; - for (i = 0; i < GF_FOP_MAXVALUE; i++) { - trace_fop_names[i].name = (gf_fop_list[i] ? - gf_fop_list[i] : ":O"); - trace_fop_names[i].enabled = 1; - } - } +int +reconfigure(xlator_t *this, dict_t *options) +{ + int32_t ret = -1; + trace_conf_t *conf = NULL; + char *includes = NULL, *excludes = NULL; + + GF_VALIDATE_OR_GOTO("quick-read", this, out); + GF_VALIDATE_OR_GOTO(this->name, this->private, out); + GF_VALIDATE_OR_GOTO(this->name, options, out); + + conf = this->private; + + includes = data_to_str(dict_get(options, "include-ops")); + excludes = data_to_str(dict_get(options, "exclude-ops")); - if (includes && excludes) { - gf_log (this->name, - GF_LOG_ERROR, - "must specify only one of 'include-ops' and 'exclude-ops'"); - return -1; + { + int i; + for (i = 0; i < GF_FOP_MAXVALUE; i++) { + if (gf_fop_list[i]) + strncpy(trace_fop_names[i].name, gf_fop_list[i], + sizeof(trace_fop_names[i].name)); + else + strncpy(trace_fop_names[i].name, ":0", + sizeof(trace_fop_names[i].name)); + trace_fop_names[i].enabled = 1; + trace_fop_names[i].name[sizeof(trace_fop_names[i].name) - 1] = 0; } - if (includes) - process_call_list (includes, 1); - if (excludes) - process_call_list (excludes, 0); + } + + if (includes && excludes) { + gf_log(this->name, GF_LOG_ERROR, + "must specify only one of 'include-ops' and " + "'exclude-ops'"); + goto out; + } + + if (includes) + process_call_list(includes, 1); + if (excludes) + process_call_list(excludes, 0); + + /* Should resizing of the event-history be allowed in reconfigure? + * for which a new event_history might have to be allocated and the + * older history has to be freed. + */ + GF_OPTION_RECONF("log-file", conf->log_file, options, bool, out); + + GF_OPTION_RECONF("log-history", conf->log_history, options, bool, out); - if (gf_log_get_loglevel () < GF_LOG_NORMAL) - gf_log_set_loglevel (GF_LOG_NORMAL); + ret = 0; - /* Set this translator's inode table pointer to child node's pointer. */ - this->itable = FIRST_CHILD (this)->itable; +out: + return ret; +} - return 0; +int32_t +init(xlator_t *this) +{ + dict_t *options = NULL; + char *includes = NULL, *excludes = NULL; + char *forced_loglevel = NULL; + eh_t *history = NULL; + int ret = -1; + uint64_t history_size = TRACE_DEFAULT_HISTORY_SIZE; + trace_conf_t *conf = NULL; + + if (!this) + return -1; + + if (!this->children || this->children->next) { + gf_log(this->name, GF_LOG_ERROR, + "trace translator requires one subvolume"); + return -1; + } + if (!this->parents) { + gf_log(this->name, GF_LOG_WARNING, "dangling volume. check volfile "); + } + + conf = GF_CALLOC(1, sizeof(trace_conf_t), gf_trace_mt_trace_conf_t); + if (!conf) { + gf_log(this->name, GF_LOG_ERROR, + "cannot allocate " + "xl->private"); + return -1; + } + + options = this->options; + includes = data_to_str(dict_get(options, "include-ops")); + excludes = data_to_str(dict_get(options, "exclude-ops")); + + { + int i; + for (i = 0; i < GF_FOP_MAXVALUE; i++) { + if (gf_fop_list[i]) + strncpy(trace_fop_names[i].name, gf_fop_list[i], + sizeof(trace_fop_names[i].name)); + else + strncpy(trace_fop_names[i].name, ":O", + sizeof(trace_fop_names[i].name)); + trace_fop_names[i].enabled = 1; + trace_fop_names[i].name[sizeof(trace_fop_names[i].name) - 1] = 0; + } + } + + if (includes && excludes) { + gf_log(this->name, GF_LOG_ERROR, + "must specify only one of 'include-ops' and " + "'exclude-ops'"); + return -1; + } + + if (includes) + process_call_list(includes, 1); + if (excludes) + process_call_list(excludes, 0); + + GF_OPTION_INIT("history-size", history_size, size, out); + conf->history_size = history_size; + + gf_log(this->name, GF_LOG_INFO, "history size %" PRIu64, history_size); + + GF_OPTION_INIT("log-file", conf->log_file, bool, out); + + gf_log(this->name, GF_LOG_INFO, "logging to file %s", + (conf->log_file == _gf_true) ? "enabled" : "disabled"); + + GF_OPTION_INIT("log-history", conf->log_history, bool, out); + + gf_log(this->name, GF_LOG_DEBUG, "logging to history %s", + (conf->log_history == _gf_true) ? "enabled" : "disabled"); + + history = eh_new(history_size, _gf_false, NULL); + if (!history) { + gf_log(this->name, GF_LOG_ERROR, + "event history cannot be " + "initialized"); + return -1; + } + + this->history = history; + + conf->trace_log_level = GF_LOG_INFO; + + if (dict_get(options, "force-log-level")) { + forced_loglevel = data_to_str(dict_get(options, "force-log-level")); + if (!forced_loglevel) + goto setloglevel; + + if (strcmp(forced_loglevel, "INFO") == 0) + conf->trace_log_level = GF_LOG_INFO; + else if (strcmp(forced_loglevel, "TRACE") == 0) + conf->trace_log_level = GF_LOG_TRACE; + else if (strcmp(forced_loglevel, "ERROR") == 0) + conf->trace_log_level = GF_LOG_ERROR; + else if (strcmp(forced_loglevel, "DEBUG") == 0) + conf->trace_log_level = GF_LOG_DEBUG; + else if (strcmp(forced_loglevel, "WARNING") == 0) + conf->trace_log_level = GF_LOG_WARNING; + else if (strcmp(forced_loglevel, "CRITICAL") == 0) + conf->trace_log_level = GF_LOG_CRITICAL; + else if (strcmp(forced_loglevel, "NONE") == 0) + conf->trace_log_level = GF_LOG_NONE; + } + +setloglevel: + gf_log_set_loglevel(this->ctx, conf->trace_log_level); + this->private = conf; + ret = 0; +out: + if (ret == -1) { + if (history) + GF_FREE(history); + if (conf) + GF_FREE(conf); + } + + return ret; } void -fini (xlator_t *this) +fini(xlator_t *this) { - if (!this) - return; - - gf_log (this->name, GF_LOG_NORMAL, - "trace translator unloaded"); + if (!this) return; + + if (this->history) + eh_destroy(this->history); + + gf_log(this->name, GF_LOG_INFO, "trace translator unloaded"); + return; } struct xlator_fops fops = { - .stat = trace_stat, - .readlink = trace_readlink, - .mknod = trace_mknod, - .mkdir = trace_mkdir, - .unlink = trace_unlink, - .rmdir = trace_rmdir, - .symlink = trace_symlink, - .rename = trace_rename, - .link = trace_link, - .truncate = trace_truncate, - .open = trace_open, - .readv = trace_readv, - .writev = trace_writev, - .statfs = trace_statfs, - .flush = trace_flush, - .fsync = trace_fsync, - .setxattr = trace_setxattr, - .getxattr = trace_getxattr, - .removexattr = trace_removexattr, - .opendir = trace_opendir, - .readdir = trace_readdir, - .readdirp = trace_readdirp, - .fsyncdir = trace_fsyncdir, - .access = trace_access, - .ftruncate = trace_ftruncate, - .fstat = trace_fstat, - .create = trace_create, - .lk = trace_lk, - .inodelk = trace_inodelk, - .finodelk = trace_finodelk, - .entrylk = trace_entrylk, - .lookup = trace_lookup, - .setdents = trace_setdents, - .getdents = trace_getdents, - .checksum = trace_checksum, - .xattrop = trace_xattrop, - .fxattrop = trace_fxattrop, - .setattr = trace_setattr, - .fsetattr = trace_fsetattr, -}; - -struct xlator_mops mops = { - .stats = trace_stats, + .stat = trace_stat, + .readlink = trace_readlink, + .mknod = trace_mknod, + .mkdir = trace_mkdir, + .unlink = trace_unlink, + .rmdir = trace_rmdir, + .symlink = trace_symlink, + .rename = trace_rename, + .link = trace_link, + .truncate = trace_truncate, + .open = trace_open, + .readv = trace_readv, + .writev = trace_writev, + .statfs = trace_statfs, + .flush = trace_flush, + .fsync = trace_fsync, + .setxattr = trace_setxattr, + .getxattr = trace_getxattr, + .fsetxattr = trace_fsetxattr, + .fgetxattr = trace_fgetxattr, + .removexattr = trace_removexattr, + .opendir = trace_opendir, + .readdir = trace_readdir, + .readdirp = trace_readdirp, + .fsyncdir = trace_fsyncdir, + .access = trace_access, + .ftruncate = trace_ftruncate, + .fstat = trace_fstat, + .create = trace_create, + .lk = trace_lk, + .inodelk = trace_inodelk, + .finodelk = trace_finodelk, + .entrylk = trace_entrylk, + .fentrylk = trace_fentrylk, + .lookup = trace_lookup, + .rchecksum = trace_rchecksum, + .xattrop = trace_xattrop, + .fxattrop = trace_fxattrop, + .setattr = trace_setattr, + .fsetattr = trace_fsetattr, + .seek = trace_seek, }; struct xlator_cbks cbks = { + .release = trace_release, + .releasedir = trace_releasedir, + .forget = trace_forget, }; struct volume_options options[] = { - { .key = {"include-ops", "include"}, - .type = GF_OPTION_TYPE_STR, - /*.value = { ""} */ - }, - { .key = {"exclude-ops", "exclude"}, - .type = GF_OPTION_TYPE_STR - /*.value = { ""} */ - }, - { .key = {NULL} }, + { + .key = {"include-ops", "include"}, + .type = GF_OPTION_TYPE_STR, + /*.value = { ""} */ + }, + { + .key = {"exclude-ops", "exclude"}, + .type = GF_OPTION_TYPE_STR + /*.value = { ""} */ + }, + { + .key = {"history-size"}, + .type = GF_OPTION_TYPE_SIZET, + .default_value = "1024", + }, + { + .key = {"log-file"}, + .type = GF_OPTION_TYPE_BOOL, + .default_value = "no", + }, + { + .key = {"log-history"}, + .type = GF_OPTION_TYPE_BOOL, + .default_value = "no", + }, + {.key = {NULL}}, +}; + +struct xlator_dumpops dumpops = {.history = trace_dump_history}; + +xlator_api_t xlator_api = { + .init = init, + .fini = fini, + .reconfigure = reconfigure, + .mem_acct_init = mem_acct_init, + .op_version = {1}, + .dumpops = &dumpops, + .fops = &fops, + .cbks = &cbks, + .options = options, + .identifier = "trace", + .category = GF_TECH_PREVIEW, }; diff --git a/xlators/debug/trace/src/trace.h b/xlators/debug/trace/src/trace.h new file mode 100644 index 00000000000..b16304799da --- /dev/null +++ b/xlators/debug/trace/src/trace.h @@ -0,0 +1,55 @@ +/* + Copyright (c) 2006-2012 Red Hat, Inc. <http://www.redhat.com> + This file is part of GlusterFS. + + This file is licensed to you under your choice of the GNU Lesser + General Public License, version 3 or any later version (LGPLv3 or + later), or the GNU General Public License, version 2 (GPLv2), in all + cases as published by the Free Software Foundation. +*/ + +#include <time.h> +#include <errno.h> +#include <glusterfs/glusterfs.h> +#include <glusterfs/xlator.h> +#include <glusterfs/common-utils.h> +#include <glusterfs/event-history.h> +#include <glusterfs/logging.h> +#include <glusterfs/circ-buff.h> +#include <glusterfs/statedump.h> +#include <glusterfs/options.h> + +#define TRACE_DEFAULT_HISTORY_SIZE 1024 + +typedef struct { + /* Since the longest fop name is fremovexattr i.e 12 characters, array size + * is kept 24, i.e double of the maximum. + */ + char name[24]; + int enabled; +} trace_fop_name_t; + +trace_fop_name_t trace_fop_names[GF_FOP_MAXVALUE]; + +typedef struct { + gf_boolean_t log_file; + gf_boolean_t log_history; + uint64_t history_size; + int trace_log_level; +} trace_conf_t; + +#define TRACE_STACK_UNWIND(op, frame, params...) \ + do { \ + frame->local = NULL; \ + STACK_UNWIND_STRICT(op, frame, params); \ + } while (0); + +#define LOG_ELEMENT(_conf, _string) \ + do { \ + if (_conf) { \ + if ((_conf->log_history) == _gf_true) \ + gf_log_eh("%s", _string); \ + if ((_conf->log_file) == _gf_true) \ + gf_log(THIS->name, _conf->trace_log_level, "%s", _string); \ + } \ + } while (0); |
