summaryrefslogtreecommitdiffstats
path: root/shlibs/mount
diff options
context:
space:
mode:
authorKarel Zak2010-01-12 13:43:07 +0100
committerKarel Zak2010-06-03 15:20:10 +0200
commitd115ee9bd183412c41f2a8cc7b3485c1e286e34f (patch)
tree3779f3edc76094408c4726d4ad125a086792bb72 /shlibs/mount
parentlibmount: add mtab locking code (diff)
downloadkernel-qcow2-util-linux-d115ee9bd183412c41f2a8cc7b3485c1e286e34f.tar.gz
kernel-qcow2-util-linux-d115ee9bd183412c41f2a8cc7b3485c1e286e34f.tar.xz
kernel-qcow2-util-linux-d115ee9bd183412c41f2a8cc7b3485c1e286e34f.zip
libmount: add mnt_entry
Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'shlibs/mount')
-rw-r--r--shlibs/mount/src/Makefile.am1
-rw-r--r--shlibs/mount/src/fs.c545
-rw-r--r--shlibs/mount/src/mount.h.in45
-rw-r--r--shlibs/mount/src/mountP.h39
4 files changed, 630 insertions, 0 deletions
diff --git a/shlibs/mount/src/Makefile.am b/shlibs/mount/src/Makefile.am
index 5cba0da9d..de265c9d5 100644
--- a/shlibs/mount/src/Makefile.am
+++ b/shlibs/mount/src/Makefile.am
@@ -13,6 +13,7 @@ libmount_la_SOURCES = $(mountinc_HEADERS)
nodist_libmount_la_SOURCES = mount.h version.c utils.c test.c init.c cache.c \
optstr.c optmap.c optent.c optls.c iter.c list.h lock.c \
+ fs.c \
$(top_srcdir)/lib/canonicalize.c
libmount_la_LIBADD = $(ul_libblkid_la)
diff --git a/shlibs/mount/src/fs.c b/shlibs/mount/src/fs.c
new file mode 100644
index 000000000..0e12052d5
--- /dev/null
+++ b/shlibs/mount/src/fs.c
@@ -0,0 +1,545 @@
+/*
+ * Copyright (C) 2008-2009 Karel Zak <kzak@redhat.com>
+ *
+ * This file may be redistributed under the terms of the
+ * GNU Lesser General Public License.
+ *
+ * The mnt_fs is representation of one line in a fstab / mtab / mountinfo.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <blkid/blkid.h>
+
+#include "nls.h"
+#include "mountP.h"
+
+/**
+ * mnt_new_fs:
+ *
+ * Returns newly allocated mnt_file fs.
+ */
+mnt_fs *mnt_new_fs(void)
+{
+ mnt_fs *fs = calloc(1, sizeof(struct _mnt_fs));
+ if (!fs)
+ return NULL;
+
+ INIT_LIST_HEAD(&fs->ents);
+ return fs;
+}
+
+/**
+ * mnt_free_fs:
+ * @fs: fs pointer
+ *
+ * Deallocates the fs.
+ */
+void mnt_free_fs(mnt_fs *fs)
+{
+ if (!fs)
+ return;
+ list_del(&fs->ents);
+
+ free(fs->source);
+ free(fs->tagname);
+ free(fs->tagval);
+ free(fs->mntroot);
+ free(fs->target);
+ free(fs->fstype);
+ free(fs->optstr);
+ free(fs->vfs_optstr);
+ free(fs->fs_optstr);
+
+ free(fs);
+}
+
+/**
+ * mnt_fs_get_srcpath:
+ * @fs: mnt_file (fstab/mtab/mountinfo) fs
+ *
+ * The mount "source path" is:
+ * - a directory for 'bind' mounts (in fstab or mtab only)
+ * - a device name for standard mounts
+ * - NULL when path is not set (for example when TAG
+ * (LABEL/UUID) is defined)
+ *
+ * See also mnt_fs_get_tag() and mnt_fs_get_source().
+ *
+ * Returns mount "source" path or NULL in case of error or when the path
+ * is not defined.
+ *
+ */
+const char *mnt_fs_get_srcpath(mnt_fs *fs)
+{
+ assert(fs);
+ if (!fs)
+ return NULL;
+
+ /* fstab-like fs */
+ if (fs->tagname)
+ return NULL; /* the source contains a "NAME=value" */
+ return fs->source;
+}
+
+/**
+ * @fs: mnt_file (fstab/mtab/mountinfo) fs
+ *
+ * Returns mount "source". Note that the source could be unparsed TAG
+ * (LABEL/UUID). See also mnt_fs_get_srcpath() and mnt_fs_get_tag().
+ */
+const char *mnt_fs_get_source(mnt_fs *fs)
+{
+ return fs ? fs->source : NULL;
+}
+
+/* Used by parser mnt_file ONLY (@source has to be allocated) */
+int __mnt_fs_set_source(mnt_fs *fs, char *source)
+{
+ assert(fs);
+
+ if (!source)
+ return -1;
+
+ if (strchr(source, '=')) {
+ char *name, *val;
+
+ if (blkid_parse_tag_string(source, &name, &val) != 0)
+ return -1;
+
+ fs->tagval = val;
+ fs->tagname = name;
+ }
+
+ fs->source = source;
+ return 0;
+}
+
+/**
+ * mnt_fs_set_source:
+ * @fs: fstab/mtab/mountinfo entry
+ * @source: new source
+ *
+ * Returns 0 on success or -1 in case of error.
+ */
+int mnt_fs_set_source(mnt_fs *fs, const char *source)
+{
+ char *p;
+
+ if (!fs && !source)
+ return -1;
+
+ p = strdup(source);
+ if (!p)
+ return -1;
+
+ free(fs->tagval);
+ free(fs->tagname);
+ free(fs->source);
+ fs->tagval = fs->tagname = fs->source = NULL;
+
+ return __mnt_fs_set_source(fs, p);
+}
+
+/**
+ * mnt_fs_get_tag:
+ * @fs: fs
+ * @name: returns pointer to NAME string
+ * @value: returns pointer to VALUE string
+ *
+ * "TAG" is NAME=VALUE (e.g. LABEL=foo)
+ *
+ * The TAG is the first column in the fstab file. The TAG
+ * or "srcpath" has to be always set for all entries.
+ *
+ * See also mnt_fs_get_source().
+ *
+ * Example:
+ * char *src;
+ * mnt_fs *fs = mnt_file_find_target(mf, "/home");
+ *
+ * if (!fs)
+ * goto err;
+ *
+ * src = mnt_fs_get_srcpath(fs);
+ * if (!src) {
+ * char *tag, *val;
+ * if (mnt_fs_get_tag(fs, &tag, &val) == 0)
+ * printf("%s: %s\n", tag, val); // LABEL or UUID
+ * } else
+ * printf("device: %s\n", src); // device or bind path
+ *
+ * Returns 0 on success or -1 in case that a TAG is not defined.
+ */
+int mnt_fs_get_tag(mnt_fs *fs, const char **name, const char **value)
+{
+ if (fs == NULL || !fs->tagname)
+ return -1;
+ if (name)
+ *name = fs->tagname;
+ if (value)
+ *value = fs->tagval;
+ return 0;
+}
+
+/**
+ * mnt_fs_get_target:
+ * @fs: fstab/mtab/mountinfo entry pointer
+ *
+ * Returns pointer to mountpoint path or NULL
+ */
+const char *mnt_fs_get_target(mnt_fs *fs)
+{
+ assert(fs);
+ return fs ? fs->target : NULL;
+}
+
+/**
+ * mnt_fs_set_target:
+ * @fs: fstab/mtab/mountinfo entry
+ * @target: mountpoint
+ *
+ * Returns 0 on success or -1 in case of error.
+ */
+int mnt_fs_set_target(mnt_fs *fs, const char *target)
+{
+ char *p;
+
+ assert(fs);
+
+ if (!fs || !target)
+ return -1;
+
+ p = strdup(target);
+ if (!p)
+ return -1;
+ free(fs->target);
+ fs->target = p;
+
+ return 0;
+}
+
+/**
+ * mnt_fs_get_fstype:
+ * @fs: fstab/mtab/mountinfo entry pointer
+ *
+ * Returns pointer to filesystem type.
+ */
+const char *mnt_fs_get_fstype(mnt_fs *fs)
+{
+ assert(fs);
+ return fs ? fs->fstype : NULL;
+}
+
+/* Used by mnt_file parser only */
+int __mnt_fs_set_fstype(mnt_fs *fs, char *fstype)
+{
+ assert(fs);
+
+ if (!fstype)
+ return -1;
+
+ fs->fstype = fstype;
+ fs->flags &= ~MNT_FS_PSEUDO;
+ fs->flags &= ~MNT_FS_NET;
+
+ /* save info about pseudo filesystems */
+ if (mnt_fstype_is_pseudofs(fs->fstype))
+ fs->flags |= MNT_FS_PSEUDO;
+ else if (mnt_fstype_is_netfs(fs->fstype))
+ fs->flags |= MNT_FS_NET;
+
+ return 0;
+}
+
+/**
+ * mnt_fs_set_fstype:
+ * @fs: fstab/mtab/mountinfo entry
+ * @fstype: filesystem type
+ *
+ * Returns 0 on success or -1 in case of error.
+ */
+int mnt_fs_set_fstype(mnt_fs *fs, const char *fstype)
+{
+ char *p;
+
+ if (!fs || !fstype)
+ return -1;
+
+ p = strdup(fstype);
+ if (!p)
+ return -1;
+ free(fs->fstype);
+
+ return __mnt_fs_set_fstype(fs, p);
+}
+
+/**
+ * mnt_fs_get_optstr:
+ * @fs: fstab/mtab/mountinfo entry pointer
+ *
+ * Returns pointer to mount option string with all options (FS and VFS)
+ */
+const char *mnt_fs_get_optstr(mnt_fs *fs)
+{
+ assert(fs);
+ return fs ? fs->optstr : NULL;
+}
+
+/**
+ * mnt_fs_set_optstr:
+ * @fs: fstab/mtab/mountinfo entry
+ * @optstr: options string
+ *
+ * Returns 0 on success or -1 in case of error.
+ */
+int mnt_fs_set_optstr(mnt_fs *fs, const char *optstr)
+{
+ assert(fs);
+
+ if (!fs || !optstr)
+ return -1;
+ free(fs->optstr);
+ free(fs->fs_optstr);
+ free(fs->vfs_optstr);
+ fs->fs_optstr = fs->vfs_optstr = NULL;
+
+ fs->optstr = strdup(optstr);
+
+ return fs->optstr ? 0 : -1;
+}
+
+/**
+ * mnt_fs_get_fs_optstr:
+ * @fs: fstab/mtab/mountinfo entry pointer
+ *
+ * This function works for "mountinfo" files only.
+ *
+ * Returns pointer to superblock (fs-depend) mount option string or NULL.
+ */
+const char *mnt_fs_get_fs_optstr(mnt_fs *fs)
+{
+ assert(fs);
+ return fs ? fs->fs_optstr : NULL;
+}
+
+/**
+ * mnt_fs_get_vfs_optstr:
+ * @fs: fstab/mtab/mountinfo entry pointer
+ *
+ * This function works for "mountinfo" files only.
+ *
+ * Returns pointer to fs-independent (VFS) mount option string or NULL.
+ */
+const char *mnt_fs_get_vfs_optstr(mnt_fs *fs)
+{
+ assert(fs);
+ return fs ? fs->vfs_optstr : NULL;
+}
+
+
+/**
+ * mnt_fs_get_freq:
+ * @fs: fstab/mtab/mountinfo entry pointer
+ *
+ * Returns "dump frequency in days".
+ */
+int mnt_fs_get_freq(mnt_fs *fs)
+{
+ assert(fs);
+ return fs ? fs->freq : 0;
+}
+
+/**
+ * mnt_fs_set_freq:
+ * @fs: fstab/mtab/mountinfo entry pointer
+ * @freq: dump frequency in days
+ *
+ * Returns 0 on success or -1 in case of error.
+ */
+int mnt_fs_set_freq(mnt_fs *fs, int freq)
+{
+ assert(fs);
+
+ if (!fs)
+ return -1;
+ fs->freq = freq;
+ return 0;
+}
+
+/**
+ * mnt_fs_get_passno:
+ * @fs: fstab/mtab/mountinfo entry pointer
+ *
+ * Returns "pass number on parallel fsck".
+ */
+int mnt_fs_get_passno(mnt_fs *fs)
+{
+ assert(fs);
+ return fs ? fs->passno: 0;
+}
+
+/**
+ * mnt_fs_set_passno:
+ * @fs: fstab/mtab/mountinfo entry pointer
+ * @passno: pass number
+ *
+ * Returns 0 on success or -1 in case of error.
+ */
+int mnt_fs_set_passno(mnt_fs *fs, int passno)
+{
+ assert(fs);
+
+ if (!fs)
+ return -1;
+ fs->passno = passno;
+ return 0;
+}
+
+/**
+ * mnt_fs_get_option:
+ * @fs: fstab/mtab/mountinfo entry pointer
+ * @name: option name
+ * @value: returns pointer to the begin of the value (e.g. name=VALUE) or NULL
+ * @valsz: returns size of options value or 0
+ *
+ * Returns 0 on success, 1 when not found the @name or -1 in case of error.
+ */
+int mnt_fs_get_option(mnt_fs *fs, const char *name,
+ char **value, size_t *valsz)
+{
+ char *optstr = (char *) mnt_fs_get_optstr(fs);
+ return optstr ? mnt_optstr_get_option(optstr, name, value, valsz) : 1;
+}
+
+
+/* Unfortunately the classical Unix /etc/mtab and /etc/fstab
+ do not handle directory names containing spaces.
+ Here we mangle them, replacing a space by \040.
+ What do other Unices do? */
+
+static unsigned char need_escaping[] = { ' ', '\t', '\n', '\\' };
+
+static char *mangle(const char *s)
+{
+ char *ss, *sp;
+ int n;
+
+ n = strlen(s);
+ ss = sp = malloc(4*n+1);
+ if (!sp)
+ return NULL;
+ while(1) {
+ for (n = 0; n < sizeof(need_escaping); n++) {
+ if (*s == need_escaping[n]) {
+ *sp++ = '\\';
+ *sp++ = '0' + ((*s & 0300) >> 6);
+ *sp++ = '0' + ((*s & 070) >> 3);
+ *sp++ = '0' + (*s & 07);
+ goto next;
+ }
+ }
+ *sp++ = *s;
+ if (*s == 0)
+ break;
+ next:
+ s++;
+ }
+ return ss;
+}
+
+/**
+ * mnt_fprintf_line:
+ * @f: FILE
+ * @fmt: printf-like format string (see MNT_MFILE_PRINTFMT)
+ * @source: (spec) device name or tag=value
+ * @target: mountpoint
+ * @fstype: filesystem type
+ * @options: mount options
+ * @freq: dump frequency in days
+ * @passno: pass number on parallel fsck
+ *
+ * Returns return value from fprintf().
+ */
+int mnt_fprintf_line( FILE *f,
+ const char *fmt,
+ const char *source,
+ const char *target,
+ const char *fstype,
+ const char *options,
+ int freq,
+ int passno)
+{
+ char *m1 = NULL, *m2 = NULL, *m3 = NULL, *m4 = NULL;
+ int rc = -1;
+
+ if (!f || !fmt || !source || !target || !fstype || !options)
+ return -1;
+
+ m1 = mangle(source);
+ m2 = mangle(target);
+ m3 = mangle(fstype);
+ m4 = mangle(options);
+
+ if (!m1 || !m2 || !m3 || !m4)
+ goto done;
+
+ rc = fprintf(f, fmt, m1, m2, m3, m4, freq, passno);
+done:
+ free(m1);
+ free(m2);
+ free(m3);
+ free(m4);
+
+ return rc;
+}
+
+/**
+ * mnt_fs_fprintf:
+ * @fs: fstab/mtab/mountinfo entry
+ * @f: FILE
+ * @fmt: printf-like format string (see MNT_MFILE_PRINTFMT)
+ *
+ * Returns return value from fprintf().
+ */
+int mnt_fs_fprintf(mnt_fs *fs, FILE *f, const char *fmt)
+{
+ assert(fs);
+ assert(f);
+ assert(fmt);
+
+ if (!fs || !f)
+ return -1;
+
+ return mnt_fprintf_line(f, fmt,
+ mnt_fs_get_source(fs),
+ mnt_fs_get_target(fs),
+ mnt_fs_get_fstype(fs),
+ mnt_fs_get_optstr(fs),
+ mnt_fs_get_freq(fs),
+ mnt_fs_get_passno(fs));
+}
+
+/**
+ * mnt_fs_print_debug
+ * @fs: fstab/mtab/mountinfo entry
+ * @file: output
+ *
+ * Returns 0 on success or -1 in case of error.
+ */
+int mnt_fs_print_debug(mnt_fs *fs, FILE *file)
+{
+ if (!fs)
+ return -1;
+ fprintf(file, "------ fs: %p\n", fs);
+ fprintf(file, "source: %s\n", mnt_fs_get_source(fs));
+ fprintf(file, "target: %s\n", mnt_fs_get_target(fs));
+ fprintf(file, "fstype: %s\n", mnt_fs_get_fstype(fs));
+ fprintf(file, "optstr: %s\n", mnt_fs_get_optstr(fs));
+ fprintf(file, "freq: %d\n", mnt_fs_get_freq(fs));
+ fprintf(file, "pass: %d\n", mnt_fs_get_passno(fs));
+
+ return 0;
+}
diff --git a/shlibs/mount/src/mount.h.in b/shlibs/mount/src/mount.h.in
index 05912e112..0c3f80bfb 100644
--- a/shlibs/mount/src/mount.h.in
+++ b/shlibs/mount/src/mount.h.in
@@ -88,6 +88,14 @@ struct mnt_optmap
#define MNT_INVERT (1 << 3) /* invert the mountflag */
#define MNT_NOMTAB (1 << 4) /* skip in the mtab option string */
+/**
+ * mnt_fs:
+ *
+ * Parsed fstab/mtab/mountinfo entry
+ */
+typedef struct _mnt_fs mnt_fs;
+
+
/* version.c */
extern int mnt_parse_version_string(const char *ver_string);
extern int mnt_get_library_version(const char **ver_string);
@@ -191,6 +199,43 @@ extern const char *mnt_lock_get_linkfile(mnt_lock *ml);
extern void mnt_unlock_file(mnt_lock *ml);
extern int mnt_lock_file(mnt_lock *ml);
+/* fs.c */
+extern mnt_fs *mnt_new_fs(void);
+extern void mnt_free_fs(mnt_fs *ent);
+extern const char *mnt_fs_get_source(mnt_fs *ent);
+extern int mnt_fs_set_source(mnt_fs *ent, const char *source);
+extern const char *mnt_fs_get_srcpath(mnt_fs *ent);
+extern int mnt_fs_get_tag(mnt_fs *ent, const char **name, const char **value);
+extern const char *mnt_fs_get_target(mnt_fs *ent);
+extern int mnt_fs_set_target(mnt_fs *ent, const char *target);
+extern const char *mnt_fs_get_fstype(mnt_fs *ent);
+extern int mnt_fs_set_fstype(mnt_fs *ent, const char *fstype);
+extern const char *mnt_fs_get_optstr(mnt_fs *ent);
+extern int mnt_fs_set_optstr(mnt_fs *ent, const char *optstr);
+extern const char *mnt_fs_get_optfs(mnt_fs *ent);
+extern const char *mnt_fs_get_optvfs(mnt_fs *ent);
+extern int mnt_fs_get_freq(mnt_fs *ent);
+extern int mnt_fs_set_freq(mnt_fs *ent, int freq);
+extern int mnt_fs_get_passno(mnt_fs *ent);
+extern int mnt_fs_set_passno(mnt_fs *ent, int passno);
+extern int mnt_fs_get_option(mnt_fs *ent, const char *name,
+ char **value, size_t *valsz);
+
+/* mtab/fstab line */
+#define MNT_MFILE_PRINTFMT "%s %s %s %s %d %d\n"
+
+extern int mnt_fprintf_line(
+ FILE *f,
+ const char *fmt,
+ const char *source,
+ const char *target,
+ const char *fstype,
+ const char *options,
+ int freq,
+ int passno);
+
+extern int mnt_fs_fprintf(mnt_fs *ent, FILE *f, const char *fmt);
+extern int mnt_fs_print_debug(mnt_fs *ent, FILE *file);
/*
* mount(8) userspace options masks (MNT_MAP_USERSPACE map)
diff --git a/shlibs/mount/src/mountP.h b/shlibs/mount/src/mountP.h
index 82c557b4e..b6eb8cd34 100644
--- a/shlibs/mount/src/mountP.h
+++ b/shlibs/mount/src/mountP.h
@@ -126,6 +126,42 @@ struct _mnt_optls {
struct list_head opts; /* list of options */
};
+/*
+ * This struct represents one entry in mtab/fstab/mountinfo file.
+ */
+struct _mnt_fs {
+ struct list_head ents;
+
+ int id; /* mountinfo[1]: ID */
+ int parent; /* moutninfo[2]: parent */
+
+ char *source; /* fstab[1]: mountinfo[10]:
+ * source dev, file, dir or TAG */
+ char *tagname; /* fstab[1]: tag name - "LABEL", "UUID", ..*/
+ char *tagval; /* tag value */
+
+ char *mntroot; /* mountinfo[4]: root of the mount within the FS */
+ char *target; /* mountinfo[5], fstab[2]: mountpoint */
+ char *fstype; /* mountinfo[9], fstab[3]: filesystem type */
+
+ char *optstr; /* mountinfo[6,11], fstab[4]: option string */
+ char *vfs_optstr; /* mountinfo[6]: fs-independent (VFS) options */
+ char *fs_optstr; /* mountinfo[11]: fs-depend options */
+
+ int freq; /* fstab[5]: dump frequency in days */
+ int passno; /* fstab[6]: pass number on parallel fsck */
+
+ int flags; /* MNT_ENTRY_* flags */
+ int lineno; /* line number in the parental file */
+};
+
+/*
+ * fs flags
+ */
+#define MNT_FS_ERROR (1 << 1) /* broken entry */
+#define MNT_FS_PSEUDO (1 << 2) /* pseudo filesystem */
+#define MNT_FS_NET (1 << 3) /* network filesystem */
+
/* optmap.c */
extern const struct mnt_optmap *mnt_optmap_get_entry(struct mnt_optmap const **maps,
int nmaps, const char *name,
@@ -149,5 +185,8 @@ extern mnt_optent *mnt_new_optent_from_optstr(char **optstr,
extern int mnt_optent_assign_map(mnt_optent *op,
struct mnt_optmap const **maps, int nmaps);
+/* fs.c */
+extern int __mnt_fs_set_source(mnt_fs *fs, char *source);
+extern int __mnt_fs_set_fstype(mnt_fs *fs, char *fstype);
#endif /* _LIBMOUNT_PRIVATE_H */