diff options
Diffstat (limited to 'libglusterfs/src/store.c')
| -rw-r--r-- | libglusterfs/src/store.c | 105 |
1 files changed, 91 insertions, 14 deletions
diff --git a/libglusterfs/src/store.c b/libglusterfs/src/store.c index 8642538ce..1e6601837 100644 --- a/libglusterfs/src/store.c +++ b/libglusterfs/src/store.c @@ -168,10 +168,12 @@ int gf_store_read_and_tokenize (FILE *file, char *str, char **iter_key, char **iter_val, gf_store_op_errno_t *store_errno) { - int32_t ret = -1; - char *savetok = NULL; - char *key = NULL; - char *value = NULL; + int32_t ret = -1; + char *savetok = NULL; + char *key = NULL; + char *value = NULL; + char *temp = NULL; + size_t str_len = 0; GF_ASSERT (file); GF_ASSERT (str); @@ -179,13 +181,17 @@ gf_store_read_and_tokenize (FILE *file, char *str, char **iter_key, GF_ASSERT (iter_val); GF_ASSERT (store_errno); - ret = fscanf (file, "%s", str); - if (ret <= 0 || feof (file)) { + temp = fgets (str, PATH_MAX, file); + if (temp == NULL || feof (file)) { ret = -1; *store_errno = GD_STORE_EOF; goto out; } + str_len = strlen(str); + str[str_len - 1] = '\0'; + /* Truncate the "\n", as fgets stores "\n" in str */ + key = strtok_r (str, "=", &savetok); if (!key) { ret = -1; @@ -221,7 +227,12 @@ gf_store_retrieve_value (gf_store_handle_t *handle, char *key, char **value) GF_ASSERT (handle); - handle->fd = open (handle->path, O_RDWR); + if (handle->locked == F_ULOCK) + /* no locking is used handle->fd gets closed() after usage */ + handle->fd = open (handle->path, O_RDWR); + else + /* handle->fd is valid already, kept open for lockf() */ + lseek (handle->fd, 0, SEEK_SET); if (handle->fd == -1) { gf_log ("", GF_LOG_ERROR, "Unable to open file %s errno: %s", @@ -229,7 +240,9 @@ gf_store_retrieve_value (gf_store_handle_t *handle, char *key, char **value) goto out; } if (!handle->read) - handle->read = fdopen (handle->fd, "r"); + handle->read = fdopen (dup(handle->fd), "r"); + else + fseek (handle->read, 0, SEEK_SET); if (!handle->read) { gf_log ("", GF_LOG_ERROR, "Unable to open file %s errno: %s", @@ -246,8 +259,13 @@ gf_store_retrieve_value (gf_store_handle_t *handle, char *key, char **value) goto out; } - scan_str = GF_CALLOC (1, st.st_size, + /* "st.st_size + 1" is used as we are fetching each + * line of a file using fgets, fgets will append "\0" + * to the end of the string + */ + scan_str = GF_CALLOC (1, st.st_size + 1, gf_common_mt_char); + if (scan_str == NULL) { ret = -1; store_errno = GD_STORE_ENOMEM; @@ -278,11 +296,16 @@ gf_store_retrieve_value (gf_store_handle_t *handle, char *key, char **value) } } while (1); out: - if (handle->fd > 0) { - close (handle->fd); + if (handle->read) { + fclose (handle->read); handle->read = NULL; } + if (handle->fd > 0 && handle->locked == F_ULOCK) { + /* only invalidate handle->fd if not locked */ + close (handle->fd); + } + GF_FREE (free_str); return ret; @@ -366,6 +389,7 @@ gf_store_handle_new (char *path, gf_store_handle_t **handle) goto out; shandle->path = spath; + shandle->locked = F_ULOCK; *handle = shandle; ret = 0; @@ -390,8 +414,9 @@ gf_store_handle_retrieve (char *path, gf_store_handle_t **handle) ret = stat (path, &statbuf); if (ret) { - gf_log ("", GF_LOG_ERROR, "Unable to retrieve store handle " - "%s, error: %s", path, strerror (errno)); + gf_log ("", GF_LOG_ERROR, "Path corresponding to " + "%s, returned error: (%s)", + path, strerror (errno)); goto out; } ret = gf_store_handle_new (path, handle); @@ -518,7 +543,11 @@ gf_store_iter_get_next (gf_store_iter_t *iter, char **key, char **value, goto out; } - scan_str = GF_CALLOC (1, st.st_size, + /* "st.st_size + 1" is used as we are fetching each + * line of a file using fgets, fgets will append "\0" + * to the end of the string + */ + scan_str = GF_CALLOC (1, st.st_size + 1, gf_common_mt_char); if (!scan_str) { ret = -1; @@ -582,7 +611,9 @@ gf_store_iter_get_matching (gf_store_iter_t *iter, char *key, char **value) goto out; } GF_FREE (tmp_key); + tmp_key = NULL; GF_FREE (tmp_value); + tmp_value = NULL; ret = gf_store_iter_get_next (iter, &tmp_key, &tmp_value, NULL); } @@ -630,3 +661,49 @@ gf_store_strerror (gf_store_op_errno_t op_errno) } return "Invalid errno"; } + +int +gf_store_lock (gf_store_handle_t *sh) +{ + int ret; + + GF_ASSERT (sh); + GF_ASSERT (sh->path); + GF_ASSERT (sh->locked == F_ULOCK); + + sh->fd = open (sh->path, O_RDWR); + if (sh->fd == -1) { + gf_log ("", GF_LOG_ERROR, "Failed to open '%s': %s", sh->path, + strerror (errno)); + return -1; + } + + ret = lockf (sh->fd, F_LOCK, 0); + if (ret) + gf_log ("", GF_LOG_ERROR, "Failed to gain lock on '%s': %s", + sh->path, strerror (errno)); + else + /* sh->locked is protected by the lockf(sh->fd) above */ + sh->locked = F_LOCK; + + return ret; +} + +void +gf_store_unlock (gf_store_handle_t *sh) +{ + GF_ASSERT (sh); + GF_ASSERT (sh->locked == F_LOCK); + + sh->locked = F_ULOCK; + lockf (sh->fd, F_ULOCK, 0); + close (sh->fd); +} + +int +gf_store_locked_local (gf_store_handle_t *sh) +{ + GF_ASSERT (sh); + + return (sh->locked == F_LOCK); +} |
