2.19.1-2: merge changes from f15 (#716483, #709681, #709319)

Signed-off-by: Karel Zak <kzak@redhat.com>
This commit is contained in:
Karel Zak 2011-07-05 00:05:24 +02:00
parent 1d99930816
commit 6d73e5dfdf
6 changed files with 561 additions and 1 deletions

View File

@ -0,0 +1,32 @@
From fa7e0d6d442de9f5940f99fd93f4522602439131 Mon Sep 17 00:00:00 2001
From: Karel Zak <kzak@redhat.com>
Date: Mon, 6 Jun 2011 12:35:26 +0200
Subject: [PATCH] lib: [linux_version.c] accommodate two-component linux
version (e.g. 3.0)
Signed-off-by: Karel Zak <kzak@redhat.com>
---
lib/linux_version.c | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/lib/linux_version.c b/lib/linux_version.c
index f9fbd8d..ada566a 100644
--- a/lib/linux_version.c
+++ b/lib/linux_version.c
@@ -16,10 +16,10 @@ get_linux_version (void)
return kver;
if (uname (&uts))
kver = 0;
- else if (sscanf (uts.release, "%d.%d.%d", &major, &minor, &teeny) != 3)
- kver = 0;
- else
+ else if (sscanf (uts.release, "%d.%d.%d", &major, &minor, &teeny) == 3)
kver = KERNEL_VERSION (major, minor, teeny);
+ else if (sscanf (uts.release, "%d.%d", &major, &minor) == 2)
+ kver = KERNEL_VERSION (major, minor, 0);
return kver;
}
--
1.7.5.2

View File

@ -0,0 +1,290 @@
From 5c60a0eab5155043f58fa88909d89e0b06cad2f8 Mon Sep 17 00:00:00 2001
From: Karel Zak <kzak@redhat.com>
Date: Tue, 31 May 2011 18:01:36 +0200
Subject: [PATCH] libmount: add mnt_table_is_mounted()
Signed-off-by: Karel Zak <kzak@redhat.com>
---
shlibs/mount/src/libmount.h.in | 3 +
shlibs/mount/src/libmount.sym | 1 +
shlibs/mount/src/tab.c | 210 ++++++++++++++++++++++++++++++++++++++++
shlibs/mount/src/tab_update.c | 2 +-
4 files changed, 215 insertions(+), 1 deletions(-)
diff --git a/shlibs/mount/src/libmount.h.in b/shlibs/mount/src/libmount.h.in
index 3ea2f92..1522208 100644
--- a/shlibs/mount/src/libmount.h.in
+++ b/shlibs/mount/src/libmount.h.in
@@ -308,6 +308,9 @@ extern int mnt_table_find_next_fs(struct libmnt_table *tb,
int (*match_func)(struct libmnt_fs *, void *), void *userdata,
struct libmnt_fs **fs);
+extern int mnt_table_is_fs_mounted(struct libmnt_table *tb, struct libmnt_fs *fstab_fs);
+
+
/* tab_update.c */
extern struct libmnt_update *mnt_new_update(void);
extern void mnt_free_update(struct libmnt_update *upd);
diff --git a/shlibs/mount/src/libmount.sym b/shlibs/mount/src/libmount.sym
index 0b7c560..a498916 100644
--- a/shlibs/mount/src/libmount.sym
+++ b/shlibs/mount/src/libmount.sym
@@ -195,6 +195,7 @@ global:
mnt_update_is_ready;
mnt_update_set_fs;
mnt_update_table;
+ mnt_table_is_fs_mounted;
local:
*;
};
diff --git a/shlibs/mount/src/tab.c b/shlibs/mount/src/tab.c
index 2a6a235..38a5d5b 100644
--- a/shlibs/mount/src/tab.c
+++ b/shlibs/mount/src/tab.c
@@ -712,6 +712,175 @@ struct libmnt_fs *mnt_table_find_pair(struct libmnt_table *tb, const char *sourc
return NULL;
}
+/*
+ * @tb: /proc/self/mountinfo
+ * @fs: filesystem
+ * @mountflags: MS_BIND or 0
+ * @fsroot: fs-root that will be probably used in the mountinfo file
+ * for @fs after mount(2)
+ *
+ * For btrfs subvolumes this function returns NULL, but @fsroot properly set.
+ *
+ * Returns: entry from @tb that will be used as a source for @fs if the @fs is
+ * bindmount.
+ */
+struct libmnt_fs *mnt_table_get_fs_root(struct libmnt_table *tb,
+ struct libmnt_fs *fs,
+ unsigned long mountflags,
+ char **fsroot)
+{
+ char *root = NULL, *mnt = NULL;
+ const char *fstype;
+ struct libmnt_fs *src_fs = NULL;
+
+ assert(tb);
+ assert(fs);
+ assert(fsroot);
+
+ DBG(TAB, mnt_debug("lookup fs-root for %s", mnt_fs_get_source(fs)));
+
+ fstype = mnt_fs_get_fstype(fs);
+
+ if (mountflags & MS_BIND) {
+ const char *src, *src_root;
+
+ DBG(TAB, mnt_debug("fs-root for bind"));
+
+ src = mnt_resolve_spec(mnt_fs_get_source(fs), tb->cache);
+ if (!src)
+ goto err;
+
+ mnt = mnt_get_mountpoint(src);
+ if (!mnt)
+ goto err;
+
+ root = mnt_get_fs_root(src, mnt);
+
+ src_fs = mnt_table_find_target(tb, mnt, MNT_ITER_BACKWARD);
+ if (!src_fs) {
+ DBG(TAB, mnt_debug("not found '%s' in mountinfo -- using default", mnt));
+ goto dflt;
+ }
+
+ /* on btrfs the subvolume is used as fs-root in
+ * /proc/self/mountinfo, so we have to get the original subvolume
+ * name from src_fs and prepend the subvolume name to the
+ * fs-root path
+ */
+ src_root = mnt_fs_get_root(src_fs);
+ if (src_root && !startswith(root, src_root)) {
+ size_t sz = strlen(root) + strlen(src_root) + 1;
+ char *tmp = malloc(sz);
+
+ if (!tmp)
+ goto err;
+ snprintf(tmp, sz, "%s%s", src_root, root);
+ free(root);
+ root = tmp;
+ }
+ }
+
+ /*
+ * btrfs-subvolume mount -- get subvolume name and use it as a root-fs path
+ */
+ else if (fstype && !strcmp(fstype, "btrfs")) {
+ char *vol = NULL, *p;
+ size_t sz, volsz = 0;
+
+ if (mnt_fs_get_option(fs, "subvol", &vol, &volsz))
+ goto dflt;
+
+ DBG(TAB, mnt_debug("setting FS root: btrfs subvol"));
+
+ sz = volsz;
+ if (*vol != '/')
+ sz++;
+ root = malloc(sz + 1);
+ if (!root)
+ goto err;
+ p = root;
+ if (*vol != '/')
+ *p++ = '/';
+ memcpy(p, vol, volsz);
+ *(root + sz) = '\0';
+ }
+dflt:
+ if (!root) {
+ root = strdup("/");
+ if (!root)
+ goto err;
+ }
+ *fsroot = root;
+
+ DBG(TAB, mnt_debug("FS root result: %s", root));
+
+ free(mnt);
+ return src_fs;
+err:
+ free(root);
+ free(mnt);
+ return NULL;
+}
+
+/**
+ * mnt_table_is_mounted:
+ * @tb: /proc/self/mountinfo file
+ * @fstab_fs: /etc/fstab entry
+ *
+ * Checks if the @fstab_fs entry is already in the @tb table. The "swap"
+ * is ignored.
+ *
+ * TODO: check for loopdev (see mount/mount.c is_fstab_entry_mounted().
+ *
+ * Returns: 0 or 1
+ */
+int mnt_table_is_fs_mounted(struct libmnt_table *tb, struct libmnt_fs *fstab_fs)
+{
+ char *root = NULL;
+ struct libmnt_fs *src_fs;
+ const char *src, *tgt;
+ int flags = 0, rc = 0;
+
+ assert(tb);
+ assert(fstab_fs);
+
+ if (fstab_fs->flags & MNT_FS_SWAP)
+ return 0;
+
+ if (mnt_fs_get_option(fstab_fs, "bind", NULL, NULL) == 0)
+ flags = MS_BIND;
+
+ src_fs = mnt_table_get_fs_root(tb, fstab_fs, flags, &root);
+ if (src_fs)
+ src = mnt_fs_get_srcpath(src_fs);
+ else
+ src = mnt_resolve_spec(mnt_fs_get_source(fstab_fs), tb->cache);
+
+ tgt = mnt_fs_get_target(fstab_fs);
+
+ if (tgt || src || root) {
+ struct libmnt_iter itr;
+ struct libmnt_fs *fs;
+
+ mnt_reset_iter(&itr, MNT_ITER_FORWARD);
+
+ while(mnt_table_next_fs(tb, &itr, &fs) == 0) {
+ const char *s = mnt_fs_get_srcpath(fs),
+ *t = mnt_fs_get_target(fs),
+ *r = mnt_fs_get_root(fs);
+
+ if (s && t && r && !strcmp(t, tgt) &&
+ !strcmp(s, src) && !strcmp(r, root))
+ break;
+ }
+ if (fs)
+ rc = 1; /* success */
+ }
+
+ free(root);
+ return rc;
+}
+
#ifdef TEST_PROGRAM
static int parser_errcb(struct libmnt_table *tb, const char *filename, int line)
@@ -869,6 +1038,46 @@ done:
return rc;
}
+static int test_is_mounted(struct libmnt_test *ts, int argc, char *argv[])
+{
+ struct libmnt_table *tb = NULL, *fstab = NULL;
+ struct libmnt_fs *fs;
+ struct libmnt_iter *itr = NULL;
+ int rc;
+
+ tb = mnt_new_table_from_file("/proc/self/mountinfo");
+ if (!tb) {
+ fprintf(stderr, "failed to parse mountinfo\n");
+ return -1;
+ }
+
+ fstab = create_table(argv[1]);
+ if (!fstab)
+ goto done;
+
+ itr = mnt_new_iter(MNT_ITER_FORWARD);
+ if (!itr)
+ goto done;
+
+ while(mnt_table_next_fs(fstab, itr, &fs) == 0) {
+ if (mnt_table_is_fs_mounted(tb, fs))
+ printf("%s already mounted on %s\n",
+ mnt_fs_get_source(fs),
+ mnt_fs_get_target(fs));
+ else
+ printf("%s not mounted on %s\n",
+ mnt_fs_get_source(fs),
+ mnt_fs_get_target(fs));
+ }
+
+ rc = 0;
+done:
+ mnt_free_table(tb);
+ mnt_free_table(fstab);
+ mnt_free_iter(itr);
+ return rc;
+}
+
int main(int argc, char *argv[])
{
struct libmnt_test tss[] = {
@@ -877,6 +1086,7 @@ int main(int argc, char *argv[])
{ "--find-backward", test_find_bw, "<file> <source|target> <string>" },
{ "--find-pair", test_find_pair, "<file> <source> <target>" },
{ "--copy-fs", test_copy_fs, "<file> copy root FS from the file" },
+ { "--is-mounted", test_is_mounted, "<fstab> check what from <file> are already mounted" },
{ NULL }
};
diff --git a/shlibs/mount/src/tab_update.c b/shlibs/mount/src/tab_update.c
index 5abb566..9817f20 100644
--- a/shlibs/mount/src/tab_update.c
+++ b/shlibs/mount/src/tab_update.c
@@ -410,7 +410,7 @@ static int set_fs_root(struct libmnt_fs *result, struct libmnt_fs *fs, unsigned
mnt_fs_set_fstype(result, mnt_fs_get_fstype(src_fs));
/* on btrfs the subvolume is used as fs-root in
- * /proc/self/mountinfo, so we have get the original subvolume
+ * /proc/self/mountinfo, so we have to get the original subvolume
* name from src_fs and prepend the subvolume name to the
* fs-root path
*/
--
1.7.5.2

View File

@ -0,0 +1,105 @@
From 0cac8948216a298deaf5fd30837ed9cc80618f80 Mon Sep 17 00:00:00 2001
From: Karel Zak <kzak@redhat.com>
Date: Tue, 31 May 2011 18:02:29 +0200
Subject: [PATCH] mount: use libmount to detect already mounted bind mounts
It's pretty tricky to detect that a bind mount from fstab is already
mounted on system without /etc/mtab. Let's use functionality from
libmount.
Addresses: https://bugzilla.redhat.com/show_bug.cgi?id=701176
Signed-off-by: Karel Zak <kzak@redhat.com>
---
mount/mount.c | 42 ++++++++++++++++++++++++++++++++++++++----
1 files changed, 38 insertions(+), 4 deletions(-)
diff --git a/mount/mount.c b/mount/mount.c
index 29963c2..3ba705f 100644
--- a/mount/mount.c
+++ b/mount/mount.c
@@ -212,7 +212,7 @@ static const char *opt_loopdev, *opt_vfstype, *opt_offset, *opt_sizelimit,
*opt_encryption, *opt_speed, *opt_comment, *opt_uhelper;
static int is_readonly(const char *node);
-static int mounted (const char *spec0, const char *node0);
+static int mounted (const char *spec0, const char *node0, struct mntentchn *fstab_mc);
static int check_special_mountprog(const char *spec, const char *node,
const char *type, int flags, char *extra_opts, int *status);
@@ -1562,7 +1562,7 @@ try_mount_one (const char *spec0, const char *node0, const char *types0,
/* The "mount -f" checks for for existing record in /etc/mtab (with
* regular non-fake mount this is usually done by kernel)
*/
- if (!(flags & MS_REMOUNT) && fake && mounted (spec, node))
+ if (!(flags & MS_REMOUNT) && fake && mounted (spec, node, NULL))
die(EX_USAGE, _("mount: according to mtab, "
"%s is already mounted on %s\n"),
spec, node);
@@ -2016,13 +2016,46 @@ mount_one (const char *spec, const char *node, const char *types,
return try_mount_one (spec, node, types, opts, freq, pass, 0);
}
+#ifdef HAVE_LIBMOUNT_MOUNT
+static struct libmnt_table *minfo; /* parsed mountinfo file */
+#endif
+
/* Check if an fsname/dir pair was already in the old mtab. */
static int
-mounted (const char *spec0, const char *node0) {
+mounted (const char *spec0, const char *node0, struct mntentchn *fstab_mc) {
struct mntentchn *mc, *mc0;
const char *spec, *node;
int ret = 0;
+#ifdef HAVE_LIBMOUNT_MOUNT
+ /*
+ * Use libmount to check for already mounted bind mounts on systems
+ * without mtab.
+ */
+ if (fstab_mc && fstab_mc->m.mnt_opts &&
+ mtab_is_a_symlink() && strstr(fstab_mc->m.mnt_opts, "bind")) {
+
+ struct libmnt_fs *fs = mnt_new_fs();
+ int rc = fs ? 0 : -1;
+
+ if (!rc)
+ rc = mnt_fs_set_fstype(fs, fstab_mc->m.mnt_type);
+ if (!rc)
+ rc = mnt_fs_set_source(fs, fstab_mc->m.mnt_fsname);
+ if (!rc)
+ rc = mnt_fs_set_target(fs, fstab_mc->m.mnt_dir);
+ if (!rc)
+ rc = mnt_fs_set_options(fs, fstab_mc->m.mnt_opts);
+ if (!rc && !minfo)
+ minfo = mnt_new_table_from_file("/proc/self/mountinfo");
+ if (!rc && minfo)
+ rc = mnt_table_is_fs_mounted(minfo, fs);
+
+ mnt_free_fs(fs);
+ if (rc == 1)
+ return 1;
+ }
+#endif
/* Handle possible UUID= and LABEL= in spec */
spec = spec_to_devname(spec0);
if (!spec)
@@ -2030,6 +2063,7 @@ mounted (const char *spec0, const char *node0) {
node = canonicalize(node0);
+
mc0 = mtab_head();
for (mc = mc0->nxt; mc && mc != mc0; mc = mc->nxt)
if (streq (spec, mc->m.mnt_fsname) &&
@@ -2050,7 +2084,7 @@ is_fstab_entry_mounted(struct mntentchn *mc, int verbose)
{
struct stat st;
- if (mounted(mc->m.mnt_fsname, mc->m.mnt_dir))
+ if (mounted(mc->m.mnt_fsname, mc->m.mnt_dir, mc))
goto yes;
/* extra care for loop devices */
--
1.7.5.2

View File

@ -0,0 +1,33 @@
From aab72640daa7ee2db3d42fc8278ab86e3aef2d71 Mon Sep 17 00:00:00 2001
From: Karel Zak <kzak@redhat.com>
Date: Thu, 2 Jun 2011 14:53:42 +0200
Subject: [PATCH] mount: canonicalize fstab mnt_dir
Addresses: http://bugzilla.redhat.com/show_bug.cgi?id=709681
Signed-off-by: Karel Zak <kzak@redhat.com>
---
mount/fstab.c | 8 +++++++-
1 files changed, 7 insertions(+), 1 deletions(-)
diff --git a/mount/fstab.c b/mount/fstab.c
index 8ce733b..4fa26b4 100644
--- a/mount/fstab.c
+++ b/mount/fstab.c
@@ -455,7 +455,13 @@ getfs_by_dir (const char *dir) {
cdir = canonicalize(dir);
for (mc = mc0->nxt; mc && mc != mc0; mc = mc->nxt) {
- if (streq(mc->m.mnt_dir, cdir)) {
+ int ok = streq(mc->m.mnt_dir, cdir);
+ if (!ok) {
+ char *dr = canonicalize(mc->m.mnt_dir);
+ ok = dr ? streq(dr, cdir) : 0;
+ free(dr);
+ }
+ if (ok) {
free(cdir);
return mc;
}
--
1.7.5.2

View File

@ -0,0 +1,76 @@
From 067e9b4934372f72b89b2c0442a3d28290834537 Mon Sep 17 00:00:00 2001
From: Karel Zak <kzak@redhat.com>
Date: Wed, 29 Jun 2011 09:02:50 +0200
Subject: [PATCH] mount: first look for mountpoint
# mount <device|dir>
The current code looks for a device and then for a mountpoint in
/etc/fstab. This is not user friendly solution. People usually use
# mount /dir
to mount any filesystem. It makes more sense to check for mountpoint
and if not found then for device.
This is also important for bind mounts, for example if you have in
your fstab:
/dev/sda1 /mnt/foo auto defaults
/mnt/foo /mnt/bar none bind
then
# mount /mnt/foo
should be interpreted as the first entry and /dev/sda1 should be
mounted.
Addresses: https://bugzilla.redhat.com/show_bug.cgi?id=716483
Signed-off-by: Karel Zak <kzak@redhat.com>
---
mount/mount.8 | 11 +++++++++++
mount/mount.c | 4 ++--
2 files changed, 13 insertions(+), 2 deletions(-)
diff --git a/mount/mount.8 b/mount/mount.8
index 8982537..e9a52dd 100644
--- a/mount/mount.8
+++ b/mount/mount.8
@@ -101,6 +101,17 @@ the pathname
refers to the root of the filesystem on
.IR device .
+If only directory or device is given, for example:
+.RS
+
+.br
+.BI "mount /dir"
+.br
+
+.RE
+then mount looks for a mountpoint and if not found then for a device in the
+/etc/fstab file.
+
.B The listing and help.
.RS
Three forms of invocation do not actually mount anything:
diff --git a/mount/mount.c b/mount/mount.c
index 3ba705f..00637f5 100644
--- a/mount/mount.c
+++ b/mount/mount.c
@@ -2347,10 +2347,10 @@ getfs(const char *spec, const char *uuid, const char *label)
else if (label)
mc = getfs_by_label(label);
else {
- mc = getfs_by_spec(spec);
+ mc = getfs_by_dir(spec);
if (!mc)
- mc = getfs_by_dir(spec);
+ mc = getfs_by_spec(spec);
}
if (mc)
return mc;
--
1.7.5.4

View File

@ -2,7 +2,7 @@
Summary: A collection of basic system utilities
Name: util-linux
Version: 2.19.1
Release: 1%{?dist}
Release: 2%{?dist}
License: GPLv2 and GPLv2+ and GPLv3+ and LGPLv2+ and BSD with advertising and Public Domain
Group: System Environment/Base
URL: http://kernel.org/~kzak/util-linux/
@ -84,6 +84,18 @@ Patch7: util-linux-ng-2.13-login-lastlog.patch
# 231192 - ipcs is not printing correct values on pLinux
Patch8: util-linux-ng-2.15-ipcs-32bit.patch
### Upstream patches
###
# kernel "3.0"
Patch9: util-linux-2.19-kernel-version.patch
# 709319 - 'mount -a' mounts already mounted directories
Patch10: util-linux-2.19-libmount-mounted.patch
Patch11: util-linux-2.19-mount-a-bind.patch
# 709681 - failure to mount if a mount point ends with a slash in /etc/fstab
Patch12: util-linux-2.19-mount-fsname.patch
# 716483 - /var/tmp --(BIND-mounted)--> /tmp disrupts/hangs bootup
Patch13: util-linux-2.19-mount-mountpoint.patch
%description
The util-linux package contains a large variety of low-level system
utilities that are necessary for a Linux system to function. Among
@ -197,6 +209,12 @@ cp %{SOURCE8} %{SOURCE9} .
%patch5 -p1
%patch7 -p1
%patch8 -p1
%patch9 -p1
%patch10 -p1
%patch11 -p1
%patch12 -p1
%patch13 -p1
%build
unset LINGUAS || :
@ -742,6 +760,12 @@ fi
%changelog
* Mon Jul 4 2011 Karel Zak <kzak@redhat.com> 2.19.1-2
- fix #716483 - /var/tmp --(BIND-mounted)--> /tmp disrupts/hangs bootup
- fix #709681 - failure to mount if a mount point ends with a slash in /etc/fstab
- fix #709319 - 'mount -a' mounts already mounted directories
- fix kernel version parsing
* Fri May 6 2011 Karel Zak <kzak@redhat.com> 2.19.1-1
- upgrade to the release 2.19.1
ftp://ftp.kernel.org/pub/linux/utils/util-linux/v2.19/v2.19.1-ReleaseNotes