mount: fsprobe: remove non-blkid code

This patch removes old FS detection code and enables
blkid code only when HAVE_BLKID is defined.

Signed-off-by: Karel Zak <kzak@redhat.com>
This commit is contained in:
Karel Zak 2007-05-09 16:29:27 +02:00
parent 0964afe10d
commit 3d823454c6
10 changed files with 6 additions and 1389 deletions

View File

@ -7,13 +7,12 @@ 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 sundries.h
getusername.h loop.h sundries.h
mount_common = fstab.c sundries.c xmalloc.c realpath.c mount_mntent.c \
getusername.c get_label_uuid.c mount_by_label.c fsprobe_blkid.c \
lomount.c $(MNTHDRS) ../lib/env.c
getusername.c lomount.c $(MNTHDRS) ../lib/env.c
mount_SOURCES = mount.c $(mount_common) ../lib/setproctitle.c \
mount_guess_fstype.c
@ -25,7 +24,6 @@ umount_CFLAGS = $(SUID_CFLAGS) $(AM_CFLAGS)
umount_LDFLAGS = $(SUID_LDFLAGS) $(AM_LDFLAGS)
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
@ -36,6 +34,9 @@ umount_LDADD =
swapon_LDADD =
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

View File

@ -41,71 +41,4 @@ mount_get_devname_for_mounting(const char *spec) {
return blkid_get_devname(blkid, spec, 0);
}
#else
#include <string.h>
#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

View File

@ -1,221 +0,0 @@
#ifndef HAVE_LIBBLKID
/*
* Get label. Used by mount, umount and swapon.
*/
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include "xmalloc.h"
#include "linux_fs.h"
#include "get_label_uuid.h"
#include "../disk-utils/swapheader.h"
/*
* See whether this device has (the magic of) a RAID superblock at the end.
* 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

View File

@ -1 +0,0 @@
int get_label_uuid(const char *device, char **label, char *uuid);

View File

@ -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));
}

View File

@ -39,7 +39,6 @@
#include "loop.h"
#include "linux_fs.h" /* for BLKGETSIZE */
#include "mount_guess_fstype.h"
#include "mount_by_label.h"
#include "getusername.h"
#include "mount_paths.h"
#include "env.h"

View File

@ -1,363 +0,0 @@
#ifndef HAVE_LIBBLKID
/*
* mount_by_label.c - aeb
*
* 1999-02-22 Arkadiusz Mikiewicz <misiek@pld.ORG.PL>
* - added Native Language Support
* 2000-01-20 James Antill <james@and.org>
* - Added error message if /proc/partitions cannot be opened
* 2000-05-09 Erik Troan <ewt@redhat.com>
* - Added cache for UUID and disk labels
* 2000-11-07 Nathan Scott <nathans@sgi.com>
* - Added XFS support
* 2001-11-22 Kirby Bohling <kbohling@birddog.com>
* - Added support of labels on LVM
* 2002-03-21 Christoph Hellwig <hch@infradead.org>
* - Added JFS support
* 2002-07-11 Christoph Hellwig <hch@infradead.org>
* - Added JFS v2 format support
* 2002-07-26 Luciano Chavez <lnx1138@us.ibm.com>
* - Added EVMS support
*/
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h> /* needed for opendir */
#include <dirent.h>
#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

View File

@ -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);

View File

@ -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 <jmorriso@bogomips.ww.ubc.ca>; made into a function
for mount(8) by Mike Grupenhoff <kashmir@umiacs.umd.edu>.
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 <mkp@linuxcare.com>
Added cramfs, hfs, hpfs, adfs - Sepp Wijnands <mrrazz@garbage-coderz.net>
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;

View File

@ -15,7 +15,6 @@
#include "swap_constants.h"
#include "nls.h"
#include "fsprobe.h"
#include "mount_by_label.h"
#include "realpath.h"
#define streq(s, t) (strcmp ((s), (t)) == 0)