From: Omar Sandoval <osan...@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 <osan...@fb.com> --- debuginfod/debuginfod.cxx | 213 +++++++++++++++++--------------------- 1 file changed, 96 insertions(+), 117 deletions(-) diff --git a/debuginfod/debuginfod.cxx b/debuginfod/debuginfod.cxx index 92022f3d..24702c23 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