diff options
| -rw-r--r-- | xlators/features/changelog/src/changelog-helpers.c | 156 | ||||
| -rw-r--r-- | xlators/features/changelog/src/changelog-helpers.h | 18 | ||||
| -rw-r--r-- | xlators/features/changelog/src/changelog-misc.h | 6 | ||||
| -rw-r--r-- | xlators/features/changelog/src/changelog.c | 52 | 
4 files changed, 232 insertions, 0 deletions
diff --git a/xlators/features/changelog/src/changelog-helpers.c b/xlators/features/changelog/src/changelog-helpers.c index 07c6096dce5..9dccf45187c 100644 --- a/xlators/features/changelog/src/changelog-helpers.c +++ b/xlators/features/changelog/src/changelog-helpers.c @@ -337,6 +337,101 @@ out:          return ret;  } +/* Description: + *      Opens the snap changelog to log call path fops in it. + *      This changelos name is "CHANGELOG.SNAP", stored in + *      path ".glusterfs/changelogs/csnap". + * Returns: + *       0  : On success. + *      -1  : On failure. + */ +int +changelog_snap_open (xlator_t *this, +                         changelog_priv_t *priv) +{ +        int fd                        = -1; +        int ret                       = 0; +        int flags                     = 0; +        char buffer[1024]             = {0,}; +        char c_snap_path[PATH_MAX]    = {0,}; +        char csnap_dir_path[PATH_MAX] = {0,}; + +        CHANGELOG_FILL_CSNAP_DIR(priv->changelog_dir, csnap_dir_path); + +        (void) snprintf (c_snap_path, PATH_MAX, +                        "%s/"CSNAP_FILE_NAME, +                        csnap_dir_path); + +        flags |= (O_CREAT | O_RDWR | O_TRUNC); + +        fd = open (c_snap_path, flags, +                        S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); +        if (fd < 0) { +                gf_log (this->name, GF_LOG_ERROR, +                                "unable to open %s file " +                                "reason:(%s)", c_snap_path, strerror (errno)); +                ret = -1; +                goto out; +        } +        priv->c_snap_fd = fd; + +        (void) snprintf (buffer, 1024, CHANGELOG_HEADER, +                        CHANGELOG_VERSION_MAJOR, +                        CHANGELOG_VERSION_MINOR, +                        priv->ce->encoder); +        ret = changelog_snap_write_change (priv, buffer, strlen (buffer)); +        if (ret < 0) { +                close (priv->c_snap_fd); +                priv->c_snap_fd = -1; +                goto out; +        } + +out: +        return ret; +} + +/* + * Description: + *      Starts logging fop details in CSNAP journal. + * Returns: + *       0 : On success. + *      -1 : On Failure. + */ +int +changelog_snap_logging_start (xlator_t *this, +                                  changelog_priv_t *priv) +{ +        int ret = 0; + +        ret = changelog_snap_open (this, priv); +        gf_log (this->name, GF_LOG_INFO, +                        "Now starting to log in call path"); + +        return ret; +} + +/* + * Description: + *      Stops logging fop details in CSNAP journal. + * Returns: + *       0 : On success. + *      -1 : On Failure. + */ +int +changelog_snap_logging_stop (xlator_t *this, +                changelog_priv_t *priv) +{ +        int ret         = 0; + +        close (priv->c_snap_fd); +        priv->c_snap_fd = -1; + +        gf_log (this->name, GF_LOG_INFO, +                        "Stopped to log in call path"); + +        return ret; +} +  int  changelog_open (xlator_t *this,                  changelog_priv_t *priv) @@ -424,11 +519,72 @@ changelog_fill_rollover_data (changelog_log_data_t *cld, gf_boolean_t is_last)  }  int +changelog_snap_write_change (changelog_priv_t *priv, char *buffer, size_t len) +{ +        return changelog_write (priv->c_snap_fd, buffer, len); +} + +int  changelog_write_change (changelog_priv_t *priv, char *buffer, size_t len)  {          return changelog_write (priv->changelog_fd, buffer, len);  } +/* + * Descriptions: + *      Writes fop details in ascii format to CSNAP. + * Issues: + *      Not Encoding agnostic. + * Returns: + *      0 : On Success. + *     -1 : On Failure. + */ +int +changelog_snap_handle_ascii_change (xlator_t *this, +                                    changelog_log_data_t *cld) +{ +        size_t            off      = 0; +        size_t            gfid_len = 0; +        char             *gfid_str = NULL; +        char             *buffer   = NULL; +        changelog_priv_t *priv     = NULL; +        int               ret      = 0; + +        if (this == NULL) { +                ret = -1; +                goto out; +        } + +        priv = this->private; + +        if (priv == NULL) { +                ret = -1; +                goto out; +        } + +        gfid_str = uuid_utoa (cld->cld_gfid); +        gfid_len = strlen (gfid_str); + +        /*  extra bytes for decorations */ +        buffer = alloca (gfid_len + cld->cld_ptr_len + 10); +        CHANGELOG_STORE_ASCII (priv, buffer, +                        off, gfid_str, gfid_len, cld); + +        CHANGELOG_FILL_BUFFER (buffer, off, "\0", 1); + +        ret = changelog_snap_write_change (priv, buffer, off); + +        if (ret < 0) { +                gf_log (this->name, GF_LOG_ERROR, +                                "error writing csnap to disk"); +        } +        gf_log (this->name, GF_LOG_INFO, +                        "Successfully wrote to csnap"); +        ret = 0; +out: +        return ret; +} +  inline int  changelog_handle_change (xlator_t *this,                           changelog_priv_t *priv, changelog_log_data_t *cld) diff --git a/xlators/features/changelog/src/changelog-helpers.h b/xlators/features/changelog/src/changelog-helpers.h index 87888fb8c4f..9bd4a3ff37c 100644 --- a/xlators/features/changelog/src/changelog-helpers.h +++ b/xlators/features/changelog/src/changelog-helpers.h @@ -212,11 +212,17 @@ struct changelog_priv {          /* htime fd for current changelog session */          int htime_fd; +        /*  c_snap_fd is fd for call-path changelog */ +        int c_snap_fd; +          /* rollover_count used by htime */          int  rollover_count;          gf_lock_t lock; +        /*  lock to synchronize CSNAP updation */ +        gf_lock_t c_snap_lock; +          /* writen end of the pipe */          int wfd; @@ -431,6 +437,18 @@ changelog_drain_white_fops (xlator_t *this, changelog_priv_t *priv);  void  changelog_drain_black_fops (xlator_t *this, changelog_priv_t *priv); +/* Crash consistency of changelog wrt snapshot */ +int +changelog_snap_logging_stop ( xlator_t *this, changelog_priv_t *priv); +int +changelog_snap_logging_start ( xlator_t *this, changelog_priv_t *priv); +int +changelog_snap_open ( xlator_t *this, changelog_priv_t *priv); +int +changelog_snap_handle_ascii_change (xlator_t *this, +                changelog_log_data_t *cld); +int +changelog_snap_write_change (changelog_priv_t *priv, char *buffer, size_t len);  /* Changelog barrier routines */  void __chlog_barrier_enqueue (xlator_t *this, call_stub_t *stub);  void __chlog_barrier_disable (xlator_t *this, struct list_head *queue); diff --git a/xlators/features/changelog/src/changelog-misc.h b/xlators/features/changelog/src/changelog-misc.h index 257c1f34218..58b10961463 100644 --- a/xlators/features/changelog/src/changelog-misc.h +++ b/xlators/features/changelog/src/changelog-misc.h @@ -17,6 +17,7 @@  #define CHANGELOG_MAX_TYPE  3  #define CHANGELOG_FILE_NAME "CHANGELOG"  #define HTIME_FILE_NAME "HTIME" +#define CSNAP_FILE_NAME "CHANGELOG.SNAP"  #define HTIME_KEY "trusted.glusterfs.htime"  #define HTIME_INITIAL_VALUE "0:0" @@ -71,6 +72,11 @@                  strcpy (path, changelog_dir);                   \                  strcat (path, "/htime");                        \          } while(0) + +#define CHANGELOG_FILL_CSNAP_DIR(changelog_dir, path) do {      \ +                strcpy (path, changelog_dir);                   \ +                strcat (path, "/csnap");                        \ +        } while(0)  /**   * everything after 'CHANGELOG_TYPE_ENTRY' are internal types   * (ie. none of the fops trigger this type of event), hence diff --git a/xlators/features/changelog/src/changelog.c b/xlators/features/changelog/src/changelog.c index 36643395815..75a62d686d6 100644 --- a/xlators/features/changelog/src/changelog.c +++ b/xlators/features/changelog/src/changelog.c @@ -1433,6 +1433,16 @@ changelog_truncate (call_frame_t *frame,          CHANGELOG_INIT (this, frame->local,                          loc->inode, loc->inode->gfid, 0); +        LOCK(&priv->c_snap_lock); +        { +                if (priv->c_snap_fd != -1 && +                    priv->barrier_enabled == _gf_true) { +                        changelog_snap_handle_ascii_change (this, +                              &( ((changelog_local_t *)(frame->local))->cld)); +                } +        } +        UNLOCK(&priv->c_snap_lock); +   wind:          changelog_color_fop_and_inc_cnt (this, priv, frame->local); @@ -1476,6 +1486,15 @@ changelog_ftruncate (call_frame_t *frame,          CHANGELOG_INIT (this, frame->local,                          fd->inode, fd->inode->gfid, 0); +        LOCK(&priv->c_snap_lock); +        { +                if (priv->c_snap_fd != -1 && +                    priv->barrier_enabled == _gf_true) { +                        changelog_snap_handle_ascii_change (this, +                              &( ((changelog_local_t *)(frame->local))->cld)); +                } +        } +        UNLOCK(&priv->c_snap_lock);   wind:          changelog_color_fop_and_inc_cnt (this, priv, frame->local); @@ -1523,6 +1542,15 @@ changelog_writev (call_frame_t *frame,          CHANGELOG_INIT (this, frame->local,                          fd->inode, fd->inode->gfid, 0); +        LOCK(&priv->c_snap_lock); +        { +                if (priv->c_snap_fd != -1 && +                    priv->barrier_enabled == _gf_true) { +                        changelog_snap_handle_ascii_change (this, +                              &( ((changelog_local_t *)(frame->local))->cld)); +                } +        } +        UNLOCK(&priv->c_snap_lock);   wind:          changelog_color_fop_and_inc_cnt (this, priv, frame->local); @@ -1751,6 +1779,11 @@ notify (xlator_t *this, int event, void *data, ...)                                  "Barrier off notification");                          CHANGELOG_NOT_ON_THEN_GOTO(priv, ret, out); +                        LOCK(&priv->c_snap_lock); +                        { +                                changelog_snap_logging_stop (this, priv); +                        } +                        UNLOCK(&priv->c_snap_lock);                          LOCK (&priv->bflags.lock);                          { @@ -1800,6 +1833,11 @@ notify (xlator_t *this, int event, void *data, ...)                                  "Barrier on notification");                          CHANGELOG_NOT_ON_THEN_GOTO(priv, ret, out); +                        LOCK(&priv->c_snap_lock); +                        { +                                changelog_snap_logging_start (this, priv); +                        } +                        UNLOCK(&priv->c_snap_lock);                          LOCK (&priv->bflags.lock);                          { @@ -2080,6 +2118,7 @@ reconfigure (xlator_t *this, dict_t *options)          changelog_time_slice_t *slice          = NULL;          changelog_log_data_t    cld            = {0,};          char    htime_dir[PATH_MAX]            = {0,}; +        char    csnap_dir[PATH_MAX]            = {0,};          struct timeval          tv             = {0,};          uint32_t                timeout        = 0; @@ -2115,6 +2154,12 @@ reconfigure (xlator_t *this, dict_t *options)          if (ret)                  goto out; +        CHANGELOG_FILL_CSNAP_DIR(priv->changelog_dir, csnap_dir); +        ret = mkdir_p (csnap_dir, 0600, _gf_true); + +        if (ret) +                goto out; +          GF_OPTION_RECONF ("changelog", active_now, options, bool, out);          /** @@ -2197,6 +2242,7 @@ init (xlator_t *this)          changelog_priv_t        *priv                   = NULL;          gf_boolean_t            cond_lock_init          = _gf_false;          char                    htime_dir[PATH_MAX]     = {0,}; +        char                    csnap_dir[PATH_MAX]     = {0,};          uint32_t                timeout                 = 0;          GF_VALIDATE_OR_GOTO ("changelog", this, out); @@ -2225,6 +2271,7 @@ init (xlator_t *this)          }          LOCK_INIT (&priv->lock); +        LOCK_INIT (&priv->c_snap_lock);          GF_OPTION_INIT ("changelog-brick", tmp, str, out);          if (!tmp) { @@ -2264,6 +2311,11 @@ init (xlator_t *this)          if (ret)                  goto out; +        CHANGELOG_FILL_CSNAP_DIR(priv->changelog_dir, csnap_dir); +        ret = mkdir_p (csnap_dir, 0600, _gf_true); +        if (ret) +                goto out; +          GF_OPTION_INIT ("changelog", priv->active, bool, out);          GF_OPTION_INIT ("op-mode", tmp, str, out);  | 
