summaryrefslogtreecommitdiffstats
path: root/mount
diff options
context:
space:
mode:
authorKarel Zak2006-12-07 00:25:58 +0100
committerKarel Zak2006-12-07 00:25:58 +0100
commit63cccae4684f83d2a462bc8abf24e51d1bd6efb6 (patch)
tree433db3f0b44e0f46e4130141f4a59db9c3564557 /mount
parentImported from util-linux-2.11r tarball. (diff)
downloadkernel-qcow2-util-linux-63cccae4684f83d2a462bc8abf24e51d1bd6efb6.tar.gz
kernel-qcow2-util-linux-63cccae4684f83d2a462bc8abf24e51d1bd6efb6.tar.xz
kernel-qcow2-util-linux-63cccae4684f83d2a462bc8abf24e51d1bd6efb6.zip
Imported from util-linux-2.11t tarball.
Diffstat (limited to 'mount')
-rw-r--r--mount/Makefile16
-rw-r--r--mount/fstab.c2
-rw-r--r--mount/linux_fs.h55
-rw-r--r--mount/mount.813
-rw-r--r--mount/mount.c436
-rw-r--r--mount/mount_by_label.c30
-rw-r--r--mount/mount_constants.h4
-rw-r--r--mount/mount_guess_fstype.c5
-rw-r--r--mount/nfs.56
-rw-r--r--mount/pivot_root.c20
-rw-r--r--mount/sundries.h1
-rw-r--r--mount/swapon.818
-rw-r--r--mount/swapon.c494
13 files changed, 674 insertions, 426 deletions
diff --git a/mount/Makefile b/mount/Makefile
index 453b640ae..52c4cff6d 100644
--- a/mount/Makefile
+++ b/mount/Makefile
@@ -91,15 +91,25 @@ nfsmount_xdr.o: nfsmount_xdr.c
$(COMPILE) $(RPC_CFLAGS) nfsmount_xdr.c
ifeq "$(HAVE_GOOD_RPC)" "yes"
-nfsmount.h nfsmount_xdr.c nfsmount_clnt.c: nfsmount.x
- rm -f nfsmount.h nfsmount_xdr.c nfsmount_clnt.c
+nfsmount.h: nfsmount.x
+ rm -f nfsmount.h
$(RPCGEN) -h -o nfsmount.h nfsmount.x
+
+nfsmount_xdr.c: nfsmount.x
+ rm -f nfsmount_xdr.c
$(RPCGEN) -c -o nfsmount_xdr.c nfsmount.x
+
+nfsmount_clnt.c: nfsmount.x
+ rm -f nfsmount_clnt.c
$(RPCGEN) -l -o nfsmount_clnt.c nfsmount.x
else
-nfsmount.h nfsmount_xdr.c nfsmount_clnt.c:
+nfsmount.h:
cp $(RPCSVCDIR)/nfsmount.h .
+
+nfsmount_xdr.c:
cp $(RPCSVCDIR)/nfsmount_xdr.c .
+
+nfsmount_clnt.c:
cp $(RPCSVCDIR)/nfsmount_clnt.c .
endif
diff --git a/mount/fstab.c b/mount/fstab.c
index 9329d1ce6..3e3142238 100644
--- a/mount/fstab.c
+++ b/mount/fstab.c
@@ -515,7 +515,7 @@ update_mtab (const char *dir, struct mntent *instead) {
/* write chain to mtemp */
mftmp = my_setmntent (MOUNTED_TEMP, "w");
- if (mftmp == NULL || mfp->mntent_fp == NULL) {
+ if (mftmp == NULL || mftmp->mntent_fp == NULL) {
int errsv = errno;
error (_("cannot open %s (%s) - mtab not updated"),
MOUNTED_TEMP, strerror (errsv));
diff --git a/mount/linux_fs.h b/mount/linux_fs.h
index 3885d724b..4bcf80b6e 100644
--- a/mount/linux_fs.h
+++ b/mount/linux_fs.h
@@ -21,7 +21,7 @@ struct minix_super_block {
u_char s_dummy[16];
u_char s_magic[2];
};
-#define minixmagic(s) ((uint) s.s_magic[0] + (((uint) s.s_magic[1]) << 8))
+#define minixmagic(s) assemble2le(s.s_magic)
#define ISODCL(from, to) (to - from + 1)
#define ISO_STANDARD_ID "CD001"
@@ -46,7 +46,7 @@ struct ext_super_block {
u_char s_dummy[56];
u_char s_magic[2];
};
-#define extmagic(s) ((uint) s.s_magic[0] + (((uint) s.s_magic[1]) << 8))
+#define extmagic(s) assemble2le(s.s_magic)
#define EXT2_PRE_02B_MAGIC 0xEF51
#define EXT2_SUPER_MAGIC 0xEF53
@@ -63,7 +63,7 @@ struct ext2_super_block {
u_char s_dummy3[88];
u_char s_journal_inum[4]; /* ext3 only */
};
-#define ext2magic(s) ((uint) s.s_magic[0] + (((uint) s.s_magic[1]) << 8))
+#define ext2magic(s) assemble2le(s.s_magic)
struct reiserfs_super_block
{
@@ -96,9 +96,7 @@ struct xiafs_super_block {
u_char s_dummy[60];
u_char s_magic[4];
};
-#define xiafsmagic(s) ((uint) s.s_magic[0] + (((uint) s.s_magic[1]) << 8) + \
- (((uint) s.s_magic[2]) << 16) + \
- (((uint) s.s_magic[3]) << 24))
+#define xiafsmagic(s) assemble4le(s.s_magic)
/* From jj@sunsite.ms.mff.cuni.cz Mon Mar 23 15:19:05 1998 */
#define UFS_SUPER_MAGIC_LE 0x00011954
@@ -107,9 +105,7 @@ struct ufs_super_block {
u_char s_dummy[0x55c];
u_char s_magic[4];
};
-#define ufsmagic(s) ((uint) s.s_magic[0] + (((uint) s.s_magic[1]) << 8) + \
- (((uint) s.s_magic[2]) << 16) + \
- (((uint) s.s_magic[3]) << 24))
+#define ufsmagic(s) assemble4le(s.s_magic)
/* From Richard.Russon@ait.co.uk Wed Feb 24 08:05:27 1999 */
#define NTFS_SUPER_MAGIC "NTFS"
@@ -150,9 +146,7 @@ struct cramfs_super_block {
u_char s_dummy[12];
u_char s_id[16];
};
-#define cramfsmagic(s) ((uint) s.s_magic[0] + (((uint) s.s_magic[1]) << 8) + \
- (((uint) s.s_magic[2]) << 16) + \
- (((uint) s.s_magic[3]) << 24))
+#define cramfsmagic(s) assemble4le(s.s_magic)
#define HFS_SUPER_MAGIC 0x4244
struct hfs_super_block {
@@ -160,20 +154,15 @@ struct hfs_super_block {
u_char s_dummy[18];
u_char s_blksize[4];
};
-#define hfsmagic(s) ((uint) s.s_magic[0] + (((uint) s.s_magic[1]) << 8))
-#define hfsblksize(s) ((uint) s.s_blksize[0] + \
- (((uint) s.s_blksize[1]) << 8) + \
- (((uint) s.s_blksize[2]) << 16) + \
- (((uint) s.s_blksize[3]) << 24))
+#define hfsmagic(s) assemble2le(s.s_magic)
+#define hfsblksize(s) assemble4le(s.s_blksize)
#define HPFS_SUPER_MAGIC 0xf995e849
struct hpfs_super_block {
u_char s_magic[4];
u_char s_magic2[4];
};
-#define hpfsmagic(s) ((uint) s.s_magic[0] + (((uint) s.s_magic[1]) << 8) + \
- (((uint) s.s_magic[2]) << 16) + \
- (((uint) s.s_magic[3]) << 24))
+#define hpfsmagic(s) assemble4le(s.s_magic)
struct adfs_super_block {
u_char s_dummy[448];
@@ -187,9 +176,7 @@ struct adfs_super_block {
struct vxfs_super_block {
u_char s_magic[4];
};
-#define vxfsmagic(s) ((uint) s.s_magic[0] + (((uint) s.s_magic[1]) << 8) + \
- (((uint) s.s_magic[2]) << 16) + \
- (((uint) s.s_magic[3]) << 24))
+#define vxfsmagic(s) assemble4le(s.s_magic)
#define VXFS_SUPER_MAGIC 0xa501FCF5
struct jfs_super_block {
@@ -200,14 +187,26 @@ struct jfs_super_block {
#define JFS_SUPER1_OFF 0x8000
#define JFS_MAGIC "JFS1"
-#define SYSV_SUPER_MAGIC 0xfd187e20
-
struct sysv_super_block {
u_char s_dummy1[504];
u_char s_magic[4];
u_char type[4];
};
+#define sysvmagic(s) assemble4le(s.s_magic)
+#define SYSV_SUPER_MAGIC 0xfd187e20
+
+struct mdp_super_block {
+ u_char md_magic[4];
+};
+#define MD_SB_MAGIC 0xa92b4efc
+#define mdsbmagic(s) assemble4le(s.md_magic)
+
+static inline int
+assemble2le(unsigned char *p) {
+ return (p[0] | (p[1] << 8));
+}
-#define sysvmagic(s) ((uint) s.s_magic[0] + (((uint) s.s_magic[1]) << 8) + \
- (((uint) s.s_magic[2]) << 16) + \
- (((uint) s.s_magic[3]) << 24))
+static inline int
+assemble4le(unsigned char *p) {
+ return (p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24));
+}
diff --git a/mount/mount.8 b/mount/mount.8
index 7f2f4d932..763e8fca7 100644
--- a/mount/mount.8
+++ b/mount/mount.8
@@ -548,6 +548,11 @@ effect.
.B sync
All I/O to the file system should be done synchronously.
.TP
+.B dirsync
+All directory updates within the file system should be done synchronously.
+This affects the following system calls: creat, link, unlink, symlink,
+mkdir, rmdir, mknod and rename.
+.TP
.B user
Allow an ordinary user to mount the file system.
The name of the mounting user is written to mtab so that he can unmount
@@ -1125,8 +1130,8 @@ For details, see
Especially useful options include
.TP
.B rsize=8192,wsize=8192
-This will make your nfs connection much faster than with the default
-buffer size of 1024. (NFSv2 does not work with larger values of
+This will make your nfs connection faster than with the default
+buffer size of 4096. (NFSv2 does not work with larger values of
.B rsize
and
.BR wsize .)
@@ -1175,6 +1180,7 @@ hard links instead of being suppressed.
.TP
\fBuid=\fP\fIvalue\fP, \fBgid=\fP\fIvalue\fP and \fBumask=\fP\fIvalue\fP
Set the file permission on the filesystem.
+The umask value is given in octal.
By default, the files are owned by root and not readable by somebody else.
.SH "Mount options for proc"
@@ -1316,6 +1322,7 @@ Set the default group.
.TP
.B umask=
Set the default umask.
+The value is given in octal.
.TP
.B uid=
Set the default user.
@@ -1661,7 +1668,7 @@ temporary file
It is possible for a corrupted file system to cause a crash.
.PP
Some Linux file systems don't support
-.B "\-o sync"
+.B "\-o sync and \-o dirsync"
(the ext2 and ext3 file systems
.I do
support synchronous updates (a la BSD) when mounted with the
diff --git a/mount/mount.c b/mount/mount.c
index 125cf1abf..fb1ca716f 100644
--- a/mount/mount.c
+++ b/mount/mount.c
@@ -94,7 +94,7 @@ int sloppy = 0;
static int readwrite = 0;
/* True for all mount (-a). */
-int all = 0;
+int mount_all = 0;
/* True for fork() during all mount (-F). */
static int optfork = 0;
@@ -148,6 +148,7 @@ static const struct opt_map opt_map[] = {
{ "nodev", 0, 0, MS_NODEV }, /* don't interpret devices */
{ "sync", 0, 0, MS_SYNCHRONOUS}, /* synchronous I/O */
{ "async", 0, 1, MS_SYNCHRONOUS}, /* asynchronous I/O */
+ { "dirsync", 0, 0, MS_DIRSYNC}, /* synchronous directory modifications */
{ "remount", 0, 0, MS_REMOUNT}, /* Alter flags of mounted FS */
{ "bind", 0, 0, MS_BIND }, /* Remount part of tree elsewhere */
{ "auto", 0, 1, MS_NOAUTO }, /* Can be mounted using -a */
@@ -201,25 +202,25 @@ static struct string_opt_map {
static void
clear_string_opts(void) {
- struct string_opt_map *m;
+ struct string_opt_map *m;
- for (m = &string_opt_map[0]; m->tag; m++)
- *(m->valptr) = NULL;
+ for (m = &string_opt_map[0]; m->tag; m++)
+ *(m->valptr) = NULL;
}
static int
parse_string_opt(char *s) {
- struct string_opt_map *m;
- int lth;
-
- for (m = &string_opt_map[0]; m->tag; m++) {
- lth = strlen(m->tag);
- if (!strncmp(s, m->tag, lth)) {
- *(m->valptr) = xstrdup(s + lth);
- return 1;
- }
- }
- return 0;
+ struct string_opt_map *m;
+ int lth;
+
+ for (m = &string_opt_map[0]; m->tag; m++) {
+ lth = strlen(m->tag);
+ if (!strncmp(s, m->tag, lth)) {
+ *(m->valptr) = xstrdup(s + lth);
+ return 1;
+ }
+ }
+ return 0;
}
int mount_quiet=0;
@@ -264,54 +265,54 @@ print_all (char *types) {
*/
static inline void
parse_opt (const char *opt, int *mask, char *extra_opts) {
- const struct opt_map *om;
-
- for (om = opt_map; om->opt != NULL; om++)
- if (streq (opt, om->opt)) {
- if (om->inv)
- *mask &= ~om->mask;
- else
- *mask |= om->mask;
- if ((om->mask == MS_USER || om->mask == MS_USERS)
- && !om->inv)
- *mask |= MS_SECURE;
- if ((om->mask == MS_OWNER) && !om->inv)
- *mask |= MS_OWNERSECURE;
+ const struct opt_map *om;
+
+ for (om = opt_map; om->opt != NULL; om++)
+ if (streq (opt, om->opt)) {
+ if (om->inv)
+ *mask &= ~om->mask;
+ else
+ *mask |= om->mask;
+ if ((om->mask == MS_USER || om->mask == MS_USERS)
+ && !om->inv)
+ *mask |= MS_SECURE;
+ if ((om->mask == MS_OWNER) && !om->inv)
+ *mask |= MS_OWNERSECURE;
#ifdef MS_SILENT
- if (om->mask == MS_SILENT && om->inv) {
- mount_quiet = 1;
- verbose = 0;
- }
+ if (om->mask == MS_SILENT && om->inv) {
+ mount_quiet = 1;
+ verbose = 0;
+ }
#endif
- return;
- }
+ return;
+ }
- if (*extra_opts)
- strcat(extra_opts, ",");
+ if (*extra_opts)
+ strcat(extra_opts, ",");
- /* convert nonnumeric ids to numeric */
- if (!strncmp(opt, "uid=", 4) && !isdigit(opt[4])) {
- struct passwd *pw = getpwnam(opt+4);
- char uidbuf[20];
+ /* convert nonnumeric ids to numeric */
+ if (!strncmp(opt, "uid=", 4) && !isdigit(opt[4])) {
+ struct passwd *pw = getpwnam(opt+4);
+ char uidbuf[20];
- if (pw) {
- sprintf(uidbuf, "uid=%d", pw->pw_uid);
- strcat(extra_opts, uidbuf);
- return;
- }
- }
- if (!strncmp(opt, "gid=", 4) && !isdigit(opt[4])) {
- struct group *gr = getgrnam(opt+4);
- char gidbuf[20];
-
- if (gr) {
- sprintf(gidbuf, "gid=%d", gr->gr_gid);
- strcat(extra_opts, gidbuf);
- return;
- }
- }
+ if (pw) {
+ sprintf(uidbuf, "uid=%d", pw->pw_uid);
+ strcat(extra_opts, uidbuf);
+ return;
+ }
+ }
+ if (!strncmp(opt, "gid=", 4) && !isdigit(opt[4])) {
+ struct group *gr = getgrnam(opt+4);
+ char gidbuf[20];
+
+ if (gr) {
+ sprintf(gidbuf, "gid=%d", gr->gr_gid);
+ strcat(extra_opts, gidbuf);
+ return;
+ }
+ }
- strcat(extra_opts, opt);
+ strcat(extra_opts, opt);
}
/* Take -o options list and compute 4th and 5th args to mount(2). flags
@@ -344,30 +345,31 @@ parse_opts (char *opts, int *flags, char **extra_opts) {
/* Try to build a canonical options string. */
static char *
fix_opts_string (int flags, const char *extra_opts, const char *user) {
- const struct opt_map *om;
- const struct string_opt_map *m;
- char *new_opts;
-
- new_opts = (flags & MS_RDONLY) ? "ro" : "rw";
- for (om = opt_map; om->opt != NULL; om++) {
- if (om->skip)
- continue;
- if (om->inv || !om->mask || (flags & om->mask) != om->mask)
- continue;
- new_opts = xstrconcat3(new_opts, ",", om->opt);
- flags &= ~om->mask;
- }
- for (m = &string_opt_map[0]; m->tag; m++) {
- if (!m->skip && *(m->valptr))
- new_opts = xstrconcat4(new_opts, ",", m->tag, *(m->valptr));
- }
- if (extra_opts && *extra_opts) {
- new_opts = xstrconcat3(new_opts, ",", extra_opts);
- }
- if (user) {
- new_opts = xstrconcat3(new_opts, ",user=", user);
- }
- return new_opts;
+ const struct opt_map *om;
+ const struct string_opt_map *m;
+ char *new_opts;
+
+ new_opts = (flags & MS_RDONLY) ? "ro" : "rw";
+ for (om = opt_map; om->opt != NULL; om++) {
+ if (om->skip)
+ continue;
+ if (om->inv || !om->mask || (flags & om->mask) != om->mask)
+ continue;
+ new_opts = xstrconcat3(new_opts, ",", om->opt);
+ flags &= ~om->mask;
+ }
+ for (m = &string_opt_map[0]; m->tag; m++) {
+ if (!m->skip && *(m->valptr))
+ new_opts = xstrconcat4(new_opts, ",",
+ m->tag, *(m->valptr));
+ }
+ if (extra_opts && *extra_opts) {
+ new_opts = xstrconcat3(new_opts, ",", extra_opts);
+ }
+ if (user) {
+ new_opts = xstrconcat3(new_opts, ",user=", user);
+ }
+ return new_opts;
}
static int
@@ -757,12 +759,12 @@ try_mount_one (const char *spec0, const char *node0, char *types0,
parse_opts (xstrdup (opts), &flags, &extra_opts);
- suid_check (spec, node, &flags, &user);
-
/* quietly succeed for fstab entries that don't get mounted automatically */
- if (all && (flags & MS_NOAUTO))
+ if (mount_all && (flags & MS_NOAUTO))
return 0;
+ suid_check (spec, node, &flags, &user);
+
mount_opts = extra_opts;
if (opt_speed)
@@ -872,7 +874,7 @@ retry_nfs:
/* heuristic: if /proc/version exists, then probably proc is mounted */
if (stat ("/proc/version", &statbuf)) /* proc mounted? */
error (_("mount: %s is busy"), node); /* no */
- else if(!all || verbose) /* yes, don't mention it */
+ else if (!mount_all || verbose) /* yes, don't mention it */
error (_("mount: proc already mounted"));
} else {
error (_("mount: %s already mounted or %s busy"), spec, node);
@@ -1095,10 +1097,11 @@ mount_one (const char *spec, const char *node, char *types, const char *opts,
specset = 1;
nspec = get_spec_by_uuid(spec+5);
} else if (!strncmp(spec, "LABEL=", 6)) {
- const char *nspec2;
+ const char *nspec2 = NULL;
specset = 2;
nspec = get_spec_by_volume_label(spec+6);
- nspec2 = second_occurrence_of_vol_label(spec+6);
+ if (nspec)
+ nspec2 = second_occurrence_of_vol_label(spec+6);
if (nspec2) {
if (verbose)
printf(_("mount: the label %s occurs on "
@@ -1117,7 +1120,7 @@ mount_one (const char *spec, const char *node, char *types, const char *opts,
if (verbose > 1)
printf(_("mount: going to mount %s by %s\n"), spec,
(specset==1) ? _("UUID") : _("label"));
- } else if(!all)
+ } else if(!mount_all)
die (EX_USAGE, _("mount: no such partition found"));
/* if -a then we may be rescued by a noauto option */
}
@@ -1128,6 +1131,11 @@ mount_one (const char *spec, const char *node, char *types, const char *opts,
if (verbose)
printf(_("mount: no type was given - "
"I'll assume nfs because of the colon\n"));
+ } else if(!strncmp(spec, "//", 2)) {
+ types = "smb";
+ if (verbose)
+ printf(_("mount: no type was given - "
+ "I'll assume smb because of the // prefix\n"));
}
}
@@ -1181,6 +1189,19 @@ mounted (char *spec, char *node) {
return 0;
}
+/* avoid using stat() on things we are not going to mount anyway.. */
+static int
+has_noauto (char *opts) {
+ char *s;
+
+ if (!opts)
+ return 0;
+ s = strstr(opts, "noauto");
+ if (!s)
+ return 0;
+ return (s == opts || s[-1] == ',') && (s[6] == 0 || s[6] == ',');
+}
+
/* Mount all filesystems of the specified types except swap and root. */
/* With the --fork option: fork and let different incarnations of
mount handle different filesystems. However, try to avoid several
@@ -1188,118 +1209,131 @@ mounted (char *spec, char *node) {
#define DISKMAJOR(m) (((int) m) & ~0xf)
static int
-mount_all (char *types, char *options) {
- struct mntentchn *mc, *mc0, *mtmp;
- int status = 0;
- struct stat statbuf;
- struct child {
- pid_t pid;
- char *group;
- struct mntentchn *mec;
- struct mntentchn *meclast;
- struct child *nxt;
- } childhead, *childtail, *cp;
- char major[22];
- char *g, *colon;
-
- /* build a chain of what we have to do, or maybe
- several chains, one for each major or NFS host */
- childhead.nxt = 0;
- childtail = &childhead;
- mc0 = fstab_head();
- for (mc = mc0->nxt; mc && mc != mc0; mc = mc->nxt) {
- if (matching_type (mc->m.mnt_type, types)
- && !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);
- } else {
- mtmp = (struct mntentchn *) xmalloc(sizeof(*mtmp));
- *mtmp = *mc;
- mtmp->nxt = 0;
- g = NULL;
- if (optfork) {
- if (stat(mc->m.mnt_fsname, &statbuf) == 0 &&
- S_ISBLK(statbuf.st_mode)) {
- sprintf(major, "#%x", DISKMAJOR(statbuf.st_rdev));
- g = major;
- }
+do_mount_all (char *types, char *options) {
+ struct mntentchn *mc, *mc0, *mtmp;
+ int status = 0;
+ struct stat statbuf;
+ struct child {
+ pid_t pid;
+ char *group;
+ struct mntentchn *mec;
+ struct mntentchn *meclast;
+ struct child *nxt;
+ } childhead, *childtail, *cp;
+ char major[22];
+ char *g, *colon;
+
+ /* build a chain of what we have to do, or maybe
+ several chains, one for each major or NFS host */
+ childhead.nxt = 0;
+ childtail = &childhead;
+ mc0 = fstab_head();
+ for (mc = mc0->nxt; mc && mc != mc0; mc = mc->nxt) {
+ if (has_noauto (mc->m.mnt_opts))
+ continue;
+ if (matching_type (mc->m.mnt_type, types)
+ && !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;
+ }
+
+ mtmp = (struct mntentchn *) xmalloc(sizeof(*mtmp));
+ *mtmp = *mc;
+ mtmp->nxt = 0;
+ g = NULL;
+ if (optfork) {
+ if (stat(mc->m.mnt_fsname, &statbuf) == 0 &&
+ S_ISBLK(statbuf.st_mode)) {
+ sprintf(major, "#%x",
+ DISKMAJOR(statbuf.st_rdev));
+ g = major;
+ }
#ifdef HAVE_NFS
- if (strcmp(mc->m.mnt_type, "nfs") == 0) {
- g = xstrdup(mc->m.mnt_fsname);
- colon = strchr(g, ':');
- if (colon)
- *colon = '\0';
- }
+ if (strcmp(mc->m.mnt_type, "nfs") == 0) {
+ g = xstrdup(mc->m.mnt_fsname);
+ colon = strchr(g, ':');
+ if (colon)
+ *colon = '\0';
+ }
#endif
- }
- if (g) {
- for (cp = childhead.nxt; cp; cp = cp->nxt)
- if (cp->group && strcmp(cp->group, g) == 0) {
- cp->meclast->nxt = mtmp;
- cp->meclast = mtmp;
- goto fnd;
- }
- }
- cp = (struct child *) xmalloc(sizeof *cp);
- cp->nxt = 0;
- cp->mec = cp->meclast = mtmp;
- cp->group = xstrdup(g);
- cp->pid = 0;
- childtail->nxt = cp;
- childtail = cp;
- fnd:;
- }
- }
- }
+ }
+ if (g) {
+ for (cp = childhead.nxt; cp; cp = cp->nxt)
+ if (cp->group &&
+ strcmp(cp->group, g) == 0) {
+ cp->meclast->nxt = mtmp;
+ cp->meclast = mtmp;
+ goto fnd;
+ }
+ }
+ cp = (struct child *) xmalloc(sizeof *cp);
+ cp->nxt = 0;
+ cp->mec = cp->meclast = mtmp;
+ cp->group = xstrdup(g);
+ cp->pid = 0;
+ childtail->nxt = cp;
+ childtail = cp;
+ fnd:;
+
+ }
+ }
- /* now do everything */
- for (cp = childhead.nxt; cp; cp = cp->nxt) {
- pid_t p = -1;
- if (optfork) {
- p = fork();
- if (p == -1) {
- int errsv = errno;
- error(_("mount: cannot fork: %s"), strerror (errsv));
- }
- else if (p != 0)
- cp->pid = p;
- }
+ /* now do everything */
+ for (cp = childhead.nxt; cp; cp = cp->nxt) {
+ pid_t p = -1;
+ if (optfork) {
+ p = fork();
+ if (p == -1) {
+ int errsv = errno;
+ error(_("mount: cannot fork: %s"),
+ strerror (errsv));
+ }
+ else if (p != 0)
+ cp->pid = p;
+ }
- /* if child, or not forked, do the mounting */
- if (p == 0 || p == -1) {
- for (mc = cp->mec; mc; mc = mc->nxt)
- status |= mount_one (mc->m.mnt_fsname, mc->m.mnt_dir,
- mc->m.mnt_type, mc->m.mnt_opts,
- options, 0, 0);
- if (mountcount)
- status |= EX_SOMEOK;
- if (p == 0)
- exit(status);
- }
- }
+ /* if child, or not forked, do the mounting */
+ if (p == 0 || p == -1) {
+ for (mc = cp->mec; mc; mc = mc->nxt) {
+ status |= mount_one (mc->m.mnt_fsname,
+ mc->m.mnt_dir,
+ mc->m.mnt_type,
+ mc->m.mnt_opts,
+ options, 0, 0);
+ }
+ if (mountcount)
+ status |= EX_SOMEOK;
+ if (p == 0)
+ exit(status);
+ }
+ }
- /* wait for children, if any */
- while ((cp = childhead.nxt) != NULL) {
- childhead.nxt = cp->nxt;
- if (cp->pid) {
- int ret;
- keep_waiting:
- if(waitpid(cp->pid, &ret, 0) == -1) {
- if (errno == EINTR)
- goto keep_waiting;
- perror("waitpid");
- } else if (WIFEXITED(ret))
- status |= WEXITSTATUS(ret);
- else
- status |= EX_SYSERR;
- }
- }
- if (mountcount)
- status |= EX_SOMEOK;
- return status;
+ /* wait for children, if any */
+ while ((cp = childhead.nxt) != NULL) {
+ childhead.nxt = cp->nxt;
+ if (cp->pid) {
+ int ret;
+ keep_waiting:
+ if(waitpid(cp->pid, &ret, 0) == -1) {
+ if (errno == EINTR)
+ goto keep_waiting;
+ perror("waitpid");
+ } else if (WIFEXITED(ret))
+ status |= WEXITSTATUS(ret);
+ else
+ status |= EX_SYSERR;
+ }
+ }
+ if (mountcount)
+ status |= EX_SOMEOK;
+ return status;
}
extern char version[];
@@ -1391,10 +1425,10 @@ main (int argc, char *argv[]) {
while ((c = getopt_long (argc, argv, "afFhlL:no:rsU:vVwt:",
longopts, NULL)) != -1) {
switch (c) {
- case 'a': /* mount everything in fstab */
- ++all;
+ case 'a': /* mount everything in fstab */
+ ++mount_all;
break;
- case 'f': /* fake: don't actually call mount(2) */
+ case 'f': /* fake: don't actually call mount(2) */
++fake;
break;
case 'F':
@@ -1484,7 +1518,7 @@ main (int argc, char *argv[]) {
specseen = (uuid || volumelabel) ? 1 : 0; /* yes, .. i know */
- if (argc+specseen == 0 && !all) {
+ if (argc+specseen == 0 && !mount_all) {
if (options || mounttype)
usage (stderr, EX_USAGE);
return print_all (types);
@@ -1492,7 +1526,7 @@ main (int argc, char *argv[]) {
if (getuid () != geteuid ()) {
suid = 1;
- if (types || options || readwrite || nomtab || all ||
+ if (types || options || readwrite || nomtab || mount_all ||
fake || mounttype || (argc + specseen) != 1)
die (EX_USAGE, _("mount: only root can do that"));
}
@@ -1527,7 +1561,7 @@ main (int argc, char *argv[]) {
switch (argc+specseen) {
case 0:
/* mount -a */
- result = mount_all (types, options);
+ result = do_mount_all (types, options);
if (result == 0 && verbose)
error(_("nothing was mounted"));
break;
diff --git a/mount/mount_by_label.c b/mount/mount_by_label.c
index ee3b1d52e..2ae351d10 100644
--- a/mount/mount_by_label.c
+++ b/mount/mount_by_label.c
@@ -39,6 +39,30 @@ static struct uuidCache_s {
char *device;
} *uuidCache = NULL;
+/*
+ * See whether this device has (the magic of) a RAID superblock at the end.
+ * If so, it probably is, or has been, part of a RAID array.
+ */
+static int
+is_raid_partition(int fd) {
+ struct mdp_super_block mdsb;
+ int n;
+
+ /* hardcode 4096 here in various places, because that's
+ what it's defined to be. Note that even if we used
+ the actual kernel headers, sizeof(mdp_super_t) is
+ slightly larger in the 2.2 kernel on 64-bit archs,
+ so using that wouldn't work. */
+ lseek(fd, -4096, SEEK_END); /* Ignore possible error
+ about return value overflow */
+ n = 4096;
+ if (sizeof(mdsb) < n)
+ n = sizeof(mdsb);
+ if (read(fd, &mdsb, n) != n)
+ return 1; /* error */
+ return (mdsbmagic(mdsb) == MD_SB_MAGIC);
+}
+
/* for now, only ext2, ext3 and xfs are supported */
static int
get_label_uuid(const char *device, char **label, char *uuid) {
@@ -56,6 +80,12 @@ get_label_uuid(const char *device, char **label, char *uuid) {
if (fd < 0)
return rv;
+ /* If there is a RAID partition, or an error, ignore this partition */
+ if (is_raid_partition(fd)) {
+ close(fd);
+ return rv;
+ }
+
if (lseek(fd, 1024, SEEK_SET) == 1024
&& read(fd, (char *) &e2sb, sizeof(e2sb)) == sizeof(e2sb)
&& (ext2magic(e2sb) == EXT2_SUPER_MAGIC)) {
diff --git a/mount/mount_constants.h b/mount/mount_constants.h
index cdbced881..1eab36e03 100644
--- a/mount/mount_constants.h
+++ b/mount/mount_constants.h
@@ -19,6 +19,10 @@
#ifndef MS_MANDLOCK
#define MS_MANDLOCK 64 /* Allow mandatory locks on an FS */
#endif
+#ifndef MS_DIRSYNC
+#define MS_DIRSYNC 128 /* Directory modifications are synchronous */
+#endif
+
#ifndef MS_ACTION_MASK
#define MS_ACTION_MASK 0x380
/* Remount, but new filesystem may be different from old. Atomic
diff --git a/mount/mount_guess_fstype.c b/mount/mount_guess_fstype.c
index 63b00ba83..23a116859 100644
--- a/mount/mount_guess_fstype.c
+++ b/mount/mount_guess_fstype.c
@@ -60,11 +60,6 @@ swapped(unsigned short a) {
return (a>>8) | (a<<8);
}
-static inline int
-assemble4le(unsigned char *p) {
- return (p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24));
-}
-
/*
char *guess_fstype(const char *device);
diff --git a/mount/nfs.5 b/mount/nfs.5
index d2165b853..3f1776606 100644
--- a/mount/nfs.5
+++ b/mount/nfs.5
@@ -144,7 +144,8 @@ for hosts that can run multiple NFS servers.
The default value is version 2.
.TP 1.5i
.I nolock
-Disable NFS locking. This has to be used with some old NFS servers
+Disable NFS locking. Do not start lockd.
+This has to be used with some old NFS servers
that don't support locking.
.TP 1.5i
.I bg
@@ -196,9 +197,6 @@ server performance penalty but it allows two different NFS clients
to get reasonable good results when both clients are actively
writing to common filesystem on the server.
.TP 1.5i
-.I nolock
-Do not use locking. Do not start lockd.
-.TP 1.5i
.I tcp
Mount the NFS filesystem using the TCP protocol instead of the
default UDP protocol. Many NFS servers only support UDP.
diff --git a/mount/pivot_root.c b/mount/pivot_root.c
index 674271ad2..faa0e4d50 100644
--- a/mount/pivot_root.c
+++ b/mount/pivot_root.c
@@ -15,15 +15,15 @@ static
_syscall2(int,pivot_root,const char *,new_root,const char *,put_old)
#endif
-int main(int argc,const char **argv)
+int main(int argc, const char **argv)
{
- if (argc != 3) {
- fprintf(stderr,"usage: %s new_root put_old\n",argv[0]);
- return 1;
- }
- if (pivot_root(argv[1],argv[2]) < 0) {
- perror("pivot_root");
- return 1;
- }
- return 0;
+ if (argc != 3) {
+ fprintf(stderr, "usage: %s new_root put_old\n", argv[0]);
+ return 1;
+ }
+ if (pivot_root(argv[1],argv[2]) < 0) {
+ perror("pivot_root");
+ return 1;
+ }
+ return 0;
}
diff --git a/mount/sundries.h b/mount/sundries.h
index 5b91ca1ee..788bef645 100644
--- a/mount/sundries.h
+++ b/mount/sundries.h
@@ -22,7 +22,6 @@ extern int sloppy;
/* Functions in sundries.c that are used in mount.c and umount.c */
void block_signals (int how);
char *canonicalize (const char *path);
-char *realpath (const char *path, char *resolved_path);
void error (const char *fmt, ...);
int matching_type (const char *type, const char *types);
void *xmalloc (size_t size);
diff --git a/mount/swapon.8 b/mount/swapon.8
index 61cd3b375..4e03cf383 100644
--- a/mount/swapon.8
+++ b/mount/swapon.8
@@ -74,10 +74,8 @@ Provide help
Display version
.TP
.B \-s
-Display swap usage summary by device.
-This option is only available if
-.I /proc/swaps
-exists (probably not before kernel 2.1.25).
+Display swap usage summary by device. Equivalent to "cat /proc/swaps".
+Not available before Linux 2.1.25.
.TP
.B \-a
All devices marked as ``sw'' swap devices in
@@ -101,12 +99,14 @@ for use with
.BR "swapon -a" .
.PP
.B Swapoff
-disables swapping on the specified devices and files, or on all swap
-entries in
-.I /etc/fstab
-when the
+disables swapping on the specified devices and files.
+When the
.B \-a
-flag is given.
+flag is given, swapping is disabled on all known swap devices and files
+(as found in
+.I /proc/swaps
+or
+.IR /etc/fstab ).
.SH NOTE
You should not use
.B swapon
diff --git a/mount/swapon.c b/mount/swapon.c
index 29c859dbc..c2ae20a9e 100644
--- a/mount/swapon.c
+++ b/mount/swapon.c
@@ -1,13 +1,13 @@
/*
* A swapon(8)/swapoff(8) for Linux 0.99.
* swapon.c,v 1.1.1.1 1993/11/18 08:40:51 jrs Exp
- * Added '-s' (Summary option) <Vincent.Renardias@waw.com> 02/1997.
*
+ * 1997-02-xx <Vincent.Renardias@waw.com>
+ * - added '-s' (summary option)
* 1999-02-22 Arkadiusz Mi¶kiewicz <misiek@pld.ORG.PL>
* - added Native Language Support
- * Sun Mar 21 1999 - Arnaldo Carvalho de Melo <acme@conectiva.com.br>
+ * 1999-03-21 Arnaldo Carvalho de Melo <acme@conectiva.com.br>
* - fixed strerr(errno) in gettext calls
- *
*/
#include <stdlib.h>
@@ -28,32 +28,46 @@
#define SWAPON_NEEDS_TWO_ARGS
-/* Nonzero for chatty (-v). This is a nonstandard flag (not in BSD). */
+#define QUIET 1
+
+int all = 0;
int verbose = 0;
int priority = -1; /* non-prioritized swap by default */
extern char version[];
static char *program_name;
-static struct option longopts[] =
-{
- { "all", 0, 0, 'a' },
- { "help", 0, 0, 'h' },
- { "priority", required_argument, 0, 'p' },
- { "summary", 0, 0, 's' },
- { "verbose", 0, 0, 'v' },
- { "version", 0, 0, 'V' },
- { NULL, 0, 0, 0 }
+
+static struct option longswaponopts[] = {
+ /* swapon only */
+ { "priority", required_argument, 0, 'p' },
+ { "summary", 0, 0, 's' },
+ /* also for swapoff */
+ { "all", 0, 0, 'a' },
+ { "help", 0, 0, 'h' },
+ { "verbose", 0, 0, 'v' },
+ { "version", 0, 0, 'V' },
+ { NULL, 0, 0, 0 }
};
+static struct option *longswapoffopts = &longswaponopts[2];
+
static void
-usage (FILE *fp, int n)
-{
- fprintf (fp, _("usage: %s [-hV]\n"
- " %s -a [-v]\n"
- " %s [-v] [-p priority] special ...\n"
- " %s [-s]\n"),
- program_name, program_name, program_name, program_name);
- exit (n);
+swapon_usage(FILE *fp, int n) {
+ fprintf(fp, _("usage: %s [-hV]\n"
+ " %s -a [-v]\n"
+ " %s [-v] [-p priority] special ...\n"
+ " %s [-s]\n"),
+ program_name, program_name, program_name, program_name);
+ exit(n);
+}
+
+static void
+swapoff_usage(FILE *fp, int n) {
+ fprintf(fp, _("usage: %s [-hV]\n"
+ " %s -a [-v]\n"
+ " %s [-v] special ...\n"),
+ program_name, program_name, program_name);
+ exit(n);
}
#ifdef SWAPON_HAS_TWO_ARGS
@@ -78,168 +92,326 @@ _syscall1(int, swapoff, const char *, path);
#include <unistd.h>
#endif
-static int
-swap (const char *special, int prio)
-{
- int status;
- struct stat st;
- if (verbose)
- printf(_("%s on %s\n"), program_name, special);
+/*
+ * contents of /proc/swaps
+ */
+static int numSwaps;
+static char **swapFiles; /* array of swap file and partition names */
- if (streq (program_name, "swapon")) {
- if (stat(special, &st) < 0) {
- int errsv = errno;
- fprintf (stderr, _("swapon: cannot stat %s: %s\n"),
- special, strerror (errsv));
- return -1;
- }
-
- /* people generally dislike this warning - now it is printed
- only when `verbose' is set */
- if (verbose) {
- int permMask = (S_ISBLK(st.st_mode) ? 07007 : 07077);
-
- if ((st.st_mode & permMask) != 0) {
- fprintf(stderr,
- _("swapon: warning: %s has insecure permissions %04o, "
- "%04o suggested\n"),
- special, st.st_mode & 07777, ~permMask & 0666);
- }
- }
-
- /* test for holes by LBT */
- if (S_ISREG(st.st_mode)) {
- if (st.st_blocks * 512 < st.st_size) {
- fprintf(stderr,
- _("swapon: Skipping file %s - it appears to have holes.\n"),
- special);
- return -1;
- }
- }
+static void
+read_proc_swaps(void) {
+ FILE *swaps;
+ char line[1024];
+ char *p;
-#ifdef SWAPON_NEEDS_TWO_ARGS
- {
- int flags = 0;
+ numSwaps = 0;
+ swapFiles = NULL;
-#ifdef SWAP_FLAG_PREFER
- if (prio >= 0) {
- if (prio > SWAP_FLAG_PRIO_MASK)
- prio = SWAP_FLAG_PRIO_MASK;
- flags = SWAP_FLAG_PREFER
- | ((prio & SWAP_FLAG_PRIO_MASK) << SWAP_FLAG_PRIO_SHIFT);
- }
-#endif
- status = swapon (special, flags);
- }
-#else
- status = swapon (special);
-#endif
- } else
- status = swapoff (special);
+ swaps = fopen(PROC_SWAPS, "r");
+ if (swaps == NULL)
+ return; /* nothing wrong */
+
+ /* skip the first line */
+ fgets(line, sizeof(line), swaps);
- if (status < 0) {
- int errsv = errno;
- fprintf (stderr, "%s: %s: %s\n", program_name, special, strerror (errsv));
- }
+ while (fgets(line, sizeof(line), swaps)) {
+ /*
+ * Cut the line "swap_device ... more info" after device.
+ * This will fail with names with embedded spaces.
+ */
+ for (p = line; *p && *p != ' '; p++);
+ *p = 0;
- return status;
+ numSwaps++;
+ swapFiles = realloc(swapFiles,
+ numSwaps * sizeof(*swapFiles));
+ swapFiles[numSwaps-1] = strdup(line);
+ }
+ fclose(swaps);
+}
+
+static int
+is_in_proc_swaps(char *fname) {
+ int i;
+
+ for (i = 0; i < numSwaps; i++)
+ if (!strcmp(fname, swapFiles[i]))
+ return 1;
+ return 0;
}
static int
display_summary(void)
{
FILE *swaps;
- char line[200] ;
+ char line[1024] ;
if ((swaps = fopen(PROC_SWAPS, "r")) == NULL) {
int errsv = errno;
- fprintf (stderr, "%s: %s: %s\n", program_name, PROC_SWAPS,
- strerror (errsv));
+ fprintf(stderr, "%s: %s: %s\n", program_name, PROC_SWAPS,
+ strerror(errsv));
return -1 ;
}
- while ( fgets(line, sizeof(line), swaps))
- printf ("%s", line);
+ while (fgets(line, sizeof(line), swaps))
+ printf("%s", line);
fclose(swaps);
return 0 ;
}
-int
-main (int argc, char *argv[])
-{
- struct mntent *fstab;
- int status;
- int all = 0;
- int c;
-
- setlocale(LC_ALL, "");
- bindtextdomain(PACKAGE, LOCALEDIR);
- textdomain(PACKAGE);
-
- if (strrchr (argv[0], '/') != NULL)
- program_name = strrchr (argv[0], '/') + 1;
- else
- program_name = argv[0];
-
- while ((c = getopt_long (argc, argv, "ahp:svV", longopts, NULL)) != -1)
- switch (c)
- {
- case 'a': /* all */
- ++all;
- break;
- case 'h': /* help */
- usage (stdout, 0);
- break;
- case 'p': /* priority */
- priority = atoi(optarg);
- break;
- case 's': /* tell about current use of swap areas */
- status = display_summary();
- exit(status);
- case 'v': /* be chatty */
- ++verbose;
- break;
- case 'V': /* version */
- printf ("%s: %s\n", program_name, version);
- exit (0);
- case 0:
- break;
- case '?':
- default:
- usage (stderr, 1);
- }
-
- argv += optind;
-
- status = 0;
-
- if (all) {
- FILE *fp = setmntent(_PATH_FSTAB, "r");
- if (fp == NULL) {
- int errsv = errno;
- fprintf(stderr, _("%s: cannot open %s: %s\n"), program_name,
- _PATH_FSTAB, strerror(errsv));
- exit(2);
- }
- while ((fstab = getmntent(fp)) != NULL) {
- if (streq (fstab->mnt_type, MNTTYPE_SWAP)) {
- /* parse mount options; */
- char *opt, *opts = strdup(fstab->mnt_opts);
+static int
+do_swapon(const char *special, int prio) {
+ int status;
+ struct stat st;
+
+ if (verbose)
+ printf(_("%s on %s\n"), program_name, special);
+
+ if (stat(special, &st) < 0) {
+ int errsv = errno;
+ fprintf(stderr, _("swapon: cannot stat %s: %s\n"),
+ special, strerror(errsv));
+ return -1;
+ }
+
+ /* people generally dislike this warning - now it is printed
+ only when `verbose' is set */
+ if (verbose) {
+ int permMask = (S_ISBLK(st.st_mode) ? 07007 : 07077);
+
+ if ((st.st_mode & permMask) != 0) {
+ fprintf(stderr, _("swapon: warning: %s has "
+ "insecure permissions %04o, "
+ "%04o suggested\n"),
+ special, st.st_mode & 07777,
+ ~permMask & 0666);
+ }
+ }
+
+ /* test for holes by LBT */
+ if (S_ISREG(st.st_mode)) {
+ if (st.st_blocks * 512 < st.st_size) {
+ fprintf(stderr,
+ _("swapon: Skipping file %s - it appears "
+ "to have holes.\n"),
+ special);
+ return -1;
+ }
+ }
+
+#ifdef SWAPON_NEEDS_TWO_ARGS
+ {
+ int flags = 0;
+
+#ifdef SWAP_FLAG_PREFER
+ if (prio >= 0) {
+ if (prio > SWAP_FLAG_PRIO_MASK)
+ prio = SWAP_FLAG_PRIO_MASK;
+ flags = SWAP_FLAG_PREFER
+ | ((prio & SWAP_FLAG_PRIO_MASK)
+ << SWAP_FLAG_PRIO_SHIFT);
+ }
+#endif
+ status = swapon(special, flags);
+ }
+#else
+ status = swapon(special);
+#endif
+ if (status < 0) {
+ int errsv = errno;
+ fprintf(stderr, "%s: %s: %s\n", program_name,
+ special, strerror(errsv));
+ }
+
+ return status;
+}
+
+static int
+do_swapoff(const char *special, int quiet) {
+ if (verbose)
+ printf(_("%s on %s\n"), program_name, special);
+
+ if (swapoff(special) == 0)
+ return 0; /* success */
+
+ if (errno == EPERM) {
+ fprintf(stderr, _("Not superuser.\n"));
+ exit(1); /* any further swapoffs will also fail */
+ }
+
+ if (!quiet) {
+ int errsv = errno;
+ fprintf(stderr, "%s: %s: %s\n", program_name,
+ special, strerror(errsv));
+ }
+ return -1;
+}
+
+static int
+main_swapon(int argc, char *argv[]) {
+ FILE *fp;
+ struct mntent *fstab;
+ int status = 0;
+ int c;
+
+ while ((c = getopt_long(argc, argv, "ahp:svV",
+ longswaponopts, NULL)) != -1) {
+ switch (c) {
+ case 'a': /* all */
+ ++all;
+ break;
+ case 'h': /* help */
+ swapon_usage(stdout, 0);
+ break;
+ case 'p': /* priority */
+ priority = atoi(optarg);
+ break;
+ case 's': /* status report */
+ status = display_summary();
+ exit(status);
+ case 'v': /* be chatty */
+ ++verbose;
+ break;
+ case 'V': /* version */
+ printf("%s: %s\n", program_name, version);
+ exit(0);
+ case 0:
+ break;
+ case '?':
+ default:
+ swapon_usage(stderr, 1);
+ }
+ }
+ argv += optind;
+
+ if (!all && *argv == NULL)
+ swapon_usage(stderr, 2);
+
+ if (all) {
+ read_proc_swaps();
+
+ fp = setmntent(_PATH_FSTAB, "r");
+ if (fp == NULL) {
+ int errsv = errno;
+ fprintf(stderr, _("%s: cannot open %s: %s\n"),
+ program_name, _PATH_FSTAB, strerror(errsv));
+ exit(2);
+ }
+ while ((fstab = getmntent(fp)) != NULL) {
+ char *special = fstab->mnt_fsname;
+
+ if (streq(fstab->mnt_type, MNTTYPE_SWAP) &&
+ !is_in_proc_swaps(special)) {
+ /* parse mount options; */
+ char *opt, *opts = strdup(fstab->mnt_opts);
- for (opt = strtok (opts, ","); opt != NULL;
- opt = strtok (NULL, ","))
- if (strncmp(opt, "pri=", 4) == 0)
- priority = atoi(opt+4);
- status |= swap (fstab->mnt_fsname, priority);
- }
- }
- } else if (*argv == NULL) {
- usage (stderr, 2);
- } else {
- while (*argv != NULL)
- status |= swap (*argv++,priority);
- }
- return status;
+ for (opt = strtok(opts, ","); opt != NULL;
+ opt = strtok(NULL, ","))
+ if (strncmp(opt, "pri=", 4) == 0)
+ priority = atoi(opt+4);
+ status |= do_swapon(special, priority);
+ }
+ }
+ }
+
+ while (*argv != NULL)
+ status |= do_swapon(*argv++, priority);
+
+ return status;
+}
+
+static int
+main_swapoff(int argc, char *argv[]) {
+ FILE *fp;
+ struct mntent *fstab;
+ int status = 0;
+ int c, i;
+
+ while ((c = getopt_long(argc, argv, "ahvV",
+ longswapoffopts, NULL)) != -1) {
+ switch (c) {
+ case 'a': /* all */
+ ++all;
+ break;
+ case 'h': /* help */
+ swapoff_usage(stdout, 0);
+ break;
+ case 'v': /* be chatty */
+ ++verbose;
+ break;
+ case 'V': /* version */
+ printf("%s: %s\n", program_name, version);
+ exit(0);
+ case 0:
+ break;
+ case '?':
+ default:
+ swapoff_usage(stderr, 1);
+ }
+ }
+ argv += optind;
+
+ if (!all && *argv == NULL)
+ swapoff_usage(stderr, 2);
+
+ /*
+ * swapoff any explicitly given arguments.
+ * Complain in case the swapoff call fails.
+ */
+ while (*argv != NULL)
+ status |= do_swapoff(*argv++, !QUIET);
+
+ if (all) {
+ /*
+ * In case /proc/swaps exists, unmount stuff listed there.
+ * We are quiet but report errors in status.
+ * Errors might mean that /proc/swaps
+ * exists as ordinary file, not in procfs.
+ * do_swapoff() exits immediately on EPERM.
+ */
+ read_proc_swaps();
+ for(i=0; i<numSwaps; i++)
+ status |= do_swapoff(swapFiles[i], QUIET);
+
+ /*
+ * Unmount stuff mentioned in /etc/fstab.
+ * Probably it was unmounted already, so errors are not bad.
+ * Doing swapoff -a twice should not give error messages.
+ */
+ fp = setmntent(_PATH_FSTAB, "r");
+ if (fp == NULL) {
+ int errsv = errno;
+ fprintf(stderr, _("%s: cannot open %s: %s\n"),
+ program_name, _PATH_FSTAB, strerror(errsv));
+ exit(2);
+ }
+ while ((fstab = getmntent(fp)) != NULL) {
+ if (streq(fstab->mnt_type, MNTTYPE_SWAP) &&
+ !is_in_proc_swaps(fstab->mnt_fsname))
+ do_swapoff(fstab->mnt_fsname, QUIET);
+ }
+ }
+
+ return status;
+}
+
+int
+main(int argc, char *argv[]) {
+ char *p;
+
+ setlocale(LC_ALL, "");
+ bindtextdomain(PACKAGE, LOCALEDIR);
+ textdomain(PACKAGE);
+
+ program_name = argv[0];
+ p = strrchr(program_name, '/');
+ if (p)
+ program_name = p+1;
+
+ if (streq(program_name, "swapon"))
+ return main_swapon(argc, argv);
+ else
+ return main_swapoff(argc, argv);
}