diff options
| -rw-r--r-- | booster/src/booster.c | 131 | ||||
| -rw-r--r-- | libglusterfs/src/Makefile.am | 4 | ||||
| -rw-r--r-- | libglusterfs/src/glusterfs_fstab.c | 309 | ||||
| -rw-r--r-- | libglusterfs/src/glusterfs_fstab.h | 82 | 
4 files changed, 467 insertions, 59 deletions
diff --git a/booster/src/booster.c b/booster/src/booster.c index afe33a6abaf..de5bd325365 100644 --- a/booster/src/booster.c +++ b/booster/src/booster.c @@ -42,6 +42,7 @@  #include <dirent.h>  #include <sys/statfs.h>  #include <sys/statvfs.h> +#include <glusterfs_fstab.h>  #ifndef GF_UNIT_KB  #define GF_UNIT_KB 1024 @@ -235,81 +236,97 @@ booster_get_process_fd ()  #define DEFAULT_BOOSTER_CONF    CONFDIR"/booster.conf"  #define BOOSTER_CONF_ENV_VAR    "GLUSTERFS_BOOSTER_FSTAB" -int -booster_parse_line (char *buf, char **mount_point, -                    glusterfs_init_params_t *params) +void +clean_init_params (glusterfs_init_params_t *ipars)  { -        /* Structure of each line in booster config: -         * /virtual/mount/point /volume/specification/file volume-name /log/file loglevel cache-timeout -         * 0 can be entered for each of volume-name, /log/file, loglevel -         * to force default values. -         */ -        char    *inbufptr = NULL; +        if (!ipars) +                return; -        if (!buf || !mount_point || !params) { -                goto out; +        if (ipars->volume_name) +                free (ipars->volume_name); + +        if (ipars->specfile) +                free (ipars->specfile); + +        if (ipars->logfile) +                free (ipars->logfile); + +        if (ipars->loglevel) +                free (ipars->loglevel); + +        return; +} + +char * +get_option_value (char *opt) +{ +        char *val = NULL; +        char *saveptr = NULL; +        char *copy_opt = NULL; +        char *nextopt = NULL; +        char *retval = NULL; + +        copy_opt = strdup (opt); +        val = strtok_r (copy_opt, "=", &saveptr); +        if (val != NULL) { +                nextopt = index (val, ','); +                if (nextopt) +                        *nextopt = '\0'; + +                retval = strdup (val);          } -        memset (params, 0, sizeof (*params)); -        inbufptr = strtok (buf, " "); -        if (inbufptr == NULL) -                goto out; -        *mount_point = strdup (inbufptr); +        free (copy_opt); -        inbufptr = strtok (NULL, " "); -        if (inbufptr == NULL) -                goto out; -        params->specfile = strdup (inbufptr); +        return retval; +} -        inbufptr = strtok (NULL, " "); -        if (inbufptr == NULL) -                goto out; -        params->volume_name = strdup (inbufptr); +void +booster_mount (struct glusterfs_mntent *ent) +{ +        char                    *opt = NULL; +        glusterfs_init_params_t ipars; -        inbufptr = strtok (NULL, " "); -        if (inbufptr == NULL) -                goto out; -        params->logfile = strdup (inbufptr); +        if (!ent) +                return; -        inbufptr = strtok (NULL, " "); -        if (inbufptr == NULL) -                goto out; -        params->loglevel = strdup (inbufptr); +        memset (&ipars, 0, sizeof (glusterfs_init_params_t)); +        if (ent->mnt_fsname) +                ipars.specfile = strdup (ent->mnt_fsname); -        return 0; -out: -        return -1; +        opt = glusterfs_fstab_hasoption (ent, "subvolume"); +        if (opt) +                ipars.volume_name = get_option_value (opt); + +        opt = glusterfs_fstab_hasoption (ent, "logfile"); +        if (opt) +                ipars.logfile = get_option_value (opt); + +        opt = glusterfs_fstab_hasoption (ent, "loglevel"); +        if (opt) +                ipars.loglevel = get_option_value (opt); + +        glusterfs_mount (ent->mnt_dir, &ipars); +        clean_init_params (&ipars);  }  int  booster_configure (char *confpath)  { -        FILE                    *fp = NULL; -        int                      ret = -1; -        char                     buf[4096]; -        char                    *mount_point = NULL; -        glusterfs_init_params_t  params = {0, }; +        int                     ret = -1; +        glusterfs_fstab_t       *handle = NULL; +        struct glusterfs_mntent *ent = NULL; -        fp = fopen (confpath, "r"); -        if (fp == NULL) { +        if (!confpath)                  goto out; -        } -        while (1) { -                fgets (buf, 4096, fp); -                if (feof (fp)) { -                        break; -                } - -                mount_point = NULL; -                ret = booster_parse_line (buf, &mount_point, ¶ms); -                if (ret == -1) { -                        goto out; -                } +        handle = glusterfs_fstab_init (confpath, "r"); +        if (!handle) +                goto out; -                /* even if this mount fails, lets continue with others */ -                glusterfs_mount (mount_point, ¶ms); -        } +        while ((ent = glusterfs_fstab_getent (handle)) != NULL) +                booster_mount (ent); +        glusterfs_fstab_close (handle);          ret = 0;  out:          return ret; diff --git a/libglusterfs/src/Makefile.am b/libglusterfs/src/Makefile.am index 8ff35fbb27a..2863c755c18 100644 --- a/libglusterfs/src/Makefile.am +++ b/libglusterfs/src/Makefile.am @@ -6,9 +6,9 @@ libglusterfs_la_LIBADD = @LEXLIB@  lib_LTLIBRARIES = libglusterfs.la -libglusterfs_la_SOURCES = dict.c spec.lex.c y.tab.c xlator.c logging.c  hashfn.c defaults.c scheduler.c common-utils.c transport.c timer.c inode.c call-stub.c compat.c authenticate.c fd.c compat-errno.c event.c mem-pool.c gf-dirent.c syscall.c iobuf.c +libglusterfs_la_SOURCES = dict.c spec.lex.c y.tab.c xlator.c logging.c  hashfn.c defaults.c scheduler.c common-utils.c transport.c timer.c inode.c call-stub.c compat.c authenticate.c fd.c compat-errno.c event.c mem-pool.c gf-dirent.c syscall.c iobuf.c glusterfs_fstab.c -noinst_HEADERS = common-utils.h defaults.h dict.h glusterfs.h hashfn.h logging.h protocol.h scheduler.h xlator.h transport.h stack.h timer.h list.h inode.h call-stub.h compat.h authenticate.h fd.h revision.h compat-errno.h event.h mem-pool.h byte-order.h gf-dirent.h locking.h syscall.h iobuf.h +noinst_HEADERS = common-utils.h defaults.h dict.h glusterfs.h hashfn.h logging.h protocol.h scheduler.h xlator.h transport.h stack.h timer.h list.h inode.h call-stub.h compat.h authenticate.h fd.h revision.h compat-errno.h event.h mem-pool.h byte-order.h gf-dirent.h locking.h syscall.h iobuf.h glusterfs_fstab.h  EXTRA_DIST = spec.l spec.y diff --git a/libglusterfs/src/glusterfs_fstab.c b/libglusterfs/src/glusterfs_fstab.c new file mode 100644 index 00000000000..b21197b1d91 --- /dev/null +++ b/libglusterfs/src/glusterfs_fstab.c @@ -0,0 +1,309 @@ +/* Utilities for reading/writing fstab, mtab, etc. +   Copyright (C) 1995-2000, 2001, 2002, 2003, 2006 +   Free Software Foundation, Inc. +   This file is part of the GNU C Library. + +   The GNU C Library is free software; you can redistribute it and/or +   modify it under the terms of the GNU Lesser General Public +   License as published by the Free Software Foundation; either +   version 2.1 of the License, or (at your option) any later version. + +   The GNU C Library is distributed in the hope that it will be useful, +   but WITHOUT ANY WARRANTY; without even the implied warranty of +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +   Lesser General Public License for more details. + +   You should have received a copy of the GNU Lesser General Public +   License along with the GNU C Library; if not, write to the Free +   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +   02111-1307 USA.  */ + +#include <alloca.h> +#include <stdio.h> +#include <stdio_ext.h> +#include <string.h> +#include <sys/types.h> +#include "glusterfs_fstab.h" +#include <stdlib.h> + +/* Prepare to begin reading and/or writing mount table entries from the +   beginning of FILE.  MODE is as for `fopen'.  */ +glusterfs_fstab_t * +glusterfs_fstab_init (const char *file, const char *mode) +{ +  glusterfs_fstab_t *handle = NULL; +  /* Extend the mode parameter with "c" to disable cancellation in the +     I/O functions.  */ +  size_t modelen = strlen (mode); +  char newmode[modelen + 2]; +  memcpy (mempcpy (newmode, mode, modelen), "c", 2); + +  handle = calloc (1, sizeof (glusterfs_fstab_t)); +  if (!handle) +          goto out; + +  FILE *result = fopen (file, newmode); +  if (result != NULL) { +    /* We do the locking ourselves.  */ +    __fsetlocking (result, FSETLOCKING_BYCALLER); +    handle->fp = result; +  } else { +          free (handle); +          handle = NULL; +  } + +out: + +  return handle; +} + +int +glusterfs_fstab_close (glusterfs_fstab_t *h) +{ +  if (!h) +    return -1; + +  if (h->fp) +    fclose (h->fp); + +  return 0; +} + +/* Since the values in a line are separated by spaces, a name cannot +   contain a space.  Therefore some programs encode spaces in names +   by the strings "\040".  We undo the encoding when reading an entry. +   The decoding happens in place.  */ +static char * +decode_name (char *buf) +{ +  char *rp = buf; +  char *wp = buf; + +  do +    if (rp[0] == '\\' && rp[1] == '0' && rp[2] == '4' && rp[3] == '0') +      { +	/* \040 is a SPACE.  */ +	*wp++ = ' '; +	rp += 3; +      } +    else if (rp[0] == '\\' && rp[1] == '0' && rp[2] == '1' && rp[3] == '1') +      { +	/* \011 is a TAB.  */ +	*wp++ = '\t'; +	rp += 3; +      } +    else if (rp[0] == '\\' && rp[1] == '0' && rp[2] == '1' && rp[3] == '2') +      { +	/* \012 is a NEWLINE.  */ +	*wp++ = '\n'; +	rp += 3; +      } +    else if (rp[0] == '\\' && rp[1] == '\\') +      { +	/* We have to escape \\ to be able to represent all characters.  */ +	*wp++ = '\\'; +	rp += 1; +      } +    else if (rp[0] == '\\' && rp[1] == '1' && rp[2] == '3' && rp[3] == '4') +      { +	/* \134 is also \\.  */ +	*wp++ = '\\'; +	rp += 3; +      } +    else +      *wp++ = *rp; +  while (*rp++ != '\0'); + +  return buf; +} + + +/* Read one mount table entry from STREAM.  Returns a pointer to storage +   reused on the next call, or null for EOF or error (use feof/ferror to +   check).  */ +struct glusterfs_mntent * +__glusterfs_fstab_getent (FILE *stream, struct glusterfs_mntent *mp, +                          char *buffer, int bufsiz) +{ +  char *cp; +  char *head; + +  flockfile (stream); +  do +    { +      char *end_ptr; + +      if (fgets_unlocked (buffer, bufsiz, stream) == NULL) +	{ +	  funlockfile (stream); +	  return NULL; +	} + +      end_ptr = strchr (buffer, '\n'); +      if (end_ptr != NULL)	/* chop newline */ +	*end_ptr = '\0'; +      else +	{ +	  /* Not the whole line was read.  Do it now but forget it.  */ +	  char tmp[1024]; +	  while (fgets_unlocked (tmp, sizeof tmp, stream) != NULL) +	    if (strchr (tmp, '\n') != NULL) +	      break; +	} + +      head = buffer + strspn (buffer, " \t"); +      /* skip empty lines and comment lines:  */ +    } +  while (head[0] == '\0' || head[0] == '#'); + +  cp = strsep (&head, " \t"); +  mp->mnt_fsname = cp != NULL ? decode_name (cp) : (char *) ""; +  if (head) +    head += strspn (head, " \t"); +  cp = strsep (&head, " \t"); +  mp->mnt_dir = cp != NULL ? decode_name (cp) : (char *) ""; +  if (head) +    head += strspn (head, " \t"); +  cp = strsep (&head, " \t"); +  mp->mnt_type = cp != NULL ? decode_name (cp) : (char *) ""; +  if (head) +    head += strspn (head, " \t"); +  cp = strsep (&head, " \t"); +  mp->mnt_opts = cp != NULL ? decode_name (cp) : (char *) ""; +  switch (head ? sscanf (head, " %d %d ", &mp->mnt_freq, &mp->mnt_passno) : 0) +    { +    case 0: +      mp->mnt_freq = 0; +    case 1: +      mp->mnt_passno = 0; +    case 2: +      break; +    } +  funlockfile (stream); + +  return mp; +} + +struct glusterfs_mntent * +glusterfs_fstab_getent (glusterfs_fstab_t *h) +{ +  if (!h) +    return NULL; + +  if (!h->fp) +    return NULL; + +  return __glusterfs_fstab_getent (h->fp, &h->tmpent, h->buf, +                                   GF_MNTENT_BUFSIZE); +} + +/* We have to use an encoding for names if they contain spaces or tabs. +   To be able to represent all characters we also have to escape the +   backslash itself.  This "function" must be a macro since we use +   `alloca'.  */ +#define encode_name(name) \ +  do {									      \ +    const char *rp = name;						      \ +									      \ +    while (*rp != '\0')							      \ +      if (*rp == ' ' || *rp == '\t' || *rp == '\\')			      \ +	break;								      \ +      else								      \ +	++rp;								      \ +									      \ +    if (*rp != '\0')							      \ +      {									      \ +	/* In the worst case the length of the string can increase to	      \ +	   founr times the current length.  */				      \ +	char *wp;							      \ +									      \ +	rp = name;							      \ +	name = wp = (char *) alloca (strlen (name) * 4 + 1);		      \ +									      \ +	do								      \ +	  if (*rp == ' ')						      \ +	    {								      \ +	      *wp++ = '\\';						      \ +	      *wp++ = '0';						      \ +	      *wp++ = '4';						      \ +	      *wp++ = '0';						      \ +	    }								      \ +	  else if (*rp == '\t')						      \ +	    {								      \ +	      *wp++ = '\\';						      \ +	      *wp++ = '0';						      \ +	      *wp++ = '1';						      \ +	      *wp++ = '1';						      \ +	    }								      \ +	  else if (*rp == '\n')						      \ +	    {								      \ +	      *wp++ = '\\';						      \ +	      *wp++ = '0';						      \ +	      *wp++ = '1';						      \ +	      *wp++ = '2';						      \ +	    }								      \ +	  else if (*rp == '\\')						      \ +	    {								      \ +	      *wp++ = '\\';						      \ +	      *wp++ = '\\';						      \ +	    }								      \ +	  else								      \ +	    *wp++ = *rp;						      \ +	while (*rp++ != '\0');						      \ +      }									      \ +  } while (0) + + +int +glusterfs_fstab_addent (glusterfs_fstab_t *h, +                        const struct glusterfs_mntent *mnt) +{ +  struct glusterfs_mntent mntcopy = *mnt; +  if (!h) +    return -1; + +  if (!h->fp) +    return -1; + +  if (fseek (h->fp, 0, SEEK_END)) +    return -1; + +  /* Encode spaces and tabs in the names.  */ +  encode_name (mntcopy.mnt_fsname); +  encode_name (mntcopy.mnt_dir); +  encode_name (mntcopy.mnt_type); +  encode_name (mntcopy.mnt_opts); + +  return (fprintf (h->fp, "%s %s %s %s %d %d\n", +		   mntcopy.mnt_fsname, +		   mntcopy.mnt_dir, +		   mntcopy.mnt_type, +		   mntcopy.mnt_opts, +		   mntcopy.mnt_freq, +		   mntcopy.mnt_passno) +	  < 0 ? 1 : 0); +} + + +/* Search MNT->mnt_opts for an option matching OPT. +   Returns the address of the substring, or null if none found.  */ +char * +glusterfs_fstab_hasoption (const struct glusterfs_mntent *mnt, const char *opt) +{ +  const size_t optlen = strlen (opt); +  char *rest = mnt->mnt_opts, *p; + +  while ((p = strstr (rest, opt)) != NULL) +    { +      if ((p == rest || p[-1] == ',') +	  && (p[optlen] == '\0' || p[optlen] == '=' || p[optlen] == ',')) +	return p; + +      rest = strchr (p, ','); +      if (rest == NULL) +	break; +      ++rest; +    } + +  return NULL; +} diff --git a/libglusterfs/src/glusterfs_fstab.h b/libglusterfs/src/glusterfs_fstab.h new file mode 100644 index 00000000000..5d6c6a77f81 --- /dev/null +++ b/libglusterfs/src/glusterfs_fstab.h @@ -0,0 +1,82 @@ +/* Utilities for reading/writing fstab, mtab, etc. +   Copyright (C) 1995, 1996, 1997, 1998, 1999 Free Software Foundation, Inc. +   This file is part of the GNU C Library. + +   The GNU C Library is free software; you can redistribute it and/or +   modify it under the terms of the GNU Lesser General Public +   License as published by the Free Software Foundation; either +   version 2.1 of the License, or (at your option) any later version. + +   The GNU C Library is distributed in the hope that it will be useful, +   but WITHOUT ANY WARRANTY; without even the implied warranty of +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +   Lesser General Public License for more details. + +   You should have received a copy of the GNU Lesser General Public +   License along with the GNU C Library; if not, write to the Free +   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +   02111-1307 USA.  */ + +#ifndef	GLUSTERFS_FSTAB_MNTENT_H +#define	GLUSTERFS_FSTAB_MNTENT_H	1 + +#include <features.h> +#include <stdio.h> +#include <paths.h> + + +/* General filesystem types.  */ +#define GF_MNTTYPE_IGNORE	"ignore"	/* Ignore this entry.  */ +#define GF_MNTTYPE_NFS	"nfs"		/* Network file system.  */ +#define GF_MNTTYPE_SWAP	"swap"		/* Swap device.  */ + + +/* Generic mount options.  */ +#define GF_MNTOPT_DEFAULTS	"defaults"	/* Use all default options.  */ +#define GF_MNTOPT_RO	        "ro"		/* Read only.  */ +#define GF_MNTOPT_RW	        "rw"		/* Read/write.  */ +#define GF_MNTOPT_SUID	        "suid"		/* Set uid allowed.  */ +#define GF_MNTOPT_NOSUID	"nosuid"	/* No set uid allowed.  */ +#define GF_MNTOPT_NOAUTO	"noauto"	/* Do not auto mount.  */ + + +/* Structure describing a mount table entry.  */ +struct glusterfs_mntent +  { +    char *mnt_fsname;		/* Device or server for filesystem.  */ +    char *mnt_dir;		/* Directory mounted on.  */ +    char *mnt_type;		/* Type of filesystem: ufs, nfs, etc.  */ +    char *mnt_opts;		/* Comma-separated options for fs.  */ +    int mnt_freq;		/* Dump frequency (in days).  */ +    int mnt_passno;		/* Pass number for `fsck'.  */ +  }; + +#define GF_MNTENT_BUFSIZE       1024 +typedef struct glusterfs_fstab_handle { +        FILE *fp; +        char buf[GF_MNTENT_BUFSIZE]; +        struct glusterfs_mntent tmpent; +}glusterfs_fstab_t; + + +/* Prepare to begin reading and/or writing mount table entries from the +   beginning of FILE.  MODE is as for `fopen'.  */ +extern glusterfs_fstab_t *glusterfs_fstab_init (const char *file, +                                                const char *mode); + +extern struct glusterfs_mntent *glusterfs_fstab_getent (glusterfs_fstab_t *h); + +/* Write the mount table entry described by MNT to STREAM. +   Return zero on success, nonzero on failure.  */ +extern int glusterfs_fstab_addent (glusterfs_fstab_t *h, +		                   const struct glusterfs_mntent *mnt); + +/* Close a stream opened with `glusterfs_fstab_init'.  */ +extern int glusterfs_fstab_close (glusterfs_fstab_t *h); + +/* Search MNT->mnt_opts for an option matching OPT. +   Returns the address of the substring, or null if none found.  */ +extern char *glusterfs_fstab_hasoption (const struct glusterfs_mntent *mnt, +                                        const char *opt); + +#endif  | 
