summaryrefslogtreecommitdiffstats
path: root/libglusterfs/src/store.c
diff options
context:
space:
mode:
Diffstat (limited to 'libglusterfs/src/store.c')
-rw-r--r--libglusterfs/src/store.c105
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);
+}