@@ -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?