[comp.sys.sgi] bug in reading from disk partitions

chk%alias@csri.toronto.edu (C. Harald Koch) (11/27/90)

I was writing a program to copy disk partitions with verbose output because
of a failing drive.

I discovered the following problem:

I open the partition read-only.

when I attempt a read() system call where the current offset is within the
partition, but the length of the read passes the end of the partition, the
read fails without reading any information. Thus a 'standard' copy loop
of the form

	while((size = read(fd, buf, BUFSIZE)) > 0) {
		write(newfd, buf, size);
	}

fails at the end of file *without* copying the last partial buffer.
(Normally, the read should return 'BUFSIZE' for all reads except the one
described, where it should return the number of bytes between the current
offset and the end of the partition. The next read after that should return
0, signifying the end of the partition. This is standard UNIX read()
semantics...)

On a SCSI drive, it failes with 'ENOSPC', while on an ESDI drive it fails
with 'ENXIO'.

This happens with both the character and block special devices, on both SCSI
and ESDI drives. I am running under IRIX 3.3.1.

If it were important, I would like to write a program to figure out the size
of the partition and copy exactly the right amount of data, but I don't know
how to figure out the raw size of a partition. Can anyone at SGI tell me how
to do this?

For now, I am just going to copy the last partial block using dd(1) and a
512 byte buffer...

--
C. Harald Koch  VE3TLA                Alias Research, Inc., Toronto ON Canada
chk%alias@csri.utoronto.ca      chk@gpu.utcs.toronto.edu      chk@chk.mef.org
"Open the Zamboni! We're coming out!" - Kathrin Garland and Anson James, 2299

jeremy@perf2.asd.sgi.com (Jeremy Higdon) (11/29/90)

In article <1990Nov27.031543.16150@alias.uucp>, chk%alias@csri.toronto.edu (C. Harald Koch) writes:
> 
> If it were important, I would like to write a program to figure out the size
> of the partition and copy exactly the right amount of data, but I don't know
> how to figure out the raw size of a partition. Can anyone at SGI tell me how
> to do this?
>

The partition information is in the disk label (the first 512 bytes of
the volume header (??????vh) partition).  See /usr/include/sys/dvh.h and
vh(7m) for more info.

olson@anchor.esd.sgi.com (Dave Olson) (11/30/90)

In <76400@sgi.sgi.com> jeremy@perf2.asd.sgi.com (Jeremy Higdon) writes:

| In article <1990Nov27.031543.16150@alias.uucp>, chk%alias@csri.toronto.edu (C. Harald Koch) writes:
| > 
| > If it were important, I would like to write a program to figure out the size
| > of the partition and copy exactly the right amount of data, but I don't know
| > how to figure out the raw size of a partition. Can anyone at SGI tell me how
| > to do this?
| >
| 
| The partition information is in the disk label (the first 512 bytes of
| the volume header (??????vh) partition).  See /usr/include/sys/dvh.h and
| vh(7m) for more info.
| 

Also see the ioctls in sys/dkio.h.  In particular, look at DIOCGETVH, which
will return the volume header info for you.  It is recommended that you
use the ioctl rather than reading the volume header info directly, because
some of the drivers will patch up the volume header info when first opened,
if it appears unreasonable (e.g., with SCSI, if the partition size plus
its offset is greater than the drive capacity as returned by the SCSI
readcapacity operation.

The DIOCGETVH ioctl takes as the 3rd argument a pointer to a
struct volume_header.  You must be using the character device
for the ioctl to work.
--

	Dave Olson

Life would be so much easier if we could just look at the source code.

chk%alias@csri.toronto.edu (C. Harald Koch) (12/03/90)

In <76400@sgi.sgi.com> jeremy@perf2.asd.sgi.com (Jeremy Higdon) writes:

>The partition information is in the disk label (the first 512 bytes of
>the volume header (??????vh) partition).  See /usr/include/sys/dvh.h and
>vh(7m) for more info.

Do you have any idea how non-portable that is? It depends too much on both
the hardware platform and the OS version.

At the risk of driving the dagger deeper into SGI's heart, it works fine on
both the RS/6000 and a Sun running 3.5... Perhaps you should consider fixing
the driver in the next release?

As pointed out to me by several people, The easy fix is to remember where I
am while reading. When I get a read error, seek back to that position and
read the rest of the disk using smaller blocks.

While this works, it is a hideous kludge.

--
C. Harald Koch  VE3TLA                Alias Research, Inc., Toronto ON Canada
chk%alias@csri.utoronto.ca      chk@gpu.utcs.toronto.edu      chk@chk.mef.org
"Open the Zamboni! We're coming out!" - Kathrin Garland and Anson James, 2299

jeremy@perf2.asd.sgi.com (Jeremy Higdon) (12/10/90)

In article <1990Dec3.151353.21737@alias.uucp>, chk%alias@csri.toronto.edu (C. Harald Koch) writes:
> In <76400@sgi.sgi.com> jeremy@perf2.asd.sgi.com (Jeremy Higdon) writes:
> 
> >The partition information is in the disk label (the first 512 bytes of
> >the volume header (??????vh) partition).  See /usr/include/sys/dvh.h and
> >vh(7m) for more info.
> 
> Do you have any idea how non-portable that is? It depends too much on both
> the hardware platform and the OS version.
> 
> [ . . . .]

The question I was responding to was how to get partition sizes.
The preferred way, by the way, is to use the DIOCGETVH ioctl, as
Dave Olson pointed out later.

I was not commenting on the merits of returning short reads vs.
errors at the end of a partition.