From: Douglas Gilbert <dougg@torque.net>
To: Andries.Brouwer@cwi.nl
Cc: linux-kernel@vger.kernel.org
Subject: Re: rfc: test whether a device has a partition table
Date: Thu, 25 Sep 2003 10:42:44 +1000 [thread overview]
Message-ID: <3F723A04.2000609@torque.net> (raw)
In-Reply-To: <UTC200309242029.h8OKTo008219.aeb@smtp.cwi.nl>
Andries.Brouwer@cwi.nl wrote:
> As everyone knows it is a bad idea to let the kernel guess
> whether there is a partition table on a given block device,
> and if so, of what type.
> Nevertheless this is what almost everybody does.
>
> Until now the philosophy was: floppies do not have a partition table,
> disks do have one, and for ZIP drives nobody knows. With USB we get
> more types of block device that may or may not have a partition table
> (and if they have none, usually there is a FAT filesystem with bootsector).
> In such cases the kernel assumes a partition table, and creates a mess
> if there was none. Some heuristics are needed.
>
> Many checks are possible (for a DOS-type partition table: boot indicator
> must be 0 or 0x80, partitions are not larger than the disk,
> non-extended partitions are mutually disjoint; for a boot sector:
> it starts with a jump, the number of bytes per sector is 512 or
> at least a power of two, the number of sectors per cluster is 1
> or at least a power of two, the number of reserved sectors is 1 or 32,
> the number of FAT copies is 2, ...).
>
> I tried a minimal test, and the below is good enough for the
> boot sectors and DOS-type partition tables that I have here.
>
> So, question: are there people with DOS-type partition tables
> or FAT fs bootsectors where the below gives the wrong answer?
> I would be interested in a copy of the sector.
>
> I expect to submit some sanity check to DOS-type partition table
> parsing, and hope to recognize with high probability the presence
> of a full disk FAT filesystem.
>
> Andries
>
> ------------ sniffsect.c -----------------
>
> /*
> * Given a block device, does it have a DOS-type partition table?
> * Or does it behave like a floppy and have a whole-disk filesystem?
> * Or is it something else?
> *
> * Return 1 for pt, -1 for boot sect, 0 for unknown.
> */
>
> #include <stdio.h>
> #include <fcntl.h>
>
> /* DOS-type partition */
> struct partition {
> unsigned char bootable; /* 0 or 0x80 */
> unsigned char begin_chs[3];
> unsigned char systype;
> unsigned char end_chs[3];
> unsigned char start_sect[4];
> unsigned char nr_sects[4];
> };
>
> int sniffsect(unsigned char *p) {
> struct partition *pt;
> int i, n;
> int maybept = 1;
> int maybebs = 1;
>
> /* Both DOS-type pt and boot sector have a 55 aa signature */
> if (p[510] != 0x55 || p[511] != 0xaa)
> return 0;
>
> /* A partition table has boot indicators 0 or 0x80 */
> for (i=0; i<4; i++) {
> pt = (struct partition *)(p + 446 + 16*i);
> if (pt->bootable != 0 && pt->bootable != 0x80)
> maybept = 0;
> }
>
> /* A boot sector has a power of two as #sectors/cluster */
> n = p[13];
> if (n == 0 || (n & (n-1)) != 0)
> maybebs = 0;
>
> /* A boot sector has a power of two as #bytes/sector */
> n = (p[12] << 8) + p[11];
> if (n == 0 || (n & (n-1)) != 0)
> maybebs = 0;
>
> return maybept - maybebs;
> }
>
> int main(int argc, char **argv) {
> unsigned char sect[512];
> int fd, n;
>
> if (argc != 2) {
> fprintf(stderr, "Call: sniffsect file\n");
> exit(1);
> }
>
> fd = open(argv[1], O_RDONLY);
> if (fd == -1) {
> perror(argv[1]);
> fprintf(stderr, "Cannot open %s\n", argv[1]);
> exit(1);
> }
>
> n = read(fd, sect, sizeof(sect));
> if (n != sizeof(sect)) {
> if (n == -1)
> perror(argv[1]);
> fprintf(stderr, "Cannot read 512 bytes from %s\n", argv[1]);
> exit(1);
> }
>
> n = sniffsect(sect);
> printf((n == 1) ? "partition table\n" :
> (n == -1) ? "boot sector\n" : "no idea\n");
> return 0;
> }
>
I have a USB 500 MB USB key that confuses linux (both 2.4 and
2.6) since it has no partition table. It shows up on my laptop as:
$ cat /proc/scsi/scsi
Attached devices:
Host: scsi0 Channel: 00 Id: 00 Lun: 00
Vendor: Prolific Model: USBFlashDisk Rev: 1.00
Type: Direct-Access ANSI SCSI revision: 02
I can mount it with:
$ mount /dev/sda /mnt/extra
$ df
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/hda3 14108400 9458612 3933100 71% /
none 192256 0 192256 0% /dev/shm
/dev/sda 511856 103328 408528 21% /mnt/extra
sniffsect correctly identifies the difference between the USB
"floppy" and my main disk:
$ ./sniffsect /dev/sda
boot sector
$ ./sniffsect /dev/hda
partition table
Doug Gilbert
next prev parent reply other threads:[~2003-09-25 0:50 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2003-09-24 20:29 rfc: test whether a device has a partition table Andries.Brouwer
2003-09-24 21:54 ` Linus Torvalds
2003-09-24 23:50 ` Andries Brouwer
2003-09-25 0:05 ` viro
2003-09-25 12:14 ` Andries Brouwer
2003-09-25 0:18 ` Linus Torvalds
2003-09-25 6:53 ` Xavier Bestel
2003-09-25 10:57 ` Andries Brouwer
2003-09-25 4:47 ` Linus Torvalds
2003-09-25 4:56 ` Linus Torvalds
2003-09-25 11:42 ` Andries Brouwer
2003-10-05 9:00 ` Meelis Roos
2003-09-25 0:42 ` Douglas Gilbert [this message]
2003-09-25 1:00 ` viro
2003-09-25 1:27 ` Douglas Gilbert
-- strict thread matches above, loose matches on Subject: below --
2004-05-22 11:18 Uwe Bonnes
2004-05-22 12:37 ` John Bradford
2004-05-22 12:56 ` Andries Brouwer
2004-05-22 15:14 ` Uwe Bonnes
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=3F723A04.2000609@torque.net \
--to=dougg@torque.net \
--cc=Andries.Brouwer@cwi.nl \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.