mirror of
https://github.com/Zygo/bees.git
synced 2025-08-02 05:43:29 +02:00
Compare commits
11 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
ef9b4b3a50 | ||
|
7ca857dff0 | ||
|
8331f70db7 | ||
|
a844024395 | ||
|
47243aef14 | ||
|
a670aa5a71 | ||
|
51b3bcdbe4 | ||
|
ae58401d53 | ||
|
3e7eb43b51 | ||
|
962d94567c | ||
|
6dbef5f27b |
@@ -55,6 +55,7 @@ These bugs are particularly popular among bees users, though not all are specifi
|
||||
| 5.4 | 5.11 | spurious tree checker failures on extent ref hash | 5.4.125, 5.10.43, 5.11.5, 5.12 and later | 1119a72e223f btrfs: tree-checker: do not error out if extent ref hash doesn't match
|
||||
| - | 5.11 | tree mod log issue #5 | 4.4.263, 4.9.263, 4.14.227, 4.19.183, 5.4.108, 5.10.26, 5.11.9, 5.12 and later | dbcc7d57bffc btrfs: fix race when cloning extent buffer during rewind of an old root
|
||||
| - | 5.12 | tree mod log issue #6 | 4.14.233, 4.19.191, 5.4.118, 5.10.36, 5.11.20, 5.12.3, 5.13 and later | f9690f426b21 btrfs: fix race when picking most recent mod log operation for an old root
|
||||
| 5.11 | 5.12 | subvols marked for deletion with `btrfs sub del` become permanently undeletable ("ghost" subvols) | 5.12 stopped creation of new ghost subvols | Partially fixed in 8d488a8c7ba2 btrfs: fix subvolume/snapshot deletion not triggered on mount. Qu wrote a [patch](https://github.com/adam900710/linux/commit/9de990fcc8864c376eb28aa7482c54321f94acd4) to allow `btrfs sub del -i` to remove "ghost" subvols, but it was never merged upstream.
|
||||
| 4.15 | 5.16 | spurious warnings from `fs/fs-writeback.c` when `flushoncommit` is enabled | 5.15.27, 5.16.13, 5.17 and later | a0f0cf8341e3 btrfs: get rid of warning on transaction commit when using flushoncommit
|
||||
| - | 5.17 | crash during device removal can make filesystem unmountable | 5.15.54, 5.16.20, 5.17.3, 5.18 and later | bbac58698a55 btrfs: remove device item and update super block in the same transaction
|
||||
| - | 5.18 | wrong superblock num_devices makes filesystem unmountable | 4.14.283, 4.19.247, 5.4.198, 5.10.121, 5.15.46, 5.17.14, 5.18.3, 5.19 and later | d201238ccd2f btrfs: repair super block num_devices automatically
|
||||
|
@@ -78,9 +78,6 @@ enum btrfs_compression_type {
|
||||
#define BTRFS_SHARED_BLOCK_REF_KEY 182
|
||||
#define BTRFS_SHARED_DATA_REF_KEY 184
|
||||
#define BTRFS_BLOCK_GROUP_ITEM_KEY 192
|
||||
#define BTRFS_FREE_SPACE_INFO_KEY 198
|
||||
#define BTRFS_FREE_SPACE_EXTENT_KEY 199
|
||||
#define BTRFS_FREE_SPACE_BITMAP_KEY 200
|
||||
#define BTRFS_DEV_EXTENT_KEY 204
|
||||
#define BTRFS_DEV_ITEM_KEY 216
|
||||
#define BTRFS_CHUNK_ITEM_KEY 228
|
||||
@@ -97,6 +94,18 @@ enum btrfs_compression_type {
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef BTRFS_FREE_SPACE_INFO_KEY
|
||||
#define BTRFS_FREE_SPACE_INFO_KEY 198
|
||||
#define BTRFS_FREE_SPACE_EXTENT_KEY 199
|
||||
#define BTRFS_FREE_SPACE_BITMAP_KEY 200
|
||||
#define BTRFS_FREE_SPACE_OBJECTID -11ULL
|
||||
#endif
|
||||
|
||||
#ifndef BTRFS_BLOCK_GROUP_RAID1C4
|
||||
#define BTRFS_BLOCK_GROUP_RAID1C3 (1ULL << 9)
|
||||
#define BTRFS_BLOCK_GROUP_RAID1C4 (1ULL << 10)
|
||||
#endif
|
||||
|
||||
#ifndef BTRFS_DEFRAG_RANGE_START_IO
|
||||
|
||||
// For some reason uapi has BTRFS_DEFRAG_RANGE_COMPRESS and
|
||||
|
@@ -13,7 +13,7 @@ namespace crucible {
|
||||
hexdump(ostream &os, const V &v)
|
||||
{
|
||||
const auto v_size = v.size();
|
||||
const uint8_t* const v_data = reinterpret_cast<uint8_t*>(v.data());
|
||||
const uint8_t* const v_data = reinterpret_cast<const uint8_t*>(v.data());
|
||||
os << "V { size = " << v_size << ", data:\n";
|
||||
for (size_t i = 0; i < v_size; i += 8) {
|
||||
string hex, ascii;
|
||||
|
@@ -932,15 +932,9 @@ namespace crucible {
|
||||
NTOA_TABLE_ENTRY_ENUM(BTRFS_SHARED_BLOCK_REF_KEY),
|
||||
NTOA_TABLE_ENTRY_ENUM(BTRFS_SHARED_DATA_REF_KEY),
|
||||
NTOA_TABLE_ENTRY_ENUM(BTRFS_BLOCK_GROUP_ITEM_KEY),
|
||||
#ifdef BTRFS_FREE_SPACE_INFO_KEY
|
||||
NTOA_TABLE_ENTRY_ENUM(BTRFS_FREE_SPACE_INFO_KEY),
|
||||
#endif
|
||||
#ifdef BTRFS_FREE_SPACE_EXTENT_KEY
|
||||
NTOA_TABLE_ENTRY_ENUM(BTRFS_FREE_SPACE_EXTENT_KEY),
|
||||
#endif
|
||||
#ifdef BTRFS_FREE_SPACE_BITMAP_KEY
|
||||
NTOA_TABLE_ENTRY_ENUM(BTRFS_FREE_SPACE_BITMAP_KEY),
|
||||
#endif
|
||||
NTOA_TABLE_ENTRY_ENUM(BTRFS_DEV_EXTENT_KEY),
|
||||
NTOA_TABLE_ENTRY_ENUM(BTRFS_DEV_ITEM_KEY),
|
||||
NTOA_TABLE_ENTRY_ENUM(BTRFS_CHUNK_ITEM_KEY),
|
||||
@@ -972,9 +966,7 @@ namespace crucible {
|
||||
NTOA_TABLE_ENTRY_ENUM(BTRFS_CSUM_TREE_OBJECTID),
|
||||
NTOA_TABLE_ENTRY_ENUM(BTRFS_QUOTA_TREE_OBJECTID),
|
||||
NTOA_TABLE_ENTRY_ENUM(BTRFS_UUID_TREE_OBJECTID),
|
||||
#ifdef BTRFS_FREE_SPACE_TREE_OBJECTID
|
||||
NTOA_TABLE_ENTRY_ENUM(BTRFS_FREE_SPACE_TREE_OBJECTID),
|
||||
#endif
|
||||
NTOA_TABLE_ENTRY_ENUM(BTRFS_BALANCE_OBJECTID),
|
||||
NTOA_TABLE_ENTRY_ENUM(BTRFS_ORPHAN_OBJECTID),
|
||||
NTOA_TABLE_ENTRY_ENUM(BTRFS_TREE_LOG_OBJECTID),
|
||||
|
@@ -17,6 +17,7 @@ KillSignal=SIGTERM
|
||||
MemoryAccounting=true
|
||||
Nice=19
|
||||
Restart=on-abnormal
|
||||
RuntimeDirectoryMode=0700
|
||||
RuntimeDirectory=bees
|
||||
StartupCPUWeight=25
|
||||
StartupIOWeight=25
|
||||
|
@@ -230,8 +230,10 @@ BeesContext::dedup(const BeesRangePair &brp_in)
|
||||
BeesAddress first_addr(brp.first.fd(), brp.first.begin());
|
||||
BeesAddress second_addr(brp.second.fd(), brp.second.begin());
|
||||
|
||||
if (first_addr.get_physical_or_zero() == second_addr.get_physical_or_zero()) {
|
||||
BEESLOGTRACE("equal physical addresses in dedup");
|
||||
const auto first_gpoz = first_addr.get_physical_or_zero();
|
||||
const auto second_gpoz = second_addr.get_physical_or_zero();
|
||||
if (first_gpoz == second_gpoz) {
|
||||
BEESLOGDEBUG("equal physical addresses " << first_addr << " and " << second_addr << " in dedup");
|
||||
BEESCOUNT(bug_dedup_same_physical);
|
||||
}
|
||||
|
||||
|
@@ -819,7 +819,8 @@ BeesHashTable::BeesHashTable(shared_ptr<BeesContext> ctx, string filename, off_t
|
||||
root_info.do_ioctl(m_ctx->root_fd());
|
||||
// Hash might not be a btrfs
|
||||
BtrfsIoctlFsInfoArgs hash_info;
|
||||
if (hash_info.do_ioctl_nothrow(m_fd)) return;
|
||||
// If btrfs fs_info ioctl fails, it must be a different fs
|
||||
if (!hash_info.do_ioctl_nothrow(m_fd)) return;
|
||||
// If Hash is a btrfs, Root must be the same one
|
||||
if (root_info.fsid() != hash_info.fsid()) return;
|
||||
// Hash is on the same one, blacklist it
|
||||
|
@@ -948,22 +948,24 @@ BeesScanModeExtent::SizeTier::find_next_extent()
|
||||
const auto search_calls = BtrfsIoctlSearchKey::s_calls - init_s_calls;
|
||||
const auto search_loops = BtrfsIoctlSearchKey::s_loops - init_s_loops;
|
||||
if (crawl_time.age() > 1) {
|
||||
BEESLOGDEBUG(
|
||||
"loop_count " << loop_count
|
||||
<< " size_low_count " << size_low_count
|
||||
<< " size_high_count " << size_high_count
|
||||
<< " gen_low_count " << gen_low_count
|
||||
<< " gen_high_count " << gen_high_count
|
||||
<< " search_calls " << search_calls
|
||||
<< " search_loops " << search_loops
|
||||
<< " skips " << skip_count
|
||||
<< " flops " << flop_count
|
||||
<< " time " << crawl_time
|
||||
<< " subvol " << m_subvol
|
||||
<< " search/loop " << pretty(search_calls / loop_count)
|
||||
<< " skip/loop " << (100 * skip_count / loop_count) << "%"
|
||||
<< " flop/loop " << (100 * flop_count / loop_count) << "%"
|
||||
);
|
||||
if (loop_count) {
|
||||
BEESLOGDEBUG(
|
||||
"loop_count " << loop_count
|
||||
<< " size_low_count " << size_low_count
|
||||
<< " size_high_count " << size_high_count
|
||||
<< " gen_low_count " << gen_low_count
|
||||
<< " gen_high_count " << gen_high_count
|
||||
<< " search_calls " << search_calls
|
||||
<< " search_loops " << search_loops
|
||||
<< " skips " << skip_count
|
||||
<< " flops " << flop_count
|
||||
<< " time " << crawl_time
|
||||
<< " subvol " << m_subvol
|
||||
<< " search/loop " << pretty(search_calls / loop_count)
|
||||
<< " skip/loop " << (100 * skip_count / loop_count) << "%"
|
||||
<< " flop/loop " << (100 * flop_count / loop_count) << "%"
|
||||
);
|
||||
}
|
||||
if (debug_oss) {
|
||||
BEESLOGDEBUG("debug oss trace:\n" << debug_oss->str());
|
||||
}
|
||||
@@ -1146,7 +1148,7 @@ BeesScanModeExtent::SizeTier::find_next_extent()
|
||||
const auto hold_state = m_crawl->hold_state(this_state);
|
||||
const auto sft = shared_from_this();
|
||||
ostringstream oss;
|
||||
oss << "map_" << to_hex(this_bytenr) << "_" << pretty(this_length);
|
||||
oss << "map_" << hex << this_bytenr << dec << "_" << pretty(this_length);
|
||||
Task create_map_task(oss.str(), [sft, this_bytenr, hold_state, this_length, find_next_task]() {
|
||||
sft->create_extent_map(this_bytenr, hold_state, this_length, find_next_task);
|
||||
BEESCOUNT(crawl_extent);
|
||||
@@ -1321,7 +1323,8 @@ BeesScanModeExtent::next_transid()
|
||||
}
|
||||
const auto bytenr_offset = min(bi_last_bytenr, max(bytenr, bi.first_bytenr)) - bi.first_bytenr + bi.first_total;
|
||||
const auto bytenr_norm = bytenr_offset / double(fs_size);
|
||||
const auto time_so_far = now - min(now, this_state.m_started);
|
||||
const auto eta_start = min(now, this_state.m_started);
|
||||
const auto time_so_far = now - eta_start;
|
||||
const string start_stamp = strf_localtime(this_state.m_started);
|
||||
string eta_stamp = "-";
|
||||
string eta_pretty = "-";
|
||||
@@ -1331,9 +1334,10 @@ BeesScanModeExtent::next_transid()
|
||||
// eta_stamp = "idle";
|
||||
} else if (time_so_far > 10 && bytenr_offset > 1024 * 1024 * 1024) {
|
||||
const time_t eta_duration = time_so_far / bytenr_norm;
|
||||
const time_t eta_time = eta_duration + now;
|
||||
const time_t eta_time = eta_duration + eta_start;
|
||||
const time_t eta_remain = eta_time - now;
|
||||
eta_stamp = strf_localtime(eta_time);
|
||||
eta_pretty = pretty_seconds(eta_duration);
|
||||
eta_pretty = pretty_seconds(eta_remain);
|
||||
}
|
||||
const auto &mma = mes.m_map.at(subvol);
|
||||
const auto mma_ratio = mes_sample_size_ok ? (mma.m_bytes / double(mes.m_total)) : 1.0;
|
||||
@@ -2013,7 +2017,7 @@ BeesRoots::open_root_nocache(uint64_t rootid)
|
||||
BEESCOUNT(root_parent_open_try);
|
||||
Fd parent_fd = open_root(parent_rootid);
|
||||
if (!parent_fd) {
|
||||
BEESLOGTRACE("no parent_fd");
|
||||
BEESLOGDEBUG("no parent_fd for " << parent_rootid);
|
||||
BEESCOUNT(root_parent_open_fail);
|
||||
return Fd();
|
||||
}
|
||||
@@ -2036,7 +2040,7 @@ BeesRoots::open_root_nocache(uint64_t rootid)
|
||||
BEESTRACE("dirid " << dirid << " path " << ino.m_paths.at(0));
|
||||
parent_fd = bees_openat(parent_fd, ino.m_paths.at(0).c_str(), FLAGS_OPEN_DIR);
|
||||
if (!parent_fd) {
|
||||
BEESLOGTRACE("no parent_fd from dirid");
|
||||
BEESLOGDEBUG("no parent_fd from dirid " << dirid << " in parent_rootid " << parent_rootid);
|
||||
BEESCOUNT(root_parent_path_open_fail);
|
||||
return Fd();
|
||||
}
|
||||
@@ -2044,7 +2048,7 @@ BeesRoots::open_root_nocache(uint64_t rootid)
|
||||
BEESTRACE("openat(" << name_fd(parent_fd) << ", " << name << ")");
|
||||
Fd rv = bees_openat(parent_fd, name.c_str(), FLAGS_OPEN_DIR);
|
||||
if (!rv) {
|
||||
BEESLOGTRACE("open failed for name " << name << ": " << strerror(errno));
|
||||
BEESLOGDEBUG("open failed for name " << name << " in parent_fd " << name_fd(parent_fd) << ": " << strerror(errno));
|
||||
BEESCOUNT(root_open_fail);
|
||||
return rv;
|
||||
}
|
||||
|
@@ -28,18 +28,18 @@ BeesTracer::~BeesTracer()
|
||||
{
|
||||
if (!tl_silent && exception_check()) {
|
||||
if (tl_first) {
|
||||
BEESLOGNOTICE("--- BEGIN TRACE --- exception ---");
|
||||
BEESLOG(BEES_TRACE_LEVEL, "TRACE: --- BEGIN TRACE --- exception ---");
|
||||
tl_first = false;
|
||||
}
|
||||
try {
|
||||
m_func();
|
||||
} catch (exception &e) {
|
||||
BEESLOGNOTICE("Nested exception: " << e.what());
|
||||
BEESLOG(BEES_TRACE_LEVEL, "TRACE: Nested exception: " << e.what());
|
||||
} catch (...) {
|
||||
BEESLOGNOTICE("Nested exception ...");
|
||||
BEESLOG(BEES_TRACE_LEVEL, "TRACE: Nested exception ...");
|
||||
}
|
||||
if (!m_next_tracer) {
|
||||
BEESLOGNOTICE("--- END TRACE --- exception ---");
|
||||
BEESLOG(BEES_TRACE_LEVEL, "TRACE: --- END TRACE --- exception ---");
|
||||
}
|
||||
}
|
||||
tl_next_tracer = m_next_tracer;
|
||||
@@ -49,7 +49,7 @@ BeesTracer::~BeesTracer()
|
||||
}
|
||||
}
|
||||
|
||||
BeesTracer::BeesTracer(function<void()> f, bool silent) :
|
||||
BeesTracer::BeesTracer(const function<void()> &f, bool silent) :
|
||||
m_func(f)
|
||||
{
|
||||
m_next_tracer = tl_next_tracer;
|
||||
@@ -61,12 +61,12 @@ void
|
||||
BeesTracer::trace_now()
|
||||
{
|
||||
BeesTracer *tp = tl_next_tracer;
|
||||
BEESLOGNOTICE("--- BEGIN TRACE ---");
|
||||
BEESLOG(BEES_TRACE_LEVEL, "TRACE: --- BEGIN TRACE ---");
|
||||
while (tp) {
|
||||
tp->m_func();
|
||||
tp = tp->m_next_tracer;
|
||||
}
|
||||
BEESLOGNOTICE("--- END TRACE ---");
|
||||
BEESLOG(BEES_TRACE_LEVEL, "TRACE: --- END TRACE ---");
|
||||
}
|
||||
|
||||
bool
|
||||
|
@@ -572,7 +572,7 @@ BeesRangePair::grow(shared_ptr<BeesContext> ctx, bool constrained)
|
||||
}
|
||||
|
||||
if (first.overlaps(second)) {
|
||||
BEESLOGTRACE("after grow, first " << first << "\n\toverlaps " << second);
|
||||
BEESLOGDEBUG("after grow, first " << first << "\n\toverlaps " << second);
|
||||
BEESCOUNT(bug_grow_pair_overlaps);
|
||||
}
|
||||
|
||||
@@ -674,7 +674,7 @@ BeesAddress::magic_check(uint64_t flags)
|
||||
static const unsigned recognized_flags = compressed_flags | delalloc_flags | ignore_flags | unusable_flags;
|
||||
|
||||
if (flags & ~recognized_flags) {
|
||||
BEESLOGTRACE("Unrecognized flags in " << fiemap_extent_flags_ntoa(flags));
|
||||
BEESLOGNOTICE("Unrecognized flags in " << fiemap_extent_flags_ntoa(flags));
|
||||
m_addr = UNUSABLE;
|
||||
// maybe we throw here?
|
||||
BEESCOUNT(addr_unrecognized);
|
||||
|
91
src/bees.cc
91
src/bees.cc
@@ -4,6 +4,7 @@
|
||||
#include "crucible/process.h"
|
||||
#include "crucible/string.h"
|
||||
#include "crucible/task.h"
|
||||
#include "crucible/uname.h"
|
||||
|
||||
#include <cctype>
|
||||
#include <cmath>
|
||||
@@ -11,17 +12,19 @@
|
||||
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <regex>
|
||||
#include <sstream>
|
||||
|
||||
// PRIx64
|
||||
#include <inttypes.h>
|
||||
|
||||
#include <sched.h>
|
||||
#include <sys/fanotify.h>
|
||||
|
||||
#include <linux/fs.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
// statfs
|
||||
#include <linux/magic.h>
|
||||
#include <sys/statfs.h>
|
||||
|
||||
// setrlimit
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
@@ -391,6 +394,73 @@ BeesStringFile::read()
|
||||
return read_string(fd, st.st_size);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
bees_fsync(int const fd)
|
||||
{
|
||||
|
||||
// Note that when btrfs renames a temporary over an existing file,
|
||||
// it flushes the temporary, so we get the right behavior if we
|
||||
// just do nothing here (except when the file is first created;
|
||||
// however, in that case the result is the same as if the file
|
||||
// did not exist, was empty, or was filled with garbage).
|
||||
//
|
||||
// Kernel versions prior to 5.16 had bugs which would put ghost
|
||||
// dirents in $BEESHOME if there was a crash when we called
|
||||
// fsync() here.
|
||||
//
|
||||
// Some other filesystems will throw our data away if we don't
|
||||
// call fsync, so we do need to call fsync() on those filesystems.
|
||||
//
|
||||
// Newer btrfs kernel versions rely on fsync() to report
|
||||
// unrecoverable write errors. If we don't check the fsync()
|
||||
// result, we'll lose the data when we rename(). Kernel 6.2 added
|
||||
// a number of new root causes for the class of "unrecoverable
|
||||
// write errors" so we need to check this now.
|
||||
|
||||
BEESNOTE("checking filesystem type for " << name_fd(fd));
|
||||
// LSB deprecated statfs without providing a replacement that
|
||||
// can fill in the f_type field.
|
||||
struct statfs stf = { 0 };
|
||||
DIE_IF_NON_ZERO(fstatfs(fd, &stf));
|
||||
if (stf.f_type != BTRFS_SUPER_MAGIC) {
|
||||
BEESLOGONCE("Using fsync on non-btrfs filesystem type " << to_hex(stf.f_type));
|
||||
BEESNOTE("fsync non-btrfs " << name_fd(fd));
|
||||
DIE_IF_NON_ZERO(fsync(fd));
|
||||
return;
|
||||
}
|
||||
|
||||
static bool did_uname = false;
|
||||
static bool do_fsync = false;
|
||||
|
||||
if (!did_uname) {
|
||||
Uname uname;
|
||||
const string version(uname.release);
|
||||
static const regex version_re(R"/(^(\d+)\.(\d+)\.)/", regex::optimize | regex::ECMAScript);
|
||||
smatch m;
|
||||
// Last known bug in the fsync-rename use case was fixed in kernel 5.16
|
||||
static const auto min_major = 5, min_minor = 16;
|
||||
if (regex_search(version, m, version_re)) {
|
||||
const auto major = stoul(m[1]);
|
||||
const auto minor = stoul(m[2]);
|
||||
if (tie(major, minor) > tie(min_major, min_minor)) {
|
||||
BEESLOGONCE("Using fsync on btrfs because kernel version is " << major << "." << minor);
|
||||
do_fsync = true;
|
||||
} else {
|
||||
BEESLOGONCE("Not using fsync on btrfs because kernel version is " << major << "." << minor);
|
||||
}
|
||||
} else {
|
||||
BEESLOGONCE("Not using fsync on btrfs because can't parse kernel version '" << version << "'");
|
||||
}
|
||||
did_uname = true;
|
||||
}
|
||||
|
||||
if (do_fsync) {
|
||||
BEESNOTE("fsync btrfs " << name_fd(fd));
|
||||
DIE_IF_NON_ZERO(fsync(fd));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
BeesStringFile::write(string contents)
|
||||
{
|
||||
@@ -406,19 +476,8 @@ BeesStringFile::write(string contents)
|
||||
Fd ofd = openat_or_die(m_dir_fd, tmpname, FLAGS_CREATE_FILE, S_IRUSR | S_IWUSR);
|
||||
BEESNOTE("writing " << tmpname << " in " << name_fd(m_dir_fd));
|
||||
write_or_die(ofd, contents);
|
||||
#if 0
|
||||
// This triggers too many btrfs bugs. I wish I was kidding.
|
||||
// Forget snapshots, balance, compression, and dedupe:
|
||||
// the system call you have to fear on btrfs is fsync().
|
||||
// Also note that when bees renames a temporary over an
|
||||
// existing file, it flushes the temporary, so we get
|
||||
// the right behavior if we just do nothing here
|
||||
// (except when the file is first created; however,
|
||||
// in that case the result is the same as if the file
|
||||
// did not exist, was empty, or was filled with garbage).
|
||||
BEESNOTE("fsyncing " << tmpname << " in " << name_fd(m_dir_fd));
|
||||
DIE_IF_NON_ZERO(fsync(ofd));
|
||||
#endif
|
||||
bees_fsync(ofd);
|
||||
}
|
||||
BEESNOTE("renaming " << tmpname << " to " << m_name << " in FD " << name_fd(m_dir_fd));
|
||||
BEESTRACE("renaming " << tmpname << " to " << m_name << " in FD " << name_fd(m_dir_fd));
|
||||
@@ -682,7 +741,7 @@ bees_main(int argc, char *argv[])
|
||||
BEESLOGDEBUG("exception (ignored): " << s);
|
||||
BEESCOUNT(exception_caught_silent);
|
||||
} else {
|
||||
BEESLOGNOTICE("\n\n*** EXCEPTION ***\n\t" << s << "\n***\n");
|
||||
BEESLOGNOTICE("\n\nTRACE: *** EXCEPTION ***\n\t" << s << "\n***\n");
|
||||
BEESCOUNT(exception_caught);
|
||||
}
|
||||
});
|
||||
|
14
src/bees.h
14
src/bees.h
@@ -122,9 +122,9 @@ const int FLAGS_OPEN_FANOTIFY = O_RDWR | O_NOATIME | O_CLOEXEC | O_LARGEFILE;
|
||||
// macros ----------------------------------------
|
||||
|
||||
#define BEESLOG(lv,x) do { if (lv < bees_log_level) { Chatter __chatter(lv, BeesNote::get_name()); __chatter << x; } } while (0)
|
||||
#define BEESLOGTRACE(x) do { BEESLOG(LOG_DEBUG, x); BeesTracer::trace_now(); } while (0)
|
||||
|
||||
#define BEESTRACE(x) BeesTracer SRSLY_WTF_C(beesTracer_, __LINE__) ([&]() { BEESLOG(LOG_ERR, x << " at " << __FILE__ << ":" << __LINE__); })
|
||||
#define BEES_TRACE_LEVEL LOG_DEBUG
|
||||
#define BEESTRACE(x) BeesTracer SRSLY_WTF_C(beesTracer_, __LINE__) ([&]() { BEESLOG(BEES_TRACE_LEVEL, "TRACE: " << x << " at " << __FILE__ << ":" << __LINE__); })
|
||||
#define BEESTOOLONG(x) BeesTooLong SRSLY_WTF_C(beesTooLong_, __LINE__) ([&](ostream &_btl_os) { _btl_os << x; })
|
||||
#define BEESNOTE(x) BeesNote SRSLY_WTF_C(beesNote_, __LINE__) ([&](ostream &_btl_os) { _btl_os << x; })
|
||||
|
||||
@@ -134,6 +134,14 @@ const int FLAGS_OPEN_FANOTIFY = O_RDWR | O_NOATIME | O_CLOEXEC | O_LARGEFILE;
|
||||
#define BEESLOGINFO(x) BEESLOG(LOG_INFO, x)
|
||||
#define BEESLOGDEBUG(x) BEESLOG(LOG_DEBUG, x)
|
||||
|
||||
#define BEESLOGONCE(__x) do { \
|
||||
static bool already_logged = false; \
|
||||
if (!already_logged) { \
|
||||
already_logged = true; \
|
||||
BEESLOGNOTICE(__x); \
|
||||
} \
|
||||
} while (false)
|
||||
|
||||
#define BEESCOUNT(stat) do { \
|
||||
BeesStats::s_global.add_count(#stat); \
|
||||
} while (0)
|
||||
@@ -185,7 +193,7 @@ class BeesTracer {
|
||||
thread_local static bool tl_silent;
|
||||
thread_local static bool tl_first;
|
||||
public:
|
||||
BeesTracer(function<void()> f, bool silent = false);
|
||||
BeesTracer(const function<void()> &f, bool silent = false);
|
||||
~BeesTracer();
|
||||
static void trace_now();
|
||||
static bool get_silent();
|
||||
|
Reference in New Issue
Block a user