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>
This commit is contained in:
parent
02979e4663
commit
98db583e9b
@ -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 (¶m_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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
int fdv[4] = {0, 1, 2, xpi[1]};
|
||||
|
||||
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 */
|
||||
ret = close_fds_except(fdv, sizeof (fdv) / sizeof (*fdv));
|
||||
}
|
||||
|
||||
if (ret != -1) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user