summaryrefslogtreecommitdiffstats
path: root/mount
diff options
context:
space:
mode:
authorKarel Zak2006-12-07 00:26:14 +0100
committerKarel Zak2006-12-07 00:26:14 +0100
commitd03dd60840f0a08464d5266539ad356aefe24b03 (patch)
tree0a9ad240a7a88eb6b11b152974a7a51a0df79b75 /mount
parentImported from util-linux-2.12pre tarball. (diff)
downloadkernel-qcow2-util-linux-d03dd60840f0a08464d5266539ad356aefe24b03.tar.gz
kernel-qcow2-util-linux-d03dd60840f0a08464d5266539ad356aefe24b03.tar.xz
kernel-qcow2-util-linux-d03dd60840f0a08464d5266539ad356aefe24b03.zip
Imported from util-linux-2.12a tarball.
Diffstat (limited to 'mount')
-rw-r--r--mount/Makefile7
-rw-r--r--mount/fstab.c72
-rw-r--r--mount/fstab.h4
-rw-r--r--mount/h/loop.h37
-rw-r--r--mount/linux_fs.h36
-rw-r--r--mount/lomount.c367
-rw-r--r--mount/lomount.h9
-rw-r--r--mount/loop.h51
-rw-r--r--mount/losetup.884
-rw-r--r--mount/mk_loop_h34
-rw-r--r--mount/mount.833
-rw-r--r--mount/mount.c37
-rw-r--r--mount/mount_by_label.c26
-rw-r--r--mount/mount_guess_fstype.c28
-rw-r--r--mount/my_dev_t.h7
-rw-r--r--mount/pivot_root.297
-rw-r--r--mount/pivot_root.c15
-rw-r--r--mount/umount.c60
18 files changed, 565 insertions, 439 deletions
diff --git a/mount/Makefile b/mount/Makefile
index 5e5ca58a4..964349412 100644
--- a/mount/Makefile
+++ b/mount/Makefile
@@ -72,7 +72,7 @@ mount.o: $(LIB)/setproctitle.h
mount.o umount.o getusername.o: getusername.h
-mount.o umount.o losetup.o lomount.o: lomount.h loop.h
+mount.o umount.o losetup.o lomount.o: lomount.h loop.h my_dev_t.h
swapon.o: swap_constants.h swapargs.h
@@ -118,12 +118,9 @@ nfsmount.o: nfs_mount4.h
swapargs.h:
sh swap.configure
-loop.h:
- sh mk_loop_h
-
clean:
rm -f a.out core *~ *.o swapargs.h $(PROGS) $(MAYBE)
- rm -f loop.h nfs_mountversion.h
+ rm -f nfs_mountversion.h
clobber distclean realclean: clean
rm -f $(GEN_FILES)
diff --git a/mount/fstab.c b/mount/fstab.c
index 0d9b6e94f..85a5d2df3 100644
--- a/mount/fstab.c
+++ b/mount/fstab.c
@@ -100,7 +100,7 @@ read_mntentchn(mntFILE *mfp, const char *fnam, struct mntentchn *mc0) {
struct mntent *mnt;
while ((mnt = my_getmntent (mfp)) != NULL) {
- if (!streq (mnt->mnt_type, MNTTYPE_IGNORE)) {
+ if (!streq(mnt->mnt_type, MNTTYPE_IGNORE)) {
mc->nxt = (struct mntentchn *) xmalloc(sizeof(*mc));
mc->nxt->prev = mc;
mc = mc->nxt;
@@ -179,30 +179,62 @@ getmntfile (const char *name) {
mc0 = mtab_head();
for (mc = mc0->nxt; mc && mc != mc0; mc = mc->nxt)
- if (streq (mc->m.mnt_dir, name) ||
- streq (mc->m.mnt_fsname, name))
+ if (streq(mc->m.mnt_dir, name) ||
+ streq(mc->m.mnt_fsname, name))
return mc;
return NULL;
}
/*
- * Given the name NAME, and the place MCPREV we found it last time,
+ * Given the directory name NAME, and the place MCPREV we found it last time,
* try to find more occurrences.
*/
struct mntentchn *
-getmntfilesbackward (const char *name, struct mntentchn *mcprev) {
+getmntdirbackward (const char *name, struct mntentchn *mcprev) {
struct mntentchn *mc, *mc0;
mc0 = mtab_head();
if (!mcprev)
mcprev = mc0;
for (mc = mcprev->prev; mc && mc != mc0; mc = mc->prev)
- if (streq (mc->m.mnt_dir, name) ||
- streq (mc->m.mnt_fsname, name))
+ if (streq(mc->m.mnt_dir, name))
return mc;
return NULL;
}
+/*
+ * Given the device name NAME, and the place MCPREV we found it last time,
+ * try to find more occurrences.
+ */
+struct mntentchn *
+getmntdevbackward (const char *name, struct mntentchn *mcprev) {
+ struct mntentchn *mc, *mc0;
+
+ mc0 = mtab_head();
+ if (!mcprev)
+ mcprev = mc0;
+ for (mc = mcprev->prev; mc && mc != mc0; mc = mc->prev)
+ if (streq(mc->m.mnt_fsname, name))
+ return mc;
+ return NULL;
+}
+
+/*
+ * Given the name NAME, check that it occurs precisely once as dir or dev.
+ */
+int
+is_mounted_once(const char *name) {
+ struct mntentchn *mc, *mc0;
+ int ct = 0;
+
+ mc0 = mtab_head();
+ for (mc = mc0->prev; mc && mc != mc0; mc = mc->prev)
+ if (streq(mc->m.mnt_dir, name) ||
+ streq(mc->m.mnt_fsname, name))
+ ct++;
+ return (ct == 1);
+}
+
/* Given the name FILE, try to find the option "loop=FILE" in mtab. */
struct mntentchn *
getmntoptfile (const char *file) {
@@ -253,29 +285,29 @@ getfsspecfile (const char *spec, const char *file) {
/* first attempt: names occur precisely as given */
for (mc = mc0->nxt; mc && mc != mc0; mc = mc->nxt)
- if (streq (mc->m.mnt_dir, file) &&
- streq (mc->m.mnt_fsname, spec))
+ if (streq(mc->m.mnt_dir, file) &&
+ streq(mc->m.mnt_fsname, spec))
return mc;
/* second attempt: names found after symlink resolution */
for (mc = mc0->nxt; mc && mc != mc0; mc = mc->nxt)
- if ((streq (mc->m.mnt_dir, file) ||
- streq (canonicalize(mc->m.mnt_dir), file))
- && (streq (mc->m.mnt_fsname, spec) ||
- streq (canonicalize(mc->m.mnt_fsname), spec)))
+ if ((streq(mc->m.mnt_dir, file) ||
+ streq(canonicalize(mc->m.mnt_dir), file))
+ && (streq(mc->m.mnt_fsname, spec) ||
+ streq(canonicalize(mc->m.mnt_fsname), spec)))
return mc;
/* third attempt: names found after LABEL= or UUID= resolution */
for (mc = mc0->nxt; mc && mc != mc0; mc = mc->nxt) {
if (!strncmp (mc->m.mnt_fsname, "LABEL=", 6) &&
- (streq (mc->m.mnt_dir, file) ||
- streq (canonicalize(mc->m.mnt_dir), file))) {
+ (streq(mc->m.mnt_dir, file) ||
+ streq(canonicalize(mc->m.mnt_dir), file))) {
if (has_label(spec, mc->m.mnt_fsname+6))
return mc;
}
if (!strncmp (mc->m.mnt_fsname, "UUID=", 5) &&
- (streq (mc->m.mnt_dir, file) ||
- streq (canonicalize(mc->m.mnt_dir), file))) {
+ (streq(mc->m.mnt_dir, file) ||
+ streq(canonicalize(mc->m.mnt_dir), file))) {
if (has_uuid(spec, mc->m.mnt_fsname+5))
return mc;
}
@@ -290,7 +322,7 @@ getfsfile (const char *file) {
mc0 = fstab_head();
for (mc = mc0->nxt; mc && mc != mc0; mc = mc->nxt)
- if (streq (mc->m.mnt_dir, file))
+ if (streq(mc->m.mnt_dir, file))
return mc;
return NULL;
}
@@ -302,7 +334,7 @@ getfsspec (const char *spec) {
mc0 = fstab_head();
for (mc = mc0->nxt; mc && mc != mc0; mc = mc->nxt)
- if (streq (mc->m.mnt_fsname, spec))
+ if (streq(mc->m.mnt_fsname, spec))
return mc;
return NULL;
}
@@ -531,7 +563,7 @@ update_mtab (const char *dir, struct mntent *instead) {
/* find last occurrence of dir */
for (mc = mc0->prev; mc && mc != mc0; mc = mc->prev)
- if (streq (mc->m.mnt_dir, dir))
+ if (streq(mc->m.mnt_dir, dir))
break;
if (mc && mc != mc0) {
if (instead == NULL) {
diff --git a/mount/fstab.h b/mount/fstab.h
index 820f418a0..b55b6b5b6 100644
--- a/mount/fstab.h
+++ b/mount/fstab.h
@@ -12,6 +12,7 @@
int mtab_is_writable(void);
int mtab_does_not_exist(void);
int mtab_is_a_symlink(void);
+int is_mounted_once(const char *name);
struct mntentchn {
struct mntentchn *nxt, *prev;
@@ -21,7 +22,8 @@ struct mntentchn {
struct mntentchn *mtab_head (void);
struct mntentchn *getmntfile (const char *name);
struct mntentchn *getmntoptfile (const char *file);
-struct mntentchn *getmntfilesbackward (const char *file, struct mntentchn *mc);
+struct mntentchn *getmntdirbackward (const char *dir, struct mntentchn *mc);
+struct mntentchn *getmntdevbackward (const char *dev, struct mntentchn *mc);
struct mntentchn *fstab_head (void);
struct mntentchn *getfsfile (const char *file);
diff --git a/mount/h/loop.h b/mount/h/loop.h
deleted file mode 100644
index 1bd7fa87a..000000000
--- a/mount/h/loop.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * include/linux/loop.h
- *
- * Written by Theodore Ts'o, 3/29/93.
- *
- * Copyright 1993 by Theodore Ts'o. Redistribution of this file is
- * permitted under the GNU Public License.
- */
-
-#define LO_NAME_SIZE 64
-#define LO_KEY_SIZE 32
-
-struct loop_info {
- int lo_number; /* ioctl r/o */
- dev_t lo_device; /* ioctl r/o */
- unsigned long lo_inode; /* ioctl r/o */
- dev_t lo_rdevice; /* ioctl r/o */
- int lo_offset;
- int lo_encrypt_type;
- int lo_encrypt_key_size; /* ioctl w/o */
- int lo_flags; /* ioctl r/o */
- char lo_name[LO_NAME_SIZE];
- unsigned char lo_encrypt_key[LO_KEY_SIZE]; /* ioctl w/o */
- unsigned long lo_init[2];
- char reserved[4];
-};
-
-#define LO_CRYPT_NONE 0
-#define LO_CRYPT_XOR 1
-#define LO_CRYPT_DES 2
-#define LO_CRYPT_IDEA 3
-#define MAX_LO_CRYPT 4
-
-#define LOOP_SET_FD 0x4C00
-#define LOOP_CLR_FD 0x4C01
-#define LOOP_SET_STATUS 0x4C02
-#define LOOP_GET_STATUS 0x4C03
diff --git a/mount/linux_fs.h b/mount/linux_fs.h
index 874eb8fd3..485dbe84d 100644
--- a/mount/linux_fs.h
+++ b/mount/linux_fs.h
@@ -221,6 +221,42 @@ struct ocfs_volume_label {
#define ocfslabellen(o) assemble2le(o.label_len)
#define OCFS_MAGIC "OracleCFS"
+struct efs_volume_directory { /* size 16 */
+ char vd_name[8];
+ char vd_lbn[4];
+ char vd_nbytes[4];
+};
+
+struct efs_partition_table { /* size 12 */
+ char pt_nblks[4];
+ char pt_firstlbn[4];
+ char pt_type[4];
+};
+
+struct efs_volume_header { /* size 512 */
+ char vh_magic[4];
+ short vh_rootpt;
+ short vh_swappt;
+ char vh_bootfile[16];
+ char pad[48];
+ struct efs_volume_directory vh_vd[15];
+ struct efs_partition_table vh_pt[16];
+ int vh_csum;
+ int vh_fill;
+};
+
+struct efs_super {
+ char fs_stuff[512+28];
+ char fs_magic[4];
+ char fs_fname[6];
+ char fs_fpack[6];
+ /* ... */
+};
+
+#define EFS_VHMAGIC 0x0be5a941 /* big endian */
+#define EFS_SBMAGIC 0x00072959 /* idem */
+#define EFS_SBMAGIC2 0x0007295a /* idem */
+
static inline int
assemble2le(unsigned char *p) {
return (p[0] | (p[1] << 8));
diff --git a/mount/lomount.c b/mount/lomount.c
index 97cd9a092..0874f3ea0 100644
--- a/mount/lomount.c
+++ b/mount/lomount.c
@@ -2,13 +2,18 @@
/* Added vfs mount options - aeb - 960223 */
/* Removed lomount - aeb - 960224 */
-/* 1999-02-22 Arkadiusz Mi¶kiewicz <misiek@pld.ORG.PL>
+/*
+ * 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
+ * 2000-09-24 Marc Mutz <Marc@Mutz.com>
+ * - added -p option to pass passphrases via fd's to losetup/mount.
+ * Used for encryption in non-interactive environments.
+ * The idea behind xgetpass() is stolen from GnuPG, v.1.0.3.
*/
-#define PROC_DEVICES "/proc/devices"
+#define LOOPMAJOR 7
/*
* losetup.c - setup and control loop devices
@@ -36,93 +41,114 @@ extern char *xstrdup (const char *s); /* not: #include "sundries.h" */
extern void error (const char *fmt, ...); /* idem */
#ifdef LOOP_SET_FD
-struct crypt_type_struct {
- int id;
- char *name;
-} crypt_type_tbl[] = {
- { LO_CRYPT_NONE, "no" },
- { LO_CRYPT_NONE, "none" },
- { LO_CRYPT_XOR, "xor" },
- { LO_CRYPT_DES, "DES" },
- { -1, NULL }
-};
-
-static int
-crypt_type (const char *name) {
- int i;
-
- if (name) {
- for (i = 0; crypt_type_tbl[i].id != -1; i++)
- if (!strcasecmp (name, crypt_type_tbl[i].name))
- return crypt_type_tbl[i].id;
- }
- return -1;
+
+static int
+loop_info64_to_old(const struct loop_info64 *info64, struct loop_info *info)
+{
+ memset(info, 0, sizeof(*info));
+ info->lo_number = info64->lo_number;
+ info->lo_device = info64->lo_device;
+ info->lo_inode = info64->lo_inode;
+ info->lo_rdevice = info64->lo_rdevice;
+ info->lo_offset = info64->lo_offset;
+ info->lo_encrypt_type = info64->lo_encrypt_type;
+ info->lo_encrypt_key_size = info64->lo_encrypt_key_size;
+ info->lo_flags = info64->lo_flags;
+ info->lo_init[0] = info64->lo_init[0];
+ info->lo_init[1] = info64->lo_init[1];
+ if (info->lo_encrypt_type == LO_CRYPT_CRYPTOAPI)
+ memcpy(info->lo_name, info64->lo_crypt_name, LO_NAME_SIZE);
+ else
+ memcpy(info->lo_name, info64->lo_file_name, LO_NAME_SIZE);
+ memcpy(info->lo_encrypt_key, info64->lo_encrypt_key, LO_KEY_SIZE);
+
+ /* error in case values were truncated */
+ if (info->lo_device != info64->lo_device ||
+ info->lo_rdevice != info64->lo_rdevice ||
+ info->lo_inode != info64->lo_inode ||
+ info->lo_offset != info64->lo_offset)
+ return -EOVERFLOW;
+
+ return 0;
}
#ifdef MAIN
-static char *
-crypt_name (int id) {
- int i;
-
- for (i = 0; crypt_type_tbl[i].id != -1; i++)
- if (id == crypt_type_tbl[i].id)
- return crypt_type_tbl[i].name;
- return "undefined";
-}
static int
-show_loop (char *device) {
+show_loop(char *device) {
struct loop_info loopinfo;
- int fd;
+ struct loop_info64 loopinfo64;
+ int fd, errsv;
- if ((fd = open (device, O_RDONLY)) < 0) {
+ if ((fd = open(device, O_RDONLY)) < 0) {
int errsv = errno;
fprintf(stderr, _("loop: can't open device %s: %s\n"),
device, strerror (errsv));
return 2;
}
- if (ioctl (fd, LOOP_GET_STATUS, &loopinfo) < 0) {
- int errsv = errno;
- fprintf(stderr, _("loop: can't get info on device %s: %s\n"),
- device, strerror (errsv));
+
+ if (ioctl(fd, LOOP_GET_STATUS64, &loopinfo64) == 0) {
+
+ loopinfo64.lo_file_name[LO_NAME_SIZE-2] = '*';
+ loopinfo64.lo_file_name[LO_NAME_SIZE-1] = 0;
+ loopinfo64.lo_crypt_name[LO_NAME_SIZE-1] = 0;
+
+ printf("%s: [%04llx]:%llu (%s)",
+ device, loopinfo64.lo_device, loopinfo64.lo_inode,
+ loopinfo64.lo_file_name);
+
+ if (loopinfo64.lo_offset)
+ printf(_(", offset %lld"), loopinfo64.lo_offset);
+
+ if (loopinfo64.lo_sizelimit)
+ printf(_(", sizelimit %lld"), loopinfo64.lo_sizelimit);
+
+ if (loopinfo64.lo_encrypt_type ||
+ loopinfo64.lo_crypt_name[0]) {
+ char *e = loopinfo64.lo_crypt_name;
+
+ if (*e == 0 && loopinfo64.lo_encrypt_type == 1)
+ e = "XOR";
+ printf(_(", encryption %s (type %d)"),
+ e, loopinfo64.lo_encrypt_type);
+ }
+ printf("\n");
close (fd);
- return 1;
+ return 0;
}
- printf (_("%s: [%04x]:%ld (%s) offset %d, %s encryption\n"),
- device, loopinfo.lo_device, loopinfo.lo_inode,
- loopinfo.lo_name, loopinfo.lo_offset,
- crypt_name (loopinfo.lo_encrypt_type));
- close (fd);
- return 0;
+ if (ioctl(fd, LOOP_GET_STATUS, &loopinfo) == 0) {
+ printf ("%s: [%04x]:%ld (%s)",
+ device, loopinfo.lo_device, loopinfo.lo_inode,
+ loopinfo.lo_name);
+
+ if (loopinfo.lo_offset)
+ printf(_(", offset %d"), loopinfo.lo_offset);
+
+ if (loopinfo.lo_encrypt_type)
+ printf(_(", encryption type %d\n"),
+ loopinfo.lo_encrypt_type);
+
+ printf("\n");
+ close (fd);
+ return 0;
+ }
+
+ errsv = errno;
+ fprintf(stderr, _("loop: can't get info on device %s: %s\n"),
+ device, strerror (errsv));
+ close (fd);
+ return 1;
}
#endif
int
is_loop_device (const char *device) {
struct stat statbuf;
- int loopmajor;
-#if 1
- loopmajor = 7;
-#else
- FILE *procdev;
- char line[100], *cp;
-
- loopmajor = 0;
- if ((procdev = fopen(PROC_DEVICES, "r")) != NULL) {
- while (fgets (line, sizeof(line), procdev)) {
- if ((cp = strstr (line, " loop\n")) != NULL) {
- *cp='\0';
- loopmajor=atoi(line);
- break;
- }
- }
- fclose(procdev);
- }
-#endif
- return (loopmajor && stat(device, &statbuf) == 0 &&
+
+ return (stat(device, &statbuf) == 0 &&
S_ISBLK(statbuf.st_mode) &&
- major(statbuf.st_rdev) == loopmajor);
+ major(statbuf.st_rdev) == LOOPMAJOR);
}
#define SIZE(a) (sizeof(a)/sizeof(a[0]))
@@ -134,10 +160,9 @@ find_unused_loop_device (void) {
So, we just try /dev/loop[0-7]. */
char dev[20];
char *loop_formats[] = { "/dev/loop%d", "/dev/loop/%d" };
- int i, j, fd, somedev = 0, someloop = 0, loop_known = 0;
+ int i, j, fd, somedev = 0, someloop = 0;
struct stat statbuf;
struct loop_info loopinfo;
- FILE *procdev;
for (j = 0; j < SIZE(loop_formats); j++) {
for(i = 0; i < 256; i++) {
@@ -160,73 +185,103 @@ find_unused_loop_device (void) {
}
}
- /* Nothing found. Why not? */
- if ((procdev = fopen(PROC_DEVICES, "r")) != NULL) {
- char line[100];
- while (fgets (line, sizeof(line), procdev))
- if (strstr (line, " loop\n")) {
- loop_known = 1;
- break;
- }
- fclose(procdev);
- if (!loop_known)
- loop_known = -1;
- }
-
if (!somedev)
error(_("mount: could not find any device /dev/loop#"));
else if (!someloop) {
- if (loop_known == 1)
- error(_(
- "mount: Could not find any loop device.\n"
- " Maybe /dev/loop# has a wrong major number?"));
- else if (loop_known == -1)
- error(_(
- "mount: Could not find any loop device, and, according to %s,\n"
- " this kernel does not know about the loop device.\n"
- " (If so, then recompile or `insmod loop.o'.)"),
- PROC_DEVICES);
- else
error(_(
- "mount: Could not find any loop device. Maybe this kernel does not know\n"
- " about the loop device (then recompile or `insmod loop.o'), or\n"
- " maybe /dev/loop# has the wrong major number?"));
+ "mount: Could not find any loop device. Maybe this kernel "
+ "does not know\n"
+ " about the loop device? (If so, recompile or "
+ "`modprobe loop'.)"));
} else
error(_("mount: could not find any free loop device"));
return 0;
}
+/*
+ * A function to read the passphrase either from the terminal or from
+ * an open file descriptor.
+ */
+static char *
+xgetpass(int pfd, const char *prompt) {
+ char *pass;
+ int buflen, i;
+
+ if (pfd < 0) /* terminal */
+ return getpass(prompt);
+
+ pass = NULL;
+ buflen = 0;
+ for (i=0; ; i++) {
+ if (i >= buflen-1) {
+ /* we're running out of space in the buffer.
+ * Make it bigger: */
+ char *tmppass = pass;
+ buflen += 128;
+ pass = realloc(tmppass, buflen);
+ if (pass == NULL) {
+ /* realloc failed. Stop reading. */
+ error("Out of memory while reading passphrase");
+ pass = tmppass; /* the old buffer hasn't changed */
+ break;
+ }
+ }
+ if (read(pfd, pass+i, 1) != 1 || pass[i] == '\n')
+ break;
+ }
+ if (pass == NULL)
+ return "";
+ else {
+ pass[i] = 0;
+ return pass;
+ }
+}
+
+static int
+digits_only(const char *s) {
+ while (*s)
+ if (!isdigit(*s++))
+ return 0;
+ return 1;
+}
+
int
-set_loop (const char *device, const char *file, int offset,
- const char *encryption, int *loopro) {
- struct loop_info loopinfo;
- int fd, ffd, mode, i;
+set_loop(const char *device, const char *file, int offset,
+ const char *encryption, int pfd, int *loopro) {
+ struct loop_info64 loopinfo64;
+ int fd, ffd, mode;
char *pass;
mode = (*loopro ? O_RDONLY : O_RDWR);
- if ((ffd = open (file, mode)) < 0) {
+ if ((ffd = open(file, mode)) < 0) {
if (!*loopro && errno == EROFS)
- ffd = open (file, mode = O_RDONLY);
+ ffd = open(file, mode = O_RDONLY);
if (ffd < 0) {
- perror (file);
+ perror(file);
return 1;
}
}
- if ((fd = open (device, mode)) < 0) {
+ if ((fd = open(device, mode)) < 0) {
perror (device);
return 1;
}
*loopro = (mode == O_RDONLY);
- memset (&loopinfo, 0, sizeof (loopinfo));
- xstrncpy (loopinfo.lo_name, file, LO_NAME_SIZE);
- if (encryption && (loopinfo.lo_encrypt_type = crypt_type (encryption))
- < 0) {
- fprintf (stderr, _("Unsupported encryption type %s\n"),
- encryption);
- return 1;
+ memset(&loopinfo64, 0, sizeof(loopinfo64));
+
+ xstrncpy(loopinfo64.lo_file_name, file, LO_NAME_SIZE);
+
+ if (encryption && *encryption) {
+ if (digits_only(encryption)) {
+ loopinfo64.lo_encrypt_type = atoi(encryption);
+ } else {
+ loopinfo64.lo_encrypt_type = LO_CRYPT_CRYPTOAPI;
+ snprintf(loopinfo64.lo_crypt_name, LO_NAME_SIZE,
+ "%s", encryption);
+ }
}
- loopinfo.lo_offset = offset;
+
+ loopinfo64.lo_offset = offset;
#ifdef MCL_FUTURE
/*
@@ -241,53 +296,55 @@ set_loop (const char *device, const char *file, int offset,
}
#endif
- switch (loopinfo.lo_encrypt_type) {
+ switch (loopinfo64.lo_encrypt_type) {
case LO_CRYPT_NONE:
- loopinfo.lo_encrypt_key_size = 0;
+ loopinfo64.lo_encrypt_key_size = 0;
break;
case LO_CRYPT_XOR:
- pass = getpass (_("Password: "));
- xstrncpy (loopinfo.lo_encrypt_key, pass, LO_KEY_SIZE);
- loopinfo.lo_encrypt_key_size = strlen(loopinfo.lo_encrypt_key);
- break;
- case LO_CRYPT_DES:
- pass = getpass (_("Password: "));
- strncpy (loopinfo.lo_encrypt_key, pass, 8);
- loopinfo.lo_encrypt_key[8] = 0;
- loopinfo.lo_encrypt_key_size = 8;
- pass = getpass (_("Init (up to 16 hex digits): "));
- for (i = 0; i < 16 && pass[i]; i++)
- if (isxdigit (pass[i])) {
- loopinfo.lo_init[i >> 3] |= (pass[i] > '9' ?
- (islower (pass[i]) ? toupper (pass[i]) :
- pass[i])-'A'+10 : pass[i]-'0') << (i&7) * 4;
- } else {
- fprintf (stderr, _("Non-hex digit '%c'.\n"),
- pass[i]);
- return 1;
- }
+ pass = getpass(_("Password: "));
+ xstrncpy(loopinfo64.lo_encrypt_key, pass, LO_KEY_SIZE);
+ loopinfo64.lo_encrypt_key_size =
+ strlen(loopinfo64.lo_encrypt_key);
break;
default:
- fprintf (stderr,
- _("Don't know how to get key for encryption system %d\n"),
- loopinfo.lo_encrypt_type);
- return 1;
+ pass = xgetpass(pfd, _("Password: "));
+ xstrncpy(loopinfo64.lo_encrypt_key, pass, LO_KEY_SIZE);
+ loopinfo64.lo_encrypt_key_size = LO_KEY_SIZE;
}
- if (ioctl (fd, LOOP_SET_FD, ffd) < 0) {
- perror ("ioctl: LOOP_SET_FD");
+
+ if (ioctl(fd, LOOP_SET_FD, ffd) < 0) {
+ perror("ioctl: LOOP_SET_FD");
return 1;
}
- if (ioctl (fd, LOOP_SET_STATUS, &loopinfo) < 0) {
- (void) ioctl (fd, LOOP_CLR_FD, 0);
- perror ("ioctl: LOOP_SET_STATUS");
- return 1;
+ close (ffd);
+
+ if (ioctl(fd, LOOP_SET_STATUS64, &loopinfo64) < 0) {
+ struct loop_info loopinfo;
+ int errsv = errno;
+
+ errno = loop_info64_to_old(&loopinfo64, &loopinfo);
+ if (errno) {
+ errno = errsv;
+ perror("ioctl: LOOP_SET_STATUS64");
+ goto fail;
+ }
+
+ if (ioctl(fd, LOOP_SET_STATUS, &loopinfo) < 0) {
+ perror("ioctl: LOOP_SET_STATUS");
+ goto fail;
+ }
}
+
close (fd);
- close (ffd);
if (verbose > 1)
printf(_("set_loop(%s,%s,%d): success\n"),
device, file, offset);
return 0;
+
+ fail:
+ (void) ioctl (fd, LOOP_CLR_FD, 0);
+ close (fd);
+ return 1;
}
int
@@ -388,29 +445,34 @@ error (const char *fmt, ...) {
int
main(int argc, char **argv) {
- char *offset, *encryption;
- int delete,off,c;
+ char *offset, *encryption, *passfd;
+ int delete, off, c;
int res = 0;
int ro = 0;
+ int pfd = -1;
setlocale(LC_ALL, "");
bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE);
delete = off = 0;
- offset = encryption = NULL;
+ offset = encryption = passfd = NULL;
progname = argv[0];
- while ((c = getopt(argc,argv,"de:o:v")) != -1) {
+ while ((c = getopt(argc,argv,"de:E:o:p:v")) != -1) {
switch (c) {
case 'd':
delete = 1;
break;
+ case 'E':
case 'e':
encryption = optarg;
break;
case 'o':
offset = optarg;
break;
+ case 'p':
+ passfd = optarg;
+ break;
case 'v':
verbose = 1;
break;
@@ -430,7 +492,10 @@ main(int argc, char **argv) {
} else {
if (offset && sscanf(offset,"%d",&off) != 1)
usage();
- res = set_loop(argv[optind],argv[optind+1],off,encryption,&ro);
+ if (passfd && sscanf(passfd,"%d",&pfd) != 1)
+ usage();
+ res = set_loop(argv[optind], argv[optind+1], off,
+ encryption, pfd, &ro);
}
return res;
}
diff --git a/mount/lomount.h b/mount/lomount.h
index 1a93c693f..d81fc3b5a 100644
--- a/mount/lomount.h
+++ b/mount/lomount.h
@@ -1,5 +1,6 @@
extern int verbose;
-extern int set_loop (const char *, const char *, int, const char *, int *);
-extern int del_loop (const char *);
-extern int is_loop_device (const char *);
-extern char * find_unused_loop_device (void);
+extern int set_loop(const char *, const char *, int, const char *,
+ int, int *);
+extern int del_loop(const char *);
+extern int is_loop_device(const char *);
+extern char * find_unused_loop_device(void);
diff --git a/mount/loop.h b/mount/loop.h
new file mode 100644
index 000000000..951a5d183
--- /dev/null
+++ b/mount/loop.h
@@ -0,0 +1,51 @@
+#define LO_CRYPT_NONE 0
+#define LO_CRYPT_XOR 1
+#define LO_CRYPT_DES 2
+#define LO_CRYPT_CRYPTOAPI 18
+
+#define LOOP_SET_FD 0x4C00
+#define LOOP_CLR_FD 0x4C01
+#define LOOP_SET_STATUS 0x4C02
+#define LOOP_GET_STATUS 0x4C03
+#define LOOP_SET_STATUS64 0x4C04
+#define LOOP_GET_STATUS64 0x4C05
+
+#define LO_NAME_SIZE 64
+#define LO_KEY_SIZE 32
+
+#include "my_dev_t.h"
+
+struct loop_info {
+ int lo_number;
+ my_dev_t lo_device;
+ unsigned long lo_inode;
+ my_dev_t lo_rdevice;
+ int lo_offset;
+ int lo_encrypt_type;
+ int lo_encrypt_key_size;
+ int lo_flags;
+ char lo_name[LO_NAME_SIZE];
+ unsigned char lo_encrypt_key[LO_KEY_SIZE];
+ unsigned long lo_init[2];
+ char reserved[4];
+};
+
+/*
+ * Where to get __u8, __u32, __u64? Let us use unsigned char/int/long long
+ * and get punished when someone comes with 128-bit long longs.
+ */
+struct loop_info64 {
+ unsigned long long lo_device;
+ unsigned long long lo_inode;
+ unsigned long long lo_rdevice;
+ unsigned long long lo_offset;
+ unsigned long long lo_sizelimit; /* bytes, 0 == max available */
+ unsigned int lo_number;
+ unsigned int lo_encrypt_type;
+ unsigned int lo_encrypt_key_size;
+ unsigned int lo_flags;
+ unsigned char lo_file_name[LO_NAME_SIZE];
+ unsigned char lo_crypt_name[LO_NAME_SIZE];
+ unsigned char lo_encrypt_key[LO_KEY_SIZE];
+ unsigned long long lo_init[2];
+};
diff --git a/mount/losetup.8 b/mount/losetup.8
index d364f4f1e..9a42d70a0 100644
--- a/mount/losetup.8
+++ b/mount/losetup.8
@@ -1,15 +1,18 @@
-.TH LOSETUP 8 "Nov 24 1993" "Linux" "MAINTENANCE COMMANDS"
+.TH LOSETUP 8 "2003-07-01" "Linux" "MAINTENANCE COMMANDS"
.SH NAME
losetup \- set up and control loop devices
.SH SYNOPSIS
.ad l
.B losetup
[
-.B \-e
+.RB [ \-e | \-E ]
.I encryption
] [
.B \-o
.I offset
+] [
+.B \-p
+.I pfd
]
.I loop_device file
.br
@@ -25,27 +28,41 @@ is used to associate loop devices with regular files or block devices,
to detach loop devices and to query the status of a loop device. If only the
\fIloop_device\fP argument is given, the status of the corresponding loop
device is shown.
+
+.SS "Encryption"
+It is possible to specify transfer functions (for encryption/decryption
+or other purposes) using one of the
+.B \-E
+and
+.B \-e
+options.
+There are two mechanisms to specify the desired encryption: by number
+and by name. If an encryption is specified by number then one
+has to make sure that the Linux kernel knows about the encryption with that
+number, probably by patching the kernel. Standard numbers that are
+always present are 0 (no encryption) and 1 (XOR encryption).
+When the cryptoloop module is loaded (or compiled in), it uses number 18.
+This cryptoloop module wil take the name of an arbitrary encryption type
+and finds the module that knows how to perform that encryption.
+(Thus, either one uses a number different from 18 with the
+.B \-E
+option, or one uses a name with the
+.B \-e
+option.)
.SH OPTIONS
.IP \fB\-d\fP
-detach the file or device associated with the specified loop device.
-.IP "\fB\-e \fIencryption\fP"
-.RS
-enable data encryption. The following keywords are recognized:
-.IP \fBNONE\fP
-use no encryption (default).
-.PD 0
-.IP \fBXOR\fP
-use a simple XOR encryption.
-.IP \fBDES\fP
-use DES encryption. DES encryption is only available if the optional
-DES package has been added to the kernel. DES encryption uses an additional
-start value that is used to protect passwords against dictionary
-attacks.
-.PD
-.RE
+Detach the file or device associated with the specified loop device.
+.IP "\fB\-E \fIencryption_type\fP"
+Enable data encryption with specified number.
+.IP "\fB\-e \fIencryption_name\fP"
+Enable data encryption with specified name.
.IP "\fB\-o \fIoffset\fP"
-the data start is moved \fIoffset\fP bytes into the specified file or
+The data start is moved \fIoffset\fP bytes into the specified file or
device.
+.IP "\fB\-p \fInum\fP"
+Read the passphrase from file descriptor with number
+.I num
+instead of from the terminal.
.SH RETURN VALUE
.B losetup
returns 0 on success, nonzero on failure. When
@@ -57,7 +74,7 @@ from determining the status of the device.
.SH FILES
.nf
-/dev/loop0,/dev/loop1,... loop devices (major=7)
+/dev/loop0, /dev/loop1, ... loop devices (major=7)
.fi
.SH EXAMPLE
If you are using the loadable module you must have the module loaded
@@ -65,18 +82,23 @@ first with the command
.IP
# insmod loop.o
.LP
+Maybe also encryption modules are needed.
+.IP
+# insmod des.o
+# insmod cryptoloop.o
+.LP
The following commands can be used as an example of using the loop device.
.nf
.IP
-dd if=/dev/zero of=/file bs=1k count=100
-losetup -e des /dev/loop0 /file
+# dd if=/dev/zero of=/file bs=1k count=100
+# losetup -e des /dev/loop0 /file
Password:
Init (up to 16 hex digits):
-mkfs -t ext2 /dev/loop0 100
-mount -t ext2 /dev/loop0 /mnt
+# mkfs -t ext2 /dev/loop0 100
+# mount -t ext2 /dev/loop0 /mnt
...
-umount /dev/loop0
-losetup -d /dev/loop0
+# umount /dev/loop0
+# losetup -d /dev/loop0
.fi
.LP
If you are using the loadable module you may remove the module with
@@ -87,8 +109,8 @@ the command
.fi
.SH RESTRICTION
DES encryption is painfully slow. On the other hand, XOR is terribly weak.
-.SH AUTHORS
-.nf
-Original version: Theodore Ts'o <tytso@athena.mit.edu>
-Original DES by: Eric Young <eay@psych.psy.uq.oz.au>
-.fi
+.\" .SH AUTHORS
+.\" .nf
+.\" Original version: Theodore Ts'o <tytso@athena.mit.edu>
+.\" Original DES by: Eric Young <eay@psych.psy.uq.oz.au>
+.\" .fi
diff --git a/mount/mk_loop_h b/mount/mk_loop_h
deleted file mode 100644
index 86e76f35e..000000000
--- a/mount/mk_loop_h
+++ /dev/null
@@ -1,34 +0,0 @@
-#!/bin/sh
-#
-# Figure out (i) the type of dev_t (ii) the defines for loop stuff
-#
-
-rm -f loop.h
-
-# Since 1.3.79 there is an include file <asm/posix_types.h>
-# that defines __kernel_dev_t.
-# (The file itself appeared in 1.3.78, but there it defined __dev_t.)
-# If it exists, we use it, or, rather, <linux/posix_types.h> which
-# avoids namespace pollution. Otherwise we guess that __kernel_dev_t
-# is an unsigned short (which is true on i386, but false on alpha).
-
-if [ -f /usr/include/linux/posix_types.h ]; then
- echo '#include <linux/posix_types.h>' >> loop.h
- echo '#undef dev_t' >> loop.h
- echo '#define dev_t __kernel_dev_t' >> loop.h
-else
- echo '#undef dev_t' >> loop.h
- echo '#define dev_t unsigned short' >> loop.h
-fi
-
-# Next we have to find the loop stuff itself.
-# First try kernel source, then a private version.
-
-if [ -f /usr/include/linux/loop.h ]; then
- echo '#include <linux/loop.h>' >> loop.h
-else
- echo '#include "h/loop.h"' >> loop.h
-fi
-
-echo '#undef dev_t' >> loop.h
-
diff --git a/mount/mount.8 b/mount/mount.8
index 690b12dfd..ba547c660 100644
--- a/mount/mount.8
+++ b/mount/mount.8
@@ -118,6 +118,7 @@ a second place using
.B "mount --rbind olddir newdir"
.RE
.\" available since Linux 2.4.11.
+The mount options are not changed.
Since Linux 2.5.1 it is possible to atomically move a subtree
to another place. The call is
@@ -315,6 +316,12 @@ This is necessary for example when
.I /etc
is on a read-only file system.
.TP
+.BI \-p " num"
+In case of a loop mount with encryption, read the passphrase from
+file descriptor
+.I num
+instead of from the terminal.
+.TP
.B \-s
Tolerate sloppy mount options rather than failing. This will ignore
mount options not supported by a filesystem type. Not all filesystems
@@ -376,6 +383,7 @@ currently supported are:
.IR udf ,
.IR ufs ,
.IR umsdos ,
+.IR usbfs ,
.IR vfat ,
.IR xenix ,
.IR xfs ,
@@ -390,7 +398,10 @@ instead. Since kernel version 2.1.21 the types
.I ext
and
.I xiafs
-do not exist anymore.
+do not exist anymore. Earlier,
+.I usbfs
+was known as
+.IR usbdevfs .
For most types all the
.B mount
@@ -1479,6 +1490,9 @@ For filesystems created by SunOS or Solaris on Sparc.
.B sunx86
For filesystems created by Solaris on x86.
.TP
+.B hp
+For filesystems created by HP-UX, read-only.
+.TP
.B nextstep
For filesystems created by NeXTStep (on NeXT station) (currently read only).
.TP
@@ -1556,7 +1570,7 @@ the short name is not all upper case.
.I win95
Force the short name to upper case upon display; store a long name when
the short name is not all upper case.
-. TP
+.TP
.I winnt
Display the shortname as is; store a long name when the short name is
not all lower case or all upper case.
@@ -1568,6 +1582,21 @@ all upper case.
The default is "lower".
+.SH "Mount options for usbfs"
+.TP
+\fBdevuid=\fP\fIuid\fP and \fBdevgid=\fP\fIgid\fP and \fBdevmode=\fP\fImode\fP
+Set the owner and group and mode of the device files in the usbfs file system
+(default: uid=gid=0, mode=0644). The mode is given in octal.
+.TP
+\fBbusuid=\fP\fIuid\fP and \fBbusgid=\fP\fIgid\fP and \fBbusmode=\fP\fImode\fP
+Set the owner and group and mode of the bus directories in the usbfs
+file system (default: uid=gid=0, mode=0555). The mode is given in octal.
+.TP
+\fBlistuid=\fP\fIuid\fP and \fBlistgid=\fP\fIgid\fP and \fBlistmode=\fP\fImode\fP
+Set the owner and group and mode of the file
+.I devices
+(default: uid=gid=0, mode=0444). The mode is given in octal.
+
.SH "Mount options for xenix"
None.
diff --git a/mount/mount.c b/mount/mount.c
index 04a3cd74e..227de5607 100644
--- a/mount/mount.c
+++ b/mount/mount.c
@@ -113,6 +113,9 @@ static int mounttype = 0;
/* True if ruid != euid. */
static int suid = 0;
+/* Contains the fd to read the passphrase from, if any. */
+static int pfd = -1;
+
/* Map from -o and fstab option strings to the flag argument to mount(2). */
struct opt_map {
const char *opt; /* option name */
@@ -601,7 +604,8 @@ loop_check(char **spec, char **type, int *flags,
if (verbose)
printf(_("mount: going to use the loop device %s\n"), *loopdev);
offset = opt_offset ? strtoul(opt_offset, NULL, 0) : 0;
- if (set_loop (*loopdev, *loopfile, offset, opt_encryption, &loopro)) {
+ if (set_loop(*loopdev, *loopfile, offset,
+ opt_encryption, pfd, &loopro)) {
if (verbose)
printf(_("mount: failed setting up loop device\n"));
return EX_FAIL;
@@ -660,6 +664,14 @@ update_mtab_entry(char *spec, char *node, char *type, char *opts,
}
static void
+set_pfd(char *s) {
+ if (!isdigit(*s))
+ die(EX_USAGE,
+ _("mount: argument to -p or --pass-fd must be a number"));
+ pfd = atoi(optarg);
+}
+
+static void
cdrom_setspeed(char *spec) {
#define CDROM_SELECT_SPEED 0x5322 /* Set the CD-ROM speed */
if (opt_speed) {
@@ -768,7 +780,7 @@ try_mount_one (const char *spec0, const char *node0, char *types0,
if (mount_all && (flags & MS_NOAUTO))
return 0;
- suid_check (spec, node, &flags, &user);
+ suid_check(spec, node, &flags, &user);
mount_opts = extra_opts;
@@ -776,11 +788,12 @@ try_mount_one (const char *spec0, const char *node0, char *types0,
cdrom_setspeed(spec);
if (!(flags & MS_REMOUNT)) {
- /* don't set up a (new) loop device if we only remount - this left
+ /*
+ * Don't set up a (new) loop device if we only remount - this left
* stale assignments of files to loop devices. Nasty when used for
* encryption.
*/
- res = loop_check (&spec, &types, &flags, &loop, &loopdev, &loopfile);
+ res = loop_check(&spec, &types, &flags, &loop, &loopdev, &loopfile);
if (res)
return res;
}
@@ -841,7 +854,7 @@ retry_nfs:
#ifdef HAVE_NFS
if (mnt_err && types && streq (types, "nfs")) {
- if (nfs_mount_version == 4) {
+ if (nfs_mount_version == 4 && mnt_err != EBUSY && mnt_err != ENOENT) {
if (verbose)
printf(_("mount: failed with nfs mount version 4, trying 3..\n"));
nfs_mount_version = 3;
@@ -912,7 +925,7 @@ retry_nfs:
break;
case EINVAL:
{ int fd;
- long size;
+ unsigned long size;
int warned=0;
if (flags & MS_REMOUNT) {
@@ -922,9 +935,9 @@ retry_nfs:
" or too many mounted file systems"),
spec);
- if (stat (spec, &statbuf) == 0 && S_ISBLK(statbuf.st_mode)
+ if (stat(spec, &statbuf) == 0 && S_ISBLK(statbuf.st_mode)
&& (fd = open(spec, O_RDONLY | O_NONBLOCK)) >= 0) {
- if(ioctl(fd, BLKGETSIZE, &size) == 0) {
+ if (ioctl(fd, BLKGETSIZE, &size) == 0) {
if (size == 0) {
warned++;
error (" (could this be the IDE device where you in fact use\n"
@@ -1357,6 +1370,7 @@ static struct option longopts[] = {
{ "rw", 0, 0, 'w' },
{ "options", 1, 0, 'o' },
{ "test-opts", 1, 0, 'O' },
+ { "pass-fd", 1, 0, 'p' },
{ "types", 1, 0, 't' },
{ "bind", 0, 0, 128 },
{ "replace", 0, 0, 129 },
@@ -1394,7 +1408,7 @@ usage (FILE *fp, int n) {
" mount --move olddir newdir\n"
"A device can be given by name, say /dev/hda1 or /dev/cdrom,\n"
"or by label, using -L label or by uuid, using -U uuid .\n"
- "Other options: [-nfFrsvw] [-o options].\n"
+ "Other options: [-nfFrsvw] [-o options] [-p passwdfd].\n"
"For many more details, say man 8 mount .\n"
));
/*
@@ -1433,7 +1447,7 @@ main (int argc, char *argv[]) {
initproctitle(argc, argv);
#endif
- while ((c = getopt_long (argc, argv, "afFhilL:no:O:rsU:vVwt:",
+ while ((c = getopt_long (argc, argv, "afFhilL:no:O:p:rsU:vVwt:",
longopts, NULL)) != -1) {
switch (c) {
case 'a': /* mount everything in fstab */
@@ -1472,6 +1486,9 @@ main (int argc, char *argv[]) {
else
test_opts = xstrdup(optarg);
break;
+ case 'p': /* fd on which to read passwd */
+ set_pfd(optarg);
+ break;
case 'r': /* mount readonly */
readonly = 1;
readwrite = 0;
diff --git a/mount/mount_by_label.c b/mount/mount_by_label.c
index 524ec7ca9..54170e56f 100644
--- a/mount/mount_by_label.c
+++ b/mount/mount_by_label.c
@@ -139,24 +139,26 @@ uuidcache_init_evms(void) {
* special devices for the xfs filesystem external log & realtime device.
*/
-/*
- * XVM support - Eric Sandeen
- * Return 1 if this looks like an xvm device that should be scanned
- */
+/* Return 1 if this looks like an xvm device that should be scanned */
static int
is_xvm(char *ptname)
{
+ int len;
+
+ /* if it doesn't start with "xvm," we're done. */
+ if (strncmp(ptname, "xvm", 3))
+ return 0;
+
+ len = strlen(ptname);
/*
- * Scan anything with "xvm" and "data" in its name.
- * That might pick up non-data xvm subvols if the
- * volumename contains the string 'data' but
- * that should be harmless.
+ * check for "log/block" or "rt/block" on the end,
+ * these are special - don't scan.
*/
+ if (!strncmp(ptname+(len-9), "log/block", 9) ||
+ !strncmp(ptname+(len-8), "rt/block", 8))
+ return 0;
- if (strstr(ptname, "xvm") && strstr(ptname, "data"))
- return 1;
-
- return 0;
+ return 1;
}
static void
diff --git a/mount/mount_guess_fstype.c b/mount/mount_guess_fstype.c
index f23cfc84b..e8829ce04 100644
--- a/mount/mount_guess_fstype.c
+++ b/mount/mount_guess_fstype.c
@@ -71,7 +71,7 @@ swapped(unsigned short a) {
Corrected the test for xiafs - aeb
Read the superblock only once - aeb
Added a very weak heuristic for vfat - aeb
- Added iso9660, minix-v2, romfs, qnx4, udf, vxfs, swap - aeb
+ Added efs, iso9660, minix-v2, romfs, qnx4, udf, vxfs, swap - aeb
Added a test for high sierra (iso9660) - quinlan@bucknell.edu
Added ufs from a patch by jj. But maybe there are several types of ufs?
Added ntfs from a patch by Richard Russon.
@@ -84,7 +84,7 @@ swapped(unsigned short a) {
*/
static char
*magic_known[] = {
- "adfs", "bfs", "cramfs", "ext", "ext2", "ext3",
+ "adfs", "bfs", "cramfs", "efs", "ext", "ext2", "ext3",
"hfs", "hpfs", "iso9660", "jfs", "minix", "ntfs",
"qnx4", "reiserfs", "romfs", "swap", "sysv", "udf", "ufs",
"vxfs", "xfs", "xiafs"
@@ -229,12 +229,6 @@ do_guess_fstype(const char *device) {
int fd;
char *type = NULL;
union {
- struct minix_super_block ms;
- struct ext_super_block es;
- struct ext2_super_block e2s;
- struct vxfs_super_block vs;
- } sb; /* stuff at 1024 */
- union {
struct xiafs_super_block xiasb;
char romfs_magic[8];
char qnx4fs_magic[10]; /* ignore first 4 bytes */
@@ -243,7 +237,15 @@ do_guess_fstype(const char *device) {
struct fat_super_block fatsb;
struct xfs_super_block xfsb;
struct cramfs_super_block cramfssb;
- } xsb;
+ struct efs_volume_header efsvh;
+ struct efs_super efssb;
+ } xsb; /* stuff at 0 */
+ union {
+ struct minix_super_block ms;
+ struct ext_super_block es;
+ struct ext2_super_block e2s;
+ struct vxfs_super_block vs;
+ } sb; /* stuff at 1024 */
struct ufs_super_block ufssb;
union {
struct iso_volume_descriptor iso;
@@ -294,9 +296,17 @@ do_guess_fstype(const char *device) {
else if(cramfsmagic(xsb.cramfssb) == CRAMFS_SUPER_MAGIC ||
cramfsmagic(xsb.cramfssb) == CRAMFS_SUPER_MAGIC_BE)
type = "cramfs";
+ else if (assemble4be(xsb.efsvh.vh_magic) == EFS_VHMAGIC)
+ type = "efs"; /* EFS volume header */
+ /* might check checksum here */
+ else if (assemble4be(xsb.efssb.fs_magic) == EFS_SBMAGIC ||
+ assemble4be(xsb.efssb.fs_magic) == EFS_SBMAGIC2)
+ type = "efs"; /* EFS partition */
else if ((!strncmp(xsb.fatsb.s_os, "MSDOS", 5) ||
!strncmp(xsb.fatsb.s_os, "MSWIN", 5) ||
!strncmp(xsb.fatsb.s_os, "MTOOL", 5) ||
+ !strncmp(xsb.fatsb.s_os, "IBM", 3) ||
+ !strncmp(xsb.fatsb.s_os, "DRDOS", 5) ||
!strncmp(xsb.fatsb.s_os, "mkdosfs", 7) ||
!strncmp(xsb.fatsb.s_os, "kmkdosfs", 8) ||
/* Michal Svec: created by fdformat, old msdos utility for
diff --git a/mount/my_dev_t.h b/mount/my_dev_t.h
new file mode 100644
index 000000000..5ef97154e
--- /dev/null
+++ b/mount/my_dev_t.h
@@ -0,0 +1,7 @@
+/* silliness to get dev_t defined as the kernel defines it */
+/* glibc uses a different dev_t */
+/* maybe we need __kernel_old_dev_t -- later */
+/* for ancient systems use "unsigned short" */
+
+#include <linux/posix_types.h>
+#define my_dev_t __kernel_dev_t
diff --git a/mount/pivot_root.2 b/mount/pivot_root.2
deleted file mode 100644
index 1c8f168a7..000000000
--- a/mount/pivot_root.2
+++ /dev/null
@@ -1,97 +0,0 @@
-.TH PIVOT_ROOT 2 "Feb 23, 2000" "Linux" "System Calls"
-.SH NAME
-pivot_root \- change the root file system
-.SH SYNOPSIS
-.B #include <linux/unistd.h>
-.sp
-.B _syscall2(int,pivot_root,const char *,new_root,const char *,put_old)
-.sp
-.BI "int pivot_root(const char *" new_root ", const char *" put_old );
-.SH DESCRIPTION
-\fBpivot_root\fP moves the root file system of the current process to the
-directory \fIput_old\fP and makes \fInew_root\fP the new root file system
-of the current process.
-
-The typical use of \fBpivot_root\fP is during system startup, when the
-system mounts a temporary root file system (e.g. an \fBinitrd\fP), then
-mounts the real root file system, and eventually turns the latter into
-the current root of all relevant processes or threads.
-
-\fBpivot_root\fP may or may not change the current root and the current
-working directory (cwd) of any processes or threads which use the old
-root directory. The caller of \fBpivot_root\fP
-must ensure that processes with root or cwd at the old root operate
-correctly in either case. An easy way to ensure this is to change their
-root and cwd to \fInew_root\fP before invoking \fBpivot_root\fP.
-
-The paragraph above is intentionally vague because the implementation
-of \fBpivot_root\fP may change in the future. At the time of writing,
-\fBpivot_root\fP changes root and cwd of each process or
-thread to \fInew_root\fP if they point to the old root directory. This
-is necessary in order to prevent kernel threads from keeping the old
-root directory busy with their root and cwd, even if they never access
-the file system in any way. In the future, there may be a mechanism for
-kernel threads to explicitly relinquish any access to the file system,
-such that this fairly intrusive mechanism can be removed from
-\fBpivot_root\fP.
-
-Note that this also applies to the current process: \fBpivot_root\fP may
-or may not affect its cwd. It is therefore recommended to call
-\fBchdir("/")\fP immediately after \fBpivot_root\fP.
-
-The following restrictions apply to \fInew_root\fP and \fIput_old\fP:
-.IP \- 3
-They must be directories.
-.IP \- 3
-\fInew_root\fP and \fIput_old\fP must not be on the same file system as
-the current root.
-.IP \- 3
-\fIput_old\fP must be underneath \fInew_root\fP, i.e. adding a non-zero
-number of \fB/..\fP to the string pointed to by \fIput_old\fP must yield
-the same directory as \fInew_root\fP.
-.IP \- 3
-No other file system may be mounted on \fIput_old\fP.
-.PP
-See also \fBpivot_root(8)\fP for additional usage examples.
-
-If the current root is not a mount point (e.g. after \fBchroot(2)\fP or
-\fBpivot_root\fP, see also below), not the old root directory, but the
-mount point of that file system is mounted on \fIput_old\fP.
-.SH NOTES
-\fInew_root\fP does not have to be a mount point. In this case,
-\fB/proc/mounts\fP will show the mount point of the file system containing
-\fInew_root\fP as root (\fB/\fP).
-.SH "RETURN VALUE"
-On success, zero is returned. On error, \-1 is returned, and
-\fIerrno\fP is set appropriately.
-.SH ERRORS
-\fBpivot_root\fP may return (in \fIerrno\fP) any of the errors returned by
-\fBstat(2)\fP. Additionally, it may return:
-
-.TP
-.B EBUSY
-\fInew_root\fP or \fIput_old\fP are on the current root file system,
-or a file system is already mounted on \fIput_old\fP.
-.TP
-.B EINVAL
-\fIput_old\fP is not underneath \fInew_root\fP.
-.TP
-.B ENOTDIR
-\fInew_root\fP or \fIput_old\fP is not a directory.
-.TP
-.B EPERM
-The current process does not have the administrator capability.
-.SH BUGS
-\fBpivot_root\fP should not have to change root and cwd of all other
-processes in the system.
-
-Some of the more obscure uses of \fBpivot_root\fP may quickly lead to
-insanity.
-.SH HISTORY
-\fBpivot_root\fP was introduced in Linux 2.3.41.
-.SH "SEE ALSO"
-.BR chdir(2),
-.BR chroot(2),
-.BR initrd(4),
-.BR pivot_root(8),
-.BR stat(2)
diff --git a/mount/pivot_root.c b/mount/pivot_root.c
index a844b480e..ba2dbbed0 100644
--- a/mount/pivot_root.c
+++ b/mount/pivot_root.c
@@ -3,14 +3,17 @@
/* Written 2000 by Werner Almesberger */
#include <stdio.h>
-#include <errno.h> /* needed for <linux/unistd.h> below */
+#include <sys/syscall.h>
+#include <unistd.h>
-#ifdef __ia64__
-# include <sys/syscall.h>
-# define pivot_root(new_root,put_old) syscall(SYS_pivot_root,new_root,put_old)
-#else
-# include <linux/unistd.h>
+#define pivot_root(new_root,put_old) syscall(SYS_pivot_root,new_root,put_old)
+#if 0
+/*
+ * With kernelheaders 2.3.41 or later, and ancient libc, try the following.
+ */
+#include <errno.h>
+#include <linux/unistd.h>
static
_syscall2(int,pivot_root,const char *,new_root,const char *,put_old)
#endif
diff --git a/mount/umount.c b/mount/umount.c
index 29feff4fa..1b6c1cf27 100644
--- a/mount/umount.c
+++ b/mount/umount.c
@@ -279,7 +279,9 @@ umount_one (const char *spec, const char *node, const char *type,
if (force) { /* only supported for NFS */
res = umount2 (node, MNT_FORCE);
if (res == -1) {
+ int errsv = errno;
perror("umount2");
+ errno = errsv;
if (errno == ENOSYS) {
if (verbose)
printf(_("no umount2, trying umount...\n"));
@@ -400,15 +402,23 @@ umount_one (const char *spec, const char *node, const char *type,
* In both cases, it is best to try the last occurrence first.
*/
static int
-umount_one_bw (const char *file, struct mntentchn *mc) {
- int res = 1;
-
- while (res && mc) {
- res = umount_one(mc->m.mnt_fsname, mc->m.mnt_dir,
- mc->m.mnt_type, mc->m.mnt_opts, mc);
- mc = getmntfilesbackward (file, mc);
- }
- return res;
+umount_one_bw (const char *file, struct mntentchn *mc0) {
+ struct mntentchn *mc;
+ int res = 1;
+
+ mc = mc0;
+ while (res && mc) {
+ res = umount_one(mc->m.mnt_fsname, mc->m.mnt_dir,
+ mc->m.mnt_type, mc->m.mnt_opts, mc);
+ mc = getmntdirbackward(file, mc);
+ }
+ mc = mc0;
+ while (res && mc) {
+ res = umount_one(mc->m.mnt_fsname, mc->m.mnt_dir,
+ mc->m.mnt_type, mc->m.mnt_opts, mc);
+ mc = getmntdevbackward(file, mc);
+ }
+ return res;
}
/* Unmount all filesystems of type VFSTYPES found in mtab. Since we are
@@ -525,7 +535,6 @@ get_value(string_list list, char *s) {
}
return 0;
}
-/*=======================================================================*/
static int
umount_file (char *arg) {
@@ -534,19 +543,27 @@ umount_file (char *arg) {
string_list options;
int fstab_has_user, fstab_has_users, fstab_has_owner, ok;
- file = canonicalize (arg); /* mtab paths are canonicalized */
+ file = canonicalize(arg); /* mtab paths are canonicalized */
if (verbose > 1)
printf(_("Trying to umount %s\n"), file);
- mc = getmntfilesbackward (file, NULL);
+ mc = getmntdirbackward(file, NULL);
+ if (!mc)
+ mc = getmntdevbackward(file, NULL);
if (!mc && verbose)
printf(_("Could not find %s in mtab\n"), file);
if (suid) {
+ char *mtab_user = NULL;
+
if (!mc)
- die (2, _("umount: %s is not mounted (according to mtab)"), file);
- if (getmntfilesbackward (file, mc))
- die (2, _("umount: it seems %s is mounted multiple times"), file);
+ die(2,
+ _("umount: %s is not mounted (according to mtab)"),
+ file);
+ if (!is_mounted_once(file))
+ die(2,
+ _("umount: it seems %s is mounted multiple times"),
+ file);
/* If fstab contains the two lines
/dev/sda1 /mnt/zip auto user,noauto 0 0
@@ -558,10 +575,12 @@ umount_file (char *arg) {
if (!fs) {
if (!getfsspec (file) && !getfsfile (file))
die (2,
- _("umount: %s is not in the fstab (and you are not root)"),
+ _("umount: %s is not in the fstab "
+ "(and you are not root)"),
file);
else
- die (2, _("umount: %s mount disagrees with the fstab"), file);
+ die (2, _("umount: %s mount disagrees with "
+ "the fstab"), file);
}
/* User mounting and unmounting is allowed only
@@ -586,7 +605,6 @@ umount_file (char *arg) {
if (!ok && (fstab_has_user || fstab_has_owner)) {
char *user = getusername();
- char *mtab_user;
options = parse_list (mc->m.mnt_opts);
mtab_user = get_value(options, "user=");
@@ -595,7 +613,8 @@ umount_file (char *arg) {
ok = 1;
}
if (!ok)
- die (2, _("umount: only root can unmount %s from %s"),
+ die (2, _("umount: only %s can unmount %s from %s"),
+ mtab_user ? mtab_user : "root",
fs->m.mnt_fsname, fs->m.mnt_dir);
}
@@ -673,8 +692,9 @@ main (int argc, char *argv[]) {
argv += optind;
if (all) {
+ /* nodev stuff: sysfs, usbfs, oprofilefs, ... */
if (types == NULL)
- types = "noproc,nodevfs";
+ types = "noproc,nodevfs,nodevpts";
result = umount_all (types, test_opts);
} else if (argc < 1) {
usage (stderr, 2);