diff mbox series

R: [PATCH v2] stream_interface: Keep reading the cpio padding, if any, up to 512 bytes from the socket until the client stops writing.

Message ID DBBPR08MB4363391CD65411EA8F3FABB9F3EC0@DBBPR08MB4363.eurprd08.prod.outlook.com
State Not Applicable
Headers show
Series R: [PATCH v2] stream_interface: Keep reading the cpio padding, if any, up to 512 bytes from the socket until the client stops writing. | expand

Commit Message

Pedro Aguilar Feb. 24, 2020, 9:13 a.m. UTC
Hi Stefano,

The above patch follows all your suggestions except the function extract_padding() that remains inside the file cpio_utils.c since the 512 bytes padding is a cpio-related format.

Thanks.

Regards,
Pedro Aguilar.

Comments

Stefano Babic Feb. 28, 2020, 8:38 a.m. UTC | #1
On 24/02/20 10:13, Aguilar Pedro wrote:
> Hi Stefano,
> 
> The above patch follows all your suggestions except the function extract_padding() that remains inside the file cpio_utils.c since the 512 bytes padding is a cpio-related format.
> 

Patch is okay - I will merge it.

Regards,
Stefano


> Thanks.
> 
> Regards,
> Pedro Aguilar.
> 
> ________________________________________
> Da: Aguilar Pedro <Pedro.Aguilar@vimar.com>
> Inviato: lunedì 24 febbraio 2020 10:08
> A: swupdate@googlegroups.com
> Cc: Aguilar Pedro; Pesce Luca
> Oggetto: [PATCH v2] stream_interface: Keep reading the cpio padding, if any, up to 512 bytes from the socket until the client stops writing.
> 
> This avoids that the streaming client gets an EPIPE error when trying to write the padding to the IPC socket. This can happen when the streaming client is downloading very slowly and swupdate, after reading the trailer, closes the pipe.
> The cpio utility always adds a 512 bytes alignment after the file trailer, independently of the given format.
> 
> Signed-off-by: Pedro Aguilar <pedro.aguilar@vimar.com>
> Signed-off-by: Luca Pesce <luca.pesce@vimar.com>
> ---
>  core/cpio_utils.c       | 27 ++++++++++++++++++++++++++-
>  core/stream_interface.c |  5 +++++
>  include/cpiohdr.h       |  1 +
>  3 files changed, 32 insertions(+), 1 deletion(-)
> 
> diff --git a/core/cpio_utils.c b/core/cpio_utils.c
> index 03776e2..8cf4713 100644
> --- a/core/cpio_utils.c
> +++ b/core/cpio_utils.c
> @@ -79,6 +79,32 @@ static int fill_buffer(int fd, unsigned char *buf, unsigned int nbytes, unsigned
>         return count;
>  }
> 
> +/*
> + * Read padding that could exists between the cpio trailer and the end-of-file.
> + * cpio aligns the file to 512 bytes
> + */
> +void extract_padding(int fd, unsigned long *offset)
> +{
> +    int padding;
> +    ssize_t len;
> +       unsigned char buf[512];
> +
> +    if (fd < 0 || !offset)
> +        return;
> +
> +    padding = (512 - (*offset % 512)) % 512;
> +    if (padding) {
> +        TRACE("Expecting %d padding bytes at end-of-file", padding);
> +        len = read(fd, buf, padding);
> +        if (len < 0) {
> +            DEBUG("Failure while reading padding %d: %s", fd, strerror(errno));
> +            return;
> +        }
> +    }
> +
> +    return;
> +}
> +
>  /*
>   * Export the copy_write{,_*} functions to be used in other modules
>   * for copying a buffer to a file.
> @@ -760,7 +786,6 @@ int cpio_scan(int fd, struct swupdate_cfg *cfg, off_t start)
>         int file_listed;
>         uint32_t checksum;
> 
> -
>         while (1) {
>                 file_listed = 0;
>                 start = offset;
> diff --git a/core/stream_interface.c b/core/stream_interface.c
> index ff2f6d0..824c51a 100644
> --- a/core/stream_interface.c
> +++ b/core/stream_interface.c
> @@ -174,6 +174,11 @@ static int extract_files(int fd, struct swupdate_cfg *software)
>                                 return -1;
>                         }
>                         if (strcmp("TRAILER!!!", fdh.filename) == 0) {
> +                /*
> +                 * Keep reading the cpio padding, if any, up to 512 bytes from
> +                 * the socket until the client stops writing
> +                 */
> +                extract_padding(fd, &offset);
>                                 status = STREAM_END;
>                                 break;
>                         }
> diff --git a/include/cpiohdr.h b/include/cpiohdr.h
> index 855d5e8..aa1c9b1 100644
> --- a/include/cpiohdr.h
> +++ b/include/cpiohdr.h
> @@ -53,5 +53,6 @@ int get_cpiohdr(unsigned char *buf, unsigned long *size,
>                         unsigned long *namesize, unsigned long *chksum);
>  int extract_cpio_header(int fd, struct filehdr *fhdr, unsigned long *offset);
>  int extract_img_from_cpio(int fd, unsigned long offset, struct filehdr *fdh);
> +void extract_padding(int fd, unsigned long *offset);
> 
>  #endif
> --
> 2.17.1
>
diff mbox series

Patch

diff --git a/core/cpio_utils.c b/core/cpio_utils.c
index 03776e2..8cf4713 100644
--- a/core/cpio_utils.c
+++ b/core/cpio_utils.c
@@ -79,6 +79,32 @@  static int fill_buffer(int fd, unsigned char *buf, unsigned int nbytes, unsigned
        return count;
 }

+/*
+ * Read padding that could exists between the cpio trailer and the end-of-file.
+ * cpio aligns the file to 512 bytes
+ */
+void extract_padding(int fd, unsigned long *offset)
+{
+    int padding;
+    ssize_t len;
+       unsigned char buf[512];
+
+    if (fd < 0 || !offset)
+        return;
+
+    padding = (512 - (*offset % 512)) % 512;
+    if (padding) {
+        TRACE("Expecting %d padding bytes at end-of-file", padding);
+        len = read(fd, buf, padding);
+        if (len < 0) {
+            DEBUG("Failure while reading padding %d: %s", fd, strerror(errno));
+            return;
+        }
+    }
+
+    return;
+}
+
 /*
  * Export the copy_write{,_*} functions to be used in other modules
  * for copying a buffer to a file.
@@ -760,7 +786,6 @@  int cpio_scan(int fd, struct swupdate_cfg *cfg, off_t start)
        int file_listed;
        uint32_t checksum;

-
        while (1) {
                file_listed = 0;
                start = offset;
diff --git a/core/stream_interface.c b/core/stream_interface.c
index ff2f6d0..824c51a 100644
--- a/core/stream_interface.c
+++ b/core/stream_interface.c
@@ -174,6 +174,11 @@  static int extract_files(int fd, struct swupdate_cfg *software)
                                return -1;
                        }
                        if (strcmp("TRAILER!!!", fdh.filename) == 0) {
+                /*
+                 * Keep reading the cpio padding, if any, up to 512 bytes from
+                 * the socket until the client stops writing
+                 */
+                extract_padding(fd, &offset);
                                status = STREAM_END;
                                break;
                        }
diff --git a/include/cpiohdr.h b/include/cpiohdr.h
index 855d5e8..aa1c9b1 100644
--- a/include/cpiohdr.h
+++ b/include/cpiohdr.h
@@ -53,5 +53,6 @@  int get_cpiohdr(unsigned char *buf, unsigned long *size,
                        unsigned long *namesize, unsigned long *chksum);
 int extract_cpio_header(int fd, struct filehdr *fhdr, unsigned long *offset);
 int extract_img_from_cpio(int fd, unsigned long offset, struct filehdr *fdh);
+void extract_padding(int fd, unsigned long *offset);

 #endif