diff options
author | Karel Zak | 2006-12-07 00:25:58 +0100 |
---|---|---|
committer | Karel Zak | 2006-12-07 00:25:58 +0100 |
commit | 63cccae4684f83d2a462bc8abf24e51d1bd6efb6 (patch) | |
tree | 433db3f0b44e0f46e4130141f4a59db9c3564557 /mount | |
parent | Imported from util-linux-2.11r tarball. (diff) | |
download | kernel-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/Makefile | 16 | ||||
-rw-r--r-- | mount/fstab.c | 2 | ||||
-rw-r--r-- | mount/linux_fs.h | 55 | ||||
-rw-r--r-- | mount/mount.8 | 13 | ||||
-rw-r--r-- | mount/mount.c | 436 | ||||
-rw-r--r-- | mount/mount_by_label.c | 30 | ||||
-rw-r--r-- | mount/mount_constants.h | 4 | ||||
-rw-r--r-- | mount/mount_guess_fstype.c | 5 | ||||
-rw-r--r-- | mount/nfs.5 | 6 | ||||
-rw-r--r-- | mount/pivot_root.c | 20 | ||||
-rw-r--r-- | mount/sundries.h | 1 | ||||
-rw-r--r-- | mount/swapon.8 | 18 | ||||
-rw-r--r-- | mount/swapon.c | 494 |
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); } |