]> git.ipfire.org Git - people/ric9/pakfire.git/commitdiff
stripper: Be smarter when copying sources
authorMichael Tremer <michael.tremer@ipfire.org>
Sat, 4 Jan 2025 13:29:56 +0000 (13:29 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Sat, 4 Jan 2025 13:29:56 +0000 (13:29 +0000)
The naive approach was not very good when it came to copying sources.
Sometimes there are too many and we keep sitting here for a minute.

It is smarter to collect all files first and then look them up and copy
them only once in the end.

Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/pakfire/stripper.c

index 90546f6a65236219225b106086f23b579b3784d4..fa39e00409a7e474cb30b70ba692f1fcb5355711 100644 (file)
@@ -50,6 +50,9 @@ struct pakfire_stripper {
        // Filelist
        struct pakfire_filelist* filelist;
 
+       // Sources
+       struct pakfire_filelist* sources;
+
        // Source Directory
        int sourcesfd;
 };
@@ -106,6 +109,11 @@ int pakfire_stripper_create(struct pakfire_stripper** stripper,
        if (r < 0)
                goto ERROR;
 
+       // Create a list for the sources
+       r = pakfire_filelist_create(&s->sources, s->pakfire);
+       if (r < 0)
+               goto ERROR;
+
        // Open the source directory
        r = pakfire_stripper_open_sources(s);
        if (r < 0)
@@ -122,6 +130,8 @@ ERROR:
 }
 
 static void pakfire_stripper_free(struct pakfire_stripper* stripper) {
+       if (stripper->sources)
+               pakfire_filelist_unref(stripper->sources);
        if (stripper->sourcesfd)
                close(stripper->sourcesfd);
        if (stripper->filelist)
@@ -193,34 +203,66 @@ ERROR:
        return r;
 }
 
-static int pakfire_stripper_copy_source_file(
+static int pakfire_stripper_collect_sources(
                struct pakfire_ctx* ctx, struct pakfire_elf* elf, const char* filename, void* data) {
        struct pakfire_stripper* stripper = data;
-       char path[PATH_MAX];
-       struct stat st = {};
-       FILE* dst = NULL;
-       int fd = -EBADF;
+       struct pakfire_file* file = NULL;
        int r;
 
        // If the source file is not in the right path, we ignore it
        if (!pakfire_string_startswith(filename, DEBUG_SRC_DIR))
                return 0;
 
+       // Don't add files more than once
+       if (pakfire_filelist_contains(stripper->sources, filename))
+               return 0;
+
+       // Create a new file object
+       r = pakfire_file_create(&file, stripper->pakfire, filename);
+       if (r < 0)
+               goto ERROR;
+
+       // Add the file to the list
+       r = pakfire_filelist_add(stripper->sources, file);
+       if (r < 0)
+               goto ERROR;
+
+ERROR:
+       if (file)
+               pakfire_file_unref(file);
+
+       return r;
+}
+
+static int pakfire_stripper_copy_sources(
+               struct pakfire_ctx* ctx, struct pakfire_file* file, void* data) {
+       struct pakfire_stripper* stripper = data;
+       struct stat st = {};
+       char p[PATH_MAX];
+       FILE* dst = NULL;
+       int fd = -EBADF;
+       int r;
+
+       // Fetch the path
+       const char* path = pakfire_file_get_path(file);
+       if (!path)
+               return -EINVAL;
+
        // Remove the original source path
-       r = pakfire_path_relative(path, DEBUG_SRC_DIR, filename);
+       r = pakfire_path_relative(p, DEBUG_SRC_DIR, path);
        if (r < 0)
                goto ERROR;
 
        // Open the source file
-       fd = openat(stripper->sourcesfd, path, O_RDONLY);
+       fd = openat(stripper->sourcesfd, p, O_RDONLY);
        if (fd < 0) {
                switch (errno) {
                        // If the source file does not exist, we cannot copy anything
-                       //case ENOENT:
-                       //      goto ERROR;
+                       case ENOENT:
+                               goto ERROR;
 
                        default:
-                               ERROR(stripper->ctx, "Could not open %s: %m\n", path);
+                               ERROR(stripper->ctx, "Could not open /%s: %m\n", p);
                                r = -errno;
                                goto ERROR;
                }
@@ -229,23 +271,23 @@ static int pakfire_stripper_copy_source_file(
        // Stat the source file
        r = fstat(fd, &st);
        if (r < 0) {
-               ERROR(stripper->ctx, "Could not stat %s: %m\n", path);
+               ERROR(stripper->ctx, "Could not stat /%s: %m\n", p);
                r = -errno;
                goto ERROR;
        }
 
        // Add the buildroot
-       r = pakfire_path_append(path, stripper->path, filename);
+       r = pakfire_path_append(p, stripper->path, path);
        if (r < 0)
                goto ERROR;
 
        // Create all directories
-       r = pakfire_mkparentdir(path, 0755);
+       r = pakfire_mkparentdir(p, 0755);
        if (r < 0)
                goto ERROR;
 
        // Open the destination file
-       dst = fopen(path, "wx");
+       dst = fopen(p, "wx");
        if (!dst) {
                switch (errno) {
                        // If the file exist already, we are done
@@ -253,7 +295,7 @@ static int pakfire_stripper_copy_source_file(
                                goto ERROR;
 
                        default:
-                               ERROR(stripper->ctx, "Could not open %s: %m\n", path);
+                               ERROR(stripper->ctx, "Could not open %s: %m\n", p);
                                r = -errno;
                                goto ERROR;
                }
@@ -262,7 +304,7 @@ static int pakfire_stripper_copy_source_file(
        // Copy all content
        ssize_t bytes_written = sendfile(fileno(dst), fd, 0, st.st_size);
        if (bytes_written < st.st_size) {
-               ERROR(stripper->ctx, "Failed to copy source file %s: %m\n", filename);
+               ERROR(stripper->ctx, "Failed to copy source file %s: %m\n", path);
                r = -errno;
                goto ERROR;
        }
@@ -424,9 +466,9 @@ static int pakfire_stripper_strip(
 
        // Only strip if there is actually some debug information
        if (!pakfire_elf_is_stripped(elf)) {
-               // Copy sources
+               // Collect sources
                r = pakfire_elf_foreach_source_file(elf,
-                               pakfire_stripper_copy_source_file, stripper);
+                               pakfire_stripper_collect_sources, stripper);
                if (r < 0)
                        goto ERROR;
 
@@ -456,6 +498,16 @@ int pakfire_stripper_run(struct pakfire_stripper* stripper) {
                return 0;
 
        // Strip all files
-       return pakfire_filelist_walk(stripper->filelist, pakfire_stripper_strip,
-               stripper, PAKFIRE_FILELIST_SHOW_PROGRESS, _("Stripping Files..."));
+       r = pakfire_filelist_walk(stripper->filelist, pakfire_stripper_strip,
+                       stripper, PAKFIRE_FILELIST_SHOW_PROGRESS, _("Stripping Files..."));
+       if (r < 0)
+               return r;
+
+       // Copy sources
+       r = pakfire_filelist_walk(stripper->sources, pakfire_stripper_copy_sources,
+                       stripper, PAKFIRE_FILELIST_SHOW_PROGRESS, _("Copying Sources..."));
+       if (r < 0)
+               return r;
+
+       return 0;
 }