From: Michael Tremer Date: Sat, 4 Jan 2025 13:29:56 +0000 (+0000) Subject: stripper: Be smarter when copying sources X-Git-Tag: 0.9.30~545 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8a91294b350ae7c4d96560685836b20e03a4572d;p=pakfire.git stripper: Be smarter when copying sources 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 --- diff --git a/src/pakfire/stripper.c b/src/pakfire/stripper.c index 90546f6a6..fa39e0040 100644 --- a/src/pakfire/stripper.c +++ b/src/pakfire/stripper.c @@ -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; }