Message ID | 20200226073723.30298-1-zhuangqiubin@gmail.com |
---|---|
State | Rejected |
Headers | show |
Series | swupdate: add attribute readout-verify | expand |
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
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 --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; }