From: Omar Sandoval <osandov@osandov.com>
To: elfutils-devel@sourceware.org
Cc: linux-debuggers@vger.kernel.org
Subject: [PATCH v2 1/5] debuginfod: factor out common code for responding from an archive
Date: Mon, 15 Jul 2024 03:04:32 -0700 [thread overview]
Message-ID: <381ab6f4add85fb5673e05230067c5fa70bdb9d1.1721037200.git.osandov@fb.com> (raw)
In-Reply-To: <cover.1721037200.git.osandov@fb.com>
From: Omar Sandoval <osandov@fb.com>
handle_buildid_r_match has two very similar branches where it optionally
extracts a section and then creates a microhttpd response. In
preparation for adding a third one, factor it out into a function.
Signed-off-by: Omar Sandoval <osandov@fb.com>
---
debuginfod/debuginfod.cxx | 213 +++++++++++++++++---------------------
1 file changed, 96 insertions(+), 117 deletions(-)
diff --git a/debuginfod/debuginfod.cxx b/debuginfod/debuginfod.cxx
index 305edde8..2d709026 100644
--- a/debuginfod/debuginfod.cxx
+++ b/debuginfod/debuginfod.cxx
@@ -1965,6 +1965,81 @@ string canonicalized_archive_entry_pathname(struct archive_entry *e)
}
+// NB: takes ownership of, and may reassign, fd.
+static struct MHD_Response*
+create_buildid_r_response (int64_t b_mtime0,
+ const string& b_source0,
+ const string& b_source1,
+ const string& section,
+ const string& ima_sig,
+ const char* tmppath,
+ int& fd,
+ off_t size,
+ time_t mtime,
+ const string& metric,
+ const struct timespec& extract_begin)
+{
+ if (tmppath != NULL)
+ {
+ struct timespec extract_end;
+ clock_gettime (CLOCK_MONOTONIC, &extract_end);
+ double extract_time = (extract_end.tv_sec - extract_begin.tv_sec)
+ + (extract_end.tv_nsec - extract_begin.tv_nsec)/1.e9;
+ fdcache.intern(b_source0, b_source1, tmppath, size, true, extract_time);
+ }
+
+ if (!section.empty ())
+ {
+ int scn_fd = extract_section (fd, b_mtime0,
+ b_source0 + ":" + b_source1,
+ section, extract_begin);
+ close (fd);
+ if (scn_fd >= 0)
+ fd = scn_fd;
+ else
+ {
+ if (verbose)
+ obatched (clog) << "cannot find section " << section
+ << " for archive " << b_source0
+ << " file " << b_source1 << endl;
+ return 0;
+ }
+
+ struct stat fs;
+ if (fstat (fd, &fs) < 0)
+ {
+ close (fd);
+ throw libc_exception (errno,
+ string ("fstat ") + b_source0 + string (" ") + section);
+ }
+ size = fs.st_size;
+ }
+
+ struct MHD_Response* r = MHD_create_response_from_fd (size, fd);
+ if (r == 0)
+ {
+ if (verbose)
+ obatched(clog) << "cannot create fd-response for " << b_source0 << endl;
+ close(fd);
+ }
+ else
+ {
+ inc_metric ("http_responses_total","result",metric);
+ add_mhd_response_header (r, "Content-Type", "application/octet-stream");
+ add_mhd_response_header (r, "X-DEBUGINFOD-SIZE", to_string(size).c_str());
+ add_mhd_response_header (r, "X-DEBUGINFOD-ARCHIVE", b_source0.c_str());
+ add_mhd_response_header (r, "X-DEBUGINFOD-FILE", b_source1.c_str());
+ if(!ima_sig.empty()) add_mhd_response_header(r, "X-DEBUGINFOD-IMASIGNATURE", ima_sig.c_str());
+ add_mhd_last_modified (r, mtime);
+ if (verbose > 1)
+ obatched(clog) << "serving " << metric << " " << b_source0
+ << " file " << b_source1
+ << " section=" << section
+ << " IMA signature=" << ima_sig << endl;
+ /* libmicrohttpd will close fd. */
+ }
+ return r;
+}
static struct MHD_Response*
handle_buildid_r_match (bool internal_req_p,
@@ -2142,57 +2217,15 @@ handle_buildid_r_match (bool internal_req_p,
break; // branch out of if "loop", to try new libarchive fetch attempt
}
- if (!section.empty ())
- {
- int scn_fd = extract_section (fd, fs.st_mtime,
- b_source0 + ":" + b_source1,
- section, extract_begin);
- close (fd);
- if (scn_fd >= 0)
- fd = scn_fd;
- else
- {
- if (verbose)
- obatched (clog) << "cannot find section " << section
- << " for archive " << b_source0
- << " file " << b_source1 << endl;
- return 0;
- }
-
- rc = fstat(fd, &fs);
- if (rc < 0)
- {
- close (fd);
- throw libc_exception (errno,
- string ("fstat archive ") + b_source0 + string (" file ") + b_source1
- + string (" section ") + section);
- }
- }
-
- struct MHD_Response* r = MHD_create_response_from_fd (fs.st_size, fd);
+ struct MHD_Response* r = create_buildid_r_response (b_mtime, b_source0,
+ b_source1, section,
+ ima_sig, NULL, fd,
+ fs.st_size,
+ fs.st_mtime,
+ "archive fdcache",
+ extract_begin);
if (r == 0)
- {
- if (verbose)
- obatched(clog) << "cannot create fd-response for " << b_source0 << endl;
- close(fd);
- break; // branch out of if "loop", to try new libarchive fetch attempt
- }
-
- inc_metric ("http_responses_total","result","archive fdcache");
-
- add_mhd_response_header (r, "Content-Type", "application/octet-stream");
- add_mhd_response_header (r, "X-DEBUGINFOD-SIZE",
- to_string(fs.st_size).c_str());
- add_mhd_response_header (r, "X-DEBUGINFOD-ARCHIVE", b_source0.c_str());
- add_mhd_response_header (r, "X-DEBUGINFOD-FILE", b_source1.c_str());
- if(!ima_sig.empty()) add_mhd_response_header(r, "X-DEBUGINFOD-IMASIGNATURE", ima_sig.c_str());
- add_mhd_last_modified (r, fs.st_mtime);
- if (verbose > 1)
- obatched(clog) << "serving fdcache archive " << b_source0
- << " file " << b_source1
- << " section=" << section
- << " IMA signature=" << ima_sig << endl;
- /* libmicrohttpd will close it. */
+ break; // branch out of if "loop", to try new libarchive fetch attempt
if (result_fd)
*result_fd = fd;
return r;
@@ -2307,13 +2340,12 @@ handle_buildid_r_match (bool internal_req_p,
tvs[1].tv_nsec = archive_entry_mtime_nsec(e);
(void) futimens (fd, tvs); /* best effort */
- struct timespec extract_end;
- clock_gettime (CLOCK_MONOTONIC, &extract_end);
- double extract_time = (extract_end.tv_sec - extract_begin.tv_sec)
- + (extract_end.tv_nsec - extract_begin.tv_nsec)/1.e9;
-
if (r != 0) // stage 3
{
+ struct timespec extract_end;
+ clock_gettime (CLOCK_MONOTONIC, &extract_end);
+ double extract_time = (extract_end.tv_sec - extract_begin.tv_sec)
+ + (extract_end.tv_nsec - extract_begin.tv_nsec)/1.e9;
// NB: now we know we have a complete reusable file; make fdcache
// responsible for unlinking it later.
fdcache.intern(b_source0, fn,
@@ -2324,69 +2356,16 @@ handle_buildid_r_match (bool internal_req_p,
continue;
}
- // NB: now we know we have a complete reusable file; make fdcache
- // responsible for unlinking it later.
- fdcache.intern(b_source0, b_source1,
- tmppath, archive_entry_size(e),
- true, extract_time); // requested ones go to the front of the line
-
- if (!section.empty ())
- {
- int scn_fd = extract_section (fd, b_mtime,
- b_source0 + ":" + b_source1,
- section, extract_begin);
- close (fd);
- if (scn_fd >= 0)
- fd = scn_fd;
- else
- {
- if (verbose)
- obatched (clog) << "cannot find section " << section
- << " for archive " << b_source0
- << " file " << b_source1 << endl;
- return 0;
- }
-
- rc = fstat(fd, &fs);
- if (rc < 0)
- {
- close (fd);
- throw libc_exception (errno,
- string ("fstat ") + b_source0 + string (" ") + section);
- }
- r = MHD_create_response_from_fd (fs.st_size, fd);
- }
- else
- r = MHD_create_response_from_fd (archive_entry_size(e), fd);
-
- inc_metric ("http_responses_total","result",archive_extension + " archive");
+ r = create_buildid_r_response (b_mtime, b_source0, b_source1, section,
+ ima_sig, tmppath, fd,
+ archive_entry_size(e),
+ archive_entry_mtime(e),
+ archive_extension + " archive",
+ extract_begin);
if (r == 0)
- {
- if (verbose)
- obatched(clog) << "cannot create fd-response for " << b_source0 << endl;
- close(fd);
- break; // assume no chance of better luck around another iteration; no other copies of same file
- }
- else
- {
- add_mhd_response_header (r, "Content-Type",
- "application/octet-stream");
- add_mhd_response_header (r, "X-DEBUGINFOD-SIZE",
- to_string(archive_entry_size(e)).c_str());
- add_mhd_response_header (r, "X-DEBUGINFOD-ARCHIVE", b_source0.c_str());
- add_mhd_response_header (r, "X-DEBUGINFOD-FILE", b_source1.c_str());
- if(!ima_sig.empty()) add_mhd_response_header(r, "X-DEBUGINFOD-IMASIGNATURE", ima_sig.c_str());
- add_mhd_last_modified (r, archive_entry_mtime(e));
- if (verbose > 1)
- obatched(clog) << "serving archive " << b_source0
- << " file " << b_source1
- << " section=" << section
- << " IMA signature=" << ima_sig << endl;
- /* libmicrohttpd will close it. */
- if (result_fd)
- *result_fd = fd;
- continue;
- }
+ break; // assume no chance of better luck around another iteration; no other copies of same file
+ if (result_fd)
+ *result_fd = fd;
}
// XXX: rpm/file not found: delete this R entry?
--
2.45.2
next prev parent reply other threads:[~2024-07-15 10:04 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-07-15 10:04 [PATCH v2 0/5] debuginfod: speed up extraction from kernel debuginfo packages by 200x Omar Sandoval
2024-07-15 10:04 ` Omar Sandoval [this message]
2024-07-15 10:04 ` [PATCH v2 2/5] debugifod: add new table and views for seekable archives Omar Sandoval
2024-07-15 10:04 ` [PATCH v2 3/5] debuginfod: optimize extraction from seekable xz archives Omar Sandoval
2024-07-15 10:04 ` [PATCH v2 4/5] debuginfod: populate _r_seekable on scan Omar Sandoval
2024-07-15 10:04 ` [PATCH v2 5/5] debuginfod: populate _r_seekable on request Omar Sandoval
2024-07-16 20:16 ` [PATCH v2 0/5] debuginfod: speed up extraction from kernel debuginfo packages by 200x Frank Ch. Eigler
2024-07-16 21:15 ` Omar Sandoval
2024-07-16 22:15 ` Frank Ch. Eigler
2024-07-16 22:17 ` Omar Sandoval
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=381ab6f4add85fb5673e05230067c5fa70bdb9d1.1721037200.git.osandov@fb.com \
--to=osandov@osandov.com \
--cc=elfutils-devel@sourceware.org \
--cc=linux-debuggers@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox