From c8b9a9e9f82af7e752d4d881313374713701441d Mon Sep 17 00:00:00 2001 From: Ajeet Jha Date: Mon, 2 Dec 2013 13:04:51 +0530 Subject: features/changelog: more changelog fixes. -> log additional records. -> include FOP number for metadata. -> prevent crash if inode is not found in a fop. Change-Id: I9edd4b71819ebd68c6a2b4150ae279c471d129da BUG: 1036536 Signed-off-by: Ajeet Jha Reviewed-on: http://review.gluster.org/6403 Tested-by: Gluster Build System Reviewed-by: Amar Tumballi Reviewed-by: Venky Shankar Reviewed-on: http://review.gluster.org/6808 Reviewed-by: Vijay Bellur --- .../changelog/lib/examples/c/get-changes.c | 2 +- .../changelog/lib/src/gf-changelog-process.c | 79 ++++++++++--- .../features/changelog/src/changelog-encoders.c | 21 ++++ .../features/changelog/src/changelog-encoders.h | 2 + xlators/features/changelog/src/changelog-helpers.c | 3 + xlators/features/changelog/src/changelog-helpers.h | 12 +- xlators/features/changelog/src/changelog-misc.h | 2 +- xlators/features/changelog/src/changelog.c | 129 ++++++++++++++++++--- 8 files changed, 212 insertions(+), 38 deletions(-) diff --git a/xlators/features/changelog/lib/examples/c/get-changes.c b/xlators/features/changelog/lib/examples/c/get-changes.c index 14562585a..6d0d0357d 100644 --- a/xlators/features/changelog/lib/examples/c/get-changes.c +++ b/xlators/features/changelog/lib/examples/c/get-changes.c @@ -40,7 +40,7 @@ main (int argc, char ** argv) char fbuf[PATH_MAX] = {0,}; /* get changes for brick "/home/vshankar/export/yow/yow-1" */ - ret = gf_changelog_register ("/home/vshankar/export/yow/yow-1", + ret = gf_changelog_register ("/home/vshankar/exports/yow/yow-1", "/tmp/scratch", "/tmp/change.log", 9, 5); if (ret) { handle_error ("register failed"); diff --git a/xlators/features/changelog/lib/src/gf-changelog-process.c b/xlators/features/changelog/lib/src/gf-changelog-process.c index df7204931..3ea2700c6 100644 --- a/xlators/features/changelog/lib/src/gf-changelog-process.c +++ b/xlators/features/changelog/lib/src/gf-changelog-process.c @@ -36,6 +36,17 @@ int nr_gfids[] = { [GF_FOP_CREATE] = 1, }; +int nr_extra_recs[] = { + [GF_FOP_MKNOD] = 3, + [GF_FOP_MKDIR] = 3, + [GF_FOP_UNLINK] = 0, + [GF_FOP_RMDIR] = 0, + [GF_FOP_SYMLINK] = 0, + [GF_FOP_RENAME] = 0, + [GF_FOP_LINK] = 0, + [GF_FOP_CREATE] = 3, +}; + static char * binary_to_ascii (uuid_t uuid) { @@ -211,20 +222,20 @@ gf_changelog_parse_ascii (xlator_t *this, gf_changelog_t *gfc, int from_fd, int to_fd, size_t start_offset, struct stat *stbuf) { - int ng = 0; - int ret = -1; - int fop = 0; - int len = 0; - off_t off = 0; - off_t nleft = 0; - char *ptr = NULL; - char *eptr = NULL; - char *start = NULL; - char *mover = NULL; - int parse_err = 0; - char current_mover = ' '; - char ascii[LINE_BUFSIZE] = {0,}; - const char *fopname = NULL; + int ng = 0; + int ret = -1; + int fop = 0; + int len = 0; + off_t off = 0; + off_t nleft = 0; + char *ptr = NULL; + char *eptr = NULL; + char *start = NULL; + char *mover = NULL; + int parse_err = 0; + char current_mover = ' '; + char ascii[LINE_BUFSIZE] = {0,}; + const char *fopname = NULL; nleft = stbuf->st_size; @@ -249,7 +260,6 @@ gf_changelog_parse_ascii (xlator_t *this, switch (current_mover) { case 'D': - case 'M': MOVER_MOVE (mover, nleft, 1); /* target gfid */ @@ -258,6 +268,32 @@ gf_changelog_parse_ascii (xlator_t *this, FILL_AND_MOVE(ptr, ascii, off, mover, nleft, UUID_CANONICAL_FORM_LEN); break; + case 'M': + MOVER_MOVE (mover, nleft, 1); + + /* target gfid */ + PARSE_GFID (mover, ptr, UUID_CANONICAL_FORM_LEN, + conv_noop, parse_err); + FILL_AND_MOVE (ptr, ascii, off, + mover, nleft, UUID_CANONICAL_FORM_LEN); + FILL_AND_MOVE (" ", ascii, off, mover, nleft, 1); + + /* fop */ + len = strlen (mover); + VERIFY_SEPARATOR (mover, len, parse_err); + + fop = atoi (mover); + if ( (fopname = gf_fop_list[fop]) == NULL) { + parse_err = 1; + break; + } + + MOVER_MOVE (mover, nleft, len); + + len = strlen (fopname); + GF_CHANGELOG_FILL_BUFFER (fopname, ascii, off, len); + + break; case 'E': MOVER_MOVE (mover, nleft, 1); @@ -285,6 +321,17 @@ gf_changelog_parse_ascii (xlator_t *this, len = strlen (fopname); GF_CHANGELOG_FILL_BUFFER (fopname, ascii, off, len); + ng = nr_extra_recs[fop]; + for (;ng > 0; ng--) { + MOVER_MOVE (mover, nleft, 1); + len = strlen (mover); + VERIFY_SEPARATOR (mover, len, parse_err); + + GF_CHANGELOG_FILL_BUFFER (" ", ascii, off, 1); + FILL_AND_MOVE (mover, ascii, + off, mover, nleft, len); + } + /* pargfid + bname */ ng = nr_gfids[fop]; while (ng-- > 0) { @@ -320,7 +367,7 @@ gf_changelog_parse_ascii (xlator_t *this, if (gf_changelog_write (to_fd, ascii, off) != off) { gf_log (this->name, GF_LOG_ERROR, "processing ascii changelog failed due to " - " wrror in writing change (reason: %s)", + " error in writing change (reason: %s)", strerror (errno)); break; } diff --git a/xlators/features/changelog/src/changelog-encoders.c b/xlators/features/changelog/src/changelog-encoders.c index 553eec85c..08626ee2f 100644 --- a/xlators/features/changelog/src/changelog-encoders.c +++ b/xlators/features/changelog/src/changelog-encoders.c @@ -56,6 +56,24 @@ fop_fn (void *data, char *buffer, gf_boolean_t encode) return bufsz; } +size_t +number_fn (void *data, char *buffer, gf_boolean_t encode) +{ + size_t bufsz = 0; + unsigned int nr = 0; + char buf[20] = {0,}; + + nr = *(unsigned int *) data; + + if (encode) { + (void) snprintf (buf, sizeof (buf), "%u", nr); + CHANGELOG_FILL_BUFFER (buffer, bufsz, buf, strlen (buf)); + } else + CHANGELOG_FILL_BUFFER (buffer, bufsz, &nr, sizeof (unsigned int)); + + return bufsz; +} + void entry_free_fn (void *data) { @@ -94,6 +112,9 @@ changelog_encode_write_xtra (changelog_log_data_t *cld, case CHANGELOG_OPT_REC_ENTRY: data = &co->co_entry; break; + case CHANGELOG_OPT_REC_UINT32: + data = &co->co_uint32; + break; } if (co->co_convert) diff --git a/xlators/features/changelog/src/changelog-encoders.h b/xlators/features/changelog/src/changelog-encoders.h index a3efbee05..c5dcc8a77 100644 --- a/xlators/features/changelog/src/changelog-encoders.h +++ b/xlators/features/changelog/src/changelog-encoders.h @@ -34,6 +34,8 @@ size_t entry_fn (void *data, char *buffer, gf_boolean_t encode); size_t fop_fn (void *data, char *buffer, gf_boolean_t encode); +size_t +number_fn (void *data, char *buffer, gf_boolean_t encode); void entry_free_fn (void *data); int diff --git a/xlators/features/changelog/src/changelog-helpers.c b/xlators/features/changelog/src/changelog-helpers.c index 7ab0091b5..91c43a16c 100644 --- a/xlators/features/changelog/src/changelog-helpers.c +++ b/xlators/features/changelog/src/changelog-helpers.c @@ -55,6 +55,9 @@ changelog_get_usable_buffer (changelog_local_t *local) { changelog_log_data_t *cld = NULL; + if (!local) + return NULL; + cld = &local->cld; if (!cld->cld_iobuf) return NULL; diff --git a/xlators/features/changelog/src/changelog-helpers.h b/xlators/features/changelog/src/changelog-helpers.h index ad79636b0..16d60b99b 100644 --- a/xlators/features/changelog/src/changelog-helpers.h +++ b/xlators/features/changelog/src/changelog-helpers.h @@ -225,6 +225,7 @@ typedef struct changelog_inode_ctx { typedef enum { CHANGELOG_OPT_REC_FOP, CHANGELOG_OPT_REC_ENTRY, + CHANGELOG_OPT_REC_UINT32, } changelog_optional_rec_type_t; struct changelog_entry_fields { @@ -253,7 +254,8 @@ typedef struct { size_t co_len; union { - glusterfs_fop_t co_fop; + unsigned int co_uint32; + glusterfs_fop_t co_fop; struct changelog_entry_fields co_entry; }; } changelog_opt_t; @@ -346,6 +348,14 @@ changelog_forget (xlator_t *this, inode_t *inode); } \ } while (0) +#define CHANGELOG_FILL_UINT32(co, number, converter, xlen) do { \ + co->co_convert = converter; \ + co->co_free = NULL; \ + co->co_type = CHANGELOG_OPT_REC_UINT32; \ + co->co_uint32 = number; \ + xlen += sizeof (unsigned int); \ + } while (0) + #define CHANGLOG_FILL_FOP_NUMBER(co, fop, converter, xlen) do { \ co->co_convert = converter; \ co->co_free = NULL; \ diff --git a/xlators/features/changelog/src/changelog-misc.h b/xlators/features/changelog/src/changelog-misc.h index 0712a3771..127b03e2e 100644 --- a/xlators/features/changelog/src/changelog-misc.h +++ b/xlators/features/changelog/src/changelog-misc.h @@ -18,7 +18,7 @@ #define CHANGELOG_FILE_NAME "CHANGELOG" #define CHANGELOG_VERSION_MAJOR 1 -#define CHANGELOG_VERSION_MINOR 0 +#define CHANGELOG_VERSION_MINOR 1 #define CHANGELOG_UNIX_SOCK DEFAULT_VAR_RUN_DIRECTORY"/changelog-%s.sock" diff --git a/xlators/features/changelog/src/changelog.c b/xlators/features/changelog/src/changelog.c index cea0e8c70..5fe3b4362 100644 --- a/xlators/features/changelog/src/changelog.c +++ b/xlators/features/changelog/src/changelog.c @@ -329,19 +329,28 @@ changelog_mkdir (call_frame_t *frame, xlator_t *this, } uuid_copy (gfid, uuid_req); - CHANGELOG_INIT_NOCHECK (this, frame->local, NULL, gfid, 2); + CHANGELOG_INIT_NOCHECK (this, frame->local, NULL, gfid, 5); co = changelog_get_usable_buffer (frame->local); if (!co) goto wind; CHANGLOG_FILL_FOP_NUMBER (co, frame->root->op, fop_fn, xtra_len); + co++; + + CHANGELOG_FILL_UINT32 (co, S_IFDIR | mode, number_fn, xtra_len); + co++; + CHANGELOG_FILL_UINT32 (co, frame->root->uid, number_fn, xtra_len); co++; + + CHANGELOG_FILL_UINT32 (co, frame->root->gid, number_fn, xtra_len); + co++; + CHANGELOG_FILL_ENTRY (co, loc->pargfid, loc->name, entry_fn, entry_free_fn, xtra_len, wind); - changelog_set_usable_record_and_length (frame->local, xtra_len, 2); + changelog_set_usable_record_and_length (frame->local, xtra_len, 5); wind: STACK_WIND (frame, changelog_mkdir_cbk, @@ -405,8 +414,8 @@ changelog_symlink (call_frame_t *frame, xlator_t *this, goto wind; CHANGLOG_FILL_FOP_NUMBER (co, frame->root->op, fop_fn, xtra_len); - co++; + CHANGELOG_FILL_ENTRY (co, loc->pargfid, loc->name, entry_fn, entry_free_fn, xtra_len, wind); @@ -467,19 +476,28 @@ changelog_mknod (call_frame_t *frame, } uuid_copy (gfid, uuid_req); - CHANGELOG_INIT_NOCHECK (this, frame->local, NULL, gfid, 2); + CHANGELOG_INIT_NOCHECK (this, frame->local, NULL, gfid, 5); co = changelog_get_usable_buffer (frame->local); if (!co) goto wind; CHANGLOG_FILL_FOP_NUMBER (co, frame->root->op, fop_fn, xtra_len); + co++; + + CHANGELOG_FILL_UINT32 (co, mode, number_fn, xtra_len); + co++; + + CHANGELOG_FILL_UINT32 (co, frame->root->uid, number_fn, xtra_len); + co++; + CHANGELOG_FILL_UINT32 (co, frame->root->gid, number_fn, xtra_len); co++; + CHANGELOG_FILL_ENTRY (co, loc->pargfid, loc->name, entry_fn, entry_free_fn, xtra_len, wind); - changelog_set_usable_record_and_length (frame->local, xtra_len, 2); + changelog_set_usable_record_and_length (frame->local, xtra_len, 5); wind: STACK_WIND (frame, changelog_mknod_cbk, @@ -539,7 +557,7 @@ changelog_create (call_frame_t *frame, xlator_t *this, uuid_copy (gfid, uuid_req); /* init with two extra records */ - CHANGELOG_INIT_NOCHECK (this, frame->local, NULL, gfid, 2); + CHANGELOG_INIT_NOCHECK (this, frame->local, NULL, gfid, 5); if (!frame->local) goto wind; @@ -548,12 +566,21 @@ changelog_create (call_frame_t *frame, xlator_t *this, goto wind; CHANGLOG_FILL_FOP_NUMBER (co, frame->root->op, fop_fn, xtra_len); + co++; + CHANGELOG_FILL_UINT32 (co, mode, number_fn, xtra_len); co++; + + CHANGELOG_FILL_UINT32 (co, frame->root->uid, number_fn, xtra_len); + co++; + + CHANGELOG_FILL_UINT32 (co, frame->root->gid, number_fn, xtra_len); + co++; + CHANGELOG_FILL_ENTRY (co, loc->pargfid, loc->name, entry_fn, entry_free_fn, xtra_len, wind); - changelog_set_usable_record_and_length (frame->local, xtra_len, 2); + changelog_set_usable_record_and_length (frame->local, xtra_len, 5); wind: STACK_WIND (frame, changelog_create_cbk, @@ -601,13 +628,25 @@ changelog_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd, struct iatt *stbuf, int32_t valid, dict_t *xdata) { - changelog_priv_t *priv = NULL; + changelog_priv_t *priv = NULL; + changelog_opt_t *co = NULL; + size_t xtra_len = 0; priv = this->private; CHANGELOG_NOT_ACTIVE_THEN_GOTO (frame, priv, wind); CHANGELOG_INIT (this, frame->local, - fd->inode, fd->inode->gfid, 0); + fd->inode, fd->inode->gfid, 1); + if (!frame->local) + goto wind; + + co = changelog_get_usable_buffer (frame->local); + if (!co) + goto wind; + + CHANGLOG_FILL_FOP_NUMBER (co, frame->root->op, fop_fn, xtra_len); + + changelog_set_usable_record_and_length (frame->local, xtra_len, 1); wind: STACK_WIND (frame, changelog_fsetattr_cbk, @@ -646,13 +685,25 @@ changelog_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc, struct iatt *stbuf, int32_t valid, dict_t *xdata) { - changelog_priv_t *priv = NULL; + changelog_priv_t *priv = NULL; + changelog_opt_t *co = NULL; + size_t xtra_len = 0; priv = this->private; CHANGELOG_NOT_ACTIVE_THEN_GOTO (frame, priv, wind); CHANGELOG_INIT (this, frame->local, - loc->inode, loc->inode->gfid, 0); + loc->inode, loc->inode->gfid, 1); + if (!frame->local) + goto wind; + + co = changelog_get_usable_buffer (frame->local); + if (!co) + goto wind; + + CHANGLOG_FILL_FOP_NUMBER (co, frame->root->op, fop_fn, xtra_len); + + changelog_set_usable_record_and_length (frame->local, xtra_len, 1); wind: STACK_WIND (frame, changelog_setattr_cbk, @@ -688,13 +739,23 @@ int32_t changelog_fremovexattr (call_frame_t *frame, xlator_t *this, fd_t *fd, const char *name, dict_t *xdata) { - changelog_priv_t *priv = NULL; + changelog_priv_t *priv = NULL; + changelog_opt_t *co = NULL; + size_t xtra_len = 0; priv = this->private; CHANGELOG_NOT_ACTIVE_THEN_GOTO (frame, priv, wind); CHANGELOG_INIT (this, frame->local, - fd->inode, fd->inode->gfid, 0); + fd->inode, fd->inode->gfid, 1); + + co = changelog_get_usable_buffer (frame->local); + if (!co) + goto wind; + + CHANGLOG_FILL_FOP_NUMBER (co, frame->root->op, fop_fn, xtra_len); + + changelog_set_usable_record_and_length (frame->local, xtra_len, 1); wind: STACK_WIND (frame, changelog_fremovexattr_cbk, @@ -728,13 +789,23 @@ int32_t changelog_removexattr (call_frame_t *frame, xlator_t *this, loc_t *loc, const char *name, dict_t *xdata) { - changelog_priv_t *priv = NULL; + changelog_priv_t *priv = NULL; + changelog_opt_t *co = NULL; + size_t xtra_len = 0; priv = this->private; CHANGELOG_NOT_ACTIVE_THEN_GOTO (frame, priv, wind); CHANGELOG_INIT (this, frame->local, - loc->inode, loc->inode->gfid, 0); + loc->inode, loc->inode->gfid, 1); + + co = changelog_get_usable_buffer (frame->local); + if (!co) + goto wind; + + CHANGLOG_FILL_FOP_NUMBER (co, frame->root->op, fop_fn, xtra_len); + + changelog_set_usable_record_and_length (frame->local, xtra_len, 1); wind: STACK_WIND (frame, changelog_removexattr_cbk, @@ -771,13 +842,23 @@ changelog_setxattr (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict, int32_t flags, dict_t *xdata) { - changelog_priv_t *priv = NULL; + changelog_priv_t *priv = NULL; + changelog_opt_t *co = NULL; + size_t xtra_len = 0; priv = this->private; CHANGELOG_NOT_ACTIVE_THEN_GOTO (frame, priv, wind); CHANGELOG_INIT (this, frame->local, - loc->inode, loc->inode->gfid, 0); + loc->inode, loc->inode->gfid, 1); + + co = changelog_get_usable_buffer (frame->local); + if (!co) + goto wind; + + CHANGLOG_FILL_FOP_NUMBER (co, frame->root->op, fop_fn, xtra_len); + + changelog_set_usable_record_and_length (frame->local, xtra_len, 1); wind: STACK_WIND (frame, changelog_setxattr_cbk, @@ -812,13 +893,23 @@ changelog_fsetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *dict, int32_t flags, dict_t *xdata) { - changelog_priv_t *priv = NULL; + changelog_priv_t *priv = NULL; + changelog_opt_t *co = NULL; + size_t xtra_len = 0; priv = this->private; CHANGELOG_NOT_ACTIVE_THEN_GOTO (frame, priv, wind); CHANGELOG_INIT (this, frame->local, - fd->inode, fd->inode->gfid, 0); + fd->inode, fd->inode->gfid, 1); + + co = changelog_get_usable_buffer (frame->local); + if (!co) + goto wind; + + CHANGLOG_FILL_FOP_NUMBER (co, frame->root->op, fop_fn, xtra_len); + + changelog_set_usable_record_and_length (frame->local, xtra_len, 1); wind: STACK_WIND (frame, changelog_fsetxattr_cbk, -- cgit