Skip to content

dd: does not handle lots of rapid SIGUSR1 signals with large block writes #5902

@jfinkels

Description

@jfinkels

In the GNU test suite tests/dd/stats.sh checks that dd reports transfer statistics correctly when it receives the signal SIGUSR1. This is tested by starting a dd process that writes a lot of zeros to a named pipe, starting another process that reads from that named pipe, and then sending a bunch of SIGUSR1 signals to the dd process to force it to report progress. Unfortunately, uutils dd fails to write all the bytes to the named pipe.

In summary, the dd process is invoked as

dd iflag=fullblock if=/dev/zero of=fifo count=50 bs=5000000 2>err & pid=$!

and the SIGUSR1 signals are produced via

  until ! kill -s USR1 $pid 2>/dev/null; do
    sleep .01
  done

When using coreutils dd, this results in a predictable sequence of progress reports, one for each signal:

# ...
6+0 records in
5+0 records out
25000000 bytes (25 MB, 24 MiB) copied, 0.0387354 s, 645 MB/s
8+0 records in
7+0 records out
35000000 bytes (35 MB, 33 MiB) copied, 0.0535897 s, 653 MB/s
11+0 records in
10+0 records out
50000000 bytes (50 MB, 48 MiB) copied, 0.0688566 s, 726 MB/s
# ...

But for uutils dd (on my machine anyway), the signals do not result in a progress report (or they are not handled quickly enough? I'm not sure).

Additionally, the final progress report indicates that some blocks were only partially written to the named pipe:

50+0 records in
42+8 records out
224286848 bytes (224 MB, 214 MiB) copied, 0.0989137 s, 2.3 GB/s

but we expected

50+0 records in
50+0 records out
250000000 bytes (250 MB, 238 MiB) copied, 0.314097 s, 796 MB/s

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions