diff options
author | Karel Zak | 2006-12-07 00:26:31 +0100 |
---|---|---|
committer | Karel Zak | 2006-12-07 00:26:31 +0100 |
commit | 756bfd018eb393640dad490df1a1ca840d9ee79b (patch) | |
tree | d95fd02eefcc647d4886761ccb74e976ee7aa32a /mount | |
parent | Imported from util-linux-2.12m tarball. (diff) | |
download | kernel-qcow2-util-linux-756bfd018eb393640dad490df1a1ca840d9ee79b.tar.gz kernel-qcow2-util-linux-756bfd018eb393640dad490df1a1ca840d9ee79b.tar.xz kernel-qcow2-util-linux-756bfd018eb393640dad490df1a1ca840d9ee79b.zip |
Imported from util-linux-2.12o tarball.
Diffstat (limited to 'mount')
-rw-r--r-- | mount/Makefile | 13 | ||||
-rw-r--r-- | mount/fstab.c | 23 | ||||
-rw-r--r-- | mount/get_label_uuid.c | 162 | ||||
-rw-r--r-- | mount/lomount.c | 9 | ||||
-rw-r--r-- | mount/mount.c | 1 | ||||
-rw-r--r-- | mount/mount_blkid.c | 7 | ||||
-rw-r--r-- | mount/mount_by_label.c | 10 | ||||
-rw-r--r-- | mount/sundries.c | 54 | ||||
-rw-r--r-- | mount/sundries.h | 1 | ||||
-rw-r--r-- | mount/swapon.8 | 49 | ||||
-rw-r--r-- | mount/swapon.c | 240 | ||||
-rw-r--r-- | mount/umount.c | 5 | ||||
-rw-r--r-- | mount/xmalloc.c | 66 | ||||
-rw-r--r-- | mount/xmalloc.h | 8 |
14 files changed, 416 insertions, 232 deletions
diff --git a/mount/Makefile b/mount/Makefile index 9258fbdf4..911f96c7c 100644 --- a/mount/Makefile +++ b/mount/Makefile @@ -47,18 +47,19 @@ install: $(PROGS) %.o: %.c $(COMPILE) $< -mount: mount.o fstab.o sundries.o realpath.o mntent.o version.o \ +mount: mount.o fstab.o sundries.o xmalloc.o realpath.o mntent.o version.o \ get_label_uuid.o mount_by_label.o mount_blkid.o mount_guess_fstype.o \ getusername.o $(LIB)/setproctitle.o $(LIB)/env.o $(NFS_OBJS) $(LO_OBJS) $(LINK) $^ -o $@ $(BLKID_LIB) -umount: umount.o fstab.o sundries.o realpath.o mntent.o getusername.o \ - get_label_uuid.o mount_by_label.o mount_blkid.o version.o \ - $(LIB)/env.o $(LO_OBJS) +umount: umount.o fstab.o sundries.o xmalloc.o realpath.o mntent.o \ + getusername.o get_label_uuid.o mount_by_label.o mount_blkid.o \ + version.o $(LIB)/env.o $(LO_OBJS) $(LINK) $^ -o $@ $(BLKID_LIB) -swapon: swapon.o version.o - $(LINK) $^ -o $@ +swapon: swapon.o version.o xmalloc.o \ + get_label_uuid.o mount_by_label.o mount_blkid.o + $(LINK) $^ -o $@ $(BLKID_LIB) main_losetup.o: lomount.c $(COMPILE) -DMAIN lomount.c -o $@ diff --git a/mount/fstab.c b/mount/fstab.c index 09b5f584d..1a7ce4e58 100644 --- a/mount/fstab.c +++ b/mount/fstab.c @@ -11,7 +11,8 @@ #include <sys/stat.h> #include "mntent.h" #include "fstab.h" -#include "sundries.h" /* for xmalloc() etc */ +#include "sundries.h" +#include "xmalloc.h" #include "mount_blkid.h" #include "paths.h" #include "nls.h" @@ -411,6 +412,15 @@ setlkw_timeout (int sig) { /* nothing, fcntl will fail anyway */ } +/* Remove lock file. */ +void +unlock_mtab (void) { + if (we_created_lockfile) { + unlink (MOUNTED_LOCK); + we_created_lockfile = 0; + } +} + /* Create the lock file. The lock file will be removed if we catch a signal or when we exit. */ /* The old code here used flock on a lock file /etc/mtab~ and deleted @@ -436,6 +446,8 @@ lock_mtab (void) { int tries = 3; char linktargetfile[MOUNTLOCK_LINKTARGET_LTH]; + at_die = unlock_mtab; + if (!signals_have_been_setup) { int sig = 0; struct sigaction sa; @@ -543,15 +555,6 @@ lock_mtab (void) { } } -/* Remove lock file. */ -void -unlock_mtab (void) { - if (we_created_lockfile) { - unlink (MOUNTED_LOCK); - we_created_lockfile = 0; - } -} - /* * Update the mtab. * Used by umount with null INSTEAD: remove the last DIR entry. diff --git a/mount/get_label_uuid.c b/mount/get_label_uuid.c index 411e6a847..8b5942f71 100644 --- a/mount/get_label_uuid.c +++ b/mount/get_label_uuid.c @@ -1,6 +1,6 @@ #ifndef HAVE_BLKID /* - * Get label. Used by both mount and umount. + * Get label. Used by mount, umount and swapon. */ #include <stdio.h> #include <fcntl.h> @@ -8,8 +8,10 @@ #include <stdlib.h> #include <string.h> +#include "xmalloc.h" #include "linux_fs.h" #include "get_label_uuid.h" +#include "../disk-utils/swapheader.h" /* * See whether this device has (the magic of) a RAID superblock at the end. @@ -60,15 +62,48 @@ reiserfs_magic_version(const char *magic) { return rc; } +static void +store_uuid(char *udest, char *usrc) { + if (usrc) + memcpy(udest, usrc, 16); + else + memset(udest, 0, 16); +} + +static void +store_label(char **ldest, char *lsrc, int len) { + *ldest = xmalloc(len+1); + memset(*ldest, 0, len+1); + memcpy(*ldest, lsrc, len); +} + +static int +is_v1_swap_partition(int fd, char **label, char *uuid) { + int n = getpagesize(); + char *buf = xmalloc(n); + struct swap_header_v1_2 *p = (struct swap_header_v1_2 *) buf; + + if (lseek(fd, 0, SEEK_SET) == 0 + && read(fd, buf, n) == n + && !strncmp(buf+n-10, "SWAPSPACE2", 10) + && p->version == 1) { + store_uuid(uuid, p->uuid); + store_label(label, p->volume_name, 16); + return 1; + } + return 0; +} + + /* * Get both label and uuid. - * For now, only ext2, ext3, xfs, ocfs, ocfs2, reiserfs are supported + * For now, only ext2, ext3, xfs, ocfs, ocfs2, reiserfs, swap are supported + * + * Return 0 on success. */ int get_label_uuid(const char *device, char **label, char *uuid) { int fd; - int rv = 1; - size_t namesize; struct ext2_super_block e2sb; struct xfs_super_block xfsb; struct jfs_super_block jfssb; @@ -76,47 +111,50 @@ get_label_uuid(const char *device, char **label, char *uuid) { struct ocfs_volume_label olbl; struct ocfs2_super_block osb; struct reiserfs_super_block reiserfssb; + int blksize; + int rv = 0; fd = open(device, O_RDONLY); if (fd < 0) - return rv; + return -1; /* If there is a RAID partition, or an error, ignore this partition */ if (is_raid_partition(fd)) { - close(fd); - return rv; + rv = 1; + goto done; } + if (is_v1_swap_partition(fd, label, uuid)) + goto done; + if (lseek(fd, 1024, SEEK_SET) == 1024 && read(fd, (char *) &e2sb, sizeof(e2sb)) == sizeof(e2sb) && (ext2magic(e2sb) == EXT2_SUPER_MAGIC)) { - memcpy(uuid, e2sb.s_uuid, sizeof(e2sb.s_uuid)); - namesize = sizeof(e2sb.s_volume_name); - if ((*label = calloc(namesize + 1, 1)) != NULL) - memcpy(*label, e2sb.s_volume_name, namesize); - rv = 0; + store_uuid(uuid, e2sb.s_uuid); + store_label(label, e2sb.s_volume_name, + sizeof(e2sb.s_volume_name)); + goto done; } - else if (lseek(fd, 0, SEEK_SET) == 0 + + if (lseek(fd, 0, SEEK_SET) == 0 && read(fd, (char *) &xfsb, sizeof(xfsb)) == sizeof(xfsb) && (strncmp(xfsb.s_magic, XFS_SUPER_MAGIC, 4) == 0)) { - memcpy(uuid, xfsb.s_uuid, sizeof(xfsb.s_uuid)); - namesize = sizeof(xfsb.s_fname); - if ((*label = calloc(namesize + 1, 1)) != NULL) - memcpy(*label, xfsb.s_fname, namesize); - rv = 0; + store_uuid(uuid, xfsb.s_uuid); + store_label(label, xfsb.s_fname, sizeof(xfsb.s_fname)); + goto done; } - else if (lseek(fd, 0, SEEK_SET) == 0 + + if (lseek(fd, 0, SEEK_SET) == 0 && read(fd, (char *) &ovh, sizeof(ovh)) == sizeof(ovh) && (strncmp(ovh.signature, OCFS_MAGIC, sizeof(OCFS_MAGIC)) == 0) && (lseek(fd, 512, SEEK_SET) == 512) && read(fd, (char *) &olbl, sizeof(olbl)) == sizeof(olbl)) { - uuid[0] = '\0'; - namesize = ocfslabellen(olbl); - if ((*label = calloc(namesize + 1, 1)) != NULL) - memcpy(*label, olbl.label, namesize); - rv = 0; + store_uuid(uuid, NULL); + store_label(label, olbl.label, ocfslabellen(olbl)); + goto done; } - else if (lseek(fd, JFS_SUPER1_OFF, SEEK_SET) == JFS_SUPER1_OFF + + if (lseek(fd, JFS_SUPER1_OFF, SEEK_SET) == JFS_SUPER1_OFF && read(fd, (char *) &jfssb, sizeof(jfssb)) == sizeof(jfssb) && (strncmp(jfssb.s_magic, JFS_MAGIC, 4) == 0)) { @@ -136,55 +174,47 @@ get_label_uuid(const char *device, char **label, char *uuid) { if (assemble4le(jfssb.s_version) == 1 && strncmp(jfssb.s_label, jfssb.s_fpack, 11) != 0) { - memset(uuid, 0, 16); - namesize = sizeof(jfssb.s_fpack); - if ((*label = calloc(namesize + 1, 1)) != NULL) - memcpy(*label, jfssb.s_fpack, namesize); + store_uuid(uuid, NULL); + store_label(label, jfssb.s_fpack, + sizeof(jfssb.s_fpack)); } else { - memcpy(uuid, jfssb.s_uuid, sizeof(jfssb.s_uuid)); - namesize = sizeof(jfssb.s_label); - if ((*label = calloc(namesize + 1, 1)) != NULL) - memcpy(*label, jfssb.s_label, namesize); + store_uuid(uuid, jfssb.s_uuid); + store_label(label, jfssb.s_label, + sizeof(jfssb.s_label)); } - rv = 0; + goto done; } - else if (lseek(fd, REISERFS_DISK_OFFSET_IN_BYTES, SEEK_SET) - == REISERFS_DISK_OFFSET_IN_BYTES + + if (lseek(fd, REISERFS_DISK_OFFSET_IN_BYTES, SEEK_SET) + == REISERFS_DISK_OFFSET_IN_BYTES && read(fd, (char *) &reiserfssb, sizeof(reiserfssb)) - == sizeof(reiserfssb) - /* Only 3.6.x format supers have labels or uuids. - Label and UUID can be set by reiserfstune -l/-u. */ + == sizeof(reiserfssb) + /* Only 3.6.x format supers have labels or uuids. + Label and UUID can be set by reiserfstune -l/-u. */ && reiserfs_magic_version(reiserfssb.s_magic) > 1) { - namesize = sizeof (reiserfssb.s_label); - if ((*label = calloc(namesize + 1, 1)) != NULL) - memcpy(*label, reiserfssb.s_label, namesize); - memcpy(uuid, reiserfssb.s_uuid, sizeof (reiserfssb.s_uuid)); - rv = 0; + store_uuid(uuid, reiserfssb.s_uuid); + store_label(label, reiserfssb.s_label, + sizeof(reiserfssb.s_label)); + goto done; } - else { - int blksize, blkoff; - - for (blksize = OCFS2_MIN_BLOCKSIZE; - blksize <= OCFS2_MAX_BLOCKSIZE; - blksize <<= 1) { - blkoff = blksize * OCFS2_SUPER_BLOCK_BLKNO; - if (lseek(fd, blkoff, SEEK_SET) == blkoff - && read(fd, (char *) &osb, sizeof(osb)) - == sizeof(osb) - && strncmp(osb.signature, - OCFS2_SUPER_BLOCK_SIGNATURE, - sizeof(OCFS2_SUPER_BLOCK_SIGNATURE)) - == 0) { - memcpy(uuid, osb.s_uuid, sizeof(osb.s_uuid)); - namesize = sizeof(osb.s_label); - if ((*label = calloc(namesize, 1)) != NULL) - memcpy(*label, osb.s_label, namesize); - rv = 0; - break; - } + + for (blksize = OCFS2_MIN_BLOCKSIZE; + blksize <= OCFS2_MAX_BLOCKSIZE; + blksize <<= 1) { + int blkoff = blksize * OCFS2_SUPER_BLOCK_BLKNO; + + if (lseek(fd, blkoff, SEEK_SET) == blkoff + && read(fd, (char *) &osb, sizeof(osb)) == sizeof(osb) + && strncmp(osb.signature, + OCFS2_SUPER_BLOCK_SIGNATURE, + sizeof(OCFS2_SUPER_BLOCK_SIGNATURE)) == 0) { + store_uuid(uuid, osb.s_uuid); + store_label(label, osb.s_label, sizeof(osb.s_label)); + goto done; } } - + rv = 1; + done: close(fd); return rv; } diff --git a/mount/lomount.c b/mount/lomount.c index 002f34204..000a7b814 100644 --- a/mount/lomount.c +++ b/mount/lomount.c @@ -242,7 +242,7 @@ int set_loop(const char *device, const char *file, unsigned long long offset, const char *encryption, int pfd, int *loopro) { struct loop_info64 loopinfo64; - int fd, ffd, mode, i, n; + int fd, ffd, mode, i; char *pass; mode = (*loopro ? O_RDONLY : O_RDWR); @@ -299,11 +299,10 @@ set_loop(const char *device, const char *file, unsigned long long offset, default: pass = xgetpass(pfd, _("Password: ")); gotpass: + memset(loopinfo64.lo_encrypt_key, 0, LO_KEY_SIZE); xstrncpy(loopinfo64.lo_encrypt_key, pass, LO_KEY_SIZE); - n = strlen(pass); - memset(pass, 0, n); - loopinfo64.lo_encrypt_key_size = - (n < LO_KEY_SIZE) ? n : LO_KEY_SIZE; + memset(pass, 0, strlen(pass)); + loopinfo64.lo_encrypt_key_size = LO_KEY_SIZE; } if (ioctl(fd, LOOP_SET_FD, ffd) < 0) { diff --git a/mount/mount.c b/mount/mount.c index 3a59c370c..0f48ea931 100644 --- a/mount/mount.c +++ b/mount/mount.c @@ -24,6 +24,7 @@ #include "mount_blkid.h" #include "mount_constants.h" #include "sundries.h" +#include "xmalloc.h" #include "mntent.h" #include "fstab.h" #include "lomount.h" diff --git a/mount/mount_blkid.c b/mount/mount_blkid.c index 47c48b39e..c485c913c 100644 --- a/mount/mount_blkid.c +++ b/mount/mount_blkid.c @@ -74,6 +74,8 @@ mount_get_devname_by_uuid(const char *uuid) { return get_spec_by_uuid(uuid); } +extern char *progname; + const char * mount_get_devname_by_label(const char *volumelabel) { const char *spec, *spec2; @@ -82,9 +84,8 @@ mount_get_devname_by_label(const char *volumelabel) { spec2 = second_occurrence_of_vol_label(volumelabel); if (spec2) die (EX_FAIL, - _("mount: the label %s occurs on " - "both %s and %s - not mounted\n"), - volumelabel, spec, spec2); + _("%s: error: the label %s occurs on both %s and %s\n"), + progname, volumelabel, spec, spec2); return spec; } diff --git a/mount/mount_by_label.c b/mount/mount_by_label.c index 29ec35448..91e9f3ac8 100644 --- a/mount/mount_by_label.c +++ b/mount/mount_by_label.c @@ -40,6 +40,8 @@ #define EVMS_VOLUME_NAME_SIZE 127 #define PROC_EVMS_VOLUMES "/proc/evms/volumes" +extern char *progname; + static struct uuidCache_s { struct uuidCache_s *next; char uuid[16]; @@ -82,7 +84,7 @@ uuidcache_init_lvm(void) { sprintf(buffer, "%s/%s/LVs", VG_DIR, vg_iter->d_name); lv_list = opendir(buffer); if (lv_list == NULL) { - perror("mount (init_lvm)"); + perror("uuidcache_init_lvm"); continue; } seekdir(lv_list, 2); @@ -187,9 +189,9 @@ uuidcache_init(void) { if (!procpt) { static int warn = 0; if (!warn++) - error (_("mount: could not open %s, so UUID and LABEL " + error (_("%s: could not open %s, so UUID and LABEL " "conversion cannot be done.\n"), - PROC_PARTITIONS); + progname, PROC_PARTITIONS); return; } #if 0 @@ -310,7 +312,7 @@ get_spec_by_uuid(const char *s) { return get_spec_by_x(UUID, uuid); bad_uuid: - die(EX_USAGE, _("mount: bad UUID")); + die(EX_USAGE, _("%s: bad UUID"), progname); return NULL; /* just for gcc */ } diff --git a/mount/sundries.c b/mount/sundries.c index 2118ce285..1be9099ba 100644 --- a/mount/sundries.c +++ b/mount/sundries.c @@ -18,46 +18,6 @@ #include "nfsmount.h" #include "nls.h" -void * -xmalloc (size_t size) { - void *t; - - if (size == 0) - return NULL; - - t = malloc (size); - if (t == NULL) - die (EX_SYSERR, _("not enough memory")); - - return t; -} - -void * -xrealloc (void *p, size_t size) { - void *t; - - t = realloc(p, size); - if (t == NULL) - die (EX_SYSERR, _("not enough memory")); - - return t; -} - -char * -xstrdup (const char *s) { - char *t; - - if (s == NULL) - return NULL; - - t = strdup (s); - - if (t == NULL) - die (EX_SYSERR, _("not enough memory")); - - return t; -} - char * xstrndup (const char *s, int n) { char *t; @@ -147,20 +107,6 @@ error (const char *fmt, ...) { free (fmt2); } -/* Fatal error. Print message and exit. */ -void -die (int err, const char *fmt, ...) { - va_list args; - - va_start (args, fmt); - vfprintf (stderr, fmt, args); - fprintf (stderr, "\n"); - va_end (args); - - unlock_mtab (); - exit (err); -} - /* True if fstypes match. Null *TYPES means match anything, except that swap types always return false. */ /* Accept nonfs,proc,devpts and nonfs,noproc,nodevpts diff --git a/mount/sundries.h b/mount/sundries.h index a3a762f6f..af0df4e27 100644 --- a/mount/sundries.h +++ b/mount/sundries.h @@ -26,7 +26,6 @@ void error (const char *fmt, ...); int matching_type (const char *type, const char *types); int matching_opts (const char *options, const char *test_opts); void *xmalloc (size_t size); -void *xrealloc (void *t, size_t size); char *xstrdup (const char *s); char *xstrndup (const char *s, int n); char *xstrconcat2 (const char *, const char *); diff --git a/mount/swapon.8 b/mount/swapon.8 index f1f40263e..99d4c3c57 100644 --- a/mount/swapon.8 +++ b/mount/swapon.8 @@ -58,6 +58,15 @@ swapon, swapoff \- enable/disable devices and files for paging and swapping .SH DESCRIPTION .B Swapon is used to specify devices on which paging and swapping are to take place. + +The device or file used is given by the +.I specialfile +parameter. It may be of the form +.BI \-L " label" +or +.BI \-U " uuid" +to indicate a device by label or uuid. + Calls to .B swapon normally occur in the system multi-user initialization file @@ -67,16 +76,6 @@ is interleaved across several devices and files. Normally, the first form is used: .TP -.B \-h -Provide help -.TP -.B \-V -Display version -.TP -.B \-s -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 ``swap'' swap devices in .I /etc/fstab @@ -88,8 +87,17 @@ When .B \-a is used with swapon, .B \-e -makes swapon silently skip devices that -do not exist. +makes swapon silently skip devices that do not exist. +.TP +.B \-h +Provide help +.TP +.BI \-L " label" +Use the partition that has the specified +.IR label . +(For this, access to +.I /proc/partitions +is needed.) .TP .BI \-p " priority" Specify priority for @@ -98,7 +106,8 @@ This option is only available if .B swapon was compiled under and is used under a 1.3.2 or later kernel. .I priority -is a value between 0 and 32767. See +is a value between 0 and 32767. Higher numbers indicate higher +priority. See .BR swapon (2) for a full description of swap priorities. Add .BI pri= value @@ -107,8 +116,22 @@ to the option field of for use with .BR "swapon -a" . .TP +.B \-s +Display swap usage summary by device. Equivalent to "cat /proc/swaps". +Not available before Linux 2.1.25. +.TP +.BI \-U " uuid" +Use the partition that has the specified +.IR uuid . +(For this, access to +.I /proc/partitions +is needed.) +.TP .B \-v Be verbose. +.TP +.B \-V +Display version .PP .B Swapoff disables swapping on the specified devices and files. diff --git a/mount/swapon.c b/mount/swapon.c index dadfc04ef..28faff90b 100644 --- a/mount/swapon.c +++ b/mount/swapon.c @@ -11,9 +11,12 @@ #include <mntent.h> #include <errno.h> #include <sys/stat.h> +#include "xmalloc.h" #include "swap_constants.h" #include "swapargs.h" #include "nls.h" +#include "mount_blkid.h" +#include "mount_by_label.h" #define streq(s, t) (strcmp ((s), (t)) == 0) @@ -32,7 +35,7 @@ int priority = -1; /* non-prioritized swap by default */ int ifexists = 0; extern char version[]; -static char *program_name; +char *progname; static struct option longswaponopts[] = { /* swapon only */ @@ -53,9 +56,9 @@ static void swapon_usage(FILE *fp, int n) { fprintf(fp, _("usage: %s [-hV]\n" " %s -a [-e] [-v]\n" - " %s [-v] [-p priority] special ...\n" + " %s [-v] [-p priority] special|LABEL=volume_name ...\n" " %s [-s]\n"), - program_name, program_name, program_name, program_name); + progname, progname, progname, progname); exit(n); } @@ -64,7 +67,7 @@ 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); + progname, progname, progname); exit(n); } @@ -132,7 +135,7 @@ read_proc_swaps(void) { } static int -is_in_proc_swaps(char *fname) { +is_in_proc_swaps(const char *fname) { int i; for (i = 0; i < numSwaps; i++) @@ -149,7 +152,7 @@ display_summary(void) if ((swaps = fopen(PROC_SWAPS, "r")) == NULL) { int errsv = errno; - fprintf(stderr, "%s: %s: %s\n", program_name, PROC_SWAPS, + fprintf(stderr, "%s: %s: %s\n", progname, PROC_SWAPS, strerror(errsv)); return -1 ; } @@ -162,17 +165,25 @@ display_summary(void) } static int -do_swapon(const char *special, int prio) { +do_swapon(const char *orig_special, int prio) { int status; struct stat st; + const char *special; if (verbose) - printf(_("%s on %s\n"), program_name, special); + printf(_("%s on %s\n"), progname, orig_special); + + special = mount_get_devname(orig_special); + if (!special) { + fprintf(stderr, _("%s: cannot find the device for %s\n"), + progname, orig_special); + return -1; + } if (stat(special, &st) < 0) { int errsv = errno; - fprintf(stderr, _("swapon: cannot stat %s: %s\n"), - special, strerror(errsv)); + fprintf(stderr, _("%s: cannot stat %s: %s\n"), + progname, special, strerror(errsv)); return -1; } @@ -182,10 +193,10 @@ do_swapon(const char *special, int prio) { int permMask = (S_ISBLK(st.st_mode) ? 07007 : 07077); if ((st.st_mode & permMask) != 0) { - fprintf(stderr, _("swapon: warning: %s has " + fprintf(stderr, _("%s: warning: %s has " "insecure permissions %04o, " "%04o suggested\n"), - special, st.st_mode & 07777, + progname, special, st.st_mode & 07777, ~permMask & 0666); } } @@ -194,9 +205,9 @@ do_swapon(const char *special, int prio) { if (S_ISREG(st.st_mode)) { if (st.st_blocks * 512 < st.st_size) { fprintf(stderr, - _("swapon: Skipping file %s - it appears " + _("%s: Skipping file %s - it appears " "to have holes.\n"), - special); + progname, special); return -1; } } @@ -221,17 +232,42 @@ do_swapon(const char *special, int prio) { #endif if (status < 0) { int errsv = errno; - fprintf(stderr, "%s: %s: %s\n", program_name, - special, strerror(errsv)); + fprintf(stderr, "%s: %s: %s\n", + progname, orig_special, strerror(errsv)); } return status; } static int -do_swapoff(const char *special, int quiet) { +cannot_find(const char *special) { + fprintf(stderr, _("%s: cannot find the device for %s\n"), + progname, special); + return -1; +} + +static int +swapon_by_label(const char *label, int prio) { + const char *special = mount_get_devname_by_label(label); + return special ? do_swapon(special, prio) : cannot_find(label); +} + +static int +swapon_by_uuid(const char *uuid, int prio) { + const char *special = mount_get_devname_by_uuid(uuid); + return special ? do_swapon(special, prio) : cannot_find(uuid); +} + +static int +do_swapoff(const char *orig_special, int quiet) { + const char *special; + if (verbose) - printf(_("%s on %s\n"), program_name, special); + printf(_("%s on %s\n"), progname, orig_special); + + special = mount_get_devname(orig_special); + if (!special) + return cannot_find(orig_special); if (swapoff(special) == 0) return 0; /* success */ @@ -242,22 +278,96 @@ do_swapoff(const char *special, int quiet) { } if (!quiet || errno == ENOMEM) { - int errsv = errno; - fprintf(stderr, "%s: %s: %s\n", program_name, - special, strerror(errsv)); + fprintf(stderr, "%s: %s: %s\n", + progname, orig_special, strerror(errno)); } return -1; } static int -main_swapon(int argc, char *argv[]) { +swapoff_by_label(const char *label, int quiet) { + const char *special = mount_get_devname_by_label(label); + return special ? do_swapoff(special, quiet) : cannot_find(label); +} + +static int +swapoff_by_uuid(const char *uuid, int quiet) { + const char *special = mount_get_devname_by_uuid(uuid); + return special ? do_swapoff(special, quiet) : cannot_find(uuid); +} + +static int +swapon_all(void) { FILE *fp; struct mntent *fstab; int status = 0; - int c; - while ((c = getopt_long(argc, argv, "ahep:svV", - longswaponopts, NULL)) != -1) { + read_proc_swaps(); + + fp = setmntent(_PATH_FSTAB, "r"); + if (fp == NULL) { + int errsv = errno; + fprintf(stderr, _("%s: cannot open %s: %s\n"), + progname, _PATH_FSTAB, strerror(errsv)); + exit(2); + } + + while ((fstab = getmntent(fp)) != NULL) { + const char *orig_special = fstab->mnt_fsname; + const char *special; + int skip = 0; + int pri = priority; + + if (!streq(fstab->mnt_type, MNTTYPE_SWAP)) + continue; + + special = mount_get_devname(orig_special); + if (!special) + continue; + + if (!is_in_proc_swaps(special) && + (!ifexists || !access(special, R_OK))) { + /* 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) + pri = atoi(opt+4); + if (strcmp(opt, "noauto") == 0) + skip = 1; + } + if (!skip) + status |= do_swapon(special, pri); + } + } + fclose(fp); + + return status; +} + +static const char **llist = NULL; +static int llct = 0; +static const char **ulist = NULL; +static int ulct = 0; + +static void addl(const char *label) { + llist = (const char **) xrealloc(llist, (++llct) * sizeof(char *)); + llist[llct-1] = label; +} + +static void addu(const char *uuid) { + ulist = (const char **) xrealloc(ulist, (++ulct) * sizeof(char *)); + ulist[ulct-1] = uuid; +} + +static int +main_swapon(int argc, char *argv[]) { + int status = 0; + int c, i; + + while ((c = getopt_long(argc, argv, "ahep:svVL:U:", + longswaponopts, NULL)) != -1) { switch (c) { case 'a': /* all */ ++all; @@ -268,6 +378,12 @@ main_swapon(int argc, char *argv[]) { case 'p': /* priority */ priority = atoi(optarg); break; + case 'L': + addl(optarg); + break; + case 'U': + addu(optarg); + break; case 'e': /* ifexists */ ifexists = 1; break; @@ -278,7 +394,7 @@ main_swapon(int argc, char *argv[]) { ++verbose; break; case 'V': /* version */ - printf("%s: %s\n", program_name, version); + printf("%s: %s\n", progname, version); exit(0); case 0: break; @@ -289,46 +405,20 @@ main_swapon(int argc, char *argv[]) { } argv += optind; - if (!all && *argv == NULL) + if (!all && !llct && !ulct && *argv == NULL) swapon_usage(stderr, 2); - if (ifexists && (!all || strcmp(program_name, "swapon"))) - swapon_usage(stderr, 1); + if (ifexists && (!all || strcmp(progname, "swapon"))) + swapon_usage(stderr, 1); - if (all) { - read_proc_swaps(); + if (all) + status |= swapon_all(); - 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; - int skip = 0; - int pri = priority; + for (i = 0; i < llct; i++) + status |= swapon_by_label(llist[i], priority); - if (streq(fstab->mnt_type, MNTTYPE_SWAP) && - !is_in_proc_swaps(special) - && (!ifexists || !access(special, R_OK))) { - /* 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) - pri = atoi(opt+4); - if (strcmp(opt, "noauto") == 0) - skip = 1; - } - if (!skip) - status |= do_swapon(special, pri); - } - } - fclose(fp); - } + for (i = 0; i < ulct; i++) + status |= swapon_by_uuid(ulist[i], priority); while (*argv != NULL) status |= do_swapon(*argv++, priority); @@ -343,7 +433,7 @@ main_swapoff(int argc, char *argv[]) { int status = 0; int c, i; - while ((c = getopt_long(argc, argv, "ahvV", + while ((c = getopt_long(argc, argv, "ahvVL:U:", longswapoffopts, NULL)) != -1) { switch (c) { case 'a': /* all */ @@ -356,8 +446,14 @@ main_swapoff(int argc, char *argv[]) { ++verbose; break; case 'V': /* version */ - printf("%s: %s\n", program_name, version); + printf("%s: %s\n", progname, version); exit(0); + case 'L': + addl(optarg); + break; + case 'U': + addu(optarg); + break; case 0: break; case '?': @@ -367,13 +463,19 @@ main_swapoff(int argc, char *argv[]) { } argv += optind; - if (!all && *argv == NULL) + if (!all && !llct && !ulct && *argv == NULL) swapoff_usage(stderr, 2); /* * swapoff any explicitly given arguments. * Complain in case the swapoff call fails. */ + for (i = 0; i < llct; i++) + status |= swapoff_by_label(llist[i], !QUIET); + + for (i = 0; i < ulct; i++) + status |= swapoff_by_uuid(ulist[i], !QUIET); + while (*argv != NULL) status |= do_swapoff(*argv++, !QUIET); @@ -398,7 +500,7 @@ main_swapoff(int argc, char *argv[]) { if (fp == NULL) { int errsv = errno; fprintf(stderr, _("%s: cannot open %s: %s\n"), - program_name, _PATH_FSTAB, strerror(errsv)); + progname, _PATH_FSTAB, strerror(errsv)); exit(2); } while ((fstab = getmntent(fp)) != NULL) { @@ -420,12 +522,12 @@ main(int argc, char *argv[]) { bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); - program_name = argv[0]; - p = strrchr(program_name, '/'); + progname = argv[0]; + p = strrchr(progname, '/'); if (p) - program_name = p+1; + progname = p+1; - if (streq(program_name, "swapon")) + if (streq(progname, "swapon")) return main_swapon(argc, argv); else return main_swapoff(argc, argv); diff --git a/mount/umount.c b/mount/umount.c index 15d94f938..b26c28d45 100644 --- a/mount/umount.c +++ b/mount/umount.c @@ -571,7 +571,10 @@ umount_file (char *arg) { die(2, _("umount: %s is not mounted (according to mtab)"), file); - if (!is_mounted_once(file)) + /* The 2.4 kernel will generally refuse to mount the same + filesystem on the same mount point, but will accept NFS. + So, unmounting must be possible. */ + if (!is_mounted_once(file) && strcmp(mc->m.mnt_type,"nfs")) die(2, _("umount: it seems %s is mounted multiple times"), file); diff --git a/mount/xmalloc.c b/mount/xmalloc.c new file mode 100644 index 000000000..c3f51e50c --- /dev/null +++ b/mount/xmalloc.c @@ -0,0 +1,66 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> /* strdup() */ +#include "xmalloc.h" +#include "nls.h" /* _() */ +#include "sundries.h" /* EX_SYSERR */ + +void (*at_die)(void) = NULL; + +/* Fatal error. Print message and exit. */ +void +die(int err, const char *fmt, ...) { + va_list args; + + va_start(args, fmt); + vfprintf(stderr, fmt, args); + fprintf(stderr, "\n"); + va_end(args); + + if (at_die) + (*at_die)(); + + exit(err); +} + +static void +die_if_null(void *t) { + if (t == NULL) + die(EX_SYSERR, _("not enough memory")); +} + +void * +xmalloc (size_t size) { + void *t; + + if (size == 0) + return NULL; + + t = malloc(size); + die_if_null(t); + + return t; +} + +void * +xrealloc (void *p, size_t size) { + void *t; + + t = realloc(p, size); + die_if_null(t); + + return t; +} + +char * +xstrdup (const char *s) { + char *t; + + if (s == NULL) + return NULL; + + t = strdup(s); + die_if_null(t); + + return t; +} diff --git a/mount/xmalloc.h b/mount/xmalloc.h new file mode 100644 index 000000000..91d64c5a3 --- /dev/null +++ b/mount/xmalloc.h @@ -0,0 +1,8 @@ +#include <sys/types.h> +#include <stdarg.h> + +extern void *xmalloc(size_t size); +extern void *xrealloc(void *p, size_t size); +extern char *xstrdup(const char *s); +extern void die(int err, const char *fmt, ...); +extern void (*at_die)(void); |