Dave Gilbert wrote: > You're on 32bit, on 64bit this seems to work. My guess is that there is > a limit to the block size available on 32bit (if that limit was 2G or > just under it wouldn't surprise me), on 64bit there is a similar limit > somewhere : > > d...@major:~$ true | dd bs=3G count=1 > 0+0 records in > 0+0 records out > 0 bytes (0 B) copied, 2.1008e-05 s, 0.0 kB/s > d...@major:~$ true | dd bs=3E count=1 > dd: memory exhausted > d...@major:~$ true | dd bs=3Z count=1 > dd: invalid number `3Z' > > I can see an argument that there might want to put a better error message in, > or state that the bs is dependent on memory > size.
Thanks for the report. dd is trying to tell you not to specify such a large buffer size. A buffer size larger than a few megabytes is not normally useful. That diagnostic is not helpful indeed, but it was easy to fix, so I'll probably apply something like the following upstream. With the new diagnostic, you can see that dd tries (and fails) to allocate output buffers of the specified size: $ :|./dd bs=3EiB ./dd: failed to allocate an input buffer of size 3.0 EiB [Exit 1] $ :|./dd obs=3EiB ./dd: failed to allocate an output buffer of size 3.0 EiB [Exit 1] Making dd give a better diagnostic for e.g., "bs=3G" on an i686 system might be more work than it's worth. >From 899f17359bf4990888b54c5ae90c41a74529d04d Mon Sep 17 00:00:00 2001 From: Jim Meyering <meyer...@redhat.com> Date: Sun, 13 Jun 2010 17:34:45 +0200 Subject: [PATCH] dd: print a better diagnostic for an invalid block size MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * src/dd.c (dd_copy): Give a better diagnostic than "dd: memory exhausted" for an over-large bs= block size setting. Same for ibs= and obs=. Reported by Imre Péntek in http://bugs.launchpad.net/ubuntu/+source/coreutils/+bug/591969 --- src/dd.c | 25 +++++++++++++++++++++++-- 1 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/dd.c b/src/dd.c index 30d3d28..c9b8cbd 100644 --- a/src/dd.c +++ b/src/dd.c @@ -1557,6 +1557,16 @@ set_fd_flags (int fd, int add_flags, char const *name) } } +static char * +human_size (size_t n) +{ + static char hbuf[LONGEST_HUMAN_READABLE + 1]; + int human_opts = + (human_autoscale | human_round_to_nearest | human_base_1024 + | human_space_before_unit | human_SI | human_B); + return human_readable (n, hbuf, human_opts, 1, 1); +} + /* The main loop. */ static int @@ -1593,7 +1603,13 @@ dd_copy (void) It is necessary when accessing raw (i.e. character special) disk devices on Unixware or other SVR4-derived system. */ - real_buf = xmalloc (input_blocksize + INPUT_BLOCK_SLOP); + size_t sz = input_blocksize + INPUT_BLOCK_SLOP; + real_buf = malloc (sz); + if (!real_buf) + error (EXIT_FAILURE, 0, + _("failed to allocate an input buffer of size %s"), + human_size (sz)); + ibuf = real_buf; ibuf += SWAB_ALIGN_OFFSET; /* allow space for swab */ @@ -1602,7 +1618,12 @@ dd_copy (void) if (conversions_mask & C_TWOBUFS) { /* Page-align the output buffer, too. */ - real_obuf = xmalloc (output_blocksize + OUTPUT_BLOCK_SLOP); + sz = output_blocksize + OUTPUT_BLOCK_SLOP; + real_obuf = malloc (sz); + if (!real_obuf) + error (EXIT_FAILURE, 0, + _("failed to allocate an output buffer of size %s"), + human_size (sz)); obuf = ptr_align (real_obuf, page_size); } else -- 1.7.1.511.g2f531