Signed-off-by: Karel Zak --- mount/Makefile.am | 8 ++-- mount/fsprobe.h | 12 +++++ mount/fsprobe_blkid.c | 111 ++++++++++++++++++++++++++++++++++++++++++++ mount/fstab.c | 2 +- mount/mount.c | 2 +- mount/mount_blkid.c | 111 -------------------------------------------- mount/mount_blkid.h | 12 ----- mount/mount_guess_fstype.c | 2 +- mount/swapon.c | 2 +- 9 files changed, 131 insertions(+), 131 deletions(-) diff --git a/mount/Makefile.am b/mount/Makefile.am index 95db3dd..930a0bf 100644 --- a/mount/Makefile.am +++ b/mount/Makefile.am @@ -7,13 +7,13 @@ sbin_PROGRAMS = losetup swapon man_MANS = fstab.5 mount.8 swapoff.8 swapon.8 umount.8 losetup.8 MNTHDRS = fstab.h linux_fs.h mount_mntent.h mount_constants.h my_dev_t.h \ - mount_paths.h get_label_uuid.h lomount.h mount_blkid.h \ + mount_paths.h get_label_uuid.h lomount.h fsprobe.h \ mount_guess_fstype.h realpath.h xmalloc.h \ getusername.h loop.h mount_by_label.h mount_guess_rootdev.h \ sundries.h mount_SOURCES = mount.c fstab.c sundries.c xmalloc.c realpath.c mount_mntent.c \ - get_label_uuid.c mount_by_label.c mount_blkid.c mount_guess_fstype.c \ + get_label_uuid.c mount_by_label.c fsprobe_blkid.c mount_guess_fstype.c \ getusername.c \ lomount.c \ $(MNTHDRS) @@ -22,7 +22,7 @@ mount_LDADD = $(top_srcdir)/lib/libenv.a $(top_srcdir)/lib/libsetproctitle.a mount_CFLAGS = $(SUID_CFLAGS) umount_SOURCES = umount.c fstab.c sundries.c xmalloc.c realpath.c mount_mntent.c \ - getusername.c get_label_uuid.c mount_by_label.c mount_blkid.c \ + getusername.c get_label_uuid.c mount_by_label.c fsprobe_blkid.c \ lomount.c \ $(MNTHDRS) @@ -30,7 +30,7 @@ umount_LDADD = $(top_srcdir)/lib/libenv.a umount_CFLAGS = $(SUID_CFLAGS) swapon_SOURCES = swapon.c xmalloc.c \ - get_label_uuid.c mount_by_label.c mount_blkid.c \ + get_label_uuid.c mount_by_label.c fsprobe_blkid.c \ swap_constants.h realpath.c losetup_SOURCES = lomount.c loop.h lomount.h diff --git a/mount/fsprobe.h b/mount/fsprobe.h new file mode 100644 index 0000000..c96ff8c --- /dev/null +++ b/mount/fsprobe.h @@ -0,0 +1,12 @@ +#ifdef HAVE_LIBBLKID +#include +extern blkid_cache blkid; +#endif + +extern void mount_blkid_get_cache(void); +extern void mount_blkid_put_cache(void); +extern const char *mount_get_devname_by_uuid(const char *uuid); +extern const char *mount_get_devname_by_label(const char *label); +extern const char *mount_get_volume_label_by_spec(const char *spec); +extern const char *mount_get_devname(const char *spec); +extern const char *mount_get_devname_for_mounting(const char *spec); diff --git a/mount/fsprobe_blkid.c b/mount/fsprobe_blkid.c new file mode 100644 index 0000000..0616945 --- /dev/null +++ b/mount/fsprobe_blkid.c @@ -0,0 +1,111 @@ +#include +#include "fsprobe.h" + +#ifdef HAVE_LIBBLKID + +blkid_cache blkid; + +void +mount_blkid_get_cache(void) { + blkid_get_cache(&blkid, NULL); +} + +void +mount_blkid_put_cache(void) { + blkid_put_cache(blkid); +} + +const char * +mount_get_volume_label_by_spec(const char *spec) { + return blkid_get_tag_value(blkid, "LABEL", spec); +} + +const char * +mount_get_devname(const char *spec) { + return blkid_get_devname(blkid, spec, 0); +} + +const char * +mount_get_devname_by_uuid(const char *uuid) { + return blkid_get_devname(blkid, "UUID", uuid); +} + +const char * +mount_get_devname_by_label(const char *label) { + return blkid_get_devname(blkid, "LABEL", label); +} + +/* Also when no UUID= or LABEL= occur? No verbose? No warnings? */ +const char * +mount_get_devname_for_mounting(const char *spec) { + return blkid_get_devname(blkid, spec, 0); +} + +#else +#include +#include "sundries.h" +#include "mount_by_label.h" +#include "nls.h" + +void +mount_blkid_get_cache(void) { +} + +void +mount_blkid_put_cache(void) { +} + +const char * +mount_get_volume_label_by_spec(const char *spec) { + return xstrdup(get_volume_label_by_spec(spec)); +} + +const char * +mount_get_devname(const char *spec) { + if (!strncmp(spec, "UUID=", 5)) + return get_spec_by_uuid(spec+5); + if (!strncmp(spec, "LABEL=", 6)) + return get_spec_by_volume_label(spec+6); + return spec; +} + +const char * +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; + + spec = get_spec_by_volume_label(volumelabel); + spec2 = second_occurrence_of_vol_label(volumelabel); + if (spec2) + die (EX_FAIL, + _("%s: error: the label %s occurs on both %s and %s\n"), + progname, volumelabel, spec, spec2); + return spec; +} + +const char * +mount_get_devname_for_mounting(const char *spec) { + const char *nspec; + + if (!strncmp(spec, "UUID=", 5)) { + nspec = mount_get_devname_by_uuid(spec+5); + if (nspec && verbose > 1) + printf(_("mount: going to mount %s by UUID\n"), spec); + } else if (!strncmp(spec, "LABEL=", 6)) { + nspec = mount_get_devname_by_label(spec+6); + if (nspec && verbose > 1) + printf(_("mount: going to mount %s by label\n"), spec); + } else + nspec = spec; + + return nspec; +} + + +#endif diff --git a/mount/fstab.c b/mount/fstab.c index 72c46f3..5267f62 100644 --- a/mount/fstab.c +++ b/mount/fstab.c @@ -15,7 +15,7 @@ #include "fstab.h" #include "sundries.h" #include "xmalloc.h" -#include "mount_blkid.h" +#include "fsprobe.h" #include "mount_paths.h" #include "nls.h" diff --git a/mount/mount.c b/mount/mount.c index 5058a7e..dfa44dc 100644 --- a/mount/mount.c +++ b/mount/mount.c @@ -29,7 +29,7 @@ #include #endif -#include "mount_blkid.h" +#include "fsprobe.h" #include "mount_constants.h" #include "sundries.h" #include "xmalloc.h" diff --git a/mount/mount_blkid.c b/mount/mount_blkid.c deleted file mode 100644 index 8fa30a1..0000000 --- a/mount/mount_blkid.c +++ /dev/null @@ -1,111 +0,0 @@ -#include -#include "mount_blkid.h" - -#ifdef HAVE_LIBBLKID - -blkid_cache blkid; - -void -mount_blkid_get_cache(void) { - blkid_get_cache(&blkid, NULL); -} - -void -mount_blkid_put_cache(void) { - blkid_put_cache(blkid); -} - -const char * -mount_get_volume_label_by_spec(const char *spec) { - return blkid_get_tag_value(blkid, "LABEL", spec); -} - -const char * -mount_get_devname(const char *spec) { - return blkid_get_devname(blkid, spec, 0); -} - -const char * -mount_get_devname_by_uuid(const char *uuid) { - return blkid_get_devname(blkid, "UUID", uuid); -} - -const char * -mount_get_devname_by_label(const char *label) { - return blkid_get_devname(blkid, "LABEL", label); -} - -/* Also when no UUID= or LABEL= occur? No verbose? No warnings? */ -const char * -mount_get_devname_for_mounting(const char *spec) { - return blkid_get_devname(blkid, spec, 0); -} - -#else -#include -#include "sundries.h" -#include "mount_by_label.h" -#include "nls.h" - -void -mount_blkid_get_cache(void) { -} - -void -mount_blkid_put_cache(void) { -} - -const char * -mount_get_volume_label_by_spec(const char *spec) { - return xstrdup(get_volume_label_by_spec(spec)); -} - -const char * -mount_get_devname(const char *spec) { - if (!strncmp(spec, "UUID=", 5)) - return get_spec_by_uuid(spec+5); - if (!strncmp(spec, "LABEL=", 6)) - return get_spec_by_volume_label(spec+6); - return spec; -} - -const char * -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; - - spec = get_spec_by_volume_label(volumelabel); - spec2 = second_occurrence_of_vol_label(volumelabel); - if (spec2) - die (EX_FAIL, - _("%s: error: the label %s occurs on both %s and %s\n"), - progname, volumelabel, spec, spec2); - return spec; -} - -const char * -mount_get_devname_for_mounting(const char *spec) { - const char *nspec; - - if (!strncmp(spec, "UUID=", 5)) { - nspec = mount_get_devname_by_uuid(spec+5); - if (nspec && verbose > 1) - printf(_("mount: going to mount %s by UUID\n"), spec); - } else if (!strncmp(spec, "LABEL=", 6)) { - nspec = mount_get_devname_by_label(spec+6); - if (nspec && verbose > 1) - printf(_("mount: going to mount %s by label\n"), spec); - } else - nspec = spec; - - return nspec; -} - - -#endif diff --git a/mount/mount_blkid.h b/mount/mount_blkid.h deleted file mode 100644 index c96ff8c..0000000 --- a/mount/mount_blkid.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifdef HAVE_LIBBLKID -#include -extern blkid_cache blkid; -#endif - -extern void mount_blkid_get_cache(void); -extern void mount_blkid_put_cache(void); -extern const char *mount_get_devname_by_uuid(const char *uuid); -extern const char *mount_get_devname_by_label(const char *label); -extern const char *mount_get_volume_label_by_spec(const char *spec); -extern const char *mount_get_devname(const char *spec); -extern const char *mount_get_devname_for_mounting(const char *spec); diff --git a/mount/mount_guess_fstype.c b/mount/mount_guess_fstype.c index f1637f1..51d8750 100644 --- a/mount/mount_guess_fstype.c +++ b/mount/mount_guess_fstype.c @@ -38,7 +38,7 @@ #include #include #include "linux_fs.h" -#include "mount_blkid.h" +#include "fsprobe.h" #include "mount_guess_fstype.h" #include "sundries.h" /* for xstrdup */ #include "nls.h" diff --git a/mount/swapon.c b/mount/swapon.c index b6bcd75..af4ba96 100644 --- a/mount/swapon.c +++ b/mount/swapon.c @@ -15,7 +15,7 @@ #include "swap_constants.h" #include "swapargs.h" #include "nls.h" -#include "mount_blkid.h" +#include "fsprobe.h" #include "mount_by_label.h" #include "realpath.h" -- 1.5.0.6 - To unsubscribe from this list: send the line "unsubscribe util-linux-ng" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html This patch removes old FS detection code and enables blkid code only when HAVE_BLKID is defined. Signed-off-by: Karel Zak --- mount/Makefile.am | 12 +- mount/fsprobe_blkid.c | 67 ------- mount/get_label_uuid.c | 221 ---------------------- mount/get_label_uuid.h | 1 - mount/linux_fs.h | 292 ----------------------------- mount/mount.c | 1 - mount/mount_by_label.c | 363 ------------------------------------ mount/mount_by_label.h | 4 - mount/mount_guess_fstype.c | 434 -------------------------------------------- mount/swapon.c | 1 - 10 files changed, 7 insertions(+), 1389 deletions(-) diff --git a/mount/Makefile.am b/mount/Makefile.am index 930a0bf..6f63dcf 100644 --- a/mount/Makefile.am +++ b/mount/Makefile.am @@ -7,13 +7,13 @@ sbin_PROGRAMS = losetup swapon man_MANS = fstab.5 mount.8 swapoff.8 swapon.8 umount.8 losetup.8 MNTHDRS = fstab.h linux_fs.h mount_mntent.h mount_constants.h my_dev_t.h \ - mount_paths.h get_label_uuid.h lomount.h fsprobe.h \ + mount_paths.h lomount.h fsprobe.h \ mount_guess_fstype.h realpath.h xmalloc.h \ - getusername.h loop.h mount_by_label.h mount_guess_rootdev.h \ + getusername.h loop.h mount_guess_rootdev.h \ sundries.h mount_SOURCES = mount.c fstab.c sundries.c xmalloc.c realpath.c mount_mntent.c \ - get_label_uuid.c mount_by_label.c fsprobe_blkid.c mount_guess_fstype.c \ + mount_guess_fstype.c \ getusername.c \ lomount.c \ $(MNTHDRS) @@ -22,7 +22,7 @@ mount_LDADD = $(top_srcdir)/lib/libenv.a $(top_srcdir)/lib/libsetproctitle.a mount_CFLAGS = $(SUID_CFLAGS) umount_SOURCES = umount.c fstab.c sundries.c xmalloc.c realpath.c mount_mntent.c \ - getusername.c get_label_uuid.c mount_by_label.c fsprobe_blkid.c \ + getusername.c \ lomount.c \ $(MNTHDRS) @@ -30,13 +30,15 @@ umount_LDADD = $(top_srcdir)/lib/libenv.a umount_CFLAGS = $(SUID_CFLAGS) swapon_SOURCES = swapon.c xmalloc.c \ - get_label_uuid.c mount_by_label.c fsprobe_blkid.c \ swap_constants.h realpath.c losetup_SOURCES = lomount.c loop.h lomount.h losetup_CFLAGS = -DMAIN if HAVE_BLKID +mount_SOURCES += fsprobe_blkid.c +umount_SOURCES += fsprobe_blkid.c +swapon_SOURCES += fsprobe_blkid.c mount_LDADD += -lblkid -luuid umount_LDADD += -lblkid -luuid swapon_LDADD = -lblkid -luuid diff --git a/mount/fsprobe_blkid.c b/mount/fsprobe_blkid.c index 0616945..9ff4e31 100644 --- a/mount/fsprobe_blkid.c +++ b/mount/fsprobe_blkid.c @@ -41,71 +41,4 @@ mount_get_devname_for_mounting(const char *spec) { return blkid_get_devname(blkid, spec, 0); } -#else -#include -#include "sundries.h" -#include "mount_by_label.h" -#include "nls.h" - -void -mount_blkid_get_cache(void) { -} - -void -mount_blkid_put_cache(void) { -} - -const char * -mount_get_volume_label_by_spec(const char *spec) { - return xstrdup(get_volume_label_by_spec(spec)); -} - -const char * -mount_get_devname(const char *spec) { - if (!strncmp(spec, "UUID=", 5)) - return get_spec_by_uuid(spec+5); - if (!strncmp(spec, "LABEL=", 6)) - return get_spec_by_volume_label(spec+6); - return spec; -} - -const char * -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; - - spec = get_spec_by_volume_label(volumelabel); - spec2 = second_occurrence_of_vol_label(volumelabel); - if (spec2) - die (EX_FAIL, - _("%s: error: the label %s occurs on both %s and %s\n"), - progname, volumelabel, spec, spec2); - return spec; -} - -const char * -mount_get_devname_for_mounting(const char *spec) { - const char *nspec; - - if (!strncmp(spec, "UUID=", 5)) { - nspec = mount_get_devname_by_uuid(spec+5); - if (nspec && verbose > 1) - printf(_("mount: going to mount %s by UUID\n"), spec); - } else if (!strncmp(spec, "LABEL=", 6)) { - nspec = mount_get_devname_by_label(spec+6); - if (nspec && verbose > 1) - printf(_("mount: going to mount %s by label\n"), spec); - } else - nspec = spec; - - return nspec; -} - - #endif diff --git a/mount/get_label_uuid.c b/mount/get_label_uuid.c deleted file mode 100644 index 6d92e07..0000000 --- a/mount/get_label_uuid.c +++ /dev/null @@ -1,221 +0,0 @@ -#ifndef HAVE_LIBBLKID -/* - * Get label. Used by mount, umount and swapon. - */ -#include -#include -#include -#include -#include - -#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. - * If so, it probably is, or has been, part of a RAID array. - * - * For the moment this test is switched off - it causes problems. - * "Checking for a disk label should only be done on the full raid, - * not on the disks that form the raid array. This test causes a lot of - * problems when run on my striped promise fasttrak 100 array." - */ -static inline int -is_raid_partition(int fd) { -#if 0 - 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); -#else - return 0; -#endif -} - -int -reiserfs_magic_version(const char *magic) { - int rc = 0; - - if (!strncmp(magic, REISERFS_SUPER_MAGIC_STRING, - strlen(REISERFS_SUPER_MAGIC_STRING))) - rc = 1; - if (!strncmp(magic, REISER2FS_SUPER_MAGIC_STRING, - strlen(REISER2FS_SUPER_MAGIC_STRING))) - rc = 2; - if (!strncmp(magic, REISER3FS_SUPER_MAGIC_STRING, - strlen(REISER3FS_SUPER_MAGIC_STRING))) - rc = 3; - 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, swap are supported - * - * Return 0 on success. - */ -int -get_label_uuid(const char *device, char **label, char *uuid) { - int fd; - struct ext2_super_block e2sb; - struct xfs_super_block xfsb; - struct jfs_super_block jfssb; - struct ocfs_volume_header ovh; /* Oracle */ - 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 -1; - - /* If there is a RAID partition, or an error, ignore this partition */ - if (is_raid_partition(fd)) { - 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)) { - store_uuid(uuid, e2sb.s_uuid); - store_label(label, e2sb.s_volume_name, - sizeof(e2sb.s_volume_name)); - goto done; - } - - if (lseek(fd, 0, SEEK_SET) == 0 - && read(fd, (char *) &xfsb, sizeof(xfsb)) == sizeof(xfsb) - && (strncmp(xfsb.s_magic, XFS_SUPER_MAGIC, 4) == 0)) { - store_uuid(uuid, xfsb.s_uuid); - store_label(label, xfsb.s_fname, sizeof(xfsb.s_fname)); - goto done; - } - - 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)) { - store_uuid(uuid, NULL); - store_label(label, olbl.label, ocfslabellen(olbl)); - goto done; - } - - 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)) { - -/* The situation for jfs is rather messy. The structure of the - superblock changed a few times, but there seems to be no good way - to check what kind of sb we have. - Old (OS/2 compatible) jfs filesystems don't have UUIDs and have - an 11-byte label in s_fpack[]. - Kernel 2.5.6 supports jfs v1; 2.5.8 supports v2; 2.5.18 has label/uuid. - Kernel 2.4.20 supports jfs v2 with label/uuid. - s_version will be 2 for new filesystems using an external log. - Other new filesystems will have version 1. - Label and UUID can be set by jfs_tune. */ - -/* Let us believe label/uuid on v2, and on v1 only when label agrees - with s_fpack in the first 11 bytes. */ - - if (assemble4le(jfssb.s_version) == 1 && - strncmp(jfssb.s_label, jfssb.s_fpack, 11) != 0) { - store_uuid(uuid, NULL); - store_label(label, jfssb.s_fpack, - sizeof(jfssb.s_fpack)); - } else { - store_uuid(uuid, jfssb.s_uuid); - store_label(label, jfssb.s_label, - sizeof(jfssb.s_label)); - } - goto done; - } - - 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. */ - && reiserfs_magic_version(reiserfssb.s_magic) > 1) { - store_uuid(uuid, reiserfssb.s_uuid); - store_label(label, reiserfssb.s_label, - sizeof(reiserfssb.s_label)); - goto done; - } - - 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; -} -#endif diff --git a/mount/get_label_uuid.h b/mount/get_label_uuid.h deleted file mode 100644 index f52cc52..0000000 --- a/mount/get_label_uuid.h +++ /dev/null @@ -1 +0,0 @@ -int get_label_uuid(const char *device, char **label, char *uuid); diff --git a/mount/linux_fs.h b/mount/linux_fs.h index 430cbed..e47da2f 100644 --- a/mount/linux_fs.h +++ b/mount/linux_fs.h @@ -13,295 +13,3 @@ #endif #endif -#define MINIX_SUPER_MAGIC 0x137F /* minix v1, 14 char names */ -#define MINIX_SUPER_MAGIC2 0x138F /* minix v1, 30 char names */ -#define MINIX2_SUPER_MAGIC 0x2468 /* minix v2, 14 char names */ -#define MINIX2_SUPER_MAGIC2 0x2478 /* minix v2, 30 char names */ -struct minix_super_block { - u_char s_dummy[16]; - u_char s_magic[2]; -}; -#define minixmagic(s) assemble2le(s.s_magic) - -#define ISODCL(from, to) (to - from + 1) -#define ISO_STANDARD_ID "CD001" -struct iso_volume_descriptor { - char type[ISODCL(1,1)]; /* 711 */ - char id[ISODCL(2,6)]; - char version[ISODCL(7,7)]; - char data[ISODCL(8,2048)]; -}; - -#define HS_STANDARD_ID "CDROM" -struct hs_volume_descriptor { - char foo[ISODCL ( 1, 8)]; /* 733 */ - char type[ISODCL ( 9, 9)]; /* 711 */ - char id[ISODCL ( 10, 14)]; - char version[ISODCL ( 15, 15)]; /* 711 */ - char data[ISODCL(16,2048)]; -}; - -#define EXT_SUPER_MAGIC 0x137D -struct ext_super_block { - u_char s_dummy[56]; - u_char s_magic[2]; -}; -#define extmagic(s) assemble2le(s.s_magic) - -#define EXT2_PRE_02B_MAGIC 0xEF51 -#define EXT2_SUPER_MAGIC 0xEF53 -#define EXT3_FEATURE_COMPAT_HAS_JOURNAL 0x0004 -struct ext2_super_block { - u_char s_dummy1[56]; - u_char s_magic[2]; - u_char s_dummy2[34]; - u_char s_feature_compat[4]; - u_char s_feature_incompat[4]; - u_char s_feature_ro_compat[4]; - u_char s_uuid[16]; - u_char s_volume_name[16]; - u_char s_dummy3[88]; - u_char s_journal_inum[4]; /* ext3 only */ -}; -#define ext2magic(s) assemble2le(s.s_magic) - -struct reiserfs_super_block -{ - u_char s_block_count[4]; - u_char s_free_blocks[4]; - u_char s_root_block[4]; - u_char s_journal_block[4]; - u_char s_journal_dev[4]; - u_char s_orig_journal_size[4]; - u_char s_journal_trans_max[4]; - u_char s_journal_block_count[4]; - u_char s_journal_max_batch[4]; - u_char s_journal_max_commit_age[4]; - u_char s_journal_max_trans_age[4]; - u_char s_blocksize[2]; - u_char s_oid_maxsize[2]; - u_char s_oid_cursize[2]; - u_char s_state[2]; - u_char s_magic[10]; - u_char s_dummy1[10]; - u_char s_version[2]; /* only valid with relocated journal */ - - /* only valid in 3.6.x format --mason@suse.com */ - u_char s_dummy2[10]; - u_char s_uuid[16]; - u_char s_label[16]; -}; -#define REISERFS_SUPER_MAGIC_STRING "ReIsErFs" -#define REISER2FS_SUPER_MAGIC_STRING "ReIsEr2Fs" -/* also known as REISER2FS_JR_SUPER_MAGIC_STRING */ -#define REISER3FS_SUPER_MAGIC_STRING "ReIsEr3Fs" -#define REISERFS_DISK_OFFSET_IN_BYTES (64 * 1024) -/* the spot for the super in versions 3.5 - 3.5.10 (inclusive) */ -#define REISERFS_OLD_DISK_OFFSET_IN_BYTES (8 * 1024) - -/* values of s_version when REISER3FS_SUPER_MAGIC_STRING is found */ -#define REISERFS_VERSION_1 0 /* 3.5.x disk format */ -#define REISERFS_VERSION_2 2 /* 3.6.x disk format */ - -extern int reiserfs_magic_version(const char *magic); - -#define _XIAFS_SUPER_MAGIC 0x012FD16D -struct xiafs_super_block { - u_char s_boot_segment[512]; /* 1st sector reserved for boot */ - u_char s_dummy[60]; - u_char s_magic[4]; -}; -#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 -#define UFS_SUPER_MAGIC_BE 0x54190100 -struct ufs_super_block { - u_char s_dummy[0x55c]; - u_char s_magic[4]; -}; -#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" -struct ntfs_super_block { - u_char s_dummy[3]; - u_char s_magic[4]; -}; - -/* From inspection of a few FAT filesystems - aeb */ -/* Unfortunately I find almost the same thing on an extended partition; - it looks like a primary has some directory entries where the extended - has a partition table: IO.SYS, MSDOS.SYS, WINBOOT.SYS */ -struct fat_super_block { - u_char s_dummy[3]; - u_char s_os[8]; /* "MSDOS5.0" or "MSWIN4.0" or "MSWIN4.1" */ - /* mtools-3.9.4 writes "MTOOL394" */ - u_char s_dummy2[32]; - u_char s_label[11]; /* for DOS? */ - u_char s_fs[8]; /* "FAT12 " or "FAT16 " or all zero */ - /* OS/2 BM has "FAT " here. */ - u_char s_dummy3[9]; - u_char s_label2[11]; /* for Windows? */ - u_char s_fs2[8]; /* garbage or "FAT32 " */ -}; - -#define XFS_SUPER_MAGIC "XFSB" -struct xfs_super_block { - u_char s_magic[4]; - u_char s_dummy[28]; - u_char s_uuid[16]; - u_char s_dummy2[60]; - u_char s_fname[12]; -}; - -#define CRAMFS_SUPER_MAGIC 0x28cd3d45 -#define CRAMFS_SUPER_MAGIC_BE 0x453dcd28 -struct cramfs_super_block { - u_char s_magic[4]; - u_char s_dummy[12]; - u_char s_id[16]; -}; -#define cramfsmagic(s) assemble4le(s.s_magic) - -#define HFS_SUPER_MAGIC 0x4244 -struct hfs_super_block { - u_char s_magic[2]; /* drSigWord */ - u_char s_dummy[18]; - u_char s_blksize[4]; /* drAlBlkSiz */ -}; -#define hfsmagic(s) assemble2be(s.s_magic) -#define hfsblksize(s) assemble4be(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) assemble4le(s.s_magic) - -struct adfs_super_block { - u_char s_dummy[448]; - u_char s_blksize[1]; - u_char s_dummy2[62]; - u_char s_checksum[1]; -}; -#define adfsblksize(s) ((uint) s.s_blksize[0]) - -/* found in first 4 bytes of block 1 */ -struct vxfs_super_block { - u_char s_magic[4]; -}; -#define vxfsmagic(s) assemble4le(s.s_magic) -#define VXFS_SUPER_MAGIC 0xa501FCF5 - -struct jfs_super_block { - char s_magic[4]; - u_char s_version[4]; - u_char s_dummy1[93]; - char s_fpack[11]; - u_char s_dummy2[24]; - u_char s_uuid[16]; - char s_label[16]; -}; -#define JFS_SUPER1_OFF 0x8000 -#define JFS_MAGIC "JFS1" - -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) - -struct ocfs_volume_header { - u_char minor_version[4]; - u_char major_version[4]; - u_char signature[128]; -}; - -struct ocfs_volume_label { - u_char disk_lock[48]; - u_char label[64]; - u_char label_len[2]; -}; - -#define ocfslabellen(o) assemble2le(o.label_len) -#define OCFS_MAGIC "OracleCFS" - -struct ocfs2_super_block { - u_char signature[8]; - u_char s_dummy1[184]; - u_char s_dummy2[80]; - u_char s_label[64]; - u_char s_uuid[16]; -}; - -#define OCFS2_MIN_BLOCKSIZE 512 -#define OCFS2_MAX_BLOCKSIZE 4096 -#define OCFS2_SUPER_BLOCK_BLKNO 2 -#define OCFS2_SUPER_BLOCK_SIGNATURE "OCFSV2" - - -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)); -} - -static inline int -assemble2be(unsigned char *p) { - return (p[1] | (p[0] << 8)); -} - -static inline int -assemble4le(unsigned char *p) { - return (p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24)); -} - -static inline int -assemble4be(unsigned char *p) { - return (p[3] | (p[2] << 8) | (p[1] << 16) | (p[0] << 24)); -} diff --git a/mount/mount.c b/mount/mount.c index dfa44dc..309e41e 100644 --- a/mount/mount.c +++ b/mount/mount.c @@ -40,7 +40,6 @@ #include "linux_fs.h" /* for BLKGETSIZE */ #include "mount_guess_rootdev.h" #include "mount_guess_fstype.h" -#include "mount_by_label.h" #include "getusername.h" #include "mount_paths.h" #include "env.h" diff --git a/mount/mount_by_label.c b/mount/mount_by_label.c deleted file mode 100644 index 4899f03..0000000 --- a/mount/mount_by_label.c +++ /dev/null @@ -1,363 +0,0 @@ -#ifndef HAVE_LIBBLKID -/* - * mount_by_label.c - aeb - * - * 1999-02-22 Arkadiusz Mi¶kiewicz - * - added Native Language Support - * 2000-01-20 James Antill - * - Added error message if /proc/partitions cannot be opened - * 2000-05-09 Erik Troan - * - Added cache for UUID and disk labels - * 2000-11-07 Nathan Scott - * - Added XFS support - * 2001-11-22 Kirby Bohling - * - Added support of labels on LVM - * 2002-03-21 Christoph Hellwig - * - Added JFS support - * 2002-07-11 Christoph Hellwig - * - Added JFS v2 format support - * 2002-07-26 Luciano Chavez - * - Added EVMS support - */ - -#include -#include -#include -#include -#include -#include -#include /* needed for opendir */ -#include -#include "sundries.h" /* for xstrdup */ -#include "linux_fs.h" -#include "get_label_uuid.h" -#include "mount_by_label.h" -#include "nls.h" - -#define PROC_PARTITIONS "/proc/partitions" -#define DEVLABELDIR "/dev" -#define VG_DIR "/proc/lvm/VGs" -#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]; - char *label; - char *device; -} *uuidCache = NULL; - -static void -uuidcache_addentry(char *device, char *label, char *uuid) { - struct uuidCache_s *last; - - if (!uuidCache) { - last = uuidCache = malloc(sizeof(*uuidCache)); - } else { - for (last = uuidCache; last->next; last = last->next); - last->next = malloc(sizeof(*uuidCache)); - last = last->next; - } - last->next = NULL; - last->device = device; - last->label = label; - memcpy(last->uuid, uuid, sizeof(last->uuid)); -} - -/* LVM support - Kirby Bohling */ -static void -uuidcache_init_lvm(void) { - char buffer[PATH_MAX]; - char lvm_device[PATH_MAX]; - DIR *vg_dir, *lv_list; - struct dirent *vg_iter, *lv_iter; - char uuid[16], *label; - - vg_dir = opendir(VG_DIR); - if (vg_dir == NULL) /* to be expected */ - return; - - seekdir(vg_dir, 2); - while ((vg_iter = readdir(vg_dir)) != 0) { - sprintf(buffer, "%s/%s/LVs", VG_DIR, vg_iter->d_name); - lv_list = opendir(buffer); - if (lv_list == NULL) { - perror("uuidcache_init_lvm"); - continue; - } - seekdir(lv_list, 2); - while ((lv_iter = readdir(lv_list)) != 0) { - /* Now we have the file.. could open it and read out - * where the device is, read the first line, second - * field... Instead we guess. - */ - sprintf(lvm_device, "%s/%s/%s", DEVLABELDIR, - vg_iter->d_name, lv_iter->d_name); - if (!get_label_uuid(lvm_device, &label, uuid)) - uuidcache_addentry(xstrdup(lvm_device), - label, uuid); - } - closedir(lv_list); - } - closedir(vg_dir); -} - -static int -uuidcache_init_evms(void) { - FILE *procvol; - char *label; - char uuid[16]; - char volname[EVMS_VOLUME_NAME_SIZE+1]; - char line[EVMS_VOLUME_NAME_SIZE+80]; - - procvol = fopen(PROC_EVMS_VOLUMES, "r"); - if (!procvol) - return 0; - - while (fgets(line, sizeof(line), procvol)) { - if (sscanf(line, "%*d %*d %*d %*s %*s %[^\n]", volname) == 1) { - if (!get_label_uuid(volname, &label, uuid)) - uuidcache_addentry(xstrdup(volname), label, uuid); - } - } - - fclose(procvol); - - return 1; -} - -/* - * xvm is a proprietary sgi volume manager, it goes into /proc/partitions - * like this: - * - * 4 0 2210817 xvm/local/vol/myvolume/data/block - * 4 1 2210817 xvm/local/vol/myvolume/rt/block - * 4 2 2210817 xvm/local/vol/myvolume/log/block - * 4 3 2210818 xvm/local/vol/discs3/data/block - * - * The heuristics here are that the device should start with "xvm," - * but should not end in "log/block" or "rt/block" - those are - * special devices for the xfs filesystem external log & realtime device. - */ - -/* 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); - /* - * 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; - - return 1; -} - -static void -uuidcache_init(void) { - char line[100]; - char *s; - int ma, mi, sz; - static char ptname[100]; - FILE *procpt; - char uuid[16], *label; - char device[110]; - int firstPass; - int handleOnFirst; -#if 0 - char iobuf[32*1024]; /* For setvbuf */ -#endif - - if (uuidCache) - return; - - if (uuidcache_init_evms()) - return; - - procpt = fopen(PROC_PARTITIONS, "r"); - if (!procpt) { - static int warn = 0; - if (!warn++) - error (_("%s: could not open %s, so UUID and LABEL " - "conversion cannot be done.\n"), - progname, PROC_PARTITIONS); - return; - } -#if 0 -/* Ugly kludge - the contents of /proc/partitions change in time, - and this causes failures when the file is not read in one go. - In particular, one cannot use stdio on /proc/partitions. - Doing this ourselves is not easy either, since stat returns 0 - so the size is unknown. We might try increasing buffer sizes - until a single read gets all. For now only pick a largish buffer size. */ -/* All these troubles are mainly caused by people who patch the kernel - to keep statistics in /proc/partitions. Of course, statistics belong - in some /proc/diskstats, not in some /proc file that happened to - exist already. */ - - setvbuf(procpt, iobuf, _IOFBF, sizeof(iobuf)); -#endif - - for (firstPass = 1; firstPass >= 0; firstPass--) { - fseek(procpt, 0, SEEK_SET); - - while (fgets(line, sizeof(line), procpt)) { - if (!index(line, '\n')) - break; - - if (sscanf (line, " %d %d %d %[^\n ]", - &ma, &mi, &sz, ptname) != 4) - continue; - - /* skip extended partitions (heuristic: size 1) */ - if (sz == 1) - continue; - - /* look only at md devices on first pass */ - handleOnFirst = !strncmp(ptname, "md", 2); - if (firstPass != handleOnFirst) - continue; - - /* skip entire disk (minor 0, 64, ... on ide; - 0, 16, ... on sd) */ - /* heuristic: partition name ends in a digit */ - /* devfs has .../disc and .../part1 etc. */ - - for (s = ptname; *s; s++); - if (isdigit(s[-1]) || is_xvm(ptname)) { - - /* - * Note: this is a heuristic only - there is no reason - * why these devices should live in /dev. - * Perhaps this directory should be specifiable by option. - * One might for example have /devlabel with links to /dev - * for the devices that may be accessed in this way. - * (This is useful, if the cdrom on /dev/hdc must not - * be accessed.) - */ - sprintf(device, "%s/%s", DEVLABELDIR, ptname); - if (!get_label_uuid(device, &label, uuid)) - uuidcache_addentry(xstrdup(device), label, uuid); - } - } - } - - fclose(procpt); - - uuidcache_init_lvm(); -} - -#define UUID 1 -#define VOL 2 - -static const char * -get_spec_by_x(int n, const char *t) { - struct uuidCache_s *uc; - - uuidcache_init(); - uc = uuidCache; - - while (uc) { - switch (n) { - case UUID: - if (!memcmp(t, uc->uuid, sizeof(uc->uuid))) - return xstrdup(uc->device); - break; - case VOL: - if (uc->label && !strcmp(t, uc->label)) - return xstrdup(uc->device); - break; - } - uc = uc->next; - } - return NULL; -} - -static u_char -fromhex(char c) { - if (isdigit(c)) - return (c - '0'); - else if (islower(c)) - return (c - 'a' + 10); - else - return (c - 'A' + 10); -} - -const char * -get_spec_by_uuid(const char *s) { - u_char uuid[16]; - int i; - - if (strlen(s) != 36 || - s[8] != '-' || s[13] != '-' || s[18] != '-' || s[23] != '-') - goto bad_uuid; - for (i=0; i<16; i++) { - if (*s == '-') s++; - if (!isxdigit(s[0]) || !isxdigit(s[1])) - goto bad_uuid; - uuid[i] = ((fromhex(s[0])<<4) | fromhex(s[1])); - s += 2; - } - return get_spec_by_x(UUID, uuid); - - bad_uuid: - die(EX_USAGE, _("%s: bad UUID"), progname); - return NULL; /* just for gcc */ -} - -const char * -get_spec_by_volume_label(const char *s) { - return get_spec_by_x(VOL, s); -} - -const char * -get_volume_label_by_spec(const char *spec) { - struct uuidCache_s *uc; - - uuidcache_init(); - uc = uuidCache; - - while(uc) { - if (!strcmp(spec, uc->device)) - return uc->label; - uc = uc->next; - } - return NULL; -} - -/* - * second_occurrence_of_vol_label() - * As labels are user defined they are not necessarily - * system-wide unique. Make sure that they are. - */ -const char * -second_occurrence_of_vol_label (const char *label) { - struct uuidCache_s *last; - int occurrences = 0; - - uuidcache_init(); - - for (last = uuidCache; last; last = last->next) { - if (last->label && !strcmp(last->label, label)) { - occurrences++; - if (occurrences == 2) - return last->device; - } - } - - return NULL; -} - - -#endif diff --git a/mount/mount_by_label.h b/mount/mount_by_label.h deleted file mode 100644 index f5c930d..0000000 --- a/mount/mount_by_label.h +++ /dev/null @@ -1,4 +0,0 @@ -const char *get_spec_by_uuid(const char *uuid); -const char *get_spec_by_volume_label(const char *volumelabel); -const char *get_volume_label_by_spec(const char *spec); -const char *second_occurrence_of_vol_label(const char *label); diff --git a/mount/mount_guess_fstype.c b/mount/mount_guess_fstype.c index 51d8750..01c3fc7 100644 --- a/mount/mount_guess_fstype.c +++ b/mount/mount_guess_fstype.c @@ -46,8 +46,6 @@ #define ETC_FILESYSTEMS "/etc/filesystems" #define PROC_FILESYSTEMS "/proc/filesystems" -#ifdef HAVE_LIBBLKID - char * do_guess_fstype(const char *device) { @@ -60,438 +58,6 @@ known_fstype(const char *fstype) return blkid_known_fstype(fstype); } -#else -#define SIZE(a) (sizeof(a)/sizeof(a[0])) - -/* Most file system types can be recognized by a `magic' number - in the superblock. Note that the order of the tests is - significant: by coincidence a filesystem can have the - magic numbers for several file system types simultaneously. - For example, the romfs magic lives in the 1st sector; - xiafs does not touch the 1st sector and has its magic in - the 2nd sector; ext2 does not touch the first two sectors. */ - -static inline unsigned short -swapped(unsigned short a) { - return (a>>8) | (a<<8); -} - -/* - char *guess_fstype(const char *device); - - Probes the device and attempts to determine the type of filesystem - contained within. - - Original routine by ; made into a function - for mount(8) by Mike Grupenhoff . - Corrected the test for xiafs - aeb - Read the superblock only once - aeb - Added a very weak heuristic for vfat - 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. - Added xfs - 2000-03-21 Martin K. Petersen - Added cramfs, hfs, hpfs, adfs - Sepp Wijnands - Added ext3 - Andrew Morton - Added jfs - Christoph Hellwig - Added sysv - Tim Launchbury - Added udf - Bryce Nesbitt - Added ocfs, ocfs2 - Manish Singh - http://oss.oracle.com/projects/ocfs2/ -*/ -static char -*magic_known[] = { - "adfs", "bfs", "cramfs", "efs", "ext", "ext2", "ext3", - "hfs", "hpfs", "iso9660", "jfs", "minix", "ntfs", "ocfs", "ocfs2", - "qnx4", "reiserfs", "romfs", "swap", "sysv", "udf", "ufs", - "vxfs", "xfs", "xiafs" -}; - -static int -known_fstype(const char *fstype) { - char **m; - - for (m = magic_known; m - magic_known < SIZE(magic_known); m++) - if (!strcmp(*m, fstype)) - return 1; - return 0; -} - -/* - * udf magic - I find that trying to mount garbage as an udf fs - * causes a very large kernel delay, almost killing the machine. - * So, we do not try udf unless there is positive evidence that it - * might work. Strings below taken from ECMA 167. - */ -/* - * It seems that before udf 2.00 the volume descriptor was not well - * defined. For 2.00 you're supposed to keep scanning records until - * you find one NOT in this list. (See ECMA 2/8.3.1). - */ -static char -*udf_magic[] = { "BEA01", "BOOT2", "CD001", "CDW02", "NSR02", - "NSR03", "TEA01" }; - - -static int -may_be_udf(const char *id) { - char **m; - - for (m = udf_magic; m - udf_magic < SIZE(udf_magic); m++) - if (!strncmp(*m, id, 5)) - return 1; - return 0; -} - -/* we saw "CD001" - may be iso9660 or udf - Bryce Nesbitt */ -static int -is_really_udf(int fd) { - int j, bs; - struct iso_volume_descriptor isosb; - - /* determine the block size by scanning in 2K increments - (block sizes larger than 2K will be null padded) */ - for (bs = 1; bs < 16; bs++) { - lseek(fd, bs*2048+32768, SEEK_SET); - if (read(fd, (char *)&isosb, sizeof(isosb)) != sizeof(isosb)) - return 0; - if (isosb.id[0]) - break; - } - - /* Scan up to another 64 blocks looking for additional VSD's */ - for (j = 1; j < 64; j++) { - if (j > 1) { - lseek(fd, j*bs*2048+32768, SEEK_SET); - if (read(fd, (char *)&isosb, sizeof(isosb)) - != sizeof(isosb)) - return 0; - } - /* If we find NSR0x then call it udf: - NSR01 for UDF 1.00 - NSR02 for UDF 1.50 - NSR03 for UDF 2.00 */ - if (!strncmp(isosb.id, "NSR0", 4)) - return 1; - if (!may_be_udf(isosb.id)) - return 0; - } - - return 0; -} - -static int -may_be_swap(const char *s) { - return (strncmp(s-10, "SWAP-SPACE", 10) == 0 || - strncmp(s-10, "SWAPSPACE2", 10) == 0); -} - -/* rather weak necessary condition */ -static int -may_be_adfs(const u_char *s) { - u_char *p; - int sum; - - p = (u_char *) s + 511; - sum = 0; - while (--p != s) - sum = (sum >> 8) + (sum & 0xff) + *p; - - return (sum == p[511]); -} - -char * -do_guess_fstype(const char *device) { - int fd; - char *type = NULL; - union { - struct xiafs_super_block xiasb; - char romfs_magic[8]; - char qnx4fs_magic[10]; /* ignore first 4 bytes */ - long bfs_magic; - struct ntfs_super_block ntfssb; - struct fat_super_block fatsb; - struct xfs_super_block xfsb; - struct cramfs_super_block cramfssb; - struct ocfs_volume_header ovh; - 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; - struct hs_volume_descriptor hs; - } isosb; - struct reiserfs_super_block reiserfssb; /* block 64 or 8 */ - struct jfs_super_block jfssb; /* block 32 */ - struct hfs_super_block hfssb; - struct hpfs_super_block hpfssb; - struct adfs_super_block adfssb; - struct sysv_super_block svsb; - struct ocfs2_super_block osb; - struct stat statbuf; - - /* opening and reading an arbitrary unknown path can have - undesired side effects - first check that `device' refers - to a block device or ordinary file */ - if (stat (device, &statbuf) || - !(S_ISBLK(statbuf.st_mode) || S_ISREG(statbuf.st_mode))) - return 0; - - fd = open(device, O_RDONLY); - if (fd < 0) - return 0; - - /* do seeks and reads in disk order, otherwise a very short - partition may cause a failure because of read error */ - - if (!type) { - /* block 0 */ - if (lseek(fd, 0, SEEK_SET) != 0 - || read(fd, (char *) &xsb, sizeof(xsb)) != sizeof(xsb)) - goto try_iso9660; - /* Gyorgy Kovesdi: none of my photocds has a readable block 0 */ - - if (xiafsmagic(xsb.xiasb) == _XIAFS_SUPER_MAGIC) - type = "xiafs"; - else if(!strncmp(xsb.romfs_magic, "-rom1fs-", 8)) - type = "romfs"; - else if(!strncmp(xsb.xfsb.s_magic, XFS_SUPER_MAGIC, 4)) - type = "xfs"; - else if(!strncmp(xsb.ovh.signature, OCFS_MAGIC, sizeof(OCFS_MAGIC))) - type = "ocfs"; - else if(!strncmp(xsb.qnx4fs_magic+4, "QNX4FS", 6)) - type = "qnx4"; - else if(xsb.bfs_magic == 0x1badface) - type = "bfs"; - else if(!strncmp(xsb.ntfssb.s_magic, NTFS_SUPER_MAGIC, - sizeof(xsb.ntfssb.s_magic))) - type = "ntfs"; - 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 - formatting large (1.7) floppy disks. */ - !strncmp(xsb.fatsb.s_os, "CH-FOR18", 8)) - && (!strncmp(xsb.fatsb.s_fs, "FAT12 ", 8) || - !strncmp(xsb.fatsb.s_fs, "FAT16 ", 8) || - !strncmp(xsb.fatsb.s_fs2, "FAT32 ", 8))) - type = "vfat"; /* only guessing - might as well be fat or umsdos */ - } - - if (!type) { - /* sector 1 */ - if (lseek(fd, 512 , SEEK_SET) != 512 - || read(fd, (char *) &svsb, sizeof(svsb)) != sizeof(svsb)) - goto io_error; - if (sysvmagic(svsb) == SYSV_SUPER_MAGIC ) - type = "sysv"; - } - - if (!type) { - /* block 1 */ - if (lseek(fd, 1024, SEEK_SET) != 1024 || - read(fd, (char *) &sb, sizeof(sb)) != sizeof(sb)) - goto io_error; - - /* ext2 has magic in little-endian on disk, so "swapped" is - superfluous; however, there have existed strange byteswapped - PPC ext2 systems */ - if (ext2magic(sb.e2s) == EXT2_SUPER_MAGIC || - ext2magic(sb.e2s) == EXT2_PRE_02B_MAGIC || - ext2magic(sb.e2s) == swapped(EXT2_SUPER_MAGIC)) { - type = "ext2"; - - /* maybe even ext3? */ - if ((assemble4le(sb.e2s.s_feature_compat) - & EXT3_FEATURE_COMPAT_HAS_JOURNAL) && - assemble4le(sb.e2s.s_journal_inum) != 0) - type = "ext3"; /* "ext3,ext2" */ - } - - else if (minixmagic(sb.ms) == MINIX_SUPER_MAGIC || - minixmagic(sb.ms) == MINIX_SUPER_MAGIC2 || - minixmagic(sb.ms) == swapped(MINIX_SUPER_MAGIC2) || - minixmagic(sb.ms) == MINIX2_SUPER_MAGIC || - minixmagic(sb.ms) == MINIX2_SUPER_MAGIC2) - type = "minix"; - - else if (extmagic(sb.es) == EXT_SUPER_MAGIC) - type = "ext"; - - else if (vxfsmagic(sb.vs) == VXFS_SUPER_MAGIC) - type = "vxfs"; - } - - if (!type) { - /* block 1 */ - if (lseek(fd, 0x400, SEEK_SET) != 0x400 - || read(fd, (char *) &hfssb, sizeof(hfssb)) != sizeof(hfssb)) - goto io_error; - - /* also check if block size is equal to 512 bytes, - or a multiple. (I see 1536 here.) */ - if (hfsmagic(hfssb) == HFS_SUPER_MAGIC && /* always BE */ - hfsblksize(hfssb) != 0 && - (hfsblksize(hfssb) & 0x1ff) == 0) - type = "hfs"; - } - - if (!type) { - /* block 3 */ - if (lseek(fd, 0xc00, SEEK_SET) != 0xc00 - || read(fd, (char *) &adfssb, sizeof(adfssb)) != sizeof(adfssb)) - goto io_error; - - /* only a weak test */ - if (may_be_adfs((u_char *) &adfssb) - && (adfsblksize(adfssb) >= 8 && - adfsblksize(adfssb) <= 10)) - type = "adfs"; - } - - if (!type) { - int mag; - - /* block 8 */ - if (lseek(fd, 8192, SEEK_SET) != 8192 - || read(fd, (char *) &ufssb, sizeof(ufssb)) != sizeof(ufssb)) - goto io_error; - - mag = ufsmagic(ufssb); - if (mag == UFS_SUPER_MAGIC_LE || mag == UFS_SUPER_MAGIC_BE) - type = "ufs"; - } - - if (!type) { - /* block 8 */ - if (lseek(fd, REISERFS_OLD_DISK_OFFSET_IN_BYTES, SEEK_SET) != - REISERFS_OLD_DISK_OFFSET_IN_BYTES - || read(fd, (char *) &reiserfssb, sizeof(reiserfssb)) != - sizeof(reiserfssb)) - goto io_error; - if (reiserfs_magic_version(reiserfssb.s_magic)) - type = "reiserfs"; - } - - if (!type) { - /* block 8 */ - if (lseek(fd, 0x2000, SEEK_SET) != 0x2000 - || read(fd, (char *) &hpfssb, sizeof(hpfssb)) != sizeof(hpfssb)) - goto io_error; - - if (hpfsmagic(hpfssb) == HPFS_SUPER_MAGIC) - type = "hpfs"; - } - - if (!type) { - /* block 32 */ - if (lseek(fd, JFS_SUPER1_OFF, SEEK_SET) != JFS_SUPER1_OFF - || read(fd, (char *) &jfssb, sizeof(jfssb)) != sizeof(jfssb)) - goto io_error; - if (!strncmp(jfssb.s_magic, JFS_MAGIC, 4)) - type = "jfs"; - } - - if (!type) { - /* block 32 */ - try_iso9660: - if (lseek(fd, 0x8000, SEEK_SET) != 0x8000 - || read(fd, (char *) &isosb, sizeof(isosb)) != sizeof(isosb)) - goto io_error; - - if (strncmp(isosb.hs.id, HS_STANDARD_ID, sizeof(isosb.hs.id)) == 0) { - /* "CDROM" */ - type = "iso9660"; - } else if (strncmp(isosb.iso.id, ISO_STANDARD_ID, - sizeof(isosb.iso.id)) == 0) { - /* CD001 */ - type = "iso9660"; - if (is_really_udf(fd)) - type = "udf"; - } else if (may_be_udf(isosb.iso.id)) - type = "udf"; - } - - if (!type) { - /* block 64 */ - if (lseek(fd, REISERFS_DISK_OFFSET_IN_BYTES, SEEK_SET) != - REISERFS_DISK_OFFSET_IN_BYTES - || read(fd, (char *) &reiserfssb, sizeof(reiserfssb)) != - sizeof(reiserfssb)) - goto io_error; - if (reiserfs_magic_version(reiserfssb.s_magic)) - type = "reiserfs"; - } - - if (!type) { - 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)) - goto io_error; - if (strncmp(osb.signature, OCFS2_SUPER_BLOCK_SIGNATURE, - sizeof(OCFS2_SUPER_BLOCK_SIGNATURE)) == 0) - type = "ocfs2"; - } - } - - if (!type) { - /* perhaps the user tries to mount the swap space - on a new disk; warn her before she does mke2fs on it */ - int pagesize = getpagesize(); - int rd; - char buf[32768]; - - rd = pagesize; - if (rd < 8192) - rd = 8192; - if (rd > sizeof(buf)) - rd = sizeof(buf); - if (lseek(fd, 0, SEEK_SET) != 0 - || read(fd, buf, rd) != rd) - goto io_error; - if (may_be_swap(buf+pagesize) || - may_be_swap(buf+4096) || may_be_swap(buf+8192)) - type = "swap"; - } - - close (fd); - return(type); - -io_error: - if (errno) - perror(device); - else - fprintf(stderr, _("mount: error while guessing filesystem type\n")); - close(fd); - return 0; -} - -#endif static struct tried { struct tried *next; diff --git a/mount/swapon.c b/mount/swapon.c index af4ba96..cb055b3 100644 --- a/mount/swapon.c +++ b/mount/swapon.c @@ -16,7 +16,6 @@ #include "swapargs.h" #include "nls.h" #include "fsprobe.h" -#include "mount_by_label.h" #include "realpath.h" #define streq(s, t) (strcmp ((s), (t)) == 0) -- 1.5.0.6 - To unsubscribe from this list: send the line "unsubscribe util-linux-ng" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Signed-off-by: Kay Sievers Signed-off-by: Karel Zak --- mount/Makefile.am | 15 +-- mount/fsprobe.c | 164 ++++++++++++++++++++++++++++++++ mount/fsprobe.h | 17 ++++ mount/fsprobe_blkid.c | 11 ++ mount/mount.c | 43 +++++++-- mount/mount_guess_fstype.c | 225 -------------------------------------------- mount/mount_guess_fstype.h | 16 --- mount/mount_paths.h | 3 + 8 files changed, 232 insertions(+), 262 deletions(-) diff --git a/mount/Makefile.am b/mount/Makefile.am index 6f63dcf..b5b21b5 100644 --- a/mount/Makefile.am +++ b/mount/Makefile.am @@ -7,24 +7,17 @@ sbin_PROGRAMS = losetup swapon man_MANS = fstab.5 mount.8 swapoff.8 swapon.8 umount.8 losetup.8 MNTHDRS = fstab.h linux_fs.h mount_mntent.h mount_constants.h my_dev_t.h \ - mount_paths.h lomount.h fsprobe.h \ - mount_guess_fstype.h realpath.h xmalloc.h \ - getusername.h loop.h mount_guess_rootdev.h \ - sundries.h + mount_paths.h lomount.h fsprobe.h realpath.h xmalloc.h \ + getusername.h loop.h mount_guess_rootdev.h sundries.h mount_SOURCES = mount.c fstab.c sundries.c xmalloc.c realpath.c mount_mntent.c \ - mount_guess_fstype.c \ - getusername.c \ - lomount.c \ - $(MNTHDRS) + fsprobe.c getusername.c lomount.c $(MNTHDRS) mount_LDADD = $(top_srcdir)/lib/libenv.a $(top_srcdir)/lib/libsetproctitle.a mount_CFLAGS = $(SUID_CFLAGS) umount_SOURCES = umount.c fstab.c sundries.c xmalloc.c realpath.c mount_mntent.c \ - getusername.c \ - lomount.c \ - $(MNTHDRS) + getusername.c fsprobe.c lomount.c $(MNTHDRS) umount_LDADD = $(top_srcdir)/lib/libenv.a umount_CFLAGS = $(SUID_CFLAGS) diff --git a/mount/fsprobe.c b/mount/fsprobe.c new file mode 100644 index 0000000..4b57802 --- /dev/null +++ b/mount/fsprobe.c @@ -0,0 +1,164 @@ +#include +#include +#include +#include +#include +#include +#include +#include "mount_paths.h" +#include "linux_fs.h" +#include "fsprobe.h" +#include "sundries.h" /* for xstrdup */ +#include "nls.h" + +/* list of already tested filesystems by fsprobe_procfsloop_mount() */ +static struct tried { + struct tried *next; + char *type; +} *tried = NULL; + +static int +was_tested(const char *fstype) { + struct tried *t; + + if (fsprobe_known_fstype(fstype)) + return 1; + for (t = tried; t; t = t->next) { + if (!strcmp(t->type, fstype)) + return 1; + } + return 0; +} + +static void +set_tested(const char *fstype) { + struct tried *t = xmalloc(sizeof(struct tried)); + + t->next = tried; + t->type = xstrdup(fstype); + tried = t; +} + +static void +free_tested(void) { + struct tried *t, *tt; + + t = tried; + while(t) { + free(t->type); + tt = t->next; + free(t); + t = tt; + } + tried = NULL; +} + +static char * +procfsnext(FILE *procfs) { + char line[100]; + char fsname[100]; + + while (fgets(line, sizeof(line), procfs)) { + if (sscanf (line, "nodev %[^\n]\n", fsname) == 1) continue; + if (sscanf (line, " %[^ \n]\n", fsname) != 1) continue; + return xstrdup(fsname); + } + return 0; +} + +/* Only use /proc/filesystems here, this is meant to test what + the kernel knows about, so /etc/filesystems is irrelevant. + Return: 1: yes, 0: no, -1: cannot open procfs */ +int +fsprobe_known_fstype_in_procfs(const char *type) +{ + FILE *procfs; + char *fsname; + int ret = -1; + + procfs = fopen(PROC_FILESYSTEMS, "r"); + if (procfs) { + ret = 0; + while ((fsname = procfsnext(procfs)) != NULL) + if (!strcmp(fsname, type)) { + ret = 1; + break; + } + fclose(procfs); + procfs = NULL; + } + return ret; +} + +/* Try all types in FILESYSTEMS, except those in *types, + in case *types starts with "no" */ +/* return: 0: OK, -1: error in errno, 1: type not found */ +/* when 0 or -1 is returned, *types contains the type used */ +/* when 1 is returned, *types is NULL */ +int +fsprobe_procfsloop_mount( int (*mount_fn)(struct mountargs *), + struct mountargs *args, + const char **types) +{ + char *files[2] = { ETC_FILESYSTEMS, PROC_FILESYSTEMS }; + FILE *procfs; + char *fsname; + const char *notypes = NULL; + int no = 0; + int ret = 1; + int errsv = 0; + int i; + + if (*types && !strncmp(*types, "no", 2)) { + no = 1; + notypes = (*types) + 2; + } + *types = NULL; + + /* Use PROC_FILESYSTEMS only when ETC_FILESYSTEMS does not exist. + In some cases trying a filesystem that the kernel knows about + on the wrong data will crash the kernel; in such cases + ETC_FILESYSTEMS can be used to list the filesystems that we + are allowed to try, and in the order they should be tried. + End ETC_FILESYSTEMS with a line containing a single '*' only, + if PROC_FILESYSTEMS should be tried afterwards. */ + + for (i=0; i<2; i++) { + procfs = fopen(files[i], "r"); + if (!procfs) + continue; + while ((fsname = procfsnext(procfs)) != NULL) { + if (!strcmp(fsname, "*")) { + fclose(procfs); + goto nexti; + } + if (was_tested (fsname)) + continue; + if (no && matching_type(fsname, notypes)) + continue; + set_tested (fsname); + args->type = fsname; + if (verbose) { + printf(_("Trying %s\n"), fsname); + fflush(stdout); + } + if ((*mount_fn) (args) == 0) { + *types = fsname; + ret = 0; + break; + } else if (errno != EINVAL && + fsprobe_known_fstype_in_procfs(fsname) == 1) { + *types = "guess"; + ret = -1; + errsv = errno; + break; + } + } + free_tested(); + fclose(procfs); + errno = errsv; + return ret; + nexti:; + } + return 1; +} diff --git a/mount/fsprobe.h b/mount/fsprobe.h index c96ff8c..cc429e1 100644 --- a/mount/fsprobe.h +++ b/mount/fsprobe.h @@ -10,3 +10,20 @@ extern const char *mount_get_devname_by_label(const char *label); extern const char *mount_get_volume_label_by_spec(const char *spec); extern const char *mount_get_devname(const char *spec); extern const char *mount_get_devname_for_mounting(const char *spec); +extern int fsprobe_known_fstype(const char *fstype); +extern const char *fsprobe_get_fstype_by_devname(const char *devname); + +struct mountargs { + const char *spec; + const char *node; + const char *type; + int flags; + void *data; +}; + +extern int fsprobe_known_fstype_in_procfs(const char *type); + +extern int fsprobe_procfsloop_mount(int (*mount_fn)(struct mountargs *), + struct mountargs *args, + const char **types); + diff --git a/mount/fsprobe_blkid.c b/mount/fsprobe_blkid.c index 9ff4e31..7f8c362 100644 --- a/mount/fsprobe_blkid.c +++ b/mount/fsprobe_blkid.c @@ -41,4 +41,15 @@ mount_get_devname_for_mounting(const char *spec) { return blkid_get_devname(blkid, spec, 0); } +int +fsprobe_known_fstype(const char *fstype) +{ + return blkid_known_fstype(fstype); +} + +const char * +fsprobe_get_fstype_by_devname(const char *devname) { + return blkid_get_tag_value(blkid, "TYPE", devname); +} + #endif diff --git a/mount/mount.c b/mount/mount.c index 309e41e..be9e409 100644 --- a/mount/mount.c +++ b/mount/mount.c @@ -39,7 +39,6 @@ #include "loop.h" #include "linux_fs.h" /* for BLKGETSIZE */ #include "mount_guess_rootdev.h" -#include "mount_guess_fstype.h" #include "getusername.h" #include "mount_paths.h" #include "env.h" @@ -656,6 +655,26 @@ check_special_mountprog(const char *spec, const char *node, const char *type, in return 0; } + +static const char * +guess_fstype_by_devname(const char *devname) +{ + const char *type = fsprobe_get_fstype_by_devname(devname); + + if (verbose) { + printf (_("mount: you didn't specify a filesystem type for %s\n"), devname); + + if (!type) + printf (_(" I will try all types mentioned in %s or %s\n"), + ETC_FILESYSTEMS, PROC_FILESYSTEMS); + else if (!strcmp(type, "swap")) + printf (_(" and it looks like this is swapspace\n")); + else + printf (_(" I will try type %s\n"), type); + } + return type; +} + /* * guess_fstype_and_mount() * Mount a single file system. Guess the type when unknown. @@ -675,7 +694,7 @@ guess_fstype_and_mount(const char *spec, const char *node, const char **types, *types = "none"; /* random, but not "bind" */ if (!*types && !(flags & MS_REMOUNT)) { - *types = guess_fstype(spec); + *types = guess_fstype_by_devname(spec); if (*types) { if (!strcmp(*types, "swap")) { error(_("%s looks like swapspace - not mounted"), spec); @@ -711,7 +730,7 @@ guess_fstype_and_mount(const char *spec, const char *node, const char **types, return do_mount_syscall (&args); } - return procfsloop(do_mount_syscall, &args, types); + return fsprobe_procfsloop_mount(do_mount_syscall, &args, types); } /* @@ -1147,8 +1166,10 @@ try_mount_one (const char *spec0, const char *node0, const char *types0, case EIO: error (_("mount: %s: can't read superblock"), spec); break; case ENODEV: - { int pfs; - if ((pfs = is_in_procfs(types)) == 1 || !strcmp(types, "guess")) + { + int pfs = fsprobe_known_fstype_in_procfs(types); + + if (pfs == 1 || !strcmp(types, "guess")) error(_("mount: %s: unknown device"), spec); else if (pfs == 0) { char *lowtype, *p; @@ -1165,11 +1186,13 @@ try_mount_one (const char *spec0, const char *node0, const char *types0, u++; } } - if (u && is_in_procfs(lowtype) == 1) + if (u && fsprobe_known_fstype_in_procfs(lowtype) == 1) error (_("mount: probably you meant %s"), lowtype); - else if (!strncmp(lowtype, "iso", 3) && is_in_procfs("iso9660") == 1) + else if (!strncmp(lowtype, "iso", 3) && + fsprobe_known_fstype_in_procfs("iso9660") == 1) error (_("mount: maybe you meant 'iso9660'?")); - else if (!strncmp(lowtype, "fat", 3) && is_in_procfs("vfat") == 1) + else if (!strncmp(lowtype, "fat", 3) && + fsprobe_known_fstype_in_procfs("vfat") == 1) error (_("mount: maybe you meant 'vfat'?")); free(lowtype); } else @@ -1741,8 +1764,8 @@ main(int argc, char *argv[]) { use only for testing purposes - the guessing is not reliable at all */ { - char *fstype; - fstype = do_guess_fstype(optarg); + const char *fstype; + fstype = fsprobe_get_fstype_by_devname(optarg); printf("%s\n", fstype ? fstype : "unknown"); exit(fstype ? 0 : EX_FAIL); } diff --git a/mount/mount_guess_fstype.c b/mount/mount_guess_fstype.c deleted file mode 100644 index 01c3fc7..0000000 --- a/mount/mount_guess_fstype.c +++ /dev/null @@ -1,225 +0,0 @@ -/* - * Thu Jul 14 07:32:40 1994: faith@cs.unc.edu added changes from Adam - * J. Richter (adam@adam.yggdrasil.com) so that /proc/filesystems is used - * if no -t option is given. I modified his patches so that, if - * /proc/filesystems is not available, the behavior of mount is the same as - * it was previously. - * - * Wed Feb 8 09:23:18 1995: Mike Grupenhoff added - * a probe of the superblock for the type before /proc/filesystems is - * checked. - * - * Fri Apr 5 01:13:33 1996: quinlan@bucknell.edu, fixed up iso9660 autodetect - * - * Wed Nov 11 11:33:55 1998: K.Garloff@ping.de, try /etc/filesystems before - * /proc/filesystems - * [This was mainly in order to specify vfat before fat; these days we often - * detect *fat and then assume vfat, so perhaps /etc/filesystems isnt - * so useful anymore.] - * - * 1999-02-22 Arkadiusz Mi¶kiewicz - * added Native Language Support - * - * 2000-12-01 Sepp Wijnands - * added probes for cramfs, hfs, hpfs and adfs. - * - * 2001-10-26 Tim Launchbury - * added sysv magic. - * - * aeb - many changes. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include "linux_fs.h" -#include "fsprobe.h" -#include "mount_guess_fstype.h" -#include "sundries.h" /* for xstrdup */ -#include "nls.h" - -#define ETC_FILESYSTEMS "/etc/filesystems" -#define PROC_FILESYSTEMS "/proc/filesystems" - -char * -do_guess_fstype(const char *device) -{ - return blkid_get_tag_value(blkid, "TYPE", device); -} - -static int -known_fstype(const char *fstype) -{ - return blkid_known_fstype(fstype); -} - - -static struct tried { - struct tried *next; - char *type; -} *tried = NULL; - -static int -was_tested(const char *fstype) { - struct tried *t; - - if (known_fstype(fstype)) - return 1; - for (t = tried; t; t = t->next) { - if (!strcmp(t->type, fstype)) - return 1; - } - return 0; -} - -static void -set_tested(const char *fstype) { - struct tried *t = xmalloc(sizeof(struct tried)); - - t->next = tried; - t->type = xstrdup(fstype); - tried = t; -} - -static void -free_tested(void) { - struct tried *t, *tt; - - t = tried; - while(t) { - free(t->type); - tt = t->next; - free(t); - t = tt; - } - tried = NULL; -} - -char * -guess_fstype(const char *spec) { - char *type = do_guess_fstype(spec); - if (verbose) { - printf (_("mount: you didn't specify a filesystem type for %s\n"), - spec); - if (!type) - printf (_(" I will try all types mentioned in %s or %s\n"), - ETC_FILESYSTEMS, PROC_FILESYSTEMS); - else if (!strcmp(type, "swap")) - printf (_(" and it looks like this is swapspace\n")); - else - printf (_(" I will try type %s\n"), type); - } - return type; -} - -static char * -procfsnext(FILE *procfs) { - char line[100]; - char fsname[100]; - - while (fgets(line, sizeof(line), procfs)) { - if (sscanf (line, "nodev %[^\n]\n", fsname) == 1) continue; - if (sscanf (line, " %[^ \n]\n", fsname) != 1) continue; - return xstrdup(fsname); - } - return 0; -} - -/* Only use /proc/filesystems here, this is meant to test what - the kernel knows about, so /etc/filesystems is irrelevant. - Return: 1: yes, 0: no, -1: cannot open procfs */ -int -is_in_procfs(const char *type) { - FILE *procfs; - char *fsname; - int ret = -1; - - procfs = fopen(PROC_FILESYSTEMS, "r"); - if (procfs) { - ret = 0; - while ((fsname = procfsnext(procfs)) != NULL) - if (!strcmp(fsname, type)) { - ret = 1; - break; - } - fclose(procfs); - procfs = NULL; - } - return ret; -} - -/* Try all types in FILESYSTEMS, except those in *types, - in case *types starts with "no" */ -/* return: 0: OK, -1: error in errno, 1: type not found */ -/* when 0 or -1 is returned, *types contains the type used */ -/* when 1 is returned, *types is NULL */ -int -procfsloop(int (*mount_fn)(struct mountargs *), struct mountargs *args, - const char **types) { - char *files[2] = { ETC_FILESYSTEMS, PROC_FILESYSTEMS }; - FILE *procfs; - char *fsname; - const char *notypes = NULL; - int no = 0; - int ret = 1; - int errsv = 0; - int i; - - if (*types && !strncmp(*types, "no", 2)) { - no = 1; - notypes = (*types) + 2; - } - *types = NULL; - - /* Use PROC_FILESYSTEMS only when ETC_FILESYSTEMS does not exist. - In some cases trying a filesystem that the kernel knows about - on the wrong data will crash the kernel; in such cases - ETC_FILESYSTEMS can be used to list the filesystems that we - are allowed to try, and in the order they should be tried. - End ETC_FILESYSTEMS with a line containing a single '*' only, - if PROC_FILESYSTEMS should be tried afterwards. */ - - for (i=0; i<2; i++) { - procfs = fopen(files[i], "r"); - if (!procfs) - continue; - while ((fsname = procfsnext(procfs)) != NULL) { - if (!strcmp(fsname, "*")) { - fclose(procfs); - goto nexti; - } - if (was_tested (fsname)) - continue; - if (no && matching_type(fsname, notypes)) - continue; - set_tested (fsname); - args->type = fsname; - if (verbose) { - printf(_("Trying %s\n"), fsname); - fflush(stdout); - } - if ((*mount_fn) (args) == 0) { - *types = fsname; - ret = 0; - break; - } else if (errno != EINVAL && - is_in_procfs(fsname) == 1) { - *types = "guess"; - ret = -1; - errsv = errno; - break; - } - } - free_tested(); - fclose(procfs); - errno = errsv; - return ret; - nexti:; - } - return 1; -} diff --git a/mount/mount_guess_fstype.h b/mount/mount_guess_fstype.h deleted file mode 100644 index 63cb678..0000000 --- a/mount/mount_guess_fstype.h +++ /dev/null @@ -1,16 +0,0 @@ -struct mountargs { - const char *spec; - const char *node; - const char *type; - int flags; - void *data; -}; - -extern int verbose; - -char *guess_fstype(const char *device); -char *do_guess_fstype(const char *device); -int procfsloop(int (*mount_fn)(struct mountargs *), struct mountargs *args, - const char **type); -int is_in_procfs(const char *fstype); - diff --git a/mount/mount_paths.h b/mount/mount_paths.h index fe84e1d..9093b10 100644 --- a/mount/mount_paths.h +++ b/mount/mount_paths.h @@ -12,4 +12,7 @@ #endif #define LOCK_TIMEOUT 10 +#define ETC_FILESYSTEMS "/etc/filesystems" +#define PROC_FILESYSTEMS "/proc/filesystems" + #endif /* MOUNT_PATHS_H */ -- 1.5.0.6 - To unsubscribe from this list: send the line "unsubscribe util-linux-ng" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Signed-off-by: Karel Zak --- mount/fsprobe.h | 41 ++++++++++++++++++++++++++++------------- mount/fsprobe_blkid.c | 27 +++++++++++++++------------ mount/fstab.c | 8 ++++---- mount/mount.c | 40 +++++++++++++++++++++++----------------- mount/swapon.c | 14 +++++++------- 5 files changed, 77 insertions(+), 53 deletions(-) diff --git a/mount/fsprobe.h b/mount/fsprobe.h index cc429e1..e59440e 100644 --- a/mount/fsprobe.h +++ b/mount/fsprobe.h @@ -1,18 +1,32 @@ -#ifdef HAVE_LIBBLKID -#include -extern blkid_cache blkid; -#endif - -extern void mount_blkid_get_cache(void); -extern void mount_blkid_put_cache(void); -extern const char *mount_get_devname_by_uuid(const char *uuid); -extern const char *mount_get_devname_by_label(const char *label); -extern const char *mount_get_volume_label_by_spec(const char *spec); -extern const char *mount_get_devname(const char *spec); -extern const char *mount_get_devname_for_mounting(const char *spec); -extern int fsprobe_known_fstype(const char *fstype); +#ifndef MOUNT_FSPROBE_H +#define MOUNT_FSPROBE_H +/* + * This is the generic interface for filesystem guessing libraries. + * Implementations are provided by + * + * fsprobe_blkid.c for libblkid from e2fsprogs + * fsprobe_volumeid.c for libvolume_id from udev + * + * Copyright (C) 2007 Kay Sievers + * Copyright (C) 2007 Matthias Koenig + * Copyright (C) 2007 Karel Zak + */ + +extern void fsprobe_init(void); +extern void fsprobe_exit(void); + +extern const char *fsprobe_get_devname_by_uuid(const char *uuid); +extern const char *fsprobe_get_devname_by_label(const char *label); + +extern const char *fsprobe_get_label_by_devname(const char *devname); +extern const char *fsprobe_get_uuid_by_devname(const char *devname); extern const char *fsprobe_get_fstype_by_devname(const char *devname); +extern const char *fsprobe_get_devname(const char *spec); +extern const char *fsprobe_get_devname_for_mounting(const char *spec); + +extern int fsprobe_known_fstype(const char *fstype); + struct mountargs { const char *spec; const char *node; @@ -27,3 +41,4 @@ extern int fsprobe_procfsloop_mount(int (*mount_fn)(struct mountargs *), struct mountargs *args, const char **types); +#endif /* MOUNT_FSPROBE_H */ diff --git a/mount/fsprobe_blkid.c b/mount/fsprobe_blkid.c index 7f8c362..d25b973 100644 --- a/mount/fsprobe_blkid.c +++ b/mount/fsprobe_blkid.c @@ -1,43 +1,47 @@ #include +#include #include "fsprobe.h" -#ifdef HAVE_LIBBLKID - -blkid_cache blkid; +static blkid_cache blkid; void -mount_blkid_get_cache(void) { +fsprobe_init(void) { blkid_get_cache(&blkid, NULL); } void -mount_blkid_put_cache(void) { +fsprobe_exit(void) { blkid_put_cache(blkid); } const char * -mount_get_volume_label_by_spec(const char *spec) { - return blkid_get_tag_value(blkid, "LABEL", spec); +fsprobe_get_label_by_devname(const char *devname) { + return blkid_get_tag_value(blkid, "LABEL", devname); +} + +const char * +fsprobe_get_uuid_by_devname(const char *devname) { + return blkid_get_tag_value(blkid, "UUID", devname); } const char * -mount_get_devname(const char *spec) { +fsprobe_get_devname(const char *spec) { return blkid_get_devname(blkid, spec, 0); } const char * -mount_get_devname_by_uuid(const char *uuid) { +fsprobe_get_devname_by_uuid(const char *uuid) { return blkid_get_devname(blkid, "UUID", uuid); } const char * -mount_get_devname_by_label(const char *label) { +fsprobe_get_devname_by_label(const char *label) { return blkid_get_devname(blkid, "LABEL", label); } /* Also when no UUID= or LABEL= occur? No verbose? No warnings? */ const char * -mount_get_devname_for_mounting(const char *spec) { +fsprobe_get_devname_for_mounting(const char *spec) { return blkid_get_devname(blkid, spec, 0); } @@ -52,4 +56,3 @@ fsprobe_get_fstype_by_devname(const char *devname) { return blkid_get_tag_value(blkid, "TYPE", devname); } -#endif diff --git a/mount/fstab.c b/mount/fstab.c index 5267f62..c47f20d 100644 --- a/mount/fstab.c +++ b/mount/fstab.c @@ -292,7 +292,7 @@ has_label(const char *device, const char *label) { const char *devlabel; int ret; - devlabel = mount_get_volume_label_by_spec(device); + devlabel = fsprobe_get_label_by_devname(device); ret = !strcmp(label, devlabel); /* free(devlabel); */ return ret; @@ -303,7 +303,7 @@ has_uuid(const char *device, const char *uuid){ const char *devuuid; int ret; - devuuid = mount_get_devname_by_uuid(device); + devuuid = fsprobe_get_uuid_by_devname(device); ret = !strcmp(uuid, devuuid); /* free(devuuid); */ return ret; @@ -745,8 +745,8 @@ int verbose; int mount_quiet; char *progname; -const char *mount_get_volume_label_by_spec(const char *spec) { return NULL; } -const char *mount_get_devname_by_uuid(const char *uuid) { return NULL; } +const char *fsprobe_get_label_by_devname(const char *spec) { return NULL; } +const char *fsprobe_get_uuid_by_devname(const char *spec) { return NULL; } struct my_mntent *my_getmntent (mntFILE *mfp) { return NULL; } mntFILE *my_setmntent (const char *file, char *mode) { return NULL; } void my_endmntent (mntFILE *mfp) { } diff --git a/mount/mount.c b/mount/mount.c index be9e409..12964ca 100644 --- a/mount/mount.c +++ b/mount/mount.c @@ -233,6 +233,11 @@ parse_string_opt(char *s) { return 0; } +static void +my_free(const void *s) { + if (s) + free((void *) s); +} /* Report on a single mount. */ static void @@ -245,11 +250,18 @@ print_one (const struct my_mntent *me) { if (me->mnt_opts != NULL) printf (" (%s)", me->mnt_opts); if (list_with_volumelabel) { - const char *label; - label = mount_get_volume_label_by_spec(me->mnt_fsname); - if (label) { - printf (" [%s]", label); - /* free(label); */ + const char *devname = fsprobe_get_devname(me->mnt_fsname); + + if (devname) { + const char *label; + + label = fsprobe_get_label_by_devname(devname); + my_free(devname); + + if (label) { + printf (" [%s]", label); + my_free(label); + } } } printf ("\n"); @@ -268,12 +280,6 @@ print_all (char *types) { exit (0); } -static void -my_free(const void *s) { - if (s) - free((void *) s); -} - /* reallocates its first arg */ static char * append_opt(char *s, const char *opt, const char *val) @@ -1330,7 +1336,7 @@ mount_one (const char *spec, const char *node, const char *types, opts = append_opt(opts, cmdlineopts, NULL); /* Handle possible LABEL= and UUID= forms of spec */ - nspec = mount_get_devname_for_mounting(spec); + nspec = fsprobe_get_devname_for_mounting(spec); if (nspec) spec = nspec; @@ -1387,7 +1393,7 @@ mounted (const char *spec0, const char *node0) { int ret = 0; /* Handle possible UUID= and LABEL= in spec */ - spec0 = mount_get_devname(spec0); + spec0 = fsprobe_get_devname(spec0); if (!spec0) return ret; @@ -1669,7 +1675,7 @@ main(int argc, char *argv[]) { if (fd > 2) close(fd); - mount_blkid_get_cache(); + fsprobe_init(); #ifdef DO_PS_FIDDLING initproctitle(argc, argv); @@ -1842,9 +1848,9 @@ main(int argc, char *argv[]) { if (specseen) { if (uuid) - spec = mount_get_devname_by_uuid(uuid); + spec = fsprobe_get_devname_by_uuid(uuid); else - spec = mount_get_devname_by_label(volumelabel); + spec = fsprobe_get_devname_by_label(volumelabel); if (!spec) die (EX_USAGE, _("mount: no such partition found")); @@ -1922,7 +1928,7 @@ main(int argc, char *argv[]) { if (result == EX_SOMEOK) result = 0; - mount_blkid_put_cache(); + fsprobe_exit(); exit (result); } diff --git a/mount/swapon.c b/mount/swapon.c index cb055b3..025a6b5 100644 --- a/mount/swapon.c +++ b/mount/swapon.c @@ -180,7 +180,7 @@ do_swapon(const char *orig_special, int prio) { if (verbose) printf(_("%s on %s\n"), progname, orig_special); - special = mount_get_devname(orig_special); + special = fsprobe_get_devname(orig_special); if (!special) { fprintf(stderr, _("%s: cannot find the device for %s\n"), progname, orig_special); @@ -255,13 +255,13 @@ cannot_find(const char *special) { static int swapon_by_label(const char *label, int prio) { - const char *special = mount_get_devname_by_label(label); + const char *special = fsprobe_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); + const char *special = fsprobe_get_devname_by_uuid(uuid); return special ? do_swapon(special, prio) : cannot_find(uuid); } @@ -272,7 +272,7 @@ do_swapoff(const char *orig_special, int quiet) { if (verbose) printf(_("%s on %s\n"), progname, orig_special); - special = mount_get_devname(orig_special); + special = fsprobe_get_devname(orig_special); if (!special) return cannot_find(orig_special); @@ -293,13 +293,13 @@ do_swapoff(const char *orig_special, int quiet) { static int swapoff_by_label(const char *label, int quiet) { - const char *special = mount_get_devname_by_label(label); + const char *special = fsprobe_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); + const char *special = fsprobe_get_devname_by_uuid(uuid); return special ? do_swapoff(special, quiet) : cannot_find(uuid); } @@ -328,7 +328,7 @@ swapon_all(void) { if (!streq(fstab->mnt_type, MNTTYPE_SWAP)) continue; - special = mount_get_devname(orig_special); + special = fsprobe_get_devname(orig_special); if (!special) continue; -- 1.5.0.6 - To unsubscribe from this list: send the line "unsubscribe util-linux-ng" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html The blkid supports NAME=value parsing, but use the library for this simple task is overkill. (The libblkid requires initialized blkid cache all time, for all calls.) This patch makes the fsprobe_get_devname_for_mounting() and fsprobe_get_devname() generic for all fsprobe implementations. Signed-off-by: Karel Zak --- mount/Makefile.am | 2 +- mount/fsprobe.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++ mount/fsprobe_blkid.c | 11 --------- mount/sundries.c | 38 ++++++++++++++++++++++++++++++ mount/sundries.h | 2 + mount/swapon.c | 1 + 6 files changed, 103 insertions(+), 12 deletions(-) diff --git a/mount/Makefile.am b/mount/Makefile.am index b5b21b5..e61261f 100644 --- a/mount/Makefile.am +++ b/mount/Makefile.am @@ -23,7 +23,7 @@ umount_LDADD = $(top_srcdir)/lib/libenv.a umount_CFLAGS = $(SUID_CFLAGS) swapon_SOURCES = swapon.c xmalloc.c \ - swap_constants.h realpath.c + swap_constants.h realpath.c fsprobe.c sundries.c losetup_SOURCES = lomount.c loop.h lomount.h losetup_CFLAGS = -DMAIN diff --git a/mount/fsprobe.c b/mount/fsprobe.c index 4b57802..2629d0d 100644 --- a/mount/fsprobe.c +++ b/mount/fsprobe.c @@ -162,3 +162,64 @@ fsprobe_procfsloop_mount( int (*mount_fn)(struct mountargs *), } return 1; } + +const char * +fsprobe_get_devname_for_mounting(const char *spec) +{ + char *name, *value; + + if (!spec) + return NULL; + + if (parse_spec(spec, &name, &value) != 0) + return NULL; /* parse error */ + + if (name) { + const char *nspec = NULL; + + if (!strcmp(name,"LABEL")) + nspec = fsprobe_get_devname_by_label(value); + else if (!strcmp(name,"UUID")) + nspec = fsprobe_get_devname_by_uuid(value); + + if (nspec && verbose > 1) + printf(_("mount: going to mount %s by %s\n"), spec, name); + + free((void *) name); + return nspec; + } + + /* no LABEL, no UUID, .. probably a path */ + if (verbose > 1) + printf(_("mount: no LABEL=, no UUID=, going to mount %s by path\n"), spec); + + return canonicalize(spec); +} + +/* like fsprobe_get_devname_for_mounting(), but without verbose messages */ +const char * +fsprobe_get_devname(const char *spec) +{ + char *name, *value; + + if (!spec) + return NULL; + + if (parse_spec(spec, &name, &value) != 0) + return NULL; /* parse error */ + + if (name) { + const char *nspec = NULL; + + if (!strcmp(name,"LABEL")) + nspec = fsprobe_get_devname_by_label(value); + else if (!strcmp(name,"UUID")) + nspec = fsprobe_get_devname_by_uuid(value); + + free((void *) name); + return nspec; + } + + return canonicalize(spec); +} + diff --git a/mount/fsprobe_blkid.c b/mount/fsprobe_blkid.c index d25b973..2dc734e 100644 --- a/mount/fsprobe_blkid.c +++ b/mount/fsprobe_blkid.c @@ -25,11 +25,6 @@ fsprobe_get_uuid_by_devname(const char *devname) { } const char * -fsprobe_get_devname(const char *spec) { - return blkid_get_devname(blkid, spec, 0); -} - -const char * fsprobe_get_devname_by_uuid(const char *uuid) { return blkid_get_devname(blkid, "UUID", uuid); } @@ -39,12 +34,6 @@ fsprobe_get_devname_by_label(const char *label) { return blkid_get_devname(blkid, "LABEL", label); } -/* Also when no UUID= or LABEL= occur? No verbose? No warnings? */ -const char * -fsprobe_get_devname_for_mounting(const char *spec) { - return blkid_get_devname(blkid, spec, 0); -} - int fsprobe_known_fstype(const char *fstype) { diff --git a/mount/sundries.c b/mount/sundries.c index cdfbb42..45404c5 100644 --- a/mount/sundries.c +++ b/mount/sundries.c @@ -247,3 +247,41 @@ canonicalize (const char *path) { return xstrdup(path); } + + +/* + * Parses NAME=value, returns -1 on parse error, 0 success. The success is also + * when the 'spec' doesn't contain name=value pair (because the spec could be + * a devname too). In particular case the pointer 'name' is set to NULL. + + * The result is a new allocated string (the 'name' pointer). + */ +int +parse_spec(const char *spec, char **name, char **value) +{ + char *vl, *tk, *cp; + + *name = NULL; + *value = NULL; + + if (!(cp = strchr(spec, '='))) + return 0; /* no name= */ + + tk = xstrdup(spec); + vl = tk + (cp - spec); + *vl++ = '\0'; + + if (*vl == '"' || *vl == '\'') { + if (!(cp = strrchr(vl+1, *vl))) { + free(tk); + return -1; /* parse error */ + } + vl++; + *cp = '\0'; + } + + *name = tk; + *value = vl; + return 0; +} + diff --git a/mount/sundries.h b/mount/sundries.h index 0851145..85ccd85 100644 --- a/mount/sundries.h +++ b/mount/sundries.h @@ -35,6 +35,8 @@ char *xstrndup (const char *s, int n); char *xstrconcat3 (char *, const char *, const char *); char *xstrconcat4 (char *, const char *, const char *, const char *); +int parse_spec(const char *spec, char **name, char **value); + void die (int errcode, const char *fmt, ...); /* exit status - bits below are ORed */ diff --git a/mount/swapon.c b/mount/swapon.c index 025a6b5..3936790 100644 --- a/mount/swapon.c +++ b/mount/swapon.c @@ -30,6 +30,7 @@ int all = 0; int verbose = 0; int priority = -1; /* non-prioritized swap by default */ +int mount_quiet = 0; /* If true, don't complain if the device/file doesn't exist */ int ifexists = 0; -- 1.5.0.6 - To unsubscribe from this list: send the line "unsubscribe util-linux-ng" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html The blkid_get_cache() parses /etc/blkid.tab, it's better do it only when we really need to resolve a spec (label or uuid). Signed-off-by: Karel Zak --- mount/fsprobe_blkid.c | 38 ++++++++++++++++++++++++++++++-------- 1 files changed, 30 insertions(+), 8 deletions(-) diff --git a/mount/fsprobe_blkid.c b/mount/fsprobe_blkid.c index 2dc734e..16a093a 100644 --- a/mount/fsprobe_blkid.c +++ b/mount/fsprobe_blkid.c @@ -5,32 +5,50 @@ static blkid_cache blkid; void -fsprobe_init(void) { - blkid_get_cache(&blkid, NULL); +fsprobe_init(void) +{ + blkid = NULL; } void -fsprobe_exit(void) { +fsprobe_exit(void) +{ blkid_put_cache(blkid); } const char * -fsprobe_get_label_by_devname(const char *devname) { +fsprobe_get_label_by_devname(const char *devname) +{ + if (!blkid) + blkid_get_cache(&blkid, NULL); + return blkid_get_tag_value(blkid, "LABEL", devname); } const char * -fsprobe_get_uuid_by_devname(const char *devname) { +fsprobe_get_uuid_by_devname(const char *devname) +{ + if (!blkid) + blkid_get_cache(&blkid, NULL); + return blkid_get_tag_value(blkid, "UUID", devname); } const char * -fsprobe_get_devname_by_uuid(const char *uuid) { +fsprobe_get_devname_by_uuid(const char *uuid) +{ + if (!blkid) + blkid_get_cache(&blkid, NULL); + return blkid_get_devname(blkid, "UUID", uuid); } const char * -fsprobe_get_devname_by_label(const char *label) { +fsprobe_get_devname_by_label(const char *label) +{ + if (!blkid) + blkid_get_cache(&blkid, NULL); + return blkid_get_devname(blkid, "LABEL", label); } @@ -41,7 +59,11 @@ fsprobe_known_fstype(const char *fstype) } const char * -fsprobe_get_fstype_by_devname(const char *devname) { +fsprobe_get_fstype_by_devname(const char *devname) +{ + if (!blkid) + blkid_get_cache(&blkid, NULL); + return blkid_get_tag_value(blkid, "TYPE", devname); } -- 1.5.0.6 - To unsubscribe from this list: send the line "unsubscribe util-linux-ng" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html The functions have to check for NULL pointer. Signed-off-by: Karel Zak --- mount/fstab.c | 10 ++++++++-- 1 files changed, 8 insertions(+), 2 deletions(-) diff --git a/mount/fstab.c b/mount/fstab.c index c47f20d..eee126e 100644 --- a/mount/fstab.c +++ b/mount/fstab.c @@ -293,8 +293,11 @@ has_label(const char *device, const char *label) { int ret; devlabel = fsprobe_get_label_by_devname(device); + if (!devlabel) + return 0; + ret = !strcmp(label, devlabel); - /* free(devlabel); */ + my_free(devlabel); return ret; } @@ -304,8 +307,11 @@ has_uuid(const char *device, const char *uuid){ int ret; devuuid = fsprobe_get_uuid_by_devname(device); + if (!devuuid) + return 0; + ret = !strcmp(uuid, devuuid); - /* free(devuuid); */ + my_free(devuuid); return ret; } -- 1.5.0.6 - To unsubscribe from this list: send the line "unsubscribe util-linux-ng" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html The patch add new option --with-fsprobe= (where the is blkid or volume_id). The blkid is default. The mount cannot be compiled without a filesystem detection library. Signed-off-by: Kay Sievers Signed-off-by: Karel Zak --- configure.ac | 26 ++++++++++++++++++++++++-- 1 files changed, 24 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index d24ce09..e3ae318 100644 --- a/configure.ac +++ b/configure.ac @@ -56,8 +56,30 @@ AM_CONDITIONAL(HAVE_LIBUTIL, test x$ac_cv_lib_util_openpty = xyes) AC_CHECK_LIB(termcap, tgetnum) AM_CONDITIONAL(HAVE_TERMCAP, test x$ac_cv_lib_termcap_tgetnum = xyes) -AC_CHECK_LIB(blkid, blkid_known_fstype) -AM_CONDITIONAL(HAVE_BLKID, test x$ac_cv_lib_blkid_blkid_known_fstype = xyes) + +AC_ARG_WITH([fsprobe], + AC_HELP_STRING([--with-fsprobe], [library to guess filesystems (blkid|volume_id), default is blkid]), + with_fsprobe=$withval, with_fsprobe=blkid +) + +if test x$with_fsprobe = xblkid; then + AC_CHECK_LIB(blkid, blkid_known_fstype) + if test x$ac_cv_lib_blkid_blkid_known_fstype = xyes; then + fsprobe=blkid + fi +elif test x$with_fsprobe = xvolume_id; then + AC_CHECK_LIB(volume_id, volume_id_open_fd) + if test x$ac_cv_lib_volume_id_volume_id_open_fd = xyes; then + fsprobe=volume_id + fi +fi + +if test -z "$fsprobe"; then + AC_MSG_ERROR([Without blkid or volume_id you will not be able to build util-linux-ng.]) +fi + +AM_CONDITIONAL(HAVE_BLKID, test x"$fsprobe" = xblkid) +AM_CONDITIONAL(HAVE_VOLUME_ID, test x"$fsprobe" = xvolume_id) AM_GNU_GETTEXT_VERSION([0.14.1]) -- 1.5.0.6 - To unsubscribe from this list: send the line "unsubscribe util-linux-ng" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Signed-off-by: Matthias Koenig Signed-off-by: Kay Sievers Signed-off-by: Karel Zak --- mount/Makefile.am | 9 +++ mount/fsprobe_volumeid.c | 123 ++++++++++++++++++++++++++++++++++++++++++++++ mount/mount.8 | 5 +- mount/mount_paths.h | 4 ++ 4 files changed, 138 insertions(+), 3 deletions(-) diff --git a/mount/Makefile.am b/mount/Makefile.am index e61261f..4562b2d 100644 --- a/mount/Makefile.am +++ b/mount/Makefile.am @@ -37,6 +37,15 @@ umount_LDADD += -lblkid -luuid swapon_LDADD = -lblkid -luuid endif +if HAVE_VOLUME_ID +mount_SOURCES += fsprobe_volumeid.c +umount_SOURCES += fsprobe_volumeid.c +swapon_SOURCES += fsprobe_volumeid.c +mount_LDADD += -lvolume_id +umount_LDADD += -lvolume_id +swapon_LDADD = -lvolume_id +endif + if HAVE_PIVOT_ROOT sbin_PROGRAMS += pivot_root man_MANS += pivot_root.8 diff --git a/mount/fsprobe_volumeid.c b/mount/fsprobe_volumeid.c new file mode 100644 index 0000000..8c13987 --- /dev/null +++ b/mount/fsprobe_volumeid.c @@ -0,0 +1,123 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "fsprobe.h" +#include "realpath.h" +#include "mount_paths.h" +#include "sundries.h" + +enum probe_type { + VOLUME_ID_NONE, + VOLUME_ID_LABEL, + VOLUME_ID_UUID, + VOLUME_ID_TYPE, +}; + +static char *probe(const char *device, enum probe_type type) +{ + int fd; + uint64_t size; + struct volume_id *id; + char *value = NULL; + + fd = open(device, O_RDONLY); + if (fd < 0) + return NULL; + + id = volume_id_open_fd(fd); + if (!id) + return NULL; + + /* TODO: use blkdev_get_size() */ + if (ioctl(fd, BLKGETSIZE64, &size) != 0) + size = 0; + + if (volume_id_probe_all(id, 0, size) == 0) { + switch(type) { + case VOLUME_ID_LABEL: + value = xstrdup(id->label); + break; + case VOLUME_ID_UUID: + value = xstrdup(id->uuid); + break; + case VOLUME_ID_TYPE: + value = xstrdup(id->type); + break; + default: + break; + } + } + + volume_id_close(id); + return value; +} + +void +fsprobe_init(void) +{ +} + +void +fsprobe_exit(void) +{ +} + +int +fsprobe_known_fstype(const char *fstype) +{ + /* TODO + if (volume_id_get_prober_by_type(fstype) != NULL) + return 1; + */ + return 0; +} + +const char * +fsprobe_get_uuid_by_devname(const char *devname) +{ + return probe(devname, VOLUME_ID_UUID); +} + +const char * +fsprobe_get_label_by_devname(const char *devname) +{ + return probe(devname, VOLUME_ID_LABEL); +} + +const char * +fsprobe_get_fstype_by_devname(const char *devname) +{ + return probe(devname, VOLUME_ID_TYPE); +} + +const char * +fsprobe_get_devname_by_uuid(const char *uuid) +{ + char dev[PATH_MAX]; + + if (!uuid) + return NULL; + + snprintf(dev, sizeof(dev), PATH_DEV_BYUUID "/%s", uuid); + return canonicalize(dev); +} + +const char * +fsprobe_get_devname_by_label(const char *label) +{ + char dev[PATH_MAX]; + + if (!label) + return NULL; + + snprintf(dev, sizeof(dev), PATH_DEV_BYLABEL "/%s", label); + return canonicalize(dev); +} + diff --git a/mount/mount.8 b/mount/mount.8 index 8ed5a11..be6e537 100644 --- a/mount/mount.8 +++ b/mount/mount.8 @@ -477,9 +477,8 @@ If no option is given, or if the .B auto type is specified, mount will try to guess the desired type. -If mount was compiled with the blkid library, the guessing is done -by this library. Otherwise, mount guesses itself by probing the -superblock; if that does not turn up anything that looks familiar, +Mount uses the blkid or volume_id library for guessing the filesystem +type; if that does not turn up anything that looks familiar, mount will try to read the file .IR /etc/filesystems , or, if that does not exist, diff --git a/mount/mount_paths.h b/mount/mount_paths.h index 9093b10..d726d06 100644 --- a/mount/mount_paths.h +++ b/mount/mount_paths.h @@ -15,4 +15,8 @@ #define ETC_FILESYSTEMS "/etc/filesystems" #define PROC_FILESYSTEMS "/proc/filesystems" +/* udev paths */ +#define PATH_DEV_BYLABEL "/dev/disk/by-label" +#define PATH_DEV_BYUUID "/dev/disk/by-uuid" + #endif /* MOUNT_PATHS_H */ -- 1.5.0.6 - To unsubscribe from this list: send the line "unsubscribe util-linux-ng" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html The util-linux-ng tests have to be useful with blkid and also with volume_id. Signed-off-by: Karel Zak --- tests/ts-cramfs-mkfs | 15 +++++++++++---- tests/ts-mkswap-doit | 16 ++++++++++++---- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/tests/ts-cramfs-mkfs b/tests/ts-cramfs-mkfs index 6a9e029..1f7156e 100755 --- a/tests/ts-cramfs-mkfs +++ b/tests/ts-cramfs-mkfs @@ -40,6 +40,11 @@ IMAGE_RE=$( echo $IMAGE | sed 's:/:\\/:g' ) LABEL="testCramfs" MOUNTPOINT="$TS_OUTDIR/cramfs-mnt" +ldd $TS_CMD_MOUNT | grep -q 'libvolume_id' 2>&1 >> $TS_OUTPUT +if [ "$?" == "0" ]; then + HAS_VOLUMEID="yes" +fi + echo "create mountpoint dir" >> $TS_OUTPUT if [ ! -d "$MOUNTPOINT" ]; then mkdir -p $MOUNTPOINT @@ -78,15 +83,17 @@ echo "create loop device from image" >> $TS_OUTPUT DEVICE=$( $TS_CMD_LOSETUP -f ) $TS_CMD_LOSETUP $DEVICE $IMAGE 2>&1 >> $TS_OUTPUT - echo "check the image" >> $TS_OUTPUT -blkid -c /dev/null -w /dev/null -s TYPE $DEVICE 2>&1 | grep -q 'TYPE="cramfs"' 2>&1 >> $TS_OUTPUT - -if [ "$?" != "0" ]; then +if [ "$($TS_CMD_MOUNT --guess-fstype $DEVICE)" != "cramfs" ]; then echo "Cannot found cramfs on $DEVICE" >> $TS_OUTPUT ts_finalize fi +if [ -n "$HAS_VOLUMEID" ] && [ ! -L "/dev/disk/by-label/$LABEL" ]; then + $TS_CMD_LOSETUP -d $DEVICE 2>&1 >> $TS_OUTPUT + ts_skip "udev ignores /dev/loop*" +fi + echo "mount the image" >> $TS_OUTPUT $TS_CMD_MOUNT -L $LABEL $MOUNTPOINT 2>&1 >> $TS_OUTPUT diff --git a/tests/ts-mkswap-doit b/tests/ts-mkswap-doit index 6e19b46..e4b5b76 100755 --- a/tests/ts-mkswap-doit +++ b/tests/ts-mkswap-doit @@ -38,6 +38,11 @@ IMAGE="$TS_OUTDIR/loop-swap.img" IMAGE_RE=$( echo $IMAGE | sed 's:/:\\/:g' ) LABEL="testSwap" +ldd $TS_CMD_SWAPON | grep -q 'libvolume_id' 2>&1 >> $TS_OUTPUT +if [ "$?" == "0" ]; then + HAS_VOLUMEID="yes" +fi + dd if=/dev/zero of=$IMAGE bs=1M count=20 &> /dev/null DEVICE=$( $TS_CMD_LOSETUP -f ) @@ -54,14 +59,17 @@ $TS_CMD_LOSETUP $DEVICE $IMAGE 2>&1 >> $TS_OUTPUT $TS_CMD_MKSWAP -L $LABEL $DEVICE 2>&1 >> $TS_OUTPUT # check it -blkid -c /dev/null -w /dev/null -s TYPE $DEVICE 2>&1 | grep -q 'TYPE="swap"' 2>&1 >> $TS_OUTPUT - -if [ "$?" != "0" ]; then +if [ "$($TS_CMD_MOUNT --guess-fstype $DEVICE)" != "swap" ]; then echo "Cannot found Linux swap on $DEVICE" >> $TS_OUTPUT - #$TS_CMD_LOSETUP -d $DEVICE 2>&1 >> $TS_OUTPUT + $TS_CMD_LOSETUP -d $DEVICE 2>&1 >> $TS_OUTPUT ts_finalize fi +if [ -n "$HAS_VOLUMEID" ] && [ ! -L "/dev/disk/by-label/$LABEL" ]; then + $TS_CMD_LOSETUP -d $DEVICE 2>&1 >> $TS_OUTPUT + ts_skip "udev ignores /dev/loop*" +fi + # try connect it to system (and found the device by label) $TS_CMD_SWAPON -L $LABEL 2>&1 >> $TS_OUTPUT -- 1.5.0.6 - To unsubscribe from this list: send the line "unsubscribe util-linux-ng" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html