summaryrefslogtreecommitdiff
path: root/mount
diff options
context:
space:
mode:
Diffstat (limited to 'mount')
-rw-r--r--mount/Makefile.am19
-rw-r--r--mount/mount.832
-rw-r--r--mount/mount.c87
-rw-r--r--mount/swapon.812
-rw-r--r--mount/swapon.c6
-rw-r--r--mount/umount.c11
6 files changed, 116 insertions, 51 deletions
diff --git a/mount/Makefile.am b/mount/Makefile.am
index 1fbdfe82..5ff4fc9e 100644
--- a/mount/Makefile.am
+++ b/mount/Makefile.am
@@ -7,7 +7,7 @@ sbin_PROGRAMS = losetup swapon
dist_man_MANS = fstab.5 mount.8 swapoff.8 swapon.8 umount.8 losetup.8
# generic sources for all programs (mount, umount, losetup)
-srcs_common = sundries.c xmalloc.c ../lib/canonicalize.c sundries.h xmalloc.h rmd160.c
+srcs_common = sundries.c xmalloc.c $(top_srcdir)/lib/canonicalize.c sundries.h xmalloc.h rmd160.c
# generic header for mount and umount
hdrs_mount = fstab.h mount_mntent.h mount_constants.h \
@@ -15,8 +15,9 @@ hdrs_mount = fstab.h mount_mntent.h mount_constants.h \
# generic sources for mount and umount
srcs_mount = fstab.c mount_mntent.c getusername.c lomount.c devname.c devname.h \
- $(srcs_common) $(hdrs_mount) ../lib/env.c ../lib/linux_version.c \
- ../lib/blkdev.c ../lib/fsprobe.c ../lib/mangle.c
+ $(srcs_common) $(hdrs_mount) $(top_srcdir)/lib/env.c \
+ $(top_srcdir)/lib/linux_version.c $(top_srcdir)/lib/blkdev.c \
+ $(top_srcdir)/lib/fsprobe.c $(top_srcdir)/lib/mangle.c
# generic flags for all programs (except losetup)
# -- note that pkg-config autoconf macros (pkg.m4) does not differentiate
@@ -26,7 +27,8 @@ ldadd_static =
cflags_common = $(AM_CFLAGS)
ldflags_static = -all-static
-mount_SOURCES = mount.c $(srcs_mount) ../lib/setproctitle.c ../lib/strtosize.c
+mount_SOURCES = mount.c $(srcs_mount) $(top_srcdir)/lib/setproctitle.c \
+ $(top_srcdir)/lib/strtosize.c
mount_CFLAGS = $(SUID_CFLAGS) $(cflags_common)
mount_LDFLAGS = $(SUID_LDFLAGS) $(AM_LDFLAGS)
mount_LDADD = $(ldadd_common)
@@ -36,13 +38,14 @@ umount_CFLAGS = $(SUID_CFLAGS) $(cflags_common)
umount_LDFLAGS = $(SUID_LDFLAGS) $(AM_LDFLAGS)
umount_LDADD = $(ldadd_common)
-swapon_SOURCES = swapon.c swap_constants.h ../lib/linux_version.c \
- ../lib/blkdev.c ../lib/fsprobe.c ../lib/canonicalize.c \
- ../lib/mangle.c
+swapon_SOURCES = swapon.c swap_constants.h $(top_srcdir)/lib/linux_version.c \
+ $(top_srcdir)/lib/blkdev.c $(top_srcdir)/lib/fsprobe.c \
+ $(top_srcdir)/lib/canonicalize.c $(top_srcdir)/lib/mangle.c
swapon_CFLAGS = $(cflags_common)
swapon_LDADD = $(ldadd_common)
-losetup_SOURCES = lomount.c $(srcs_common) loop.h lomount.h ../lib/strtosize.c
+losetup_SOURCES = lomount.c $(srcs_common) loop.h lomount.h \
+ $(top_srcdir)/lib/strtosize.c
losetup_CPPFLAGS = -DMAIN $(AM_CPPFLAGS)
mount_static_LDADD =
diff --git a/mount/mount.8 b/mount/mount.8
index bf5a419a..4146958a 100644
--- a/mount/mount.8
+++ b/mount/mount.8
@@ -359,6 +359,21 @@ changed by a separate remount command, for example:
.I newdir
.RE
+Note that behavior of the remount operation depends on the /etc/mtab file. The
+first command stores the 'bind' flag to the /etc/mtab file and the second
+command reads the flag from the file. If you have a system without the
+/etc/mtab file or if you explicitly define source and target for the remount
+command (then mount(8) does not read /etc/mtab), then you have to use bind flag
+(or option) for the remount command too. For example:
+
+.RS
+.br
+.B mount --bind
+.I olddir newdir
+.br
+.B mount -o remount,ro,bind
+.I olddir newdir
+.RE
.RE
.B The move operation.
@@ -387,7 +402,7 @@ private, slave or unbindable. A shared mount provides ability to create mirrors
of that mount such that mounts and umounts within any of the mirrors propagate
to the other mirror. A slave mount receives propagation from its master, but
any not vice-versa. A private mount carries no propagation abilities. A
-unbindable mount is a private mount which cannot cloned through a bind
+unbindable mount is a private mount which cannot be cloned through a bind
operation. Detailed semantics is documented in Documentation/sharedsubtree.txt
file in the kernel source tree.
@@ -1391,7 +1406,7 @@ small amount of time to see if any other transactions can piggyback on the
synchronous write. The algorithm used is designed to automatically tune for
the speed of the disk, by measuring the amount of time (on average) that it
takes to finish committing a transaction. Call this time the "commit time".
-If the time that the transactoin has been running is less than the commit time,
+If the time that the transaction has been running is less than the commit time,
ext4 will try sleeping for the commit time to see if other operations will join
the transaction. The commit time is capped by the max_batch_time, which
defaults to 15000us (15ms). This optimization can be turned off entirely by
@@ -1423,7 +1438,7 @@ If auto_da_alloc is enabled, ext4 will detect the replace-via-rename and
replace-via-truncate patterns and force that any delayed allocation blocks are
allocated such that at the next journal commit, in the default data=ordered
mode, the data blocks of the new file are forced to disk before the rename()
-operation is commited. This provides roughly the same level of guarantees as
+operation is committed. This provides roughly the same level of guarantees as
ext3, and avoids the "zero-length" problem that can happen when a system
crashes before the delayed allocation blocks are forced to disk.
@@ -2425,13 +2440,7 @@ was specified.
.BI logbufs= value
Set the number of in-memory log buffers. Valid numbers range
from 2-8 inclusive.
-The default value is 8 buffers for filesystems with a
-blocksize of 64KiB, 4 buffers for filesystems with a blocksize
-of 32KiB, 3 buffers for filesystems with a blocksize of 16KiB
-and 2 buffers for all other configurations. Increasing the
-number of buffers may increase performance on some workloads
-at the cost of the memory used for the additional log buffers
-and their associated control structures.
+The default value is 8 buffers for any recent kernel.
.TP
.BI logbsize= value
Set the size of each in-memory log buffer.
@@ -2439,8 +2448,7 @@ Size may be specified in bytes, or in kilobytes with a "k" suffix.
Valid sizes for version 1 and version 2 logs are 16384 (16k) and
32768 (32k). Valid sizes for version 2 logs also include
65536 (64k), 131072 (128k) and 262144 (256k).
-The default value for machines with more than 32MiB of memory
-is 32768, machines with less memory use 16384 by default.
+The default value for any recent kernel is 32768.
.TP
\fBlogdev=\fP\fIdevice\fP and \fBrtdev=\fP\fIdevice\fP
Use an external log (metadata journal) and/or real-time device.
diff --git a/mount/mount.c b/mount/mount.c
index 26a8afed..a412bc37 100644
--- a/mount/mount.c
+++ b/mount/mount.c
@@ -326,11 +326,11 @@ append_opt(char *s, const char *opt, const char *val)
}
static char *
-append_numopt(char *s, const char *opt, long num)
+append_numopt(char *s, const char *opt, unsigned int num)
{
char buf[32];
- snprintf(buf, sizeof(buf), "%ld", num);
+ snprintf(buf, sizeof(buf), "%u", num);
return append_opt(s, opt, buf);
}
@@ -1139,8 +1139,9 @@ loop_check(const char **spec, const char **type, int *flags,
* file as a mount(2) source argument. A filesystem that is able to mount
* regular files could be implemented.
*/
- if (!*loop && (!*type || strcmp(*type, "auto") == 0 ||
- fsprobe_known_fstype(*type))) {
+ if (!*loop && !(*flags & (MS_BIND | MS_MOVE | MS_PROPAGATION)) &&
+ (!*type || strcmp(*type, "auto") == 0 || fsprobe_known_fstype(*type))) {
+
struct stat st;
if (stat(*loopfile, &st) == 0)
*loop = S_ISREG(st.st_mode);
@@ -1152,7 +1153,8 @@ loop_check(const char **spec, const char **type, int *flags,
if (verbose)
printf(_("mount: skipping the setup of a loop device\n"));
} else {
- int loop_opts = SETLOOP_AUTOCLEAR; /* always attempt autoclear */
+ /* use autoclear loopdev on system without regular mtab only */
+ int loop_opts = mtab_is_writable() ? 0 : SETLOOP_AUTOCLEAR;
int res;
if (*flags & MS_RDONLY)
@@ -1440,7 +1442,7 @@ try_mount_one (const char *spec0, const char *node0, const char *types0,
}
/* Kernel allows to use MS_RDONLY for bind mounts, but the read-only request
- * could be silently ignored. Check it to avoid 'ro' in ntab and 'rw' in
+ * could be silently ignored. Check it to avoid 'ro' in mtab and 'rw' in
* /proc/mounts.
*/
if (!fake && mnt5_res == 0 &&
@@ -1450,17 +1452,31 @@ try_mount_one (const char *spec0, const char *node0, const char *types0,
flags &= ~MS_RDONLY;
}
+ /* Kernel can silently add MS_RDONLY flag when mounting file system that
+ * does not have write support. Check this to avoid 'ro' in /proc/mounts
+ * and 'rw' in mtab.
+ */
+ if (!fake && mnt5_res == 0 &&
+ !(flags & (MS_RDONLY | MS_PROPAGATION | MS_MOVE)) &&
+ is_readonly(node)) {
+
+ printf(_("mount: warning: %s seems to be mounted read-only.\n"), node);
+ flags |= MS_RDONLY;
+ }
+
if (fake || mnt5_res == 0) {
/* Mount succeeded, report this (if verbose) and write mtab entry. */
if (!(mounttype & MS_PROPAGATION)) {
+ char *mtab_opts = fix_opts_string (flags & ~MS_NOMTAB, extra_opts, user);
update_mtab_entry(loop ? loopfile : spec,
node,
types ? types : "unknown",
- fix_opts_string (flags & ~MS_NOMTAB, extra_opts, user),
+ mtab_opts,
flags,
freq,
pass);
+ free (mtab_opts);
}
block_signals (SIG_UNBLOCK);
@@ -1731,12 +1747,12 @@ usersubst(const char *opts) {
s = "uid=useruid";
if (opts && (w = strstr(opts, s)) != NULL) {
- sprintf(id, "uid=%d", getuid());
+ sprintf(id, "uid=%u", getuid());
opts = subst_string(opts, w, strlen(s), id);
}
s = "gid=usergid";
if (opts && (w = strstr(opts, s)) != NULL) {
- sprintf(id, "gid=%d", getgid());
+ sprintf(id, "gid=%u", getgid());
opts = subst_string(opts, w, strlen(s), id);
}
return xstrdup(opts);
@@ -1820,6 +1836,41 @@ mounted (const char *spec0, const char *node0) {
return ret;
}
+/* returns 0 if not mounted, 1 if mounted and -1 in case of error */
+static int
+is_fstab_entry_mounted(struct mntentchn *mc, int verbose)
+{
+ struct stat st;
+
+ if (mounted(mc->m.mnt_fsname, mc->m.mnt_dir))
+ goto yes;
+
+ /* extra care for loop devices */
+ if ((strstr(mc->m.mnt_opts, "loop=") ||
+ (stat(mc->m.mnt_fsname, &st) == 0 && S_ISREG(st.st_mode)))) {
+
+ char *p = strstr(mc->m.mnt_opts, "offset=");
+ uintmax_t offset = 0;
+
+ if (p && strtosize(p + 7, &offset) != 0) {
+ if (verbose)
+ printf(_("mount: ignore %s "
+ "(unparsable offset= option)\n"),
+ mc->m.mnt_fsname);
+ return -1;
+ }
+ if (is_mounted_same_loopfile(mc->m.mnt_dir, mc->m.mnt_fsname, offset))
+ goto yes;
+ }
+
+ return 0;
+yes:
+ if (verbose)
+ printf(_("mount: %s already mounted on %s\n"),
+ mc->m.mnt_fsname, mc->m.mnt_dir);
+ return 1;
+}
+
/* avoid using stat() on things we are not going to mount anyway.. */
static int
has_noauto (const char *opts) {
@@ -1865,16 +1916,8 @@ do_mount_all (char *types, char *options, char *test_opts) {
if (matching_type (mc->m.mnt_type, types)
&& matching_opts (mc->m.mnt_opts, test_opts)
&& !streq (mc->m.mnt_dir, "/")
- && !streq (mc->m.mnt_dir, "root")) {
-
- if (mounted (mc->m.mnt_fsname, mc->m.mnt_dir)) {
- if (verbose)
- printf(_("mount: %s already mounted "
- "on %s\n"),
- mc->m.mnt_fsname,
- mc->m.mnt_dir);
- continue;
- }
+ && !streq (mc->m.mnt_dir, "root")
+ && !is_fstab_entry_mounted(mc, verbose)) {
mtmp = (struct mntentchn *) xmalloc(sizeof(*mtmp));
*mtmp = *mc;
@@ -2306,8 +2349,8 @@ main(int argc, char *argv[]) {
printf("mount: mtab path: \"%s\"\n", _PATH_MOUNTED);
printf("mount: lock path: \"%s\"\n", _PATH_MOUNTED_LOCK);
printf("mount: temp path: \"%s\"\n", _PATH_MOUNTED_TMP);
- printf("mount: UID: %d\n", getuid());
- printf("mount: eUID: %d\n", geteuid());
+ printf("mount: UID: %u\n", getuid());
+ printf("mount: eUID: %u\n", geteuid());
}
argc -= optind;
@@ -2338,7 +2381,7 @@ main(int argc, char *argv[]) {
if (ruid == 0 && euid != 0)
/* user is root, but setuid to non-root */
die (EX_USAGE, _("mount: only root can do that "
- "(effective UID is %d)"), euid);
+ "(effective UID is %u)"), euid);
die (EX_USAGE, _("mount: only root can do that"));
}
diff --git a/mount/swapon.8 b/mount/swapon.8
index 25fc5e81..a3ebc97c 100644
--- a/mount/swapon.8
+++ b/mount/swapon.8
@@ -167,6 +167,18 @@ automatically detects and rewrites swap space signature with old software
suspend data (e.g S1SUSPEND, S2SUSPEND, ...). The problem is that if we don't
do it, then we get data corruption the next time an attempt at unsuspending is
made.
+.PP
+.B swapon
+may not work correctly when using a swap file with some versions of btrfs.
+This is due to the swap file implementation in the kernel expecting to be able
+to write to the file directly, without the assistance of the file system.
+Since btrfs is a copy-on-write file system, the file location may not be
+static and corruption can result. Btrfs actively disallows the use of files
+on its file systems by refusing to map the file. This can be seen in the system
+log as "swapon: swapfile has holes." One possible workaround is to map the
+file to a loopback device. This will allow the file system to determine the
+mapping properly but may come with a performance impact.
+
.SH SEE ALSO
.BR swapon (2),
.BR swapoff (2),
diff --git a/mount/swapon.c b/mount/swapon.c
index 4ee3c2f7..c7006550 100644
--- a/mount/swapon.c
+++ b/mount/swapon.c
@@ -425,7 +425,7 @@ swapon_checks(const char *special)
unsigned long long swapsize =
swap_get_size(hdr, special, pagesize);
if (verbose)
- warnx("%s: pagesize=%d, swapsize=%llu, devsize=%llu",
+ warnx(_("%s: pagesize=%d, swapsize=%llu, devsize=%llu"),
special, pagesize, swapsize, devsize);
if (swapsize > devsize) {
@@ -663,7 +663,7 @@ main_swapon(int argc, char *argv[]) {
++verbose;
break;
case 'V': /* version */
- printf("%s: (%s)\n", progname, PACKAGE_STRING);
+ printf(_("%s (%s)\n"), progname, PACKAGE_STRING);
exit(0);
case 0:
break;
@@ -715,7 +715,7 @@ main_swapoff(int argc, char *argv[]) {
++verbose;
break;
case 'V': /* version */
- printf("%s (%s)\n", progname, PACKAGE_STRING);
+ printf(_("%s (%s)\n"), progname, PACKAGE_STRING);
exit(0);
case 'L':
addl(optarg);
diff --git a/mount/umount.c b/mount/umount.c
index 6786ac57..5bd53604 100644
--- a/mount/umount.c
+++ b/mount/umount.c
@@ -275,7 +275,7 @@ umount_one (const char *spec, const char *node, const char *type,
if (res >= 0) {
/* Umount succeeded */
if (verbose)
- printf (_("%s umounted\n"), spec);
+ printf (_("%s has been unmounted\n"), spec);
/* Free any loop devices that we allocated ourselves */
if (mc) {
@@ -379,7 +379,6 @@ umount_all (char *types, char *test_opts) {
}
}
- sync ();
return errors;
}
@@ -491,13 +490,13 @@ umount_file (char *arg) {
int ok;
if (!*arg) { /* "" would be expanded to `pwd` */
- die(2, _("Cannot umount \"\"\n"));
+ die(2, _("Cannot unmount \"\"\n"));
return 0;
}
file = canonicalize(arg); /* mtab paths are canonicalized */
if (verbose > 1)
- printf(_("Trying to umount %s\n"), file);
+ printf(_("Trying to unmount %s\n"), file);
mc = getmntdirbackward(file, NULL);
if (!mc) {
@@ -515,8 +514,8 @@ umount_file (char *arg) {
if (strcmp(file, mc1->m.mnt_fsname)) {
/* Something was stacked over `file' on the
same mount point. */
- die(EX_FAIL, _("umount: cannot umount %s -- %s is "
- "mounted over it on the same point."),
+ die(EX_FAIL, _("umount: cannot unmount %s -- %s is "
+ "mounted over it on the same point"),
file, mc1->m.mnt_fsname);
}
}