Lines Matching +full:- +full:- +full:job +full:- +full:success +full:- +full:regex
1 /* Debuginfo-over-http server.
2 Copyright (C) 2019-2021 Red Hat, Inc.
20 /* cargo-cult from libdwfl linux-kernel-modules.c */
45 #undef __attribute__ /* glibc bug - rhbz 1763325 */
86 // #include <regex> // on rhel7 gcc 4.8, not competent
87 #include <regex.h>
123 equal(haystack.end()-needle.size(), haystack.end(), in string_endswith()
139 "pragma synchronous = 0;\n" // disable fsync()s - this cache is disposable across a machine crash
145 // NB: all these are overridable with -D option
271 // XXX: we could have migration queries here to bring prior-schema
299 // buildids5: redefine srcfile1 column to be '.'-less (for rpms)
324 // buildids1: made buildid and artifacttype NULLable, to represent cached-negative
325 // lookups from sources, e.g. files or rpms that contain no buildid-indexable content
348 { "scan-file-dir", 'F', NULL, 0, "Enable ELF/DWARF file scanning.", 0 },
349 { "scan-rpm-dir", 'R', NULL, 0, "Enable RPM scanning.", 0 },
350 { "scan-deb-dir", 'U', NULL, 0, "Enable DEB scanning.", 0 },
351 { "scan-archive", 'Z', "EXT=CMD", 0, "Enable arbitrary archive scanning.", 0 },
352 // "source-oci-imageregistry" ...
356 { "rescan-time", 't', "SECONDS", 0, "Number of seconds to wait between rescans, 0=disable.", 0 },
357 …{ "groom-time", 'g', "SECONDS", 0, "Number of seconds to wait between database grooming, 0=disable…
360 { "connection-pool", 'C', "NUM", OPTION_ARG_OPTIONAL,
362 { "include", 'I', "REGEX", 0, "Include files matching REGEX, default=all.", 0 },
363 { "exclude", 'X', "REGEX", 0, "Exclude files matching REGEX, default=none.", 0 },
368 { "regex-groom", 'r', NULL, 0,"Uses regexes from -I and -X arguments to groom the database.",0},
370 …{ "fdcache-fds", ARGP_KEY_FDCACHE_FDS, "NUM", 0, "Maximum number of archive files to keep in fdcac…
372 …{ "fdcache-mbs", ARGP_KEY_FDCACHE_MBS, "MB", 0, "Maximum total size of archive file fdcache.", 0 },
374 …{ "fdcache-prefetch", ARGP_KEY_FDCACHE_PREFETCH, "NUM", 0, "Number of archive files to prefetch in…
376 { "fdcache-mintmp", ARGP_KEY_FDCACHE_MINTMP, "NUM", 0, "Minimum free space% on tmpdir.", 0 },
378 { "fdcache-prefetch-mbs", ARGP_KEY_FDCACHE_PREFETCH_MBS, "MB", 0,"Megabytes allocated to the \
381 …{ "fdcache-prefetch-fds", ARGP_KEY_FDCACHE_PREFETCH_FDS, "NUM", 0,"Number of files allocated to th…
384 …{"forwarded-ttl-limit", ARGP_KEY_FORWARDED_TTL_LIMIT, "NUM", 0, "Limit of X-Forwarded-For hops, de…
386 { "passive", ARGP_KEY_PASSIVE, NULL, 0, "Do not scan or groom, read-only database.", 0 },
388 …{ "disable-source-scan", ARGP_KEY_DISABLE_SOURCE_SCAN, NULL, 0, "Do not scan dwarf source info.", …
393 static const char doc[] = "Serve debuginfo-related content across HTTP from files under PATHs.";
410 static sqlite3 *dbq; // webapi query-servicing readonly connection, serialized ditto!
461 class tmp_inc_metric { // a RAII style wrapper for exception-safe scoped increment & decrement
471 add_metric (m, n, v, -1); in ~tmp_inc_metric()
475 class tmp_ms_metric { // a RAII style wrapper for exception-safe scoped timing
488 double deltas = (ts_end.tv_sec - ts_start.tv_sec) in ~tmp_ms_metric()
489 + (ts_end.tv_nsec - ts_start.tv_nsec)/1.e9; in ~tmp_ms_metric()
507 /* When using the in-memory database make sure it is shareable, in parse_opt()
508 so we can open it twice as read/write and read-only. */ in parse_opt()
523 scan_archives[".deb"]="(bsdtar -O -x -f - data.tar\\*)<"; in parse_opt()
524 scan_archives[".ddeb"]="(bsdtar -O -x -f - data.tar\\*)<"; in parse_opt()
525 scan_archives[".ipk"]="(bsdtar -O -x -f - data.tar\\*)<"; in parse_opt()
534 scan_archives[string(arg, (extension-arg))]=string(extension+1); in parse_opt()
541 argp_failure(state, 1, EINVAL, "-L option inconsistent with passive mode"); in parse_opt()
546 argp_failure(state, 1, EINVAL, "-D option inconsistent with passive mode"); in parse_opt()
551 argp_failure(state, 1, EINVAL, "-t option inconsistent with passive mode"); in parse_opt()
556 argp_failure(state, 1, EINVAL, "-g option inconsistent with passive mode"); in parse_opt()
561 argp_failure(state, 1, EINVAL, "-G option inconsistent with passive mode"); in parse_opt()
566 argp_failure(state, 1, EINVAL, "-c option inconsistent with passive mode"); in parse_opt()
575 argp_failure(state, 1, EINVAL, "-C NUM minimum 2"); in parse_opt()
579 // NB: no problem with unconditional free here - an earlier failed regcomp would exit program in parse_opt()
581 argp_failure(state, 1, EINVAL, "-I option inconsistent with passive mode"); in parse_opt()
589 argp_failure(state, 1, EINVAL, "-X option inconsistent with passive mode"); in parse_opt()
597 argp_failure(state, 1, EINVAL, "-r option inconsistent with passive mode"); in parse_opt()
673 add_mhd_response_header (r, "Content-Type", "text/plain"); in mhd_send_response()
785 fronters --; in done_front()
803 idlers --; in done_idle()
822 // Unique set is a thread-safe structure that lends 'ownership' of a value
824 // It's like a semaphore-on-demand.
855 // RAII-pattern way.
917 mutex obatched::lock; // just the one, since cout/cerr iostreams are not thread-safe
928 // RAII style sqlite prepared-statement holder that matches { } block lifetime
946 int rc = sqlite3_prepare_v2 (db, sql.c_str(), -1 /* to \0 */, & this->pp, NULL); in sqlite_ps()
954 sqlite3_reset(this->pp); in reset()
962 int rc = sqlite3_bind_text (this->pp, parameter, str.c_str(), -1, SQLITE_TRANSIENT); in bind()
972 int rc = sqlite3_bind_int64 (this->pp, parameter, value); in bind()
982 int rc = sqlite3_bind_null (this->pp, parameter); in bind()
991 int rc = sqlite3_step (this->pp); in step_ok_done()
993 obatched(clog) << nickname << " step-ok-done(" << sqlite3_errstr(rc) << ") " << sql << endl; in step_ok_done()
996 (void) sqlite3_reset (this->pp); in step_ok_done()
1002 int rc = sqlite3_step (this->pp); in step()
1008 ~sqlite_ps () { sqlite3_finalize (this->pp); } in ~sqlite_ps()
1009 operator sqlite3_stmt* () { return this->pp; } in operator sqlite3_stmt*()
1059 int sts = -1; in conninfo()
1067 struct sockaddr *so = u ? u->client_addr : 0; in conninfo()
1069 if (so && so->sa_family == AF_INET) { in conninfo()
1074 } else if (so && so->sa_family == AF_INET6) { in conninfo()
1076 if (IN6_IS_ADDR_V4MAPPED(&addr6->sin6_addr)) { in conninfo()
1080 addr4.sin_port = addr6->sin6_port; in conninfo()
1081 memcpy (&addr4.sin_addr.s_addr, addr6->sin6_addr.s6_addr+12, sizeof(addr4.sin_addr.s_addr)); in conninfo()
1099 const char* user_agent = MHD_lookup_connection_value (conn, MHD_HEADER_KIND, "User-Agent") ?: ""; in conninfo()
1100 …const char* x_forwarded_for = MHD_lookup_connection_value (conn, MHD_HEADER_KIND, "X-Forwarded-For… in conninfo()
1101 // NB: these are untrustworthy, beware if machine-processing log files in conninfo()
1133 add_mhd_response_header (resp, "Last-Modified", datebuf); in add_mhd_last_modified()
1136 add_mhd_response_header (resp, "Cache-Control", "public"); in add_mhd_last_modified()
1139 // quote all questionable characters of str for safe passage through a sh -c expansion.
1157 // // -> /
1158 // /foo/../ -> /
1159 // /./ -> /
1161 // This mapping is done on dwarf-side source path names, which may
1167 // do with the build-time symlinks, thus they must not be considered.
1190 i = ""; // no need to handle "/." complete-path-segment case; we're dealing with file names in canon_pathname()
1201 i = ""; // no need to handle "/.." complete-path-segment case; we're dealing with file names in canon_pathname()
1247 // A map-like class that owns a cache of file descriptors (indexed by
1265 newfd = -1;
1269 return -1;
1299 fdcache_mb += i->fd_size_mb; in set_metrics()
1301 prefetch_mb += j->fd_size_mb; in set_metrics()
1315 if (i->archive == a && i->entry == b) in intern()
1317 unlink (i->fd.c_str()); in intern()
1326 if (i->archive == a && i->entry == b) in intern()
1328 unlink (i->fd.c_str()); in intern()
1356 inc_metric("fdcache_op_count","op","emerg-flush"); in intern()
1358 this->limit(0, 0, 0, 0); // emergency flush in intern()
1361 this->limit(max_fds, max_mbs, max_prefetch_fds, max_prefetch_mbs); // age cache if required in intern()
1366 int fd = -1; in lookup()
1371 if (i->archive == a && i->entry == b) in lookup()
1381 // Iterate through prefetch while fd == -1 to ensure that no duplication between lru and in lookup()
1383 for ( auto i = prefetch.begin(); fd == -1 && i < prefetch.end(); ++i) in lookup()
1385 if (i->archive == a && i->entry == b) in lookup()
1399 inc_metric("fdcache_op_count","op","emerg-flush"); in lookup()
1401 this->limit(0, 0, 0, 0); // emergency flush in lookup()
1404 this->limit(max_fds, max_mbs, max_prefetch_fds, max_prefetch_mbs); // age cache if required in lookup()
1409 …int probe(const string& a, const string& b) // just a cache residency check - don't modify LRU sta… in probe()
1414 if (i->archive == a && i->entry == b) in probe()
1422 if (i->archive == a && i->entry == b) in probe()
1437 if (i->archive == a && i->entry == b) in clear()
1449 if (i->archive == a && i->entry == b) in clear()
1463 if (verbose > 3 && (this->max_fds != maxfds || this->max_mbs != maxmbs)) in limit()
1467 this->max_fds = maxfds; in limit()
1468 this->max_mbs = maxmbs; in limit()
1469 this->max_prefetch_fds = maxprefetchfds; in limit()
1470 this->max_prefetch_mbs = maxprefetchmbs; in limit()
1477 total_mb += i->fd_size_mb; in limit()
1478 if (total_fd > this->max_fds || total_mb > this->max_mbs) in limit()
1485 obatched(clog) << "fdcache evicted a=" << j->archive << " b=" << j->entry in limit()
1486 << " fd=" << j->fd << " mb=" << j->fd_size_mb << endl; in limit()
1489 unlink (j->fd.c_str()); in limit()
1501 total_mb += i->fd_size_mb; in limit()
1502 if (total_fd > this->max_prefetch_fds || total_mb > this->max_prefetch_mbs) in limit()
1508 … obatched(clog) << "fdcache evicted from prefetch a=" << j->archive << " b=" << j->entry in limit()
1509 << " fd=" << j->fd << " mb=" << j->fd_size_mb << endl; in limit()
1512 unlink (j->fd.c_str()); in limit()
1534 its file descriptor, otherwise return -1.
1555 return -1; in extract_section()
1563 return -1; in extract_section()
1565 /* Success. */ in extract_section()
1571 return -1; in extract_section()
1592 const char *scn_name = elf_strptr (elf, shstrndx, shdr->sh_name); in extract_section()
1603 if (data->d_buf == NULL) in extract_section()
1619 ssize_t res = write_retry (fd, data->d_buf, data->d_size); in extract_section()
1620 if (res < 0 || (size_t) res != data->d_size) in extract_section()
1633 fdcache.intern (b_source, section, tmppath, data->d_size, true); in extract_section()
1642 fd = -1; in extract_section()
1710 obatched(clog) << "cannot create fd-response for " << b_source0 in handle_buildid_f_match()
1717 add_mhd_response_header (r, "Content-Type", "application/octet-stream"); in handle_buildid_f_match()
1718 add_mhd_response_header (r, "X-DEBUGINFOD-SIZE", in handle_buildid_f_match()
1720 add_mhd_response_header (r, "X-DEBUGINFOD-FILE", file.c_str()); in handle_buildid_f_match()
1732 // For security/portability reasons, many distro-package archives have
1735 // assumption that this matches the dwarf-derived file names too.
1816 obatched(clog) << "cannot create fd-response for " << b_source0 << endl; in handle_buildid_r_match()
1823 add_mhd_response_header (r, "Content-Type", "application/octet-stream"); in handle_buildid_r_match()
1824 add_mhd_response_header (r, "X-DEBUGINFOD-SIZE", in handle_buildid_r_match()
1826 add_mhd_response_header (r, "X-DEBUGINFOD-ARCHIVE", b_source0.c_str()); in handle_buildid_r_match()
1827 add_mhd_response_header (r, "X-DEBUGINFOD-FILE", b_source1.c_str()); in handle_buildid_r_match()
1907 if (! S_ISREG(archive_entry_mode (e))) // skip non-files completely in handle_buildid_r_match()
1952 prefetch_count --; in handle_buildid_r_match()
1953 close (fd); // we're not saving this fd to make a mhd-response from! in handle_buildid_r_match()
1996 obatched(clog) << "cannot create fd-response for " << b_source0 << endl; in handle_buildid_r_match()
2003 add_mhd_response_header (r, "Content-Type", in handle_buildid_r_match()
2004 "application/octet-stream"); in handle_buildid_r_match()
2005 add_mhd_response_header (r, "X-DEBUGINFOD-SIZE", in handle_buildid_r_match()
2007 add_mhd_response_header (r, "X-DEBUGINFOD-ARCHIVE", in handle_buildid_r_match()
2009 add_mhd_response_header (r, "X-DEBUGINFOD-FILE", file.c_str()); in handle_buildid_r_match()
2076 inc_metric("dc_pool_op_count","op","begin-reuse"); in debuginfod_pool_begin()
2081 inc_metric("dc_pool_op_count","op","begin-new"); in debuginfod_pool_begin()
2101 inc_metric("dc_pool_op_count","op","end-save"); in debuginfod_pool_end()
2150 // If invoked from the scanner threads, use the scanners' read-write in handle_buildid()
2151 // connection. Otherwise use the web query threads' read-only connection. in handle_buildid()
2158 pp = new sqlite_ps (thisdb, "mhd-query-d", in handle_buildid()
2161 pp->reset(); in handle_buildid()
2162 pp->bind(1, buildid); in handle_buildid()
2166 pp = new sqlite_ps (thisdb, "mhd-query-e", in handle_buildid()
2169 pp->reset(); in handle_buildid()
2170 pp->bind(1, buildid); in handle_buildid()
2175 // Incoming source queries may come in with either dwarf-level OR canonicalized paths. in handle_buildid()
2178 pp = new sqlite_ps (thisdb, "mhd-query-s", in handle_buildid()
2181 pp->reset(); in handle_buildid()
2182 pp->bind(1, buildid); in handle_buildid()
2183 // NB: we don't store the non-canonicalized path names any more, but old databases in handle_buildid()
2185 pp->bind(2, suffix); in handle_buildid()
2186 pp->bind(3, canon_pathname(suffix)); in handle_buildid()
2190 pp = new sqlite_ps (thisdb, "mhd-query-i", in handle_buildid()
2195 pp->reset(); in handle_buildid()
2196 pp->bind(1, buildid); in handle_buildid()
2197 pp->bind(2, buildid); in handle_buildid()
2206 int rc = pp->step(); in handle_buildid()
2242 pp->reset(); in handle_buildid()
2250 int fd = -1; in handle_buildid()
2258 // Transcribe incoming User-Agent: in handle_buildid()
2259 string ua = MHD_lookup_connection_value (conn, MHD_HEADER_KIND, "User-Agent") ?: ""; in handle_buildid()
2260 string ua_complete = string("User-Agent: ") + ua; in handle_buildid()
2265 string xff = MHD_lookup_connection_value (conn, MHD_HEADER_KIND, "X-Forwarded-For") ?: ""; in handle_buildid()
2274 // if X-Forwarded-For: exceeds N hops, in handle_buildid()
2277 … throw reportable_exception(MHD_HTTP_NOT_FOUND, "not found, --forwared-ttl-limit reached \ in handle_buildid()
2280 // Compute the client's numeric IP address only - so can't merge with conninfo() in handle_buildid()
2283 struct sockaddr *so = u ? u->client_addr : 0; in handle_buildid()
2285 if (so && so->sa_family == AF_INET) { in handle_buildid()
2288 } else if (so && so->sa_family == AF_INET6) { in handle_buildid()
2290 if (IN6_IS_ADDR_V4MAPPED(&addr6->sin6_addr)) { in handle_buildid()
2294 addr4.sin_port = addr6->sin6_port; in handle_buildid()
2295 … memcpy (&addr4.sin_addr.s_addr, addr6->sin6_addr.s6_addr+12, sizeof(addr4.sin_addr.s_addr)); in handle_buildid()
2305 string xff_complete = string("X-Forwarded-For: ")+xff+string(hostname); in handle_buildid()
2328 fd = -errno; /* Set by debuginfod_begin. */ in handle_buildid()
2342 add_mhd_response_header (r, "Content-Type", in handle_buildid()
2343 "application/octet-stream"); in handle_buildid()
2357 string value = header_dup.substr(colon+1,newline-colon-1); in handle_buildid()
2379 case -ENOSYS: in handle_buildid()
2381 case -ENOENT: in handle_buildid()
2384 throw libc_exception(-fd, "upstream debuginfod query failed"); in handle_buildid()
2399 // utility function for assembling prometheus-compatible
2400 // name="escaped-value" strings
2419 // add prometheus-format metric name + label tuple (if any) + value
2519 add_mhd_response_header (r, "Content-Type", "text/plain"); in handle_metrics()
2535 add_mhd_response_header (r, "Content-Type", "text/plain"); in handle_root()
2561 queue a response, libmicrohttpd would suppress http keep-alive in handler_cb()
2562 (via connection->read_closed = true). */ in handler_cb()
2572 …*maxsize_string = MHD_lookup_connection_value(connection, MHD_HEADER_KIND, "X-DEBUGINFOD-MAXSIZE"); in handler_cb()
2585 off_t http_size = -1; in handler_cb()
2605 add_metric ("thread_busy", "role", "http-buildid-after-you", 1); in handler_cb()
2607 (void) pthread_setname_np (pthread_self(), "mhd-buildid-after-you"); in handler_cb()
2614 … afteryou = (tsay_end.tv_sec - tsay_start.tv_sec) + (tsay_end.tv_nsec - tsay_start.tv_nsec)/1.e9; in handler_cb()
2615 add_metric ("thread_busy", "role", "http-buildid-after-you", -1); in handler_cb()
2617 tmp_inc_metric m ("thread_busy", "role", "http-buildid"); in handler_cb()
2619 (void) pthread_setname_np (pthread_self(), "mhd-buildid"); in handler_cb()
2625 string buildid = url_copy.substr(slash1+1, slash2-slash1-1); in handler_cb()
2636 artifacttype = url_copy.substr(slash2+1, slash3-slash2-1); in handler_cb()
2653 tmp_inc_metric m ("thread_busy", "role", "http-metrics"); in handler_cb()
2690 double deltas = (ts_end.tv_sec - ts_start.tv_sec) + (ts_end.tv_nsec - ts_start.tv_nsec)/1.e9; in handler_cb()
2696 << ' ' << (int)(afteryou*1000) << '+' << (int)((deltas-afteryou)*1000) << "ms" in handler_cb()
2725 noexcept // no exceptions - so we can simplify the altdbg resource release at end in dwarf_extract_source_paths()
2732 int altdbg_fd = -1; in dwarf_extract_source_paths()
2734 // DWZ handling: if we have an unsatisfied debug-alt-link, add an in dwarf_extract_source_paths()
2738 const void *alt_build_id; // elfutils-owned memory in dwarf_extract_source_paths()
2771 // NB: this is not actually recursive! This invokes the web-query in dwarf_extract_source_paths()
2786 // NB: dwarf_setalt(alt) inappropriate - already done! in dwarf_extract_source_paths()
2795 else // (alt == NULL) - signal possible presence of poor debuginfo in dwarf_extract_source_paths()
2840 // This is a common symptom for dwz-compressed debug files, in dwarf_extract_source_paths()
2853 if (string(hat) == "<built-in>") // gcc intrinsics, don't bother record in dwarf_extract_source_paths()
2914 auto elf_type = ehdr->e_type; in elf_classify()
2916 const void *build_id; // elfutils-owned memory in elf_classify()
2920 // It's not a diagnostic-worthy error for an elf file to lack build-id. in elf_classify()
2934 // now decide whether it's an executable - namely, any allocatable section has in elf_classify()
2955 // allocated (loadable / vm-addr-assigned) section with available content? in elf_classify()
2956 if ((shdr->sh_type == SHT_PROGBITS) && (shdr->sh_flags & SHF_ALLOC)) in elf_classify()
2966 // now decide whether it's a debuginfo - namely, if it has any .debug* or .zdebug* sections in elf_classify()
2985 const char *section_name = elf_strptr (elf, shstrndx, shdr->sh_name); in elf_classify()
3002 else if (shdr->sh_type == SHT_SYMTAB) in elf_classify()
3006 else if (shdr->sh_type != SHT_NOBITS in elf_classify()
3007 && shdr->sh_type != SHT_NOTE in elf_classify()
3008 && (shdr->sh_flags & SHF_ALLOC) != 0) in elf_classify()
3014 // For more expansive elf/split-debuginfo classification, we in elf_classify()
3015 // want to identify as debuginfo "strip -s"-produced files in elf_classify()
3017 // identify "strip -g" executables (with .symtab left there). in elf_classify()
3051 // specifically, no need to elf-begin a file we already determined is non-elf in scan_source_file()
3074 // cache the corrupt-elf case (!executable_p && in scan_source_file()
3099 // register this build-id in the interning table in scan_source_file()
3197 // Analyze given archive file of given age; record buildids / exec/debuginfo-ness of its
3269 if (! S_ISREG(archive_entry_mode (e))) // skip non-files completely in archive_classify()
3317 // elf_classify() - because it'll end up in the in archive_classify()
3372 else // potential source - sdef record in archive_classify()
3504 …sqlite_ps ps_f_upsert_buildids (db, "file-buildids-intern", "insert or ignore into " BUILDIDS "_bu… in thread_main_scanner()
3505 …sqlite_ps ps_f_upsert_files (db, "file-files-intern", "insert or ignore into " BUILDIDS "_files VA… in thread_main_scanner()
3506 sqlite_ps ps_f_upsert_de (db, "file-de-upsert", in thread_main_scanner()
3512 sqlite_ps ps_f_upsert_s (db, "file-s-upsert", in thread_main_scanner()
3519 sqlite_ps ps_f_query (db, "file-negativehit-find", in thread_main_scanner()
3522 sqlite_ps ps_f_scan_done (db, "file-scanned", in thread_main_scanner()
3527 …sqlite_ps ps_r_upsert_buildids (db, "rpm-buildid-intern", "insert or ignore into " BUILDIDS "_buil… in thread_main_scanner()
3528 …sqlite_ps ps_r_upsert_files (db, "rpm-file-intern", "insert or ignore into " BUILDIDS "_files VALU… in thread_main_scanner()
3529 sqlite_ps ps_r_upsert_de (db, "rpm-de-insert", in thread_main_scanner()
3534 sqlite_ps ps_r_upsert_sref (db, "rpm-sref-insert", in thread_main_scanner()
3538 sqlite_ps ps_r_upsert_sdef (db, "rpm-sdef-insert", in thread_main_scanner()
3542 sqlite_ps ps_r_query (db, "rpm-negativehit-query", in thread_main_scanner()
3545 sqlite_ps ps_r_scan_done (db, "rpm-scanned", in thread_main_scanner()
3559 add_metric("thread_busy", "role", "scan", -1); in thread_main_scanner()
3605 {} // NB: not just if a successful scan - we might have encountered -ENOSPC & failed in thread_main_scanner()
3609 // finished a scanning step -- not a "loop", because we just in thread_main_scanner()
3615 add_metric("thread_busy", "role", "scan", -1); in thread_main_scanner()
3631 // Turn the source_paths into an fts(3)-compatible char**. Since in scan_source_paths()
3665 obatched(clog) << "fts traversing " << f->fts_path << endl; in scan_source_paths()
3667 switch (f->fts_info) in scan_source_paths()
3675 char *rp = realpath(f->fts_path, NULL); in scan_source_paths()
3686 obatched(clog) << "fts skipped by regex " in scan_source_paths()
3690 inc_metric("traversed_total","type","file-skipped-I"); in scan_source_paths()
3692 inc_metric("traversed_total","type","file-skipped-X"); in scan_source_paths()
3696 scanq.push_back (make_pair(rps, *f->fts_statp)); in scan_source_paths()
3706 auto x = libc_exception(f->fts_errno, string("fts traversal ") + string(f->fts_path)); in scan_source_paths()
3712 case FTS_SL: // ignore, but count because debuginfod -L would traverse these in scan_source_paths()
3726 double deltas = (ts_end.tv_sec - ts_start.tv_sec) + (ts_end.tv_nsec - ts_start.tv_nsec)/1.e9; in scan_source_paths()
3729 << ", regex-skipped=" << fts_regex << endl; in scan_source_paths()
3746 scanq.wait_idle(); // don't start a new traversal while scanners haven't finished the job in thread_main_fts_source_paths()
3752 if (last_rescan == 0) // at least one initial rescan is documented even for -t0 in thread_main_fts_source_paths()
3789 sqlite_ps ps_query (db, "database-overview", in database_stats_report()
3835 // DECISION TIME - we enumerate stale fileids/mtimes in groom()
3944 …B: "vacuum" is too heavy for even daily runs: it rewrites the entire db, so is done as maxigroom -G in groom()
3964 double deltas = (ts_end.tv_sec - ts_start.tv_sec) + (ts_end.tv_nsec - ts_start.tv_nsec)/1.e9; in groom()
3986 if (last_groom == 0) // at least one initial groom is documented even for -g0 in thread_main_groom()
4061 // A user-defined sqlite function, to score the sharedness of the
4063 // / source-rpm names, so that the closest match
4064 // (directory-topology-wise closest) is found. This is important in
4065 // case the same sref (source file name) is in many -debuginfo or
4066 // -debugsource RPMs, such as when multiple versions/releases of the
4072 sqlite3_result_error(c, "expect 2 string arguments", -1); in sqlite3_sharedprefix_fn()
4117 fdcache_prefetch = 64; // guesstimate storage is this much less costly than re-decompression in main()
4136 obatched(clog) << "warning: without -F -R -U -Z, ignoring PATHs" << endl; in main()
4144 (void) signal (SIGUSR1, sigusr1_handler); // end-user in main()
4145 (void) signal (SIGUSR2, sigusr2_handler); // end-user in main()
4154 |SQLITE_OPEN_FULLMUTEX), /* thread-safe */ in main()
4175 |SQLITE_OPEN_FULLMUTEX), /* thread-safe */ in main()
4189 // add special string-prefix-similarity function used in rpm sref/sdef resolution in main()
4210 /* If '-C' wasn't given or was given with no arg, pick a reasonable default in main()
4235 // Start httpd server threads. Use a single dual-homed pool. in main()
4278 // add maxigroom sql if -G given in main()
4287 // tables that have file foreign-keys, which is a lot. in main()
4290 // vs. =off (only 2x but may corrupt database if program dies mid-vacuum) in main()
4297 // run extra -D sql if given in main()
4338 if (du && du[0] != '\0') // set to non-empty string? in main()
4384 scanq.nuke(); // wake up any remaining scanq-related threads, let them die in main()
4411 // NB: no problem with unconditional free here - an earlier failed regcomp would exit program in main()