]> git.ipfire.org Git - people/stevee/pakfire.git/commitdiff
snapshot: Refactor composing archive
authorMichael Tremer <michael.tremer@ipfire.org>
Wed, 17 Aug 2022 13:11:14 +0000 (13:11 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Wed, 17 Aug 2022 13:11:14 +0000 (13:11 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/libpakfire/build.c
src/libpakfire/snapshot.c

index c5fdd9a53b2d41fc06b1d6fda7ad517ce5af32b2..7c37fbdc7e3bc69b76116f0bb406be5769301331 100644 (file)
@@ -1165,28 +1165,29 @@ static int pakfire_build_init(struct pakfire_build* build) {
                }
        }
 
+       // Compose path for snapshot
+       r = pakfire_make_cache_path(build->pakfire, path, "%s", "snapshot.tar.zst");
+       if (r < 0) {
+               ERROR(build->pakfire, "Could not compose snapshot path: %m\n");
+               return 1;
+       }
+
        // Tells us whether we need to (re-)create the snapshot
        int snapshot_needs_update = 0;
 
-       // Check if the user wants a snapshot extracted
+       // Extract snapshot
        if (!pakfire_build_has_flag(build, PAKFIRE_BUILD_DISABLE_SNAPSHOT)) {
-               // Extract snapshot
-               r = pakfire_make_cache_path(build->pakfire, path, "%s", "snapshot.tar.zst");
-               if (r < 0) {
-                       ERROR(build->pakfire, "Could not compose snapshot path: %m\n");
-                       return 1;
-               }
-
                // Open the snapshot
                f = fopen(path, "r");
 
                // Try restoring the snapshot
                if (f) {
                        r = pakfire_snapshot_restore(build->pakfire, f);
-                       if (r) {
-                               fclose(f);
+                       fclose(f);
+
+                       // Exit on error
+                       if (r)
                                return r;
-                       }
                }
        }
 
index 968b225b3b4c14024ecb298b1ba8572becd2ea5b..8214a594c9feed3fb85e5b474fc164e801c1ab90 100644 (file)
@@ -116,84 +116,97 @@ ERROR:
        return NULL;
 }
 
-int pakfire_snapshot_create(struct pakfire* pakfire, FILE* f) {
+int pakfire_snapshot_create(struct pakfire* pakfire, FILE* snapshot) {
+       struct pakfire_filelist* filelist = NULL;
+       struct archive* a = NULL;
        int r = 1;
 
-       if (!f) {
+       if (!snapshot) {
                errno = EINVAL;
                return 1;
        }
 
+       // Create a new filelist
+       r = pakfire_filelist_create(&filelist, pakfire);
+       if (r)
+               goto ERROR;
+
        const char* root = pakfire_get_path(pakfire);
 
        INFO(pakfire, "Creating snapshot of %s...\n", root);
 
-       struct archive* a = pakfire_snapshot_create_archive(pakfire, f);
-       if (!a) {
-               ERROR(pakfire, "Could not open archive for writing\n");
-               return 1;
-       }
-
-       // Create disk reader
-       struct archive* reader = pakfire_make_archive_disk_reader(pakfire, 1);
-       if (!reader)
+       // Scan for all files
+       r = pakfire_filelist_scan(filelist, root, NULL, NULL);
+       if (r)
                goto ERROR;
 
-       // Open path
-       r = archive_read_disk_open(reader, root);
-       if (r) {
-               ERROR(pakfire, "Could not open %s: %s\n", root, archive_error_string(reader));
+       const size_t size = pakfire_filelist_size(filelist);
+
+       // Check if we have any files
+       if (!size) {
+               ERROR(pakfire, "The snapshot is unexpectedly empty\n");
+               r = 1;
                goto ERROR;
        }
 
-       struct archive_entry* entry = NULL;
-       while (1) {
-               r = archive_read_next_header(reader, &entry);
-               if (r == ARCHIVE_EOF)
-                       break;
-               else if (r == ARCHIVE_RETRY)
-                       continue;
-               else if (r) {
-                       ERROR(pakfire, "Could not read next entry: %s\n", archive_error_string(reader));
-                       goto ERROR;
-               }
-
-               const char* full_path = archive_entry_pathname(entry);
+       // Sort the filelist in place
+       pakfire_filelist_sort(filelist);
 
-               // Compute the relative path
-               const char* path = pakfire_path_relpath(root, full_path);
-               if (!path)
-                       continue;
+       a = pakfire_snapshot_create_archive(pakfire, snapshot);
+       if (!a) {
+               ERROR(pakfire, "Could not open archive for writing\n");
+               goto ERROR;
+       }
 
-               // Skip mountpoints
-               if (pakfire_is_mountpoint(pakfire, full_path)) {
-                       DEBUG(pakfire, "Skipping mountpoint %s...\n", path);
+       for (unsigned int i = 0; i < size; i++) {
+               struct pakfire_file* file = pakfire_filelist_get(filelist, i);
+               if (!file)
                        continue;
-               }
 
-               archive_read_disk_descend(reader);
+               FILE* f = NULL;
 
-               // Reset path to relative path in archive
-               archive_entry_set_pathname(entry, path);
+               // Make archive entry
+               struct archive_entry* entry = pakfire_file_archive_entry(file);
+               if (!entry) {
+                       ERROR(pakfire, "Could not make archive entry from file: %m\n");
+                       r = 1;
+                       goto OUT;
+               }
 
                // Write header
                r = archive_write_header(a, entry);
                if (r) {
                        ERROR(pakfire, "Could not write header: %s\n", archive_error_string(a));
-                       goto ERROR;
+                       goto OUT;
                }
 
                // Copy payload
                if (archive_entry_filetype(entry) == AE_IFREG) {
-                       r = pakfire_archive_copy_data(pakfire, reader, a);
+                       f = pakfire_file_open(file);
+                       if (!f) {
+                               r = 1;
+                               goto OUT;
+                       }
+
+                       r = pakfire_archive_copy_data_from_file(pakfire, a, f);
                        if (r) {
                                ERROR(pakfire, "Could not copy %s\n", archive_entry_pathname(entry));
-                               goto ERROR;
+                               goto OUT;
                        }
                }
 
                // Write trailer
                r = archive_write_finish_entry(a);
+               if (r)
+                       goto OUT;
+
+OUT:
+               if (file)
+                       pakfire_file_unref(file);
+               if (f)
+                       fclose(f);
+
+               // Move on to ERROR
                if (r)
                        goto ERROR;
        }
@@ -209,9 +222,10 @@ int pakfire_snapshot_create(struct pakfire* pakfire, FILE* f) {
        r = 0;
 
 ERROR:
-       if (reader)
-               archive_read_free(reader);
-       archive_write_free(a);
+       if (filelist)
+               pakfire_filelist_unref(filelist);
+       if (a)
+               archive_write_free(a);
 
        return r;
 }