diff --git a/.gitignore b/.gitignore index d8ca283..cb02a07 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,4 @@ latex/ make.log make.log.new localconf +scripts/beesd diff --git a/README.md b/README.md index 7a96397..5ed161b 100644 --- a/README.md +++ b/README.md @@ -107,9 +107,9 @@ fresh full-filesystem rescan, and restart `bees'. Things You Might Expect That Bees Doesn't Have ---------------------------------------------- -* There's no configuration file or getopt command line option processing -(patches welcome!). There are some tunables hardcoded in the source -that could eventually become configuration options. +* There's no configuration file (patches welcome!). There are some tunables +hardcoded in the source that could eventually become configuration options. +There's also an incomplete option parser (patches welcome!). * There's no way to *stop* the Bees daemon. Use SIGKILL, SIGTERM, or Ctrl-C for now. Some of the destructors are unreachable and have never diff --git a/include/crucible/chatter.h b/include/crucible/chatter.h index d14c80c..e42620e 100644 --- a/include/crucible/chatter.h +++ b/include/crucible/chatter.h @@ -86,6 +86,11 @@ namespace crucible { } }; + class ChatterTimestamp { + public: + ChatterTimestamp(int); + }; + class ChatterBox { string m_file; int m_line; diff --git a/lib/chatter.cc b/lib/chatter.cc index c9d187b..60dbb61 100644 --- a/lib/chatter.cc +++ b/lib/chatter.cc @@ -17,6 +17,7 @@ namespace crucible { static shared_ptr> chatter_names; static const char *SPACETAB = " \t"; + static int chatter_prefix_timestamp = 1; static void @@ -52,16 +53,21 @@ namespace crucible { { ostringstream header_stream; - time_t ltime; - DIE_IF_MINUS_ONE(time(<ime)); - struct tm ltm; - DIE_IF_ZERO(localtime_r(<ime, <m)); + if (chatter_prefix_timestamp) { + time_t ltime; + DIE_IF_MINUS_ONE(time(<ime)); + struct tm ltm; + DIE_IF_ZERO(localtime_r(<ime, <m)); - char buf[1024]; - DIE_IF_ZERO(strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", <m)); + char buf[1024]; + DIE_IF_ZERO(strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", <m)); + + header_stream << buf; + header_stream << " " << getpid() << "." << gettid(); + } else { + header_stream << "tid " << gettid(); + } - header_stream << buf; - header_stream << " " << getpid() << "." << gettid(); if (!m_name.empty()) { header_stream << " " << m_name; } @@ -91,6 +97,11 @@ namespace crucible { c.m_oss.str(""); } + ChatterTimestamp::ChatterTimestamp(int prefix_timestamp) + { + chatter_prefix_timestamp = prefix_timestamp; + } + set ChatterBox::s_boxes; set& ChatterBox::all_boxes() diff --git a/scripts/beesd.in b/scripts/beesd.in index f99ea09..044fc98 100755 --- a/scripts/beesd.in +++ b/scripts/beesd.in @@ -23,7 +23,23 @@ readonly CONFIG_DIR=@PREFIX@/etc/bees/ command -v @LIBEXEC_PREFIX@/bees &> /dev/null || ERRO "Missing 'bees' agent" ## Parse args -UUID="$1" +ARGUMENTS=() +while [ $# -gt 0 ]; do + case "$1" in + -*) + ARGUMENTS+=($1) + ;; + *) + if [ -z "$UUID" ]; then + UUID="$1" + else + ERRO "Only one filesystem may be supplied" + fi + ;; + esac + shift +done + case "$UUID" in *-*-*-*-*) FILE_CONFIG="" @@ -38,7 +54,7 @@ case "$UUID" in source "$FILE_CONFIG" ;; *) - echo "beesd " + echo "beesd [options] " exit 1 ;; esac @@ -49,17 +65,16 @@ BEESHOME="${BEESHOME:-$MNT_DIR/.beeshome}" BEESSTATUS="${BEESSTATUS:-$WORK_DIR/$UUID.status}" DB_SIZE="${DB_SIZE:-$((64*AL16M))}" LOG_SHORT_PATH="${LOG_SHORT_PATH:-N}" -LOG_FILTER_TIME="${LOG_FILTER_TIME:-N}" INFO "Check: Disk exists" if [ ! -b "/dev/disk/by-uuid/$UUID" ]; then ERRO "Missing disk: /dev/disk/by-uuid/$UUID" fi -it_btrfs(){ [ "$(blkid -s TYPE -o value "$1")" == "btrfs" ]; } +is_btrfs(){ [ "$(blkid -s TYPE -o value "$1")" == "btrfs" ]; } INFO "Check: Disk with btrfs" -if ! it_btrfs "/dev/disk/by-uuid/$UUID"; then +if ! is_btrfs "/dev/disk/by-uuid/$UUID"; then ERRO "Disk not contain btrfs: /dev/disk/by-uuid/$UUID" fi @@ -101,19 +116,6 @@ fi MNT_DIR="${MNT_DIR//\/\//\/}" -filter_time(){ - if YN $LOG_FILTER_TIME; then - sed -e 's/^.*crawl:/crawl:/g' \ - -e 's/^.*status:/status:/g' \ - -e 's/^.*bees:/bees:/g' \ - -e 's/^.*crawl_writeback:/crawl_writeback:/g' \ - -e 's/^.*main:/main:/g' \ - -e 's/^.*hash_prefetch:/hash_prefetch:/g' - else - cat - fi -} - filter_path(){ if YN $LOG_SHORT_PATH; then sed -e "s#$MNT_DIR##g" @@ -122,6 +124,6 @@ filter_path(){ fi } -@LIBEXEC_PREFIX@/bees "$MNT_DIR" 3>&1 2>&1 | filter_time | filter_path +@LIBEXEC_PREFIX@/bees ${ARGUMENTS[@]} $OPTIONS "$MNT_DIR" 3>&1 2>&1 | filter_path exit 0 diff --git a/src/bees.cc b/src/bees.cc index 69634cd..02c9b55 100644 --- a/src/bees.cc +++ b/src/bees.cc @@ -19,18 +19,25 @@ #include #include +#include + using namespace crucible; using namespace std; int -do_cmd_help(const char **argv) +do_cmd_help(char *argv[]) { - cerr << "Usage: " << argv[0] << " fs-root-path [fs-root-path-2...]\n" + cerr << "Usage: " << argv[0] << " [options] fs-root-path [fs-root-path-2...]\n" "Performs best-effort extent-same deduplication on btrfs.\n" "\n" "fs-root-path MUST be the root of a btrfs filesystem tree (id 5).\n" "Other directories will be rejected.\n" "\n" + "Options:\n" + "\t-h, --help\t\tShow this help\n" + "\t-t, --timestamps\tShow timestamps in log output (default)\n" + "\t-T, --notimestamps\tOmit timestamps in log output\n" + "\n" "Optional environment variables:\n" "\tBEESHOME\tPath to hash table and configuration files\n" "\t\t\t(default is .beeshome/ in the root of each filesystem).\n" @@ -589,7 +596,7 @@ bees_worker_thread_count() } int -bees_main(int argc, const char **argv) +bees_main(int argc, char *argv[]) { set_catch_explainer([&](string s) { BEESLOG("\n\n*** EXCEPTION ***\n\t" << s << "\n***\n"); @@ -603,17 +610,50 @@ bees_main(int argc, const char **argv) shared_ptr bc; THROW_CHECK1(invalid_argument, argc, argc >= 0); - vector args(argv + 1, argv + argc); + + // Defaults + int chatter_prefix_timestamp = 1; + + // Parse options + int c; + while (1) { + int option_index = 0; + static struct option long_options[] = { + { "timestamps", no_argument, NULL, 't' }, + { "notimestamps", no_argument, NULL, 'T' }, + { "help", no_argument, NULL, 'h' } + }; + + c = getopt_long(argc, argv, "Tth", long_options, &option_index); + if (-1 == c) { + break; + } + + switch (c) { + case 'T': + chatter_prefix_timestamp = 0; + break; + case 't': + chatter_prefix_timestamp = 1; + break; + case 'h': + do_cmd_help(argv); + default: + return 2; + } + } + + ChatterTimestamp cts(chatter_prefix_timestamp); // There can be only one because we measure running time with it bees_ioctl_lock_set.max_size(1); // Create a context and start crawlers bool did_subscription = false; - for (string arg : args) { + while (optind < argc) { catch_all([&]() { bc = make_shared(bc); - bc->set_root_path(arg); + bc->set_root_path(argv[optind++]); did_subscription = true; }); } @@ -634,7 +674,7 @@ bees_main(int argc, const char **argv) } int -main(int argc, const char **argv) +main(int argc, char *argv[]) { cerr << "bees version " << BEES_VERSION << endl;