From: Mateusz Moscicki Date: Wed, 10 May 2023 12:02:24 +0000 (+0200) Subject: upgrade-apply: Stop copying data twice X-Git-Tag: accepted/tizen/unified/20230822.043319~2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=533a1e8caed9b4734ec6fdf3687fff3588c074bb;p=platform%2Fcore%2Fsystem%2Fupgrade.git upgrade-apply: Stop copying data twice In case the destination partition is the clone of the source partition, then there is no need to copy data again, because it is already in place. Change-Id: I31efe018a76f1237452109fd463056c949e88bf9 --- diff --git a/scripts/upgrade-support/upgrade-common.inc b/scripts/upgrade-support/upgrade-common.inc index 88473fe..2829dc3 100644 --- a/scripts/upgrade-support/upgrade-common.inc +++ b/scripts/upgrade-support/upgrade-common.inc @@ -235,6 +235,7 @@ upgrade_images() { --archive-file "$DELTA_NAME" \ --kind ss_brotli_patch \ --patch-orig "$CURR_PARTITION" \ + --no-write-all \ --dest-sha1 "$NEW_SHA" && UP_RES=$? || UP_RES=$? ;; DELTA_FS) diff --git a/src/upgrade-apply/main.c b/src/upgrade-apply/main.c index ecde48a..5711e75 100644 --- a/src/upgrade-apply/main.c +++ b/src/upgrade-apply/main.c @@ -69,6 +69,7 @@ struct parse_result { const char *patch_orig; const char *dest_sha1; size_t dest_size; + bool write_all; enum archive_kind kind; }; @@ -82,6 +83,7 @@ struct parse_result parse_args(int argc, char **argv) long long int dest_size = 0; enum archive_kind kind = -1; bool help = false; + bool write_all = true; for (;;) { const struct option long_options[] = { @@ -92,10 +94,11 @@ struct parse_result parse_args(int argc, char **argv) {"patch-orig", required_argument, NULL, 4 }, {"dest-sha1", required_argument, NULL, 5 }, {"dest-size", required_argument, NULL, 6 }, + {"no-write-all", no_argument, NULL, 'n'}, {"help", no_argument, NULL, 'h'}, {0} }; - int option = getopt_long(argc, argv, "h", long_options, NULL); + int option = getopt_long(argc, argv, "hn", long_options, NULL); if (option < 0) break; @@ -149,6 +152,12 @@ struct parse_result parse_args(int argc, char **argv) return (struct parse_result) { .result = PARSE_BAD_SIZE }; break; + case 'n': // no-write-all + if (!write_all) + return (struct parse_result) { .result = PARSE_REPEATED_ARGUMENT }; + write_all = false; + break; + case 'h': // help if (help) return (struct parse_result) { .result = PARSE_REPEATED_ARGUMENT }; @@ -189,6 +198,7 @@ struct parse_result parse_args(int argc, char **argv) .dest_sha1 = dest_sha1, .dest_size = dest_size, .kind = kind, + .write_all = write_all, }; } @@ -249,7 +259,7 @@ ssize_t gzip_write(__attribute__((unused)) int useless_fd, __attribute__((unused void help(char *name) { fprintf(stderr, - "Usage: %s --archive ARCHIVE --archive-file FILE --dest DESTINATION --kind KIND [--patch-orig ORIGIN] [--dest-sha1 SHA1] [--dest-size SIZE]\n" + "Usage: %s --archive ARCHIVE --archive-file FILE --dest DESTINATION --kind KIND [--patch-orig ORIGIN] [--dest-sha1 SHA1] [--dest-size SIZE] [--no-write-all]\n" "\n" "Patches a partition using an archive.\n" "It will look for a file named FILE in an archive called ARCHIVE; the archive should have an extension\n" @@ -261,7 +271,9 @@ void help(char *name) "The results will be written to the DESTINATION partition.\n" "If SHA1 is provided (lowercase hexadecimal), it is compared to the one calculated on DESTINATION after writing.\n" "Additionally, if SIZE is provided, it is used as the destination size; this matters for SHA1 comparision,\n" - "and also if ss_brotli_patch.\n", + "and also if ss_brotli_patch.\n" + "In case the KIND is ss_brotli_path and the DESTINATION is the clone of the ORIGIN you can specify\n" + "the --no-write-all flag to not copy the data from the source, because it is already there.\n", name); } @@ -474,7 +486,7 @@ int main(int argc, char **argv) case KIND_BROTLI_PATCH: { struct dec_funcs funcs = { init_brotli, decompress_brotli, free_brotli }; - r = apply_patch(parsed.patch_orig, parsed.dest, tar, parsed.dest_size, NULL, &funcs); + r = apply_patch(parsed.patch_orig, parsed.dest, tar, parsed.dest_size, NULL, parsed.write_all, &funcs); break; } } diff --git a/src/upgrade-apply/patch/patch.c b/src/upgrade-apply/patch/patch.c index e2af145..6f29640 100644 --- a/src/upgrade-apply/patch/patch.c +++ b/src/upgrade-apply/patch/patch.c @@ -335,7 +335,7 @@ int read_header(struct dec_funcs *funcs, struct bs_data *data, uint8_t **buff_ou return PF_OK; } -int apply_patch(const char *source_file, const char *dest_file, TAR *patch_tar, size_t dest_size, size_t *free_space, struct dec_funcs *funcs) +int apply_patch(const char *source_file, const char *dest_file, TAR *patch_tar, size_t dest_size, size_t *free_space, bool write_all, struct dec_funcs *funcs) { assert(source_file); assert(dest_file); @@ -411,7 +411,14 @@ int apply_patch(const char *source_file, const char *dest_file, TAR *patch_tar, goto exit; if ((result = remmap_if_needed(&data.dest)) != PF_OK) goto exit; - *data.dest.pos = *(uint8_t*)data.src.pos + *(uint8_t*)buff_out_pos; + /* + * If *buff_out_pos == 0 and old_pos == new_pos then it is basically a data copy. + * In case the destination partition is the clone of the source partition, + * then there is no need to copy data again, because it is already in place. + */ + if (write_all || old_pos != new_pos || *(uint8_t*)buff_out_pos != 0) { + *data.dest.pos = *(uint8_t*)data.src.pos + *(uint8_t*)buff_out_pos; + } data.dest.pos++; data.src.pos++; buff_out_pos++; diff --git a/src/upgrade-apply/patch/patch.h b/src/upgrade-apply/patch/patch.h index 8a2c462..476e025 100644 --- a/src/upgrade-apply/patch/patch.h +++ b/src/upgrade-apply/patch/patch.h @@ -21,6 +21,7 @@ #include #include +#include #include #define PF_OK 0 @@ -65,4 +66,4 @@ struct dec_funcs { void (*clean)(struct bs_data *data); }; -extern int apply_patch(const char *source_file, const char *dest_file, TAR *patch_tar, size_t dest_size, size_t *free_space, struct dec_funcs *funcs); +extern int apply_patch(const char *source_file, const char *dest_file, TAR *patch_tar, size_t dest_size, size_t *free_space, bool write_all, struct dec_funcs *funcs); diff --git a/src/upgrade-apply/patch/patch_helper.c b/src/upgrade-apply/patch/patch_helper.c index fb6e7d1..d71d454 100644 --- a/src/upgrade-apply/patch/patch_helper.c +++ b/src/upgrade-apply/patch/patch_helper.c @@ -18,8 +18,8 @@ #include "brotli.h" -int apply_patch_brotli(const char *source_file, const char *dest_file, TAR *patch_tar, size_t dest_size, size_t *free_space) +int apply_patch_brotli(const char *source_file, const char *dest_file, TAR *patch_tar, size_t dest_size, size_t *free_space, bool write_all) { struct dec_funcs funcs = { init_brotli, decompress_brotli, free_brotli }; - return apply_patch(source_file, dest_file, patch_tar, dest_size, free_space, &funcs); + return apply_patch(source_file, dest_file, patch_tar, dest_size, free_space, write_all, &funcs); }