summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCsaba Henk <csaba@redhat.com>2017-05-09 19:23:18 +0200
committerShyamsundar Ranganathan <srangana@redhat.com>2017-06-20 13:44:34 +0000
commit8f658c9501245bc0730e1724b016ca28f6ddfb3b (patch)
treed1e4e2df114397593529bab6cad5739b0cdf16ed
parentb7b91962e7ae6e94b15019ed1e60d75bab7bc1f2 (diff)
libglusterfs: extract some functionality to functions
- code in run.c to close all file descriptors, except for specified ones is extracted to int close_fds_except (int *fdv, size_t count); - tokenizing and editing a string that consists of comma-separated tokens (as done eg. in mount_param_to_flag() of contrib/fuse/mount.c is abstacted into the following API: char *token_iter_init (char *str, char sep, token_iter_t *tit); gf_boolean_t next_token (char **tokenp, token_iter_t *tit); void drop_token (char *token, token_iter_t *tit); Updates #153 > Change-Id: I7cb5bda38f680f08882e2a7ef84f9142ffaa54eb > Signed-off-by: Csaba Henk <csaba@redhat.com> > Reviewed-on: https://review.gluster.org/17229 > Smoke: Gluster Build System <jenkins@build.gluster.org> > NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org> > CentOS-regression: Gluster Build System <jenkins@build.gluster.org> > Reviewed-by: Amar Tumballi <amarts@redhat.com> (cherry picked from commit 98db583e9b2e7aa8e095a75a6bb5f42b0d65ae79) Change-Id: I7cb5bda38f680f08882e2a7ef84f9142ffaa54eb Signed-off-by: Csaba Henk <csaba@redhat.com> Reviewed-on: https://review.gluster.org/17569 Tested-by: Amar Tumballi <amarts@redhat.com> NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org> Smoke: Gluster Build System <jenkins@build.gluster.org> CentOS-regression: Gluster Build System <jenkins@build.gluster.org> Reviewed-by: Amar Tumballi <amarts@redhat.com>
-rw-r--r--contrib/fuse-lib/mount.c39
-rw-r--r--libglusterfs/src/common-utils.c202
-rw-r--r--libglusterfs/src/common-utils.h10
-rw-r--r--libglusterfs/src/run.c35
4 files changed, 229 insertions, 57 deletions
diff --git a/contrib/fuse-lib/mount.c b/contrib/fuse-lib/mount.c
index 1dfd2a7..5bdf454 100644
--- a/contrib/fuse-lib/mount.c
+++ b/contrib/fuse-lib/mount.c
@@ -252,38 +252,30 @@ static int
mount_param_to_flag (char *mnt_param, mount_flag_t *mntflags,
char **mnt_param_new)
{
- int i = 0;
- int j = 0;
- char *p = NULL;
gf_boolean_t found = _gf_false;
struct mount_flags *flag = NULL;
+ char *param_tok = NULL;
+ token_iter_t tit = {0,};
+ gf_boolean_t iter_end = _gf_false;
/* Allocate a buffer that will hold the mount parameters remaining
* after the ones corresponding to mount flags are processed and
* removed.The length of the original params are a good upper bound
* of the size needed.
*/
- *mnt_param_new = CALLOC (1, strlen (mnt_param) + 1);
+ *mnt_param_new = strdup (mnt_param);
if (!*mnt_param_new)
return -1;
- p = *mnt_param_new;
-
- while (mnt_param[j]) {
- if (j > 0)
- i = j+1;
- j = i;
- /* Seek the delimiters. */
- while (mnt_param[j] != ',' && mnt_param[j] != '\0')
- j++;
+ for (param_tok = token_iter_init (*mnt_param_new, ',', &tit) ;;) {
+ iter_end = next_token (&param_tok, &tit);
found = _gf_false;
for (flag = mount_flags; flag->opt; flag++) {
/* Compare the mount flag name to the param
- * name at hand (from i to j in mnt_param).
+ * name at hand.
*/
- if (strlen (flag->opt) == j - i &&
- memcmp (flag->opt, mnt_param + i, j - i) == 0) {
+ if (strcmp (flag->opt, param_tok) == 0) {
/* If there is a match, adjust mntflags
* accordingly and break.
*/
@@ -296,15 +288,12 @@ mount_param_to_flag (char *mnt_param, mount_flag_t *mntflags,
break;
}
}
- /* If the param did't match any flag name, retain it (ie. copy
- * over to the new param buffer).
- */
- if (!found) {
- if (p != *mnt_param_new)
- *p++ = ',';
- memcpy (p, mnt_param + i, j - i);
- p += j - i;
- }
+ /* Exclude flag names from new parameter list. */
+ if (found)
+ drop_token (param_tok, &tit);
+
+ if (iter_end)
+ break;
}
return 0;
diff --git a/libglusterfs/src/common-utils.c b/libglusterfs/src/common-utils.c
index 1b24d3e..65557fe 100644
--- a/libglusterfs/src/common-utils.c
+++ b/libglusterfs/src/common-utils.c
@@ -35,6 +35,9 @@
#include <sys/sysctl.h>
#endif
#include <libgen.h>
+#ifndef GF_LINUX_HOST_OS
+#include <sys/resource.h>
+#endif
#include "compat-errno.h"
#include "logging.h"
@@ -2129,6 +2132,145 @@ get_nth_word (const char *str, int n)
return word;
}
+/**
+ * token_iter_init -- initialize tokenization
+ *
+ * @str: string to be tokenized
+ * @sep: token separator character
+ * @tit: pointer to iteration state
+ *
+ * @return: token string
+ *
+ * The returned token string and tit are
+ * not to be used directly, but through
+ * next_token().
+ */
+char *
+token_iter_init (char *str, char sep, token_iter_t *tit)
+{
+ tit->end = str + strlen (str);
+ tit->sep = sep;
+
+ return str;
+}
+
+/**
+ * next_token -- fetch next token in tokenization
+ * inited by token_iter_init().
+ *
+ * @tokenp: pointer to token
+ * @tit: pointer to iteration state
+ *
+ * @return: true if iteration ends, else false
+ *
+ * The token pointed by @tokenp can be used
+ * after a call to next_token(). When next_token()
+ * returns true the iteration is to be stopped
+ * and the string with which the tokenization
+ * was inited (see token_iter_init() is restored,
+ * apart from dropped tokens (see drop_token()).
+ */
+gf_boolean_t
+next_token (char **tokenp, token_iter_t *tit)
+{
+ char *cursor = NULL;
+ gf_boolean_t is_last = _gf_false;
+
+ for (cursor = *tokenp; *cursor; cursor++);
+ if (cursor < tit->end) {
+ /*
+ * We detect that in between current token and end a zero
+ * marker has already been inserted. This means that the
+ * token has already been returned. We restore the
+ * separator and move ahead.
+ */
+ *cursor = tit->sep;
+ *tokenp = cursor + 1;
+ }
+
+ for (cursor = *tokenp; *cursor && *cursor != tit->sep; cursor++);
+ /* If the cursor ended up on a zero byte, then it's the last token. */
+ is_last = !*cursor;
+ /* Zero-terminate the token. */
+ *cursor = 0;
+
+ return is_last;
+}
+
+/*
+ * drop_token -- drop a token during iterated calls of next_token().
+ *
+ * Sample program that uses these functions to tokenize
+ * a comma-separated first argument while dropping the
+ * rest of the arguments if they occur as token:
+ *
+ * #include <stdio.h>
+ * #include <stdlib.h>
+ * #include <string.h>
+ * #include "common-utils.h"
+ *
+ * int
+ * main (int argc, char **argv)
+ * {
+ * char *buf;
+ * char *token;
+ * token_iter_t tit;
+ * int i;
+ * gf_boolean_t iter_end;
+ *
+ * if (argc <= 1)
+ * abort();
+ *
+ * buf = strdup (argv[1]);
+ * if (!buf)
+ * abort();
+ *
+ * for (token = token_iter_init (buf, ',', &tit) ;;) {
+ * iter_end = next_token (&token, &tit);
+ * printf("found token: '%s'\n", token);
+ * for (i = 2; i < argc; i++) {
+ * if (strcmp (argv[i], token) == 0) {
+ * printf ("%s\n", "dropping token!");
+ * drop_token (token, &tit);
+ * break;
+ * }
+ * }
+ * if (iter_end)
+ * break;
+ * }
+ *
+ * printf ("finally: '%s'\n", buf);
+ *
+ * return 0;
+ * }
+ */
+void
+drop_token (char *token, token_iter_t *tit)
+{
+ char *cursor = NULL;
+
+ for (cursor = token; *cursor; cursor++);
+ if (cursor < tit->end) {
+ /*
+ * We detect a zero inserted by next_token().
+ * Step the cursor and copy what comes after
+ * to token.
+ */
+ for (cursor++; cursor < tit->end; *token++ = *cursor++);
+ }
+
+ /*
+ * Zero out the remainder of the buffer.
+ * It would be enough to insert just a single zero,
+ * but we continue 'till the end to have cleaner
+ * memory content.
+ */
+ for (cursor = token; cursor < tit->end; *cursor++ = 0);
+
+ /* Adjust the end to point to the new terminating zero. */
+ tit->end = token;
+}
+
/* Syntax formed according to RFC 1912 (RFC 1123 & 952 are more restrictive) *
<hname> ::= <gen-name>*["."<gen-name>] *
<gen-name> ::= <let-or-digit> <[*[<let-or-digit-or-hyphen>]<let-or-digit>] */
@@ -4657,3 +4799,63 @@ gf_fop_string (glusterfs_fop_t fop)
return gf_fop_list[fop];
return "INVALID";
}
+
+int
+close_fds_except (int *fdv, size_t count)
+{
+ int i = 0;
+ size_t j = 0;
+ gf_boolean_t should_close = _gf_true;
+#ifdef GF_LINUX_HOST_OS
+ DIR *d = NULL;
+ struct dirent *de = NULL;
+ struct dirent scratch[2] = {{0,},};
+ char *e = NULL;
+
+ d = sys_opendir ("/proc/self/fd");
+ if (!d)
+ return -1;
+
+ for (;;) {
+ should_close = _gf_true;
+
+ errno = 0;
+ de = sys_readdir (d, scratch);
+ if (!de || errno != 0)
+ break;
+ i = strtoul (de->d_name, &e, 10);
+ if (*e != '\0' || i == dirfd (d))
+ continue;
+
+ for (j = 0; j < count; j++) {
+ if (i == fdv[j]) {
+ should_close = _gf_false;
+ break;
+ }
+ }
+ if (should_close)
+ sys_close (i);
+ }
+ sys_closedir (d);
+#else /* !GF_LINUX_HOST_OS */
+ struct rlimit rl;
+ int ret = -1;
+
+ ret = getrlimit (RLIMIT_NOFILE, &rl);
+ if (ret)
+ return ret;
+
+ for (i = 0; i < rl.rlim_cur; i++) {
+ should_close = _gf_true;
+ for (j = 0; j < count; j++) {
+ if (i == fdv[j]) {
+ should_close = _gf_false;
+ break;
+ }
+ }
+ if (should_close)
+ sys_close (i);
+ }
+#endif /* !GF_LINUX_HOST_OS */
+ return 0;
+}
diff --git a/libglusterfs/src/common-utils.h b/libglusterfs/src/common-utils.h
index 6243732..6bd2417 100644
--- a/libglusterfs/src/common-utils.h
+++ b/libglusterfs/src/common-utils.h
@@ -774,6 +774,14 @@ void skip_word (char **str);
/* returns a new string with nth word of given string. n>=1 */
char *get_nth_word (const char *str, int n);
+typedef struct token_iter {
+ char *end;
+ char sep;
+} token_iter_t;
+char *token_iter_init (char *str, char sep, token_iter_t *tit);
+gf_boolean_t next_token (char **tokenp, token_iter_t *tit);
+void drop_token (char *token, token_iter_t *tit);
+
gf_boolean_t mask_match (const uint32_t a, const uint32_t b, const uint32_t m);
gf_boolean_t gf_is_ip_in_net (const char *network, const char *ip_str);
char valid_host_name (char *address, int length);
@@ -903,4 +911,6 @@ gf_fop_string (glusterfs_fop_t fop);
char *
get_ip_from_addrinfo (struct addrinfo *addr, char **ip);
+int
+close_fds_except (int *fdv, size_t count);
#endif /* _COMMON_UTILS_H */
diff --git a/libglusterfs/src/run.c b/libglusterfs/src/run.c
index ff587f7..a7d98af 100644
--- a/libglusterfs/src/run.c
+++ b/libglusterfs/src/run.c
@@ -23,7 +23,6 @@
#include <assert.h>
#include <signal.h>
#include <sys/wait.h>
-#include <sys/resource.h>
#include "syscall.h"
#ifdef RUN_STANDALONE
@@ -274,37 +273,9 @@ runner_start (runner_t *runner)
}
if (ret != -1 ) {
-#ifdef GF_LINUX_HOST_OS
- DIR *d = NULL;
- struct dirent *de = NULL;
- struct dirent scratch[2] = {{0,},};
- char *e = NULL;
-
- d = sys_opendir ("/proc/self/fd");
- if (d) {
- for (;;) {
- errno = 0;
- de = sys_readdir (d, scratch);
- if (!de || errno != 0)
- break;
- i = strtoul (de->d_name, &e, 10);
- if (*e == '\0' && i > 2 &&
- i != dirfd (d) && i != xpi[1])
- sys_close (i);
- }
- sys_closedir (d);
- } else
- ret = -1;
-#else /* !GF_LINUX_HOST_OS */
- struct rlimit rl;
- ret = getrlimit (RLIMIT_NOFILE, &rl);
- GF_ASSERT (ret == 0);
-
- for (i = 3; i < rl.rlim_cur; i++) {
- if (i != xpi[1])
- sys_close (i);
- }
-#endif /* !GF_LINUX_HOST_OS */
+ int fdv[4] = {0, 1, 2, xpi[1]};
+
+ ret = close_fds_except(fdv, sizeof (fdv) / sizeof (*fdv));
}
if (ret != -1) {