diff options
Diffstat (limited to 'mount/mount_by_label.c')
-rw-r--r-- | mount/mount_by_label.c | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/mount/mount_by_label.c b/mount/mount_by_label.c index ee3b1d52e..2ae351d10 100644 --- a/mount/mount_by_label.c +++ b/mount/mount_by_label.c @@ -39,6 +39,30 @@ static struct uuidCache_s { char *device; } *uuidCache = NULL; +/* + * See whether this device has (the magic of) a RAID superblock at the end. + * If so, it probably is, or has been, part of a RAID array. + */ +static int +is_raid_partition(int fd) { + struct mdp_super_block mdsb; + int n; + + /* hardcode 4096 here in various places, because that's + what it's defined to be. Note that even if we used + the actual kernel headers, sizeof(mdp_super_t) is + slightly larger in the 2.2 kernel on 64-bit archs, + so using that wouldn't work. */ + lseek(fd, -4096, SEEK_END); /* Ignore possible error + about return value overflow */ + n = 4096; + if (sizeof(mdsb) < n) + n = sizeof(mdsb); + if (read(fd, &mdsb, n) != n) + return 1; /* error */ + return (mdsbmagic(mdsb) == MD_SB_MAGIC); +} + /* for now, only ext2, ext3 and xfs are supported */ static int get_label_uuid(const char *device, char **label, char *uuid) { @@ -56,6 +80,12 @@ get_label_uuid(const char *device, char **label, char *uuid) { if (fd < 0) return rv; + /* If there is a RAID partition, or an error, ignore this partition */ + if (is_raid_partition(fd)) { + close(fd); + return rv; + } + if (lseek(fd, 1024, SEEK_SET) == 1024 && read(fd, (char *) &e2sb, sizeof(e2sb)) == sizeof(e2sb) && (ext2magic(e2sb) == EXT2_SUPER_MAGIC)) { |