On 10/04/17 09:39, David Balažic wrote: > On 10 April 2017 at 18:04, David Balažic wrote: >> On 10 April 2017 at 17:05, Pádraig Brady wrote: >>> On 10/04/17 06:37, David Balažic wrote: >>>> Hi! >>>> >>>> Using dd on Ubuntu 16.04.2 LTS (64 bit) I discovered this behavior >>>> that was (for me) unexpected. >>>> >>>> There is a bad sector on /dev/sda which on read attempt returns an i/o >>>> error. >>>> Suppose it is sector number 50. >>>> >>>> So: dd if=/dev/sda bs=512 count=1 skip=50 >>>> result: I/O error printed on stderr, exit status code is 1 (non zero, >>>> don't remember the exact value) >>>> >>>> But this: dd if=/dev/sda bs=2048 count=1 skip=12 >>>> returns exit code 0 and no error. It reads 1024 bytes (up to the >>>> erroring sector) >>>> >>>> Is this by design? I would expect an I/O error to be reported (in exit >>>> code). >>> >>> Your probably hitting the default short read behavior of dd >>> which is defined by POSIX. I.E. the read() system call will >>> return what's available before returning the read() error, >>> however with a count=1 dd will only consider the first read operation. >>> >>> You can change this operation with the iflag=fullblock flag. >>> Note also the conv=sync,noerror settings which would be useful >>> for reading as much as possible from the disk. >> >> Thanks. >> The dd docs (at [1]) say: >> >> ‘fullblock’ >> >> Accumulate full blocks from input. The read system call may return >> early if a full block is not available. When that happens, continue >> calling read to fill the remainder of the block. This flag can be used >> only with iflag. This flag is useful with pipes for example as they >> may return short reads. In that case, this flag is needed to ensure >> that a ‘count=’ argument is interpreted as a block count rather than a >> count of read operations. >> >> >> Does POSIX mandate treating short reads and error reads the same? Can >> you point me to the relevant text? >> >> >> [1] >> https://www.gnu.org/software/coreutils/manual/html_node/dd-invocation.html#dd-invocation > > > I checked the reading code in dd (see below) and apparently if would > fail on read error, if it were reported by the read() function. > So apparently it is read() not reporting the error. I'll check with kernel > guys.
Everything is behaving as expected here. The read() call returns less than asked for, but that's fine and best to do as it's better to provide what's available. A subsequent read() will fail though, but because dd is limited to only 1 read() with count=1 (and without iflag=fullblock) that error is never encountered by dd. cheers, Pádraig
