diff options
Diffstat (limited to 'xlators/features/changelog/src')
| -rw-r--r-- | xlators/features/changelog/src/changelog-encoders.c | 44 | ||||
| -rw-r--r-- | xlators/features/changelog/src/changelog-encoders.h | 4 | ||||
| -rw-r--r-- | xlators/features/changelog/src/changelog-helpers.c | 85 | ||||
| -rw-r--r-- | xlators/features/changelog/src/changelog-helpers.h | 26 | ||||
| -rw-r--r-- | xlators/features/changelog/src/changelog-misc.h | 2 | ||||
| -rw-r--r-- | xlators/features/changelog/src/changelog.c | 32 | 
6 files changed, 188 insertions, 5 deletions
diff --git a/xlators/features/changelog/src/changelog-encoders.c b/xlators/features/changelog/src/changelog-encoders.c index ea9db4061ca..ea395e11f90 100644 --- a/xlators/features/changelog/src/changelog-encoders.c +++ b/xlators/features/changelog/src/changelog-encoders.c @@ -39,6 +39,38 @@ entry_fn (void *data, char *buffer, gf_boolean_t encode)  }  size_t +del_entry_fn (void *data, char *buffer, gf_boolean_t encode) +{ +        char    *tmpbuf = NULL; +        size_t  bufsz  = 0; +        struct changelog_entry_fields *ce = NULL; + +        ce = (struct changelog_entry_fields *) data; + +        if (encode) { +                tmpbuf = uuid_utoa (ce->cef_uuid); +                CHANGELOG_FILL_BUFFER (buffer, bufsz, tmpbuf, strlen (tmpbuf)); +        } else { +                CHANGELOG_FILL_BUFFER (buffer, bufsz, +                                       ce->cef_uuid, sizeof (uuid_t)); +        } + +        CHANGELOG_FILL_BUFFER (buffer, bufsz, "/", 1); +        CHANGELOG_FILL_BUFFER (buffer, bufsz, +                               ce->cef_bname, strlen (ce->cef_bname)); +        CHANGELOG_FILL_BUFFER (buffer, bufsz, "\0", 1); + +        if (ce->cef_path[0] == '\0') { +                CHANGELOG_FILL_BUFFER (buffer, bufsz, "\0", 1); +        } else { +                CHANGELOG_FILL_BUFFER (buffer, bufsz, +                                       ce->cef_path, strlen (ce->cef_path)); +        } + +        return bufsz; +} + +size_t  fop_fn (void *data, char *buffer, gf_boolean_t encode)  {          char buf[10]          = {0,}; @@ -85,6 +117,18 @@ entry_free_fn (void *data)          GF_FREE (co->co_entry.cef_bname);  } +void +del_entry_free_fn (void *data) +{ +        changelog_opt_t *co = data; + +        if (!co) +                return; + +        GF_FREE (co->co_entry.cef_bname); +        GF_FREE (co->co_entry.cef_path); +} +  /**   * try to write all data in one shot   */ diff --git a/xlators/features/changelog/src/changelog-encoders.h b/xlators/features/changelog/src/changelog-encoders.h index c5dcc8a77d9..d6a50cc9ef7 100644 --- a/xlators/features/changelog/src/changelog-encoders.h +++ b/xlators/features/changelog/src/changelog-encoders.h @@ -33,11 +33,15 @@  size_t  entry_fn (void *data, char *buffer, gf_boolean_t encode);  size_t +del_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); +void +del_entry_free_fn (void *data);  int  changelog_encode_binary (xlator_t *, changelog_log_data_t *);  int diff --git a/xlators/features/changelog/src/changelog-helpers.c b/xlators/features/changelog/src/changelog-helpers.c index a72ad25e4bc..0a29969194e 100644 --- a/xlators/features/changelog/src/changelog-helpers.c +++ b/xlators/features/changelog/src/changelog-helpers.c @@ -1735,3 +1735,88 @@ err:                  inode_unref (parent);          return -1;  } + +/* + * resolve_pargfid_to_path: + *      It converts given pargfid to path by doing recursive readlinks at the + * backend. If bname is given, it suffixes bname to pargfid to form the + * complete path else it doesn't. It allocates memory for the path and is + * caller's responsibility to free the same. If bname is NULL and pargfid + * is ROOT, then it returns "." + */ + +int +resolve_pargfid_to_path (xlator_t *this, uuid_t pargfid, +                         char **path, char *bname) +{ +        char             *linkname                  = NULL; +        char             *dir_handle                = NULL; +        char             *pgfidstr                  = NULL; +        char             *saveptr                   = NULL; +        ssize_t           len                       = 0; +        int               ret                       = 0; +        uuid_t            tmp_gfid                  = {0, }; +        changelog_priv_t *priv                      = NULL; +        char              gpath[PATH_MAX]           = {0,}; +        char              result[PATH_MAX]          = {0,}; +        char             *dir_name                  = NULL; +        char              pre_dir_name[PATH_MAX]    = {0,}; + +        GF_ASSERT (this); +        priv = this->private; +        GF_ASSERT (priv); + +        if (!path || gf_uuid_is_null (pargfid)) { +                ret = -1; +                goto out; +        } + +        if (__is_root_gfid (pargfid)) { +                if (bname) +                        *path = gf_strdup (bname); +                else +                        *path = gf_strdup ("."); +                return ret; +        } + +        dir_handle = alloca (PATH_MAX); +        linkname   = alloca (PATH_MAX); +        (void) snprintf (gpath, PATH_MAX, "%s/.glusterfs/", +                         priv->changelog_brick); + +        while (!(__is_root_gfid (pargfid))) { +                snprintf (dir_handle, PATH_MAX, "%s/%02x/%02x/%s", gpath, +                          pargfid[0], pargfid[1], uuid_utoa (pargfid)); + +                len = readlink (dir_handle, linkname, PATH_MAX); +                if (len < 0) { +                        gf_log (this->name, GF_LOG_ERROR, "could not read the " +                                "link from the gfid handle %s (%s)", dir_handle, +                                strerror (errno)); +                        ret = -1; +                        goto out; +                } + +                linkname[len] = '\0'; + +                pgfidstr = strtok_r (linkname + strlen("../../00/00/"), "/", +                                     &saveptr); +                dir_name = strtok_r (NULL, "/", &saveptr); + +                strncpy (result, dir_name, PATH_MAX); +                strncat (result, "/", 1); +                strncat (result, pre_dir_name, PATH_MAX); +                strncpy (pre_dir_name, result, PATH_MAX); + +                gf_uuid_parse (pgfidstr, tmp_gfid); +                gf_uuid_copy (pargfid, tmp_gfid); +        } + +        if (bname) +                strncat (result, bname, PATH_MAX); + +        *path = gf_strdup (result); + +out: +        return ret; +} diff --git a/xlators/features/changelog/src/changelog-helpers.h b/xlators/features/changelog/src/changelog-helpers.h index b552c308e0f..ccfbf9113d8 100644 --- a/xlators/features/changelog/src/changelog-helpers.h +++ b/xlators/features/changelog/src/changelog-helpers.h @@ -306,6 +306,9 @@ struct changelog_priv {          pthread_t *ev_dispatcher;          changelog_clnt_t connections; + +        /* glusterfind dependency to capture paths on deleted entries*/ +        gf_boolean_t capture_del_path;  };  struct changelog_local { @@ -349,6 +352,7 @@ typedef enum {  struct changelog_entry_fields {          uuid_t  cef_uuid;          char   *cef_bname; +        char   *cef_path;  };  typedef struct { @@ -497,6 +501,8 @@ changelog_dispatch_event (xlator_t *, changelog_priv_t *, changelog_event_t *);  changelog_inode_ctx_t *  __changelog_inode_ctx_get (xlator_t *, inode_t *, unsigned long **,                             unsigned long *, changelog_log_type); +int +resolve_pargfid_to_path (xlator_t *this, uuid_t gfid, char **path, char *bname);  /* macros */ @@ -566,6 +572,26 @@ __changelog_inode_ctx_get (xlator_t *, inode_t *, unsigned long **,                  xlen += (UUID_CANONICAL_FORM_LEN + strlen (bname));     \          } while (0) +#define CHANGELOG_FILL_ENTRY_DIR_PATH(co, pargfid, bname, converter,        \ +                                      del_freefn, xlen, label, capture_del) \ +        do {                                                                \ +                co->co_convert = converter;                                 \ +                co->co_free = del_freefn;                                   \ +                co->co_type = CHANGELOG_OPT_REC_ENTRY;                      \ +                gf_uuid_copy (co->co_entry.cef_uuid, pargfid);              \ +                co->co_entry.cef_bname = gf_strdup(bname);                  \ +                if (!co->co_entry.cef_bname)                                \ +                        goto label;                                         \ +                xlen += (UUID_CANONICAL_FORM_LEN + strlen (bname));         \ +                if (!capture_del || resolve_pargfid_to_path (this, pargfid, \ +                    &(co->co_entry.cef_path), co->co_entry.cef_bname)) {    \ +                        co->co_entry.cef_path = gf_strdup ("\0");           \ +                        xlen += 1;                                          \ +                } else {                                                    \ +                        xlen += (strlen (co->co_entry.cef_path));           \ +                }                                                           \ +        } while (0) +  #define CHANGELOG_INIT(this, local, inode, gfid, xrec)                  \          local = changelog_local_init (this, inode, gfid, xrec, _gf_false) diff --git a/xlators/features/changelog/src/changelog-misc.h b/xlators/features/changelog/src/changelog-misc.h index b7b1b95d3df..6658552ecf1 100644 --- a/xlators/features/changelog/src/changelog-misc.h +++ b/xlators/features/changelog/src/changelog-misc.h @@ -23,7 +23,7 @@  #define HTIME_INITIAL_VALUE "0:0"  #define CHANGELOG_VERSION_MAJOR  1 -#define CHANGELOG_VERSION_MINOR  1 +#define CHANGELOG_VERSION_MINOR  2  #define CHANGELOG_UNIX_SOCK  DEFAULT_VAR_RUN_DIRECTORY"/changelog-%s.sock"  #define CHANGELOG_TMP_UNIX_SOCK  DEFAULT_VAR_RUN_DIRECTORY"/.%s%lu.sock" diff --git a/xlators/features/changelog/src/changelog.c b/xlators/features/changelog/src/changelog.c index 7429fc5e891..53c0cf85728 100644 --- a/xlators/features/changelog/src/changelog.c +++ b/xlators/features/changelog/src/changelog.c @@ -110,8 +110,15 @@ changelog_rmdir (call_frame_t *frame, xlator_t *this,          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); +        if (priv->capture_del_path) { +                CHANGELOG_FILL_ENTRY_DIR_PATH (co, loc->pargfid, loc->name, +                                               del_entry_fn, del_entry_free_fn, +                                              xtra_len, wind, _gf_true); +        } else { +                CHANGELOG_FILL_ENTRY_DIR_PATH (co, loc->pargfid, loc->name, +                                               del_entry_fn, del_entry_free_fn, +                                              xtra_len, wind, _gf_false); +        }          changelog_set_usable_record_and_length (frame->local, xtra_len, 2); @@ -227,8 +234,15 @@ changelog_unlink (call_frame_t *frame, xlator_t *this,          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); +        if (priv->capture_del_path) { +                CHANGELOG_FILL_ENTRY_DIR_PATH (co, loc->pargfid, loc->name, +                                               del_entry_fn, del_entry_free_fn, +                                              xtra_len, wind, _gf_true); +        } else { +                CHANGELOG_FILL_ENTRY_DIR_PATH (co, loc->pargfid, loc->name, +                                               del_entry_fn, del_entry_free_fn, +                                              xtra_len, wind, _gf_false); +        }          changelog_set_usable_record_and_length (frame->local, xtra_len, 2); @@ -2339,6 +2353,9 @@ reconfigure (xlator_t *this, dict_t *options)                            timeout, options, time, out);          changelog_assign_barrier_timeout (priv, timeout); +        GF_OPTION_RECONF ("capture-del-path", priv->capture_del_path, options, +                          bool, out); +          if (active_now || active_earlier) {                  ret = changelog_fill_rollover_data (&cld, !active_now);                  if (ret) @@ -2443,6 +2460,8 @@ changelog_init_options (xlator_t *this, changelog_priv_t *priv)                  goto dealloc_2;          GF_OPTION_INIT ("changelog", priv->active, bool, dealloc_2); +        GF_OPTION_INIT ("capture-del-path", priv->capture_del_path, +                        bool, dealloc_2);          GF_OPTION_INIT ("op-mode", tmp, str, dealloc_2);          changelog_assign_opmode (priv, tmp); @@ -2719,6 +2738,11 @@ struct volume_options options[] = {                           "operations are no longer blocked and previously "                           "blocked fops are allowed to go through"          }, +        {.key = {"capture-del-path"}, +         .type = GF_OPTION_TYPE_BOOL, +         .default_value = "off", +         .description = "enable/disable capturing paths of deleted entries" +        },          {.key = {NULL}          },  };  | 
