[lxc-devel] [patch 4/6] [draft] Add separate interface for mounting fstab

Andrian Nord nightnord at gmail.com
Mon Nov 16 22:27:35 UTC 2009


This patch adds mount.c mount.h files, which contains a functions for
parsing and mounting mount entries/files.

lxc_mount_line does not require lxc_conf, as it's intended to be used
from setup_mount_entries, which are already resolved into config

Signed-off-by: Andrian Nord <NightNord at gmail.com>

diff --git a/src/lxc/mount.c b/src/lxc/mount.c
new file mode 100644
index 0000000..1d2437d
--- /dev/null
+++ b/src/lxc/mount.c
@@ -0,0 +1,314 @@
+/*
+ * lxc: linux Container library
+ *
+ * (C) Copyright IBM Corp. 2007, 2008
+ *
+ * Authors:
+ * Daniel Lezcano <dlezcano at fr.ibm.com>
+ *
+ * This 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.
+ *
+ * This 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 this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <mntent.h>
+#include <string.h>
+#include <errno.h>
+
+#include <sys/mount.h>
+
+#include "parse.h"
+#include "variables.h"
+
+#include <lxc/lxc.h>
+#include <lxc/log.h>
+
+lxc_log_define(lxc_mount, lxc);
+
+#ifndef MS_REC
+#define MS_REC 16384
+#endif
+
+struct parsing_state {
+	const char *file;
+	int line;
+	struct lxc_conf *lxc_conf;
+};
+
+struct mount_opt {
+	char *name;
+	int clear;
+	int flag;
+};
+
+static struct mount_opt mount_opt[] = {
+	{ "defaults",   0, 0              },
+	{ "ro",         0, MS_RDONLY      },
+	{ "rw",         1, MS_RDONLY      },
+	{ "suid",       1, MS_NOSUID      },
+	{ "nosuid",     0, MS_NOSUID      },
+	{ "dev",        1, MS_NODEV       },
+	{ "nodev",      0, MS_NODEV       },
+	{ "exec",       1, MS_NOEXEC      },
+	{ "noexec",     0, MS_NOEXEC      },
+	{ "sync",       0, MS_SYNCHRONOUS },
+	{ "async",      1, MS_SYNCHRONOUS },
+	{ "remount",    0, MS_REMOUNT     },
+	{ "mand",       0, MS_MANDLOCK    },
+	{ "nomand",     1, MS_MANDLOCK    },
+	{ "atime",      1, MS_NOATIME     },
+	{ "noatime",    0, MS_NOATIME     },
+	{ "diratime",   1, MS_NODIRATIME  },
+	{ "nodiratime", 0, MS_NODIRATIME  },
+	{ "bind",       0, MS_BIND        },
+	{ "rbind",      0, MS_BIND|MS_REC },
+	{ NULL,         0, 0              },
+};
+
+static void parse_mntopt(char *opt, unsigned long *flags, char **data)
+{
+	struct mount_opt *mo;
+
+	/* If opt is found in mount_opt, set or clear flags.
+	 * Otherwise append it to data. */
+
+	for (mo = &mount_opt[0]; mo->name != NULL; mo++) {
+		if (!strncmp(opt, mo->name, strlen(mo->name))) {
+			if (mo->clear)
+				*flags &= ~mo->flag;
+			else
+				*flags |= mo->flag;
+			return;
+		}
+	}
+
+	if (strlen(*data))
+		strcat(*data, ",");
+	strcat(*data, opt);
+}
+
+static int parse_mntopts(struct mntent *mntent, unsigned long *mntflags,
+			 char **mntdata)
+{
+	char *s, *data;
+	char *p, *saveptr = NULL;
+
+	if (!mntent->mnt_opts)
+		return 0;
+
+	s = strdup(mntent->mnt_opts);
+	if (!s) {
+		SYSERROR("failed to allocate memory");
+		return -1;
+	}
+
+	data = malloc(strlen(s) + 1);
+	if (!data) {
+		SYSERROR("failed to allocate memory");
+		free(s);
+		return -1;
+	}
+	*data = 0;
+
+	for (p = strtok_r(s, ",", &saveptr); p != NULL;
+	     p = strtok_r(NULL, ",", &saveptr))
+		parse_mntopt(p, mntflags, &data);
+
+	if (*data)
+		*mntdata = data;
+	else
+		free(data);
+	free(s);
+
+	return 0;
+}
+
+static int mount_entry(struct mntent *mntent)
+{
+	unsigned long mntflags;
+	char *mntdata;
+
+	int ret = -1;
+
+	mntflags = 0;
+	mntdata = NULL;
+
+	if (parse_mntopts(mntent, &mntflags, &mntdata) < 0) {
+		ERROR("failed to parse mount option '%s'", mntent->mnt_opts);
+		goto out;
+	}
+
+	if (mount(mntent->mnt_fsname, mntent->mnt_dir,
+				  mntent->mnt_type, mntflags, mntdata)) {
+		SYSERROR("failed to mount '%s' on '%s'",
+					mntent->mnt_fsname, mntent->mnt_dir);
+		goto free;
+	}
+
+	DEBUG("mounted %s on %s, type %s", mntent->mnt_fsname,
+					mntent->mnt_dir, mntent->mnt_type);
+
+	ret = 0;
+free:
+	free(mntdata);
+out:
+	return ret;
+}
+
+static void mntent_free(struct mntent* mntent)
+{
+	if (mntent->mnt_opts)
+		free(mntent->mnt_opts);
+
+	if (mntent->mnt_type)
+		free(mntent->mnt_type);
+
+	if (mntent->mnt_dir)
+		free(mntent->mnt_dir);
+
+	if (mntent->mnt_fsname)
+		free(mntent->mnt_fsname);
+
+	free(mntent);
+}
+
+static int parse_mount_line(char *line, struct mntent **mntent)
+{
+	struct mntent *entry;
+
+	int ret = -1;
+	int anchor = 0, length = strlen(line);
+	char *token;
+	int toknum = 0;
+	int *int_holder = NULL;
+
+	*mntent = NULL;
+
+	if (lxc_is_line_empty(line))
+		return 0;
+
+	entry = malloc(sizeof(struct mntent));
+
+	if (!entry) {
+		SYSERROR("failed to allocate memory");
+		goto out;
+	}
+
+	memset(entry, 0, sizeof(struct mntent));
+
+	while ((token = lxc_next_token(line, &anchor, length))) {
+		if ( *token == '#' ) 
+			break;
+
+		toknum++;
+
+		switch (toknum) {
+		case 1: entry->mnt_fsname = token; break;
+		case 2: entry->mnt_dir = token; break;
+		case 3: entry->mnt_type = token; break;
+		case 4: entry->mnt_opts = token; break;
+		case 5:
+			int_holder = &entry->mnt_freq;
+		case 6:
+			if (!int_holder)
+				int_holder = &entry->mnt_passno;
+
+			if (sscanf(token, "%u", int_holder) < 0) {
+				ERROR("invalid integer '%s'", token);
+				goto fail;
+			}
+
+			int_holder = NULL;
+		break;
+		}
+	}
+
+	if (toknum == 0) {
+		ret = 0;
+		goto fail;
+	} else if (toknum < 6) {
+		ERROR("too less columns into '%s': %u", line, toknum - 1);
+		goto fail;
+	} else if (toknum > 6) {
+		ERROR("garbage at the end of string '%s'", line);
+		goto fail;
+	}
+
+	ret = 0;
+	*mntent = entry;
+
+	goto out;
+fail:
+	mntent_free(entry);
+out:
+	return ret;
+}
+
+int lxc_mount_line(char *line)
+{
+	struct mntent *mntent;
+	int ret = -1;
+
+	if (parse_mount_line(line, &mntent)) {
+		ERROR("parsing of line '%s' failed", line);
+		return ret;
+	}
+
+	if (!mntent)
+		return 0;
+
+	if (mount_entry(mntent)) {
+		ERROR("'%s' entry mount failed", line);
+		goto out;
+	}
+
+	ret = 0;
+
+out:
+	free(mntent);
+
+	return ret;
+}
+
+static int parse_fstab_line(void *buffer, void *data)
+{
+	struct parsing_state *state = data;
+	char *line;
+
+	if (lxc_resolve_variables(buffer, &line, state->lxc_conf)) {
+		ERROR("%s: %u: variable resolving failed",
+						state->file, state->line);
+
+		return -1;
+	}
+
+	state->line++;
+
+	return lxc_mount_line(line);
+}
+
+int lxc_mount_fstab(const char *fstab, struct lxc_conf *lxc_conf)
+{
+	char buffer[MAXPATHLEN];
+
+	struct parsing_state state = {
+		.file = fstab,
+		.line = 1,
+		.lxc_conf = lxc_conf
+	};
+
+	return lxc_file_for_each_line(fstab, parse_fstab_line,
+						buffer, MAXPATHLEN, &state);
+
+}
diff --git a/src/lxc/mount.h b/src/lxc/mount.h
new file mode 100644
index 0000000..c6c6983
--- /dev/null
+++ b/src/lxc/mount.h
@@ -0,0 +1,27 @@
+/*
+ * lxc: linux Container library
+ *
+ * (C) Copyright IBM Corp. 2007, 2008
+ *
+ * Authors:
+ * Daniel Lezcano <dlezcano at fr.ibm.com>
+ *
+ * This 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.
+ *
+ * This 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 this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+struct lxc_conf;
+
+extern int lxc_mount_fstab(const char *file, struct lxc_conf *conf);
+extern int lxc_mount_line(char *line);




More information about the lxc-devel mailing list