]> wimlib.net Git - wimlib/commitdiff
wimupdate: add --ref option for updating delta WIMs
authorEric Biggers <ebiggers3@gmail.com>
Sun, 2 Apr 2023 19:32:46 +0000 (12:32 -0700)
committerEric Biggers <ebiggers3@gmail.com>
Sun, 2 Apr 2023 19:32:46 +0000 (12:32 -0700)
Resolves https://wimlib.net/forums/viewtopic.php?t=450

NEWS.md
doc/man1/wimupdate.1
programs/imagex.c

diff --git a/NEWS.md b/NEWS.md
index 9b3a70590bd213c1f3f99594940865411521b4c7..87c28d71d9eb5f72ce96c91a2d05a58b47639bd0 100644 (file)
--- a/NEWS.md
+++ b/NEWS.md
@@ -20,6 +20,9 @@
 - Fixed a bug in `wimsplit` where it didn't accept part sizes of 4 GiB or larger
   on Windows and on 32-bit platforms.
 
 - Fixed a bug in `wimsplit` where it didn't accept part sizes of 4 GiB or larger
   on Windows and on 32-bit platforms.
 
+- `wimupdate` now supports the `--ref` option.  It should be specified when
+  updating a delta WIM to avoid two minor issues.
+
 - Removed support for Windows XP.
 
 - Added a GitHub Actions workflow that tests wimlib.
 - Removed support for Windows XP.
 
 - Added a GitHub Actions workflow that tests wimlib.
index 26b9cdcf3a61b43dc1130d6a1fb325ea5c8c1311..7c07914946543a82a7bc6d15c2ef30c1d8c8a259 100644 (file)
@@ -163,6 +163,13 @@ Compact the WIM archive in-place and append any new data, eliminating "holes".
 This is efficient, but in general this option should \fInot\fR be used because a
 failed or interrupted compaction will corrupt the WIM archive.  For more
 information, see the documentation for this option in \fBwimoptimize\fR(1).
 This is efficient, but in general this option should \fInot\fR be used because a
 failed or interrupted compaction will corrupt the WIM archive.  For more
 information, see the documentation for this option in \fBwimoptimize\fR(1).
+.TP
+\fB--ref\fR="\fIGLOB\fR"
+File glob of WIM(s) on which the delta WIM is based.  Updating split WIMs is not
+allowed, but updating delta WIMs is allowed.  When updating a delta WIM, the
+WIM(s) on which the delta WIM is based should be specified using this option.
+(It isn't a hard requirement, but it's needed for data deduplication to work
+fully and for the TOTALBYTES statistic to be correctly updated.)
 .SH NOTES
 \fBwimupdate\fR can be viewed as redundant with \fBwimmountrw\fR, since a WIM
 image can also be updated by mounting it read-write.  However, \fBwimupdate\fR
 .SH NOTES
 \fBwimupdate\fR can be viewed as redundant with \fBwimmountrw\fR, since a WIM
 image can also be updated by mounting it read-write.  However, \fBwimupdate\fR
index 078cff19c9cb0af15b19ba58a26d047367fa0f2a..f1434bf2c8948b3577ce46d5d5c0ff3b9dd4cbc4 100644 (file)
@@ -6,7 +6,7 @@
  */
 
 /*
  */
 
 /*
- * Copyright (C) 2012-2023 Eric Biggers
+ * Copyright 2012-2023 Eric Biggers
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -416,14 +416,14 @@ static const struct option unmount_options[] = {
 static const struct option update_options[] = {
        /* Careful: some of the options here set the defaults for update
         * commands, but the flags given to an actual update command (and not to
 static const struct option update_options[] = {
        /* Careful: some of the options here set the defaults for update
         * commands, but the flags given to an actual update command (and not to
-        * `imagex update' itself are also handled in
-        * update_command_add_option().  */
+        * wimupdate itself) are also handled in update_command_add_option(). */
        {T("threads"),     required_argument, NULL, IMAGEX_THREADS_OPTION},
        {T("check"),       no_argument,       NULL, IMAGEX_CHECK_OPTION},
        {T("include-integrity"), no_argument, NULL, IMAGEX_INCLUDE_INTEGRITY_OPTION},
        {T("rebuild"),     no_argument,       NULL, IMAGEX_REBUILD_OPTION},
        {T("command"),     required_argument, NULL, IMAGEX_COMMAND_OPTION},
        {T("wimboot-config"), required_argument, NULL, IMAGEX_WIMBOOT_CONFIG_OPTION},
        {T("threads"),     required_argument, NULL, IMAGEX_THREADS_OPTION},
        {T("check"),       no_argument,       NULL, IMAGEX_CHECK_OPTION},
        {T("include-integrity"), no_argument, NULL, IMAGEX_INCLUDE_INTEGRITY_OPTION},
        {T("rebuild"),     no_argument,       NULL, IMAGEX_REBUILD_OPTION},
        {T("command"),     required_argument, NULL, IMAGEX_COMMAND_OPTION},
        {T("wimboot-config"), required_argument, NULL, IMAGEX_WIMBOOT_CONFIG_OPTION},
+       {T("ref"),         required_argument, NULL, IMAGEX_REF_OPTION},
 
        /* Default delete options */
        {T("force"),       no_argument,       NULL, IMAGEX_FORCE_OPTION},
 
        /* Default delete options */
        {T("force"),       no_argument,       NULL, IMAGEX_FORCE_OPTION},
@@ -1529,7 +1529,7 @@ update_command_add_option(int op, const tchar *option,
        return recognized;
 }
 
        return recognized;
 }
 
-/* How many nonoption arguments each `imagex update' command expects */
+/* How many nonoption arguments each wimupdate command expects */
 static const unsigned update_command_num_nonoptions[] = {
        [WIMLIB_UPDATE_OP_ADD] = 2,
        [WIMLIB_UPDATE_OP_DELETE] = 1,
 static const unsigned update_command_num_nonoptions[] = {
        [WIMLIB_UPDATE_OP_ADD] = 2,
        [WIMLIB_UPDATE_OP_DELETE] = 1,
@@ -1561,7 +1561,7 @@ update_command_add_nonoption(int op, const tchar *nonoption,
 }
 
 /*
 }
 
 /*
- * Parse a command passed on stdin to `imagex update'.
+ * Parse a command passed on stdin to wimupdate.
  *
  * @line:      Text of the command.
  * @len:       Length of the line, including a null terminator
  *
  * @line:      Text of the command.
  * @len:       Length of the line, including a null terminator
@@ -4145,6 +4145,7 @@ imagex_update(int argc, tchar **argv, int cmd)
                                WIMLIB_ADD_FLAG_WINCONFIG;
        int default_delete_flags = 0;
        unsigned num_threads = 0;
                                WIMLIB_ADD_FLAG_WINCONFIG;
        int default_delete_flags = 0;
        unsigned num_threads = 0;
+       STRING_LIST(refglobs);
        int c;
        tchar *cmd_file_contents;
        size_t cmd_file_nchars;
        int c;
        tchar *cmd_file_contents;
        size_t cmd_file_nchars;
@@ -4188,6 +4189,13 @@ imagex_update(int argc, tchar **argv, int cmd)
                case IMAGEX_WIMBOOT_CONFIG_OPTION:
                        wimboot_config = optarg;
                        break;
                case IMAGEX_WIMBOOT_CONFIG_OPTION:
                        wimboot_config = optarg;
                        break;
+               case IMAGEX_REF_OPTION:
+                       ret = string_list_append(&refglobs, optarg);
+                       if (ret)
+                               goto out;
+                       /* assume delta WIM */
+                       write_flags |= WIMLIB_WRITE_FLAG_SKIP_EXTERNAL_WIMS;
+                       break;
                /* Default delete options */
                case IMAGEX_FORCE_OPTION:
                        default_delete_flags |= WIMLIB_DELETE_FLAG_FORCE;
                /* Default delete options */
                case IMAGEX_FORCE_OPTION:
                        default_delete_flags |= WIMLIB_DELETE_FLAG_FORCE;
@@ -4238,7 +4246,7 @@ imagex_update(int argc, tchar **argv, int cmd)
        ret = wimlib_open_wim_with_progress(wimfile, open_flags, &wim,
                                            imagex_progress_func, NULL);
        if (ret)
        ret = wimlib_open_wim_with_progress(wimfile, open_flags, &wim,
                                            imagex_progress_func, NULL);
        if (ret)
-               goto out_free_command_str;
+               goto out;
 
        if (argc >= 2) {
                /* Image explicitly specified.  */
 
        if (argc >= 2) {
                /* Image explicitly specified.  */
@@ -4262,6 +4270,10 @@ imagex_update(int argc, tchar **argv, int cmd)
                image = 1;
        }
 
                image = 1;
        }
 
+       ret = wim_reference_globs(wim, &refglobs, open_flags);
+       if (ret)
+               goto out_wimlib_free;
+
        /* Read update commands from standard input, or the command string if
         * specified.  */
        if (command_str) {
        /* Read update commands from standard input, or the command string if
         * specified.  */
        if (command_str) {
@@ -4341,15 +4353,16 @@ out_free_cmd_file_contents:
        free(cmd_file_contents);
 out_wimlib_free:
        wimlib_free(wim);
        free(cmd_file_contents);
 out_wimlib_free:
        wimlib_free(wim);
-out_free_command_str:
+out:
        free(command_str);
        free(command_str);
+       string_list_destroy(&refglobs);
        return ret;
 
 out_usage:
        usage(CMD_UPDATE, stderr);
 out_err:
        ret = -1;
        return ret;
 
 out_usage:
        usage(CMD_UPDATE, stderr);
 out_err:
        ret = -1;
-       goto out_free_command_str;
+       goto out;
 }
 
 /* Verify a WIM file.  */
 }
 
 /* Verify a WIM file.  */
@@ -4612,7 +4625,7 @@ version(void)
        static const tchar * const fmt =
        T(
 "wimlib-imagex " PACKAGE_VERSION " (using wimlib %"TS")\n"
        static const tchar * const fmt =
        T(
 "wimlib-imagex " PACKAGE_VERSION " (using wimlib %"TS")\n"
-"Copyright (C) 2012-2023 Eric Biggers\n"
+"Copyright 2012-2023 Eric Biggers\n"
 "License GPLv3+; GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>.\n"
 "This is free software: you are free to change and redistribute it.\n"
 "There is NO WARRANTY, to the extent permitted by law.\n"
 "License GPLv3+; GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>.\n"
 "This is free software: you are free to change and redistribute it.\n"
 "There is NO WARRANTY, to the extent permitted by law.\n"