diff mbox series

swupdate: add attribute readout-verify

Message ID 20200226073723.30298-1-zhuangqiubin@gmail.com
State Rejected
Headers show
Series swupdate: add attribute readout-verify | expand

Commit Message

zqb-all Feb. 26, 2020, 7:37 a.m. UTC
From: zhuangqiubin <zhuangqiubin@allwinnertech.com>

This commit add an attribute readout-verify.
With this attribute, swupdate will read data and
do verify after each write.

Signed-off-by: zhuangqiubin <zhuangqiubin@allwinnertech.com>
---

 core/cpio_utils.c       | 78 +++++++++++++++++++++++++++++++++++++++++
 handlers/raw_handler.c  |  5 ++-
 include/swupdate.h      |  1 +
 include/util.h          |  1 +
 parser/parse_external.c |  2 ++
 parser/parser.c         |  1 +
 6 files changed, 87 insertions(+), 1 deletion(-)

Comments

Stefano Babic Feb. 28, 2020, 10:04 a.m. UTC | #1
On 26.02.20 08:37, zhuangqiubin wrote:
> From: zhuangqiubin <zhuangqiubin@allwinnertech.com>
> 
> This commit add an attribute readout-verify.
> With this attribute, swupdate will read data and
> do verify after each write.
> 
> Signed-off-by: zhuangqiubin <zhuangqiubin@allwinnertech.com>
> ---
> 
>  core/cpio_utils.c       | 78 +++++++++++++++++++++++++++++++++++++++++
>  handlers/raw_handler.c  |  5 ++-
>  include/swupdate.h      |  1 +
>  include/util.h          |  1 +
>  parser/parse_external.c |  2 ++
>  parser/parser.c         |  1 +
>  6 files changed, 87 insertions(+), 1 deletion(-)
> 
> diff --git a/core/cpio_utils.c b/core/cpio_utils.c
> index 03776e2..8dfb4d7 100644
> --- a/core/cpio_utils.c
> +++ b/core/cpio_utils.c
> @@ -110,6 +110,84 @@ int copy_write(void *out, const void *buf, unsigned int len)
>  	return 0;
>  }
>  
> +int copy_lseek_back(void *out, const void *buf, unsigned int len)
> +{
> +	int ret;
> +	int fd = (out != NULL) ? *(int *)out : -1;
> +	off_t offset_back = (off_t)len * -1;
> +
> +	if (lseek(fd, offset_back, SEEK_CUR) < 0) {
> +		ERROR("cannot lseek %d bytes back: %s", len, strerror(errno));
> +		return -1;
> +	}
> +
> +	return 0;
> +}
> +
> +int copy_verify(void *in, void *buf, unsigned int len, const void *source_buf)
> +{
> +	int ret;
> +	int fd = (in != NULL) ? *(int *)in : -1;
> +
> +	while (len) {
> +		errno = 0;
> +		ret = read(fd, buf, len);
> +		if (ret < 0) {
> +			if (errno == EINTR)
> +				continue;
> +			ERROR("cannot read %d bytes: %s", len, strerror(errno));
> +			return -1;
> +		}
> +
> +		if (ret == 0) {
> +			ERROR("cannot read %d bytes: %s", len, strerror(errno));
> +			return -1;
> +		}
> +
> +		if (memcmp(buf, source_buf, ret) != 0) {
> +			ERROR("verify fail\n");
> +			return -1;
> +		}
> +
> +		len -= ret;
> +		buf += ret;
> +		source_buf += ret;
> +	}
> +
> +	return 0;
> +}
> +
> +int copy_write_verify(void *out, const void *buf, unsigned int len)
> +{
> +	int ret;
> +	int fd = (out != NULL) ? *(int *)out : -1;
> +	void *verify_buf;
> +
> +	verify_buf = malloc(len);
> +	if (!verify_buf) {
> +		ERROR("No memory: malloc %d for verify failed", len);
> +		goto copy_write_verify_exit;
> +	}
> +
> +	ret = copy_write(out, buf, len);
> +	if (ret != 0)
> +		goto copy_write_verify_exit;
> +
> +	ret = copy_lseek_back(out, buf, len);
> +	if (ret != 0)
> +		goto copy_write_verify_exit;
> +
> +	ret = copy_verify(out, verify_buf, len, buf);
> +	if (ret != 0)
> +		goto copy_write_verify_exit;
> +
> +copy_write_verify_exit:
> +	if (verify_buf)
> +		free(verify_buf);
> +
> +	return ret;
> +}
> +
>  #if defined(__FreeBSD__)
>  /*
>   * FreeBSD likes to have multiples of 512 bytes written
> diff --git a/handlers/raw_handler.c b/handlers/raw_handler.c
> index fb48170..1011f05 100644
> --- a/handlers/raw_handler.c
> +++ b/handlers/raw_handler.c
> @@ -124,7 +124,10 @@ static int install_raw_image(struct img_type *img,
>  #if defined(__FreeBSD__)
>  	ret = copyimage(&fdout, img, copy_write_padded);
>  #else
> -	ret = copyimage(&fdout, img, NULL);
> +	if (img->readout_verify)
> +		ret = copyimage(&fdout, img, copy_write_verify);
> +	else
> +		ret = copyimage(&fdout, img, NULL);
>  #endif
>  
>  	if (prot_stat == 1) {
> diff --git a/include/swupdate.h b/include/swupdate.h
> index 8cd1574..941d1f9 100644
> --- a/include/swupdate.h
> +++ b/include/swupdate.h
> @@ -75,6 +75,7 @@ struct img_type {
>  	int preserve_attributes; /* whether to preserve attributes in archives */
>  	int is_encrypted;
>  	int install_directly;
> +	int readout_verify;
>  	int is_script;
>  	int is_partitioner;
>  	struct dict properties;
> diff --git a/include/util.h b/include/util.h
> index 906be9a..44bfa9e 100644
> --- a/include/util.h
> +++ b/include/util.h
> @@ -165,6 +165,7 @@ typedef int (*writeimage) (void *out, const void *buf, unsigned int len);
>  
>  int openfile(const char *filename);
>  int copy_write(void *out, const void *buf, unsigned int len);
> +int copy_write_verify(void *out, const void *buf, unsigned int len);
>  #if defined(__FreeBSD__)
>  int copy_write_padded(void *out, const void *buf, unsigned int len);
>  #endif
> diff --git a/parser/parse_external.c b/parser/parse_external.c
> index ef6c74c..ee995c9 100644
> --- a/parser/parse_external.c
> +++ b/parser/parse_external.c
> @@ -102,6 +102,8 @@ static void sw_append_stream(struct img_type *img, const char *key,
>  		img->id.install_if_different = 1;
>  	if (!strcmp(key, "install-if-higher"))
>  		img->id.install_if_higher = 1;
> +	if (!strcmp(key, "readout-verify"))
> +		img->readout_verify = 1;
>  }
>  
>  int parse_external(struct swupdate_cfg *software, const char *filename)
> diff --git a/parser/parser.c b/parser/parser.c
> index 8cdbfb4..cf6cd6c 100644
> --- a/parser/parser.c
> +++ b/parser/parser.c
> @@ -308,6 +308,7 @@ static int parse_common_attributes(parsertype p, void *elem, struct img_type *im
>  	get_field(p, elem, "install-if-different", &image->id.install_if_different);
>  	get_field(p, elem, "install-if-higher", &image->id.install_if_higher);
>  	get_field(p, elem, "encrypted", &image->is_encrypted);
> +	get_field(p, elem, "readout-verify", &image->readout_verify);
>  
>  	return 0;
>  }

NAK: this feature is already in SWUpdate with the "readback" handler -
just use it.

Best regards,
Stefano Babic
zqb-all Feb. 29, 2020, 10:43 a.m. UTC | #2
I did not notice that as I am using v2019.11. Thank you, I will try it.

Stefano Babic <sbabic@denx.de> 于2020年2月28日周五 下午6:04写道:

> On 26.02.20 08:37, zhuangqiubin wrote:
> > From: zhuangqiubin <zhuangqiubin@allwinnertech.com>
> >
> > This commit add an attribute readout-verify.
> > With this attribute, swupdate will read data and
> > do verify after each write.
> >
> > Signed-off-by: zhuangqiubin <zhuangqiubin@allwinnertech.com>
> > ---
> >
> >  core/cpio_utils.c       | 78 +++++++++++++++++++++++++++++++++++++++++
> >  handlers/raw_handler.c  |  5 ++-
> >  include/swupdate.h      |  1 +
> >  include/util.h          |  1 +
> >  parser/parse_external.c |  2 ++
> >  parser/parser.c         |  1 +
> >  6 files changed, 87 insertions(+), 1 deletion(-)
> >
> > diff --git a/core/cpio_utils.c b/core/cpio_utils.c
> > index 03776e2..8dfb4d7 100644
> > --- a/core/cpio_utils.c
> > +++ b/core/cpio_utils.c
> > @@ -110,6 +110,84 @@ int copy_write(void *out, const void *buf, unsigned
> int len)
> >       return 0;
> >  }
> >
> > +int copy_lseek_back(void *out, const void *buf, unsigned int len)
> > +{
> > +     int ret;
> > +     int fd = (out != NULL) ? *(int *)out : -1;
> > +     off_t offset_back = (off_t)len * -1;
> > +
> > +     if (lseek(fd, offset_back, SEEK_CUR) < 0) {
> > +             ERROR("cannot lseek %d bytes back: %s", len,
> strerror(errno));
> > +             return -1;
> > +     }
> > +
> > +     return 0;
> > +}
> > +
> > +int copy_verify(void *in, void *buf, unsigned int len, const void
> *source_buf)
> > +{
> > +     int ret;
> > +     int fd = (in != NULL) ? *(int *)in : -1;
> > +
> > +     while (len) {
> > +             errno = 0;
> > +             ret = read(fd, buf, len);
> > +             if (ret < 0) {
> > +                     if (errno == EINTR)
> > +                             continue;
> > +                     ERROR("cannot read %d bytes: %s", len,
> strerror(errno));
> > +                     return -1;
> > +             }
> > +
> > +             if (ret == 0) {
> > +                     ERROR("cannot read %d bytes: %s", len,
> strerror(errno));
> > +                     return -1;
> > +             }
> > +
> > +             if (memcmp(buf, source_buf, ret) != 0) {
> > +                     ERROR("verify fail\n");
> > +                     return -1;
> > +             }
> > +
> > +             len -= ret;
> > +             buf += ret;
> > +             source_buf += ret;
> > +     }
> > +
> > +     return 0;
> > +}
> > +
> > +int copy_write_verify(void *out, const void *buf, unsigned int len)
> > +{
> > +     int ret;
> > +     int fd = (out != NULL) ? *(int *)out : -1;
> > +     void *verify_buf;
> > +
> > +     verify_buf = malloc(len);
> > +     if (!verify_buf) {
> > +             ERROR("No memory: malloc %d for verify failed", len);
> > +             goto copy_write_verify_exit;
> > +     }
> > +
> > +     ret = copy_write(out, buf, len);
> > +     if (ret != 0)
> > +             goto copy_write_verify_exit;
> > +
> > +     ret = copy_lseek_back(out, buf, len);
> > +     if (ret != 0)
> > +             goto copy_write_verify_exit;
> > +
> > +     ret = copy_verify(out, verify_buf, len, buf);
> > +     if (ret != 0)
> > +             goto copy_write_verify_exit;
> > +
> > +copy_write_verify_exit:
> > +     if (verify_buf)
> > +             free(verify_buf);
> > +
> > +     return ret;
> > +}
> > +
> >  #if defined(__FreeBSD__)
> >  /*
> >   * FreeBSD likes to have multiples of 512 bytes written
> > diff --git a/handlers/raw_handler.c b/handlers/raw_handler.c
> > index fb48170..1011f05 100644
> > --- a/handlers/raw_handler.c
> > +++ b/handlers/raw_handler.c
> > @@ -124,7 +124,10 @@ static int install_raw_image(struct img_type *img,
> >  #if defined(__FreeBSD__)
> >       ret = copyimage(&fdout, img, copy_write_padded);
> >  #else
> > -     ret = copyimage(&fdout, img, NULL);
> > +     if (img->readout_verify)
> > +             ret = copyimage(&fdout, img, copy_write_verify);
> > +     else
> > +             ret = copyimage(&fdout, img, NULL);
> >  #endif
> >
> >       if (prot_stat == 1) {
> > diff --git a/include/swupdate.h b/include/swupdate.h
> > index 8cd1574..941d1f9 100644
> > --- a/include/swupdate.h
> > +++ b/include/swupdate.h
> > @@ -75,6 +75,7 @@ struct img_type {
> >       int preserve_attributes; /* whether to preserve attributes in
> archives */
> >       int is_encrypted;
> >       int install_directly;
> > +     int readout_verify;
> >       int is_script;
> >       int is_partitioner;
> >       struct dict properties;
> > diff --git a/include/util.h b/include/util.h
> > index 906be9a..44bfa9e 100644
> > --- a/include/util.h
> > +++ b/include/util.h
> > @@ -165,6 +165,7 @@ typedef int (*writeimage) (void *out, const void
> *buf, unsigned int len);
> >
> >  int openfile(const char *filename);
> >  int copy_write(void *out, const void *buf, unsigned int len);
> > +int copy_write_verify(void *out, const void *buf, unsigned int len);
> >  #if defined(__FreeBSD__)
> >  int copy_write_padded(void *out, const void *buf, unsigned int len);
> >  #endif
> > diff --git a/parser/parse_external.c b/parser/parse_external.c
> > index ef6c74c..ee995c9 100644
> > --- a/parser/parse_external.c
> > +++ b/parser/parse_external.c
> > @@ -102,6 +102,8 @@ static void sw_append_stream(struct img_type *img,
> const char *key,
> >               img->id.install_if_different = 1;
> >       if (!strcmp(key, "install-if-higher"))
> >               img->id.install_if_higher = 1;
> > +     if (!strcmp(key, "readout-verify"))
> > +             img->readout_verify = 1;
> >  }
> >
> >  int parse_external(struct swupdate_cfg *software, const char *filename)
> > diff --git a/parser/parser.c b/parser/parser.c
> > index 8cdbfb4..cf6cd6c 100644
> > --- a/parser/parser.c
> > +++ b/parser/parser.c
> > @@ -308,6 +308,7 @@ static int parse_common_attributes(parsertype p,
> void *elem, struct img_type *im
> >       get_field(p, elem, "install-if-different",
> &image->id.install_if_different);
> >       get_field(p, elem, "install-if-higher",
> &image->id.install_if_higher);
> >       get_field(p, elem, "encrypted", &image->is_encrypted);
> > +     get_field(p, elem, "readout-verify", &image->readout_verify);
> >
> >       return 0;
> >  }
>
> NAK: this feature is already in SWUpdate with the "readback" handler -
> just use it.
>
> Best regards,
> Stefano Babic
>
>
> --
> =====================================================================
> DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
> HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
> Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic@denx.de
> =====================================================================
>
diff mbox series

Patch

diff --git a/core/cpio_utils.c b/core/cpio_utils.c
index 03776e2..8dfb4d7 100644
--- a/core/cpio_utils.c
+++ b/core/cpio_utils.c
@@ -110,6 +110,84 @@  int copy_write(void *out, const void *buf, unsigned int len)
 	return 0;
 }
 
+int copy_lseek_back(void *out, const void *buf, unsigned int len)
+{
+	int ret;
+	int fd = (out != NULL) ? *(int *)out : -1;
+	off_t offset_back = (off_t)len * -1;
+
+	if (lseek(fd, offset_back, SEEK_CUR) < 0) {
+		ERROR("cannot lseek %d bytes back: %s", len, strerror(errno));
+		return -1;
+	}
+
+	return 0;
+}
+
+int copy_verify(void *in, void *buf, unsigned int len, const void *source_buf)
+{
+	int ret;
+	int fd = (in != NULL) ? *(int *)in : -1;
+
+	while (len) {
+		errno = 0;
+		ret = read(fd, buf, len);
+		if (ret < 0) {
+			if (errno == EINTR)
+				continue;
+			ERROR("cannot read %d bytes: %s", len, strerror(errno));
+			return -1;
+		}
+
+		if (ret == 0) {
+			ERROR("cannot read %d bytes: %s", len, strerror(errno));
+			return -1;
+		}
+
+		if (memcmp(buf, source_buf, ret) != 0) {
+			ERROR("verify fail\n");
+			return -1;
+		}
+
+		len -= ret;
+		buf += ret;
+		source_buf += ret;
+	}
+
+	return 0;
+}
+
+int copy_write_verify(void *out, const void *buf, unsigned int len)
+{
+	int ret;
+	int fd = (out != NULL) ? *(int *)out : -1;
+	void *verify_buf;
+
+	verify_buf = malloc(len);
+	if (!verify_buf) {
+		ERROR("No memory: malloc %d for verify failed", len);
+		goto copy_write_verify_exit;
+	}
+
+	ret = copy_write(out, buf, len);
+	if (ret != 0)
+		goto copy_write_verify_exit;
+
+	ret = copy_lseek_back(out, buf, len);
+	if (ret != 0)
+		goto copy_write_verify_exit;
+
+	ret = copy_verify(out, verify_buf, len, buf);
+	if (ret != 0)
+		goto copy_write_verify_exit;
+
+copy_write_verify_exit:
+	if (verify_buf)
+		free(verify_buf);
+
+	return ret;
+}
+
 #if defined(__FreeBSD__)
 /*
  * FreeBSD likes to have multiples of 512 bytes written
diff --git a/handlers/raw_handler.c b/handlers/raw_handler.c
index fb48170..1011f05 100644
--- a/handlers/raw_handler.c
+++ b/handlers/raw_handler.c
@@ -124,7 +124,10 @@  static int install_raw_image(struct img_type *img,
 #if defined(__FreeBSD__)
 	ret = copyimage(&fdout, img, copy_write_padded);
 #else
-	ret = copyimage(&fdout, img, NULL);
+	if (img->readout_verify)
+		ret = copyimage(&fdout, img, copy_write_verify);
+	else
+		ret = copyimage(&fdout, img, NULL);
 #endif
 
 	if (prot_stat == 1) {
diff --git a/include/swupdate.h b/include/swupdate.h
index 8cd1574..941d1f9 100644
--- a/include/swupdate.h
+++ b/include/swupdate.h
@@ -75,6 +75,7 @@  struct img_type {
 	int preserve_attributes; /* whether to preserve attributes in archives */
 	int is_encrypted;
 	int install_directly;
+	int readout_verify;
 	int is_script;
 	int is_partitioner;
 	struct dict properties;
diff --git a/include/util.h b/include/util.h
index 906be9a..44bfa9e 100644
--- a/include/util.h
+++ b/include/util.h
@@ -165,6 +165,7 @@  typedef int (*writeimage) (void *out, const void *buf, unsigned int len);
 
 int openfile(const char *filename);
 int copy_write(void *out, const void *buf, unsigned int len);
+int copy_write_verify(void *out, const void *buf, unsigned int len);
 #if defined(__FreeBSD__)
 int copy_write_padded(void *out, const void *buf, unsigned int len);
 #endif
diff --git a/parser/parse_external.c b/parser/parse_external.c
index ef6c74c..ee995c9 100644
--- a/parser/parse_external.c
+++ b/parser/parse_external.c
@@ -102,6 +102,8 @@  static void sw_append_stream(struct img_type *img, const char *key,
 		img->id.install_if_different = 1;
 	if (!strcmp(key, "install-if-higher"))
 		img->id.install_if_higher = 1;
+	if (!strcmp(key, "readout-verify"))
+		img->readout_verify = 1;
 }
 
 int parse_external(struct swupdate_cfg *software, const char *filename)
diff --git a/parser/parser.c b/parser/parser.c
index 8cdbfb4..cf6cd6c 100644
--- a/parser/parser.c
+++ b/parser/parser.c
@@ -308,6 +308,7 @@  static int parse_common_attributes(parsertype p, void *elem, struct img_type *im
 	get_field(p, elem, "install-if-different", &image->id.install_if_different);
 	get_field(p, elem, "install-if-higher", &image->id.install_if_higher);
 	get_field(p, elem, "encrypted", &image->is_encrypted);
+	get_field(p, elem, "readout-verify", &image->readout_verify);
 
 	return 0;
 }