Ensure write failure reports no-disk-space
authorAlvaro Herrera <alvherre@alvh.no-ip.org>
Fri, 19 Jun 2020 20:46:07 +0000 (16:46 -0400)
committerAlvaro Herrera <alvherre@alvh.no-ip.org>
Fri, 19 Jun 2020 20:46:07 +0000 (16:46 -0400)
A few places calling fwrite and gzwrite were not setting errno to ENOSPC
when reporting errors, as is customary; this led to some failures being
reported as
"could not write file: Success"
which makes us look silly.  Make a few of these places in pg_dump and
pg_basebackup use our customary pattern.

Backpatch-to: 9.5
Author: Justin Pryzby <pryzby@telsasoft.com>
Author: Tom Lane <tgl@sss.pgh.pa.us>
Author: Álvaro Herrera <alvherre@alvh.no-ip.org>
Discussion: https://postgr.es/m/20200611153753.GU14879@telsasoft.com

src/bin/pg_basebackup/pg_basebackup.c
src/bin/pg_dump/pg_backup_directory.c

index 256c0c074c7522a51885157f3b5afcee578dc8df..4f29671d0cdc8a41d4aea63c300812ad3a909998 100644 (file)
@@ -992,8 +992,12 @@ writeTarData(WriteTarState *state, char *buf, int r)
 #ifdef HAVE_LIBZ
    if (state->ztarfile != NULL)
    {
+       errno = 0;
        if (gzwrite(state->ztarfile, buf, r) != r)
        {
+           /* if write didn't set errno, assume problem is no disk space */
+           if (errno == 0)
+               errno = ENOSPC;
            pg_log_error("could not write to compressed file \"%s\": %s",
                         state->filename, get_gz_error(state->ztarfile));
            exit(1);
@@ -1002,8 +1006,12 @@ writeTarData(WriteTarState *state, char *buf, int r)
    else
 #endif
    {
+       errno = 0;
        if (fwrite(buf, r, 1, state->tarfile) != 1)
        {
+           /* if write didn't set errno, assume problem is no disk space */
+           if (errno == 0)
+               errno = ENOSPC;
            pg_log_error("could not write to file \"%s\": %m",
                         state->filename);
            exit(1);
@@ -1691,8 +1699,12 @@ ReceiveTarAndUnpackCopyChunk(size_t r, char *copybuf, void *callback_data)
            return;
        }
 
+       errno = 0;
        if (fwrite(copybuf, r, 1, state->file) != 1)
        {
+           /* if write didn't set errno, assume problem is no disk space */
+           if (errno == 0)
+               errno = ENOSPC;
            pg_log_error("could not write to file \"%s\": %m", state->filename);
            exit(1);
        }
@@ -1743,8 +1755,12 @@ ReceiveBackupManifestChunk(size_t r, char *copybuf, void *callback_data)
 {
    WriteManifestState *state = callback_data;
 
+   errno = 0;
    if (fwrite(copybuf, r, 1, state->file) != 1)
    {
+       /* if write didn't set errno, assume problem is no disk space */
+       if (errno == 0)
+           errno = ENOSPC;
        pg_log_error("could not write to file \"%s\": %m", state->filename);
        exit(1);
    }
index ac81151acc9d117997be3dc4637a19841d1acec3..cb0f7f31fd7d26b87d2983b18f4a41351490574c 100644 (file)
@@ -346,9 +346,15 @@ _WriteData(ArchiveHandle *AH, const void *data, size_t dLen)
 {
    lclContext *ctx = (lclContext *) AH->formatData;
 
+   errno = 0;
    if (dLen > 0 && cfwrite(data, dLen, ctx->dataFH) != dLen)
+   {
+       /* if write didn't set errno, assume problem is no disk space */
+       if (errno == 0)
+           errno = ENOSPC;
        fatal("could not write to output file: %s",
              get_cfp_error(ctx->dataFH));
+   }
 }
 
 /*
@@ -481,9 +487,15 @@ _WriteByte(ArchiveHandle *AH, const int i)
    unsigned char c = (unsigned char) i;
    lclContext *ctx = (lclContext *) AH->formatData;
 
+   errno = 0;
    if (cfwrite(&c, 1, ctx->dataFH) != 1)
+   {
+       /* if write didn't set errno, assume problem is no disk space */
+       if (errno == 0)
+           errno = ENOSPC;
        fatal("could not write to output file: %s",
              get_cfp_error(ctx->dataFH));
+   }
 
    return 1;
 }
@@ -511,9 +523,15 @@ _WriteBuf(ArchiveHandle *AH, const void *buf, size_t len)
 {
    lclContext *ctx = (lclContext *) AH->formatData;
 
+   errno = 0;
    if (cfwrite(buf, len, ctx->dataFH) != len)
+   {
+       /* if write didn't set errno, assume problem is no disk space */
+       if (errno == 0)
+           errno = ENOSPC;
        fatal("could not write to output file: %s",
              get_cfp_error(ctx->dataFH));
+   }
 }
 
 /*