From 109e13db243249e26b8b8d861424578400aae882 Mon Sep 17 00:00:00 2001 From: Soham Sen Date: Sun, 5 Jun 2022 22:11:31 +0530 Subject: [PATCH] dragonflydb: init at 0.1.0 --- .../from_md/release-notes/rl-2211.section.xml | 7 + .../manual/release-notes/rl-2211.section.md | 2 + nixos/modules/module-list.nix | 1 + .../services/databases/dragonflydb.nix | 152 +++++ pkgs/servers/nosql/dragonflydb/default.nix | 109 ++++ pkgs/servers/nosql/dragonflydb/fixes.patch | 132 +++++ pkgs/servers/nosql/dragonflydb/glog.patch | 553 ++++++++++++++++++ pkgs/top-level/all-packages.nix | 2 + 8 files changed, 958 insertions(+) create mode 100644 nixos/modules/services/databases/dragonflydb.nix create mode 100644 pkgs/servers/nosql/dragonflydb/default.nix create mode 100644 pkgs/servers/nosql/dragonflydb/fixes.patch create mode 100644 pkgs/servers/nosql/dragonflydb/glog.patch diff --git a/nixos/doc/manual/from_md/release-notes/rl-2211.section.xml b/nixos/doc/manual/from_md/release-notes/rl-2211.section.xml index 4a7ef8b7168..b350e1fe17d 100644 --- a/nixos/doc/manual/from_md/release-notes/rl-2211.section.xml +++ b/nixos/doc/manual/from_md/release-notes/rl-2211.section.xml @@ -48,6 +48,13 @@ virtualisation.appvm. + + + dragonflydb, + a modern replacement for Redis and Memcached. Available as + services.dragonflydb. + + infnoise, diff --git a/nixos/doc/manual/release-notes/rl-2211.section.md b/nixos/doc/manual/release-notes/rl-2211.section.md index 89a799cafc5..702efcb2dc0 100644 --- a/nixos/doc/manual/release-notes/rl-2211.section.md +++ b/nixos/doc/manual/release-notes/rl-2211.section.md @@ -25,6 +25,8 @@ In addition to numerous new and upgraded packages, this release has the followin - [appvm](https://github.com/jollheef/appvm), Nix based app VMs. Available as [virtualisation.appvm](options.html#opt-virtualisation.appvm.enable). +- [dragonflydb](https://dragonflydb.io/), a modern replacement for Redis and Memcached. Available as [services.dragonflydb](#opt-services.dragonflydb.enable). + - [infnoise](https://github.com/leetronics/infnoise), a hardware True Random Number Generator dongle. Available as [services.infnoise](options.html#opt-services.infnoise.enable). diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index d59d7bfe40d..7b1054262f5 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -348,6 +348,7 @@ ./services/databases/clickhouse.nix ./services/databases/cockroachdb.nix ./services/databases/couchdb.nix + ./services/databases/dragonflydb.nix ./services/databases/firebird.nix ./services/databases/foundationdb.nix ./services/databases/hbase.nix diff --git a/nixos/modules/services/databases/dragonflydb.nix b/nixos/modules/services/databases/dragonflydb.nix new file mode 100644 index 00000000000..e72afa9d908 --- /dev/null +++ b/nixos/modules/services/databases/dragonflydb.nix @@ -0,0 +1,152 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.services.dragonflydb; + dragonflydb = pkgs.dragonflydb; + + settings = + { + port = cfg.port; + dir = "/var/lib/dragonflydb"; + keys_output_limit = cfg.keysOutputLimit; + } // + (lib.optionalAttrs (cfg.bind != null) { bind = cfg.bind; }) // + (lib.optionalAttrs (cfg.requirePass != null) { requirepass = cfg.requirePass; }) // + (lib.optionalAttrs (cfg.maxMemory != null) { maxmemory = cfg.maxMemory; }) // + (lib.optionalAttrs (cfg.memcachePort != null) { memcache_port = cfg.memcachePort; }) // + (lib.optionalAttrs (cfg.dbNum != null) { dbnum = cfg.dbNum; }) // + (lib.optionalAttrs (cfg.cacheMode != null) { cache_mode = cfg.cacheMode; }); +in +{ + + ###### interface + + options = { + services.dragonflydb = { + enable = mkEnableOption "DragonflyDB"; + + user = mkOption { + type = types.str; + default = "dragonfly"; + description = "The user to run DragonflyDB as"; + }; + + port = mkOption { + type = types.port; + default = 6379; + description = "The TCP port to accept connections."; + }; + + bind = mkOption { + type = with types; nullOr str; + default = "127.0.0.1"; + description = '' + The IP interface to bind to. + null means "all interfaces". + ''; + }; + + requirePass = mkOption { + type = with types; nullOr str; + default = null; + description = "Password for database"; + example = "letmein!"; + }; + + maxMemory = mkOption { + type = with types; nullOr ints.unsigned; + default = null; + description = '' + The maximum amount of memory to use for storage (in bytes). + null means this will be automatically set. + ''; + }; + + memcachePort = mkOption { + type = with types; nullOr port; + default = null; + description = '' + To enable memcached compatible API on this port. + null means disabled. + ''; + }; + + keysOutputLimit = mkOption { + type = types.ints.unsigned; + default = 8192; + description = '' + Maximum number of returned keys in keys command. + keys is a dangerous command. + We truncate its result to avoid blowup in memory when fetching too many keys. + ''; + }; + + dbNum = mkOption { + type = with types; nullOr ints.unsigned; + default = null; + description = "Maximum number of supported databases for select"; + }; + + cacheMode = mkOption { + type = with types; nullOr bool; + default = null; + description = '' + Once this mode is on, Dragonfly will evict items least likely to be stumbled + upon in the future but only when it is near maxmemory limit. + ''; + }; + }; + }; + + ###### implementation + + config = mkIf config.services.dragonflydb.enable { + + users.users = optionalAttrs (cfg.user == "dragonfly") { + dragonfly.description = "DragonflyDB server user"; + dragonfly.isSystemUser = true; + dragonfly.group = "dragonfly"; + }; + users.groups = optionalAttrs (cfg.user == "dragonfly") { dragonfly = { }; }; + + environment.systemPackages = [ dragonflydb ]; + + systemd.services.dragonflydb = { + description = "DragonflyDB server"; + + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" ]; + + serviceConfig = { + ExecStart = "${dragonflydb}/bin/dragonfly --alsologtostderr ${builtins.concatStringsSep " " (attrsets.mapAttrsToList (n: v: "--${n} ${strings.escapeShellArg v}") settings)}"; + + User = cfg.user; + + # Filesystem access + ReadWritePaths = [ settings.dir ]; + StateDirectory = "dragonflydb"; + StateDirectoryMode = "0700"; + # Process Properties + LimitMEMLOCK = "infinity"; + # Caps + CapabilityBoundingSet = ""; + NoNewPrivileges = true; + # Sandboxing + ProtectSystem = "strict"; + ProtectHome = true; + PrivateTmp = true; + PrivateDevices = true; + ProtectKernelTunables = true; + ProtectKernelModules = true; + ProtectControlGroups = true; + LockPersonality = true; + RestrictAddressFamilies = [ "AF_INET" "AF_INET6" ]; + RestrictRealtime = true; + PrivateMounts = true; + MemoryDenyWriteExecute = true; + }; + }; + }; +} diff --git a/pkgs/servers/nosql/dragonflydb/default.nix b/pkgs/servers/nosql/dragonflydb/default.nix new file mode 100644 index 00000000000..ff4833cfaa6 --- /dev/null +++ b/pkgs/servers/nosql/dragonflydb/default.nix @@ -0,0 +1,109 @@ +{ fetchFromGitHub +, fetchurl +, lib +, stdenv +, double-conversion +, gperftools +, mimalloc +, rapidjson +, liburing +, xxHash +, abseil-cpp_202111 +, gbenchmark +, glog +, gtest +, jemalloc +, gcc-unwrapped +, autoconf +, autoconf-archive +, automake +, cmake +, ninja +, boost +, libunwind +, libtool +, openssl +}: + +let + pname = "dragonflydb"; + version = "0.1.0"; + + src = fetchFromGitHub { + owner = pname; + repo = "dragonfly"; + rev = "v${version}"; + hash = "sha256-P6WMW/n+VezWDXGagT4B+ZYyCp8oufDV6MTrpKpLZcs="; + fetchSubmodules = true; + }; + + # Needed exactly 5.4.4 for patch to work + lua = fetchurl { + url = "https://github.com/lua/lua/archive/refs/tags/v5.4.4.tar.gz"; + hash = "sha256-L/ibvqIqfIuRDWsAb1ukVZ7c9GiiVTfO35mI7ZD2tFA="; + }; +in +stdenv.mkDerivation { + inherit pname version src; + + postPatch = '' + mkdir -p ./build/{third_party,_deps} + ln -s ${double-conversion.src} ./build/third_party/dconv + ln -s ${mimalloc.src} ./build/third_party/mimalloc + ln -s ${rapidjson.src} ./build/third_party/rapidjson + ln -s ${gbenchmark.src} ./build/_deps/benchmark-src + ln -s ${gtest.src} ./build/_deps/gtest-src + cp -R --no-preserve=mode,ownership ${gperftools.src} ./build/third_party/gperf + cp -R --no-preserve=mode,ownership ${liburing.src} ./build/third_party/uring + cp -R --no-preserve=mode,ownership ${xxHash.src} ./build/third_party/xxhash + cp -R --no-preserve=mode,ownership ${abseil-cpp_202111.src} ./build/_deps/abseil_cpp-src + cp -R --no-preserve=mode,ownership ${glog.src} ./build/_deps/glog-src + chmod u+x ./build/third_party/uring/configure + cp ./build/third_party/xxhash/cli/xxhsum.{1,c} ./build/third_party/xxhash + patch -p1 -d ./build/_deps/glog-src < ${./glog.patch} + sed ' + s@REPLACEJEMALLOCURL@file://${jemalloc.src}@ + s@REPLACELUAURL@file://${lua}@ + ' ${./fixes.patch} | patch -p1 + ''; + + nativeBuildInputs = [ + autoconf + autoconf-archive + automake + cmake + ninja + ]; + + buildInputs = [ + boost + libunwind + libtool + openssl + ]; + + cmakeFlags = [ + "-DCMAKE_AR=${gcc-unwrapped}/bin/gcc-ar" + "-DCMAKE_RANLIB=${gcc-unwrapped}/bin/gcc-ranlib" + ]; + + ninjaFlags = "dragonfly"; + + doCheck = false; + dontUseNinjaInstall = true; + + installPhase = '' + runHook preInstall + mkdir -p $out/bin + cp ./dragonfly $out/bin + runHook postInstall + ''; + + meta = with lib; { + description = "A modern replacement for Redis and Memcached"; + homepage = "https://dragonflydb.io/"; + license = licenses.bsl11; + platforms = platforms.linux; + maintainers = with maintainers; [ yureien ]; + }; +} diff --git a/pkgs/servers/nosql/dragonflydb/fixes.patch b/pkgs/servers/nosql/dragonflydb/fixes.patch new file mode 100644 index 00000000000..d2992fbbaf8 --- /dev/null +++ b/pkgs/servers/nosql/dragonflydb/fixes.patch @@ -0,0 +1,132 @@ +diff --git a/helio/cmake/third_party.cmake b/helio/cmake/third_party.cmake +index aeb78d9..e9d4e6b 100644 +--- a/helio/cmake/third_party.cmake ++++ b/helio/cmake/third_party.cmake +@@ -143,7 +143,7 @@ endfunction() + + FetchContent_Declare( + gtest +- URL https://github.com/google/googletest/archive/release-1.11.0.zip ++ DOWNLOAD_COMMAND true + ) + + FetchContent_GetProperties(gtest) +@@ -154,7 +154,7 @@ endif () + + FetchContent_Declare( + benchmark +- URL https://github.com/google/benchmark/archive/v1.6.1.tar.gz ++ DOWNLOAD_COMMAND true + ) + + FetchContent_GetProperties(benchmark) +@@ -169,7 +169,7 @@ endif () + + FetchContent_Declare( + abseil_cpp +- URL https://github.com/abseil/abseil-cpp/archive/20211102.0.tar.gz ++ DOWNLOAD_COMMAND true + PATCH_COMMAND patch -p1 < "${CMAKE_CURRENT_LIST_DIR}/../patches/abseil-20211102.patch" + ) + +@@ -183,11 +183,7 @@ endif() + + FetchContent_Declare( + glog +- GIT_REPOSITORY https://github.com/romange/glog +- GIT_TAG Absl +- +- GIT_PROGRESS TRUE +- GIT_SHALLOW TRUE ++ DOWNLOAD_COMMAND true + ) + + FetchContent_GetProperties(glog) +@@ -233,10 +229,7 @@ endif() + + add_third_party( + gperf +- URL https://github.com/gperftools/gperftools/archive/gperftools-2.9.1.tar.gz +- #GIT_REPOSITORY https://github.com/gperftools/gperftools +- #GIT_TAG gperftools-2.9.1 +- GIT_SHALLOW TRUE ++ DOWNLOAD_COMMAND true + PATCH_COMMAND autoreconf -i # update runs every time for some reason + # CMAKE_PASS_FLAGS "-DGPERFTOOLS_BUILD_HEAP_PROFILER=OFF -DGPERFTOOLS_BUILD_HEAP_CHECKER=OFF \ + # -DGPERFTOOLS_BUILD_DEBUGALLOC=OFF -DBUILD_TESTING=OFF \ +@@ -260,11 +253,12 @@ else() + endif() + + add_third_party(mimalloc +- URL https://github.com/microsoft/mimalloc/archive/refs/tags/v2.0.5.tar.gz ++ DOWNLOAD_COMMAND true + + # Add -DCMAKE_BUILD_TYPE=Debug -DCMAKE_C_FLAGS=-O0 to debug + CMAKE_PASS_FLAGS "-DCMAKE_BUILD_TYPE=Release -DMI_BUILD_SHARED=OFF -DMI_BUILD_TESTS=OFF \ +- -DMI_INSTALL_TOPLEVEL=ON -DMI_OVERRIDE=${MI_OVERRIDE} -DCMAKE_C_FLAGS=-g" ++ -DMI_INSTALL_TOPLEVEL=ON -DMI_OVERRIDE=${MI_OVERRIDE} -DCMAKE_C_FLAGS=-g \ ++ -DCMAKE_INSTALL_LIBDIR=${THIRD_PARTY_LIB_DIR}/mimalloc/lib" + + BUILD_COMMAND make -j4 mimalloc-static + INSTALL_COMMAND make install +@@ -274,7 +268,7 @@ add_third_party(mimalloc + ) + + add_third_party(jemalloc +- URL https://github.com/jemalloc/jemalloc/releases/download/5.2.1/jemalloc-5.2.1.tar.bz2 ++ URL REPLACEJEMALLOCURL + PATCH_COMMAND ./autogen.sh + CONFIGURE_COMMAND /configure --prefix=${THIRD_PARTY_LIB_DIR}/jemalloc --with-jemalloc-prefix=je_ --disable-libdl + ) +@@ -282,24 +276,23 @@ add_third_party(jemalloc + + add_third_party( + xxhash +- URL https://github.com/Cyan4973/xxHash/archive/v0.8.0.tar.gz ++ DOWNLOAD_COMMAND true + SOURCE_SUBDIR cmake_unofficial +- CMAKE_PASS_FLAGS "-DCMAKE_POSITION_INDEPENDENT_CODE=ON -DBUILD_SHARED_LIBS=OFF" ++ CMAKE_PASS_FLAGS "-DCMAKE_POSITION_INDEPENDENT_CODE=ON -DBUILD_SHARED_LIBS=OFF \ ++ -DCMAKE_INSTALL_LIBDIR=${THIRD_PARTY_LIB_DIR}/xxhash/lib" + ) + + + add_third_party( + uring +- GIT_REPOSITORY https://github.com/axboe/liburing.git +- GIT_TAG liburing-2.1 ++ DOWNLOAD_COMMAND true + CONFIGURE_COMMAND /configure --prefix=${THIRD_PARTY_LIB_DIR}/uring + BUILD_IN_SOURCE 1 + ) + + add_third_party( + rapidjson +- GIT_REPOSITORY https://github.com/Tencent/rapidjson.git +- GIT_TAG 1a803826f1197b5e30703afe4b9c0e7dd48074f5 ++ DOWNLOAD_COMMAND true + CMAKE_PASS_FLAGS "-DRAPIDJSON_BUILD_TESTS=OFF -DRAPIDJSON_BUILD_EXAMPLES=OFF \ + -DRAPIDJSON_BUILD_DOC=OFF" + LIB "none" +diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt +index 0dc0824..d5b38b3 100644 +--- a/src/CMakeLists.txt ++++ b/src/CMakeLists.txt +@@ -1,6 +1,6 @@ + add_third_party( + lua +- URL https://github.com/lua/lua/archive/refs/tags/v5.4.4.tar.gz ++ URL REPLACELUAURL + PATCH_COMMAND patch -p1 -i "${CMAKE_SOURCE_DIR}/patches/lua-v5.4.4.patch" + CONFIGURE_COMMAND echo + BUILD_IN_SOURCE 1 +@@ -11,7 +11,8 @@ add_third_party( + + add_third_party( + dconv +- URL https://github.com/google/double-conversion/archive/refs/tags/v3.2.0.tar.gz ++ DOWNLOAD_COMMAND true ++ CMAKE_PASS_FLAGS "-DCMAKE_INSTALL_LIBDIR=${THIRD_PARTY_LIB_DIR}/dconv/lib" + LIB libdouble-conversion.a + ) + diff --git a/pkgs/servers/nosql/dragonflydb/glog.patch b/pkgs/servers/nosql/dragonflydb/glog.patch new file mode 100644 index 00000000000..2fb9c0733b8 --- /dev/null +++ b/pkgs/servers/nosql/dragonflydb/glog.patch @@ -0,0 +1,553 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 846b4448..b4900ead 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -39,6 +39,7 @@ option (PRINT_UNSYMBOLIZED_STACK_TRACES + "Print file offsets in traces instead of symbolizing" OFF) + option (WITH_CUSTOM_PREFIX "Enable support for user-generated message prefixes" ON) + option (WITH_GFLAGS "Use gflags" ON) ++option (WITH_ABSL "Use absl flags" OFF) + option (WITH_GTEST "Use Google Test" ON) + option (WITH_PKGCONFIG "Enable pkg-config support" ON) + option (WITH_SYMBOLIZE "Enable symbolize module" ON) +@@ -87,6 +88,13 @@ if (WITH_GFLAGS) + endif (gflags_FOUND) + endif (WITH_GFLAGS) + ++if (WITH_ABSL) ++ set (HAVE_ABSL_FLAGS 1) ++ set (ac_cv_have_abslflags 1) ++else (WITH_ABSL) ++set (ac_cv_have_abslflags 0) ++endif (WITH_ABSL) ++ + find_package (Threads) + find_package (Unwind) + +@@ -1025,7 +1033,7 @@ write_basic_package_version_file ( + ${CMAKE_CURRENT_BINARY_DIR}/glog-config-version.cmake + COMPATIBILITY SameMajorVersion) + +-export (TARGETS glog NAMESPACE glog:: FILE glog-targets.cmake) ++# export (TARGETS glog NAMESPACE glog:: FILE glog-targets.cmake) + export (PACKAGE glog) + + get_filename_component (_PREFIX "${CMAKE_INSTALL_PREFIX}" ABSOLUTE) +diff --git a/src/base/commandlineflags.h b/src/base/commandlineflags.h +index bcb12dea..1c9d9294 100644 +--- a/src/base/commandlineflags.h ++++ b/src/base/commandlineflags.h +@@ -57,6 +57,25 @@ + + #include + ++#else ++#ifdef HAVE_ABSL_FLAGS ++#include ++ ++#define FLAG(name) absl::GetFlag(FLAGS_##name) ++ ++#define DEFINE_bool(name, value, meaning) \ ++ ABSL_FLAG(bool, name, value, meaning) ++ ++#define DEFINE_int32(name, value, meaning) \ ++ ABSL_FLAG(GOOGLE_NAMESPACE::int32, name, value, meaning) ++ ++#define DEFINE_uint32(name, value, meaning) \ ++ ABSL_FLAG(GOOGLE_NAMESPACE::uint32, name, value, meaning) ++ ++#define DEFINE_string(name, value, meaning) \ ++ ABSL_FLAG(std::string, name, value, meaning) ++ ++ + #else + + #include +@@ -108,6 +127,7 @@ + } \ + using fLS::FLAGS_##name + ++#endif + #endif // HAVE_LIB_GFLAGS + + // Define GLOG_DEFINE_* using DEFINE_* . By using these macros, we +diff --git a/src/base/mutex.h b/src/base/mutex.h +index e82c597f..a58c1412 100644 +--- a/src/base/mutex.h ++++ b/src/base/mutex.h +@@ -319,11 +319,6 @@ class WriterMutexLock { + void operator=(const WriterMutexLock&); + }; + +-// Catch bug where variable name is omitted, e.g. MutexLock (&mu); +-#define MutexLock(x) COMPILE_ASSERT(0, mutex_lock_decl_missing_var_name) +-#define ReaderMutexLock(x) COMPILE_ASSERT(0, rmutex_lock_decl_missing_var_name) +-#define WriterMutexLock(x) COMPILE_ASSERT(0, wmutex_lock_decl_missing_var_name) +- + } // namespace MUTEX_NAMESPACE + + using namespace MUTEX_NAMESPACE; +diff --git a/src/config.h.cmake.in b/src/config.h.cmake.in +index b225b7ec..a4c58c96 100644 +--- a/src/config.h.cmake.in ++++ b/src/config.h.cmake.in +@@ -34,6 +34,8 @@ + /* define if you have google gflags library */ + #cmakedefine HAVE_LIB_GFLAGS + ++#cmakedefine HAVE_ABSL_FLAGS ++ + /* define if you have google gmock library */ + #cmakedefine HAVE_LIB_GMOCK + +diff --git a/src/glog/logging.h.in b/src/glog/logging.h.in +index 95a573b1..54cd838f 100644 +--- a/src/glog/logging.h.in ++++ b/src/glog/logging.h.in +@@ -89,6 +89,10 @@ + #include + #endif + ++#if @ac_cv_have_abslflags@ ++#include ++#endif ++ + #if @ac_cv_cxx11_atomic@ && __cplusplus >= 201103L + #include + #elif defined(GLOG_OS_WINDOWS) +@@ -395,6 +399,14 @@ typedef void(*CustomPrefixCallback)(std::ostream& s, const LogMessageInfo& l, vo + #undef DECLARE_uint32 + #endif + ++#if @ac_cv_have_abslflags@ ++#define DECLARE_VARIABLE 1 ++#define DECLARE_bool(name) ABSL_DECLARE_FLAG(bool, name) ++#define DECLARE_int32(name) ABSL_DECLARE_FLAG(@ac_google_namespace@::int32, name) ++#define DECLARE_uint32(name) ABSL_DECLARE_FLAG(@ac_google_namespace@::uint32, name) ++#define DECLARE_string(name) ABSL_DECLARE_FLAG(std::string, name) ++#endif ++ + #ifndef DECLARE_VARIABLE + #define DECLARE_VARIABLE(type, shorttype, name, tn) \ + namespace fL##shorttype { \ +diff --git a/src/glog/vlog_is_on.h.in b/src/glog/vlog_is_on.h.in +index 7526fc34..16e60f46 100644 +--- a/src/glog/vlog_is_on.h.in ++++ b/src/glog/vlog_is_on.h.in +@@ -64,6 +64,14 @@ + #include + + #if defined(__GNUC__) ++ ++#if @ac_cv_have_abslflags@ ++ extern int32_t absl_proxy_v; ++ #define VLEVEL (@ac_google_namespace@::absl_proxy_v) ++#else ++ #define VLEVEL (FLAGS_v) ++#endif ++ + // We emit an anonymous static int* variable at every VLOG_IS_ON(n) site. + // (Normally) the first time every VLOG_IS_ON(n) site is hit, + // we determine what variable will dynamically control logging at this site: +@@ -74,7 +82,7 @@ + __extension__ \ + ({ static @ac_google_namespace@::SiteFlag vlocal__ = {NULL, NULL, 0, NULL}; \ + @ac_google_namespace@::int32 verbose_level__ = (verboselevel); \ +- (vlocal__.level == NULL ? @ac_google_namespace@::InitVLOG3__(&vlocal__, &FLAGS_v, \ ++ (vlocal__.level == NULL ? @ac_google_namespace@::InitVLOG3__(&vlocal__, &VLEVEL, \ + __FILE__, verbose_level__) : *vlocal__.level >= verbose_level__); \ + }) + #else +diff --git a/src/logging.cc b/src/logging.cc +index 4028ccc0..fc618d3a 100644 +--- a/src/logging.cc ++++ b/src/logging.cc +@@ -103,7 +103,9 @@ using std::fdopen; + #endif + + // There is no thread annotation support. ++#ifndef EXCLUSIVE_LOCKS_REQUIRED + #define EXCLUSIVE_LOCKS_REQUIRED(mu) ++#endif + + static bool BoolFromEnv(const char *varname, bool defval) { + const char* const valstr = getenv(varname); +@@ -351,8 +353,9 @@ static const char* GetAnsiColorCode(GLogColor color) { + + // Safely get max_log_size, overriding to 1 if it somehow gets defined as 0 + static uint32 MaxLogSize() { +- return (FLAGS_max_log_size > 0 && FLAGS_max_log_size < 4096 +- ? FLAGS_max_log_size ++ uint32 maxlogsize = FLAG(max_log_size); ++ return (maxlogsize > 0 && maxlogsize < 4096 ++ ? maxlogsize + : 1); + } + +@@ -721,7 +724,7 @@ inline void LogDestination::SetStderrLogging(LogSeverity min_severity) { + // Prevent any subtle race conditions by wrapping a mutex lock around + // all this stuff. + MutexLock l(&log_mutex); +- FLAGS_stderrthreshold = min_severity; ++ absl::SetFlag(&FLAGS_stderrthreshold, min_severity); + } + + inline void LogDestination::LogToStderr() { +@@ -747,8 +750,8 @@ static void ColoredWriteToStderrOrStdout(FILE* output, LogSeverity severity, + const char* message, size_t len) { + bool is_stdout = (output == stdout); + const GLogColor color = (LogDestination::terminal_supports_color() && +- ((!is_stdout && FLAGS_colorlogtostderr) || +- (is_stdout && FLAGS_colorlogtostdout))) ++ ((!is_stdout && FLAG(colorlogtostderr)) || ++ (is_stdout && FLAG(colorlogtostdout)))) + ? SeverityToColor(severity) + : COLOR_DEFAULT; + +@@ -789,7 +792,7 @@ static void ColoredWriteToStdout(LogSeverity severity, const char* message, + FILE* output = stdout; + // We also need to send logs to the stderr when the severity is + // higher or equal to the stderr threshold. +- if (severity >= FLAGS_stderrthreshold) { ++ if (severity >= FLAG(stderrthreshold)) { + output = stderr; + } + ColoredWriteToStderrOrStdout(output, severity, message, len); +@@ -808,7 +811,7 @@ static void WriteToStderr(const char* message, size_t len) { + + inline void LogDestination::MaybeLogToStderr(LogSeverity severity, + const char* message, size_t message_len, size_t prefix_len) { +- if ((severity >= FLAGS_stderrthreshold) || FLAGS_alsologtostderr) { ++ if ((severity >= FLAG(stderrthreshold)) || FLAG(alsologtostderr)) { + ColoredWriteToStderr(severity, message, message_len); + #ifdef GLOG_OS_WINDOWS + (void) prefix_len; +@@ -835,8 +838,8 @@ inline void LogDestination::MaybeLogToStderr(LogSeverity severity, + inline void LogDestination::MaybeLogToEmail(LogSeverity severity, + const char* message, size_t len) { + if (severity >= email_logging_severity_ || +- severity >= FLAGS_logemaillevel) { +- string to(FLAGS_alsologtoemail); ++ severity >= FLAG(logemaillevel)) { ++ string to(FLAG(alsologtoemail)); + if (!addresses_.empty()) { + if (!to.empty()) { + to += ","; +@@ -862,7 +865,7 @@ inline void LogDestination::MaybeLogToLogfile(LogSeverity severity, + time_t timestamp, + const char* message, + size_t len) { +- const bool should_flush = severity > FLAGS_logbuflevel; ++ const bool should_flush = severity > FLAG(logbuflevel); + LogDestination* destination = log_destination(severity); + destination->logger_->Write(should_flush, timestamp, message, len); + } +@@ -871,9 +874,9 @@ inline void LogDestination::LogToAllLogfiles(LogSeverity severity, + time_t timestamp, + const char* message, + size_t len) { +- if (FLAGS_logtostdout) { // global flag: never log to file ++ if (FLAG(logtostdout)) { // global flag: never log to file + ColoredWriteToStdout(severity, message, len); +- } else if (FLAGS_logtostderr) { // global flag: never log to file ++ } else if (FLAG(logtostderr)) { // global flag: never log to file + ColoredWriteToStderr(severity, message, len); + } else { + for (int i = severity; i >= 0; --i) { +@@ -1032,25 +1035,25 @@ void LogFileObject::FlushUnlocked(){ + bytes_since_flush_ = 0; + } + // Figure out when we are due for another flush. +- const int64 next = (FLAGS_logbufsecs ++ const int64 next = (FLAG(logbufsecs) + * static_cast(1000000)); // in usec + next_flush_time_ = CycleClock_Now() + UsecToCycles(next); + } + + bool LogFileObject::CreateLogfile(const string& time_pid_string) { + string string_filename = base_filename_; +- if (FLAGS_timestamp_in_logfile_name) { ++ if (FLAG(timestamp_in_logfile_name)) { + string_filename += time_pid_string; + } + string_filename += filename_extension_; + const char* filename = string_filename.c_str(); + //only write to files, create if non-existant. + int flags = O_WRONLY | O_CREAT; +- if (FLAGS_timestamp_in_logfile_name) { ++ if (FLAG(timestamp_in_logfile_name)) { + //demand that the file is unique for our timestamp (fail if it exists). + flags = flags | O_EXCL; + } +- int fd = open(filename, flags, FLAGS_logfile_mode); ++ int fd = open(filename, flags, FLAG(logfile_mode)); + if (fd == -1) return false; + #ifdef HAVE_FCNTL + // Mark the file close-on-exec. We don't really care if this fails +@@ -1083,7 +1086,7 @@ bool LogFileObject::CreateLogfile(const string& time_pid_string) { + file_ = fdopen(fd, "a"); // Make a FILE*. + if (file_ == NULL) { // Man, we're screwed! + close(fd); +- if (FLAGS_timestamp_in_logfile_name) { ++ if (FLAG(timestamp_in_logfile_name)) { + unlink(filename); // Erase the half-baked evidence: an unusable log file, only if we just created it. + } + return false; +@@ -1125,8 +1128,8 @@ bool LogFileObject::CreateLogfile(const string& time_pid_string) { + + // Make an additional link to the log file in a place specified by + // FLAGS_log_link, if indicated +- if (!FLAGS_log_link.empty()) { +- linkpath = FLAGS_log_link + "/" + linkname; ++ if (!FLAG(log_link).empty()) { ++ linkpath = FLAG(log_link) + "/" + linkname; + unlink(linkpath.c_str()); // delete old one if it exists + if (symlink(filename, linkpath.c_str()) != 0) { + // silently ignore failures +@@ -1165,7 +1168,7 @@ void LogFileObject::Write(bool force_flush, + rollover_attempt_ = 0; + + struct ::tm tm_time; +- if (FLAGS_log_utc_time) { ++ if (FLAG(log_utc_time)) { + gmtime_r(×tamp, &tm_time); + } else { + localtime_r(×tamp, &tm_time); +@@ -1253,14 +1256,14 @@ void LogFileObject::Write(bool force_flush, + << ' ' + << setw(2) << tm_time.tm_hour << ':' + << setw(2) << tm_time.tm_min << ':' +- << setw(2) << tm_time.tm_sec << (FLAGS_log_utc_time ? " UTC\n" : "\n") ++ << setw(2) << tm_time.tm_sec << (FLAG(log_utc_time) ? " UTC\n" : "\n") + << "Running on machine: " + << LogDestination::hostname() << '\n'; + + if(!g_application_fingerprint.empty()) { + file_header_stream << "Application fingerprint: " << g_application_fingerprint << '\n'; + } +- const char* const date_time_format = FLAGS_log_year_in_prefix ++ const char* const date_time_format = FLAG(log_year_in_prefix) + ? "yyyymmdd hh:mm:ss.uuuuuu" + : "mmdd hh:mm:ss.uuuuuu"; + file_header_stream << "Running duration (h:mm:ss): " +@@ -1284,7 +1287,7 @@ void LogFileObject::Write(bool force_flush, + // greater than 4096, thereby indicating an error. + errno = 0; + fwrite(message, 1, message_len, file_); +- if ( FLAGS_stop_logging_if_full_disk && ++ if ( FLAG(stop_logging_if_full_disk) && + errno == ENOSPC ) { // disk full, stop writing to disk + stop_writing = true; // until the disk is + return; +@@ -1307,7 +1310,7 @@ void LogFileObject::Write(bool force_flush, + FlushUnlocked(); + #ifdef GLOG_OS_LINUX + // Only consider files >= 3MiB +- if (FLAGS_drop_log_memory && file_length_ >= (3U << 20U)) { ++ if (FLAG(drop_log_memory) && file_length_ >= (3U << 20U)) { + // Don't evict the most recent 1-2MiB so as not to impact a tailer + // of the log file and to avoid page rounding issue on linux < 4.7 + uint32 total_drop_length = +@@ -1348,7 +1351,7 @@ void LogCleaner::Disable() { + } + + void LogCleaner::UpdateCleanUpTime() { +- const int64 next = (FLAGS_logcleansecs ++ const int64 next = (FLAG(logcleansecs) + * 1000000); // in usec + next_cleanup_time_ = CycleClock_Now() + UsecToCycles(next); + } +@@ -1664,7 +1667,7 @@ void LogMessage::Init(const char* file, + // I20201018 160715 f5d4fbb0 logging.cc:1153] + // (log level, GMT year, month, date, time, thread_id, file basename, line) + // We exclude the thread_id for the default thread. +- if (FLAGS_log_prefix && (line != kNoLogPrefix)) { ++ if (FLAG(log_prefix) && (line != kNoLogPrefix)) { + std::ios saved_fmt(NULL); + saved_fmt.copyfmt(stream()); + stream().fill('0'); +@@ -1672,7 +1675,7 @@ void LogMessage::Init(const char* file, + if (custom_prefix_callback == NULL) { + #endif + stream() << LogSeverityNames[severity][0]; +- if (FLAGS_log_year_in_prefix) { ++ if (FLAG(log_year_in_prefix)) { + stream() << setw(4) << 1900 + logmsgtime_.year(); + } + stream() << setw(2) << 1 + logmsgtime_.month() +@@ -1703,11 +1706,11 @@ void LogMessage::Init(const char* file, + } + data_->num_prefix_chars_ = data_->stream_.pcount(); + +- if (!FLAGS_log_backtrace_at.empty()) { ++ if (!FLAG(log_backtrace_at).empty()) { + char fileline[128]; + snprintf(fileline, sizeof(fileline), "%s:%d", data_->basename_, line); + #ifdef HAVE_STACKTRACE +- if (FLAGS_log_backtrace_at == fileline) { ++ if (FLAG(log_backtrace_at) == fileline) { + string stacktrace; + DumpStackTraceToString(&stacktrace); + stream() << " (stacktrace:\n" << stacktrace << ") "; +@@ -1746,7 +1749,7 @@ ostream& LogMessage::stream() { + // Flush buffered message, called by the destructor, or any other function + // that needs to synchronize the log. + void LogMessage::Flush() { +- if (data_->has_been_flushed_ || data_->severity_ < FLAGS_minloglevel) { ++ if (data_->has_been_flushed_ || data_->severity_ < FLAG(minloglevel)) { + return; + } + +@@ -1808,7 +1811,7 @@ static char fatal_message[256]; + void ReprintFatalMessage() { + if (fatal_message[0]) { + const size_t n = strlen(fatal_message); +- if (!FLAGS_logtostderr) { ++ if (!FLAG(logtostderr)) { + // Also write to stderr (don't color to avoid terminal checks) + WriteToStderr(fatal_message, n); + } +@@ -1837,8 +1840,8 @@ void LogMessage::SendToLog() EXCLUSIVE_LOCKS_REQUIRED(log_mutex) { + // global flag: never log to file if set. Also -- don't log to a + // file if we haven't parsed the command line flags to get the + // program name. +- if (FLAGS_logtostderr || FLAGS_logtostdout || !IsGoogleLoggingInitialized()) { +- if (FLAGS_logtostdout) { ++ if (FLAG(logtostderr) || FLAG(logtostdout) || !IsGoogleLoggingInitialized()) { ++ if (FLAG(logtostdout)) { + ColoredWriteToStdout(data_->severity_, data_->message_text_, + data_->num_chars_to_log_); + } else { +@@ -1891,7 +1894,7 @@ void LogMessage::SendToLog() EXCLUSIVE_LOCKS_REQUIRED(log_mutex) { + fatal_time = logmsgtime_.timestamp(); + } + +- if (!FLAGS_logtostderr && !FLAGS_logtostdout) { ++ if (!FLAG(logtostderr) && !FLAG(logtostdout)) { + for (int i = 0; i < NUM_SEVERITIES; ++i) { + if (LogDestination::log_destinations_[i]) { + LogDestination::log_destinations_[i]->logger_->Write(true, 0, "", 0); +@@ -2238,7 +2241,7 @@ static bool SendEmailInternal(const char*dest, const char *subject, + subject, body, dest); + } + +- string logmailer = FLAGS_logmailer; ++ string logmailer = FLAG(logmailer); + if (logmailer.empty()) { + logmailer = "/bin/mail"; + } +@@ -2338,9 +2341,9 @@ const vector& GetLoggingDirectories() { + if (logging_directories_list == NULL) { + logging_directories_list = new vector; + +- if ( !FLAGS_log_dir.empty() ) { ++ if ( !FLAG(log_dir).empty() ) { + // A dir was specified, we should use it +- logging_directories_list->push_back(FLAGS_log_dir); ++ logging_directories_list->push_back(FLAG(log_dir)); + } else { + GetTempDirectories(logging_directories_list); + #ifdef GLOG_OS_WINDOWS +@@ -2654,7 +2657,7 @@ LogMessageTime::LogMessageTime(std::tm t) { + + LogMessageTime::LogMessageTime(std::time_t timestamp, WallTime now) { + std::tm t; +- if (FLAGS_log_utc_time) ++ if (FLAG(log_utc_time)) + gmtime_r(×tamp, &t); + else + localtime_r(×tamp, &t); +@@ -2673,7 +2676,7 @@ void LogMessageTime::init(const std::tm& t, std::time_t timestamp, + void LogMessageTime::CalcGmtOffset() { + std::tm gmt_struct; + int isDst = 0; +- if ( FLAGS_log_utc_time ) { ++ if ( FLAG(log_utc_time )) { + localtime_r(×tamp_, &gmt_struct); + isDst = gmt_struct.tm_isdst; + gmt_struct = time_struct_; +diff --git a/src/raw_logging.cc b/src/raw_logging.cc +index 43159832..8532362b 100644 +--- a/src/raw_logging.cc ++++ b/src/raw_logging.cc +@@ -123,8 +123,8 @@ static char crash_buf[kLogBufSize + 1] = { 0 }; // Will end in '\0' + GLOG_ATTRIBUTE_FORMAT(printf, 4, 5) + void RawLog__(LogSeverity severity, const char* file, int line, + const char* format, ...) { +- if (!(FLAGS_logtostdout || FLAGS_logtostderr || +- severity >= FLAGS_stderrthreshold || FLAGS_alsologtostderr || ++ if (!(FLAG(logtostdout) || FLAG(logtostderr) || ++ severity >= FLAG(stderrthreshold) || FLAG(alsologtostderr) || + !IsGoogleLoggingInitialized())) { + return; // this stderr log message is suppressed + } +diff --git a/src/utilities.cc b/src/utilities.cc +index a332f1a1..a9d5102a 100644 +--- a/src/utilities.cc ++++ b/src/utilities.cc +@@ -141,7 +141,7 @@ static void DumpStackTrace(int skip_count, DebugWriter *writerfn, void *arg) { + int depth = GetStackTrace(stack, ARRAYSIZE(stack), skip_count+1); + for (int i = 0; i < depth; i++) { + #if defined(HAVE_SYMBOLIZE) +- if (FLAGS_symbolize_stacktrace) { ++ if (FLAG(symbolize_stacktrace)) { + DumpPCAndSymbol(writerfn, arg, stack[i], " "); + } else { + DumpPC(writerfn, arg, stack[i], " "); +diff --git a/src/vlog_is_on.cc b/src/vlog_is_on.cc +index e478a366..4b7a5cae 100644 +--- a/src/vlog_is_on.cc ++++ b/src/vlog_is_on.cc +@@ -43,14 +43,24 @@ + #include + #include + #include "base/googleinit.h" ++#include "config.h" + + // glog doesn't have annotation + #define ANNOTATE_BENIGN_RACE(address, description) + + using std::string; + ++#ifdef HAVE_ABSL_FLAGS ++ ++ABSL_FLAG(int32_t, v, 0, "Show all VLOG(m) messages for m <= this." ++" Overridable by --vmodule.").OnUpdate([] { ++ GOOGLE_NAMESPACE::absl_proxy_v = absl::GetFlag(FLAGS_v); ++ }); ++ ++#else + GLOG_DEFINE_int32(v, 0, "Show all VLOG(m) messages for m <= this." + " Overridable by --vmodule."); ++#endif + + GLOG_DEFINE_string(vmodule, "", "per-module verbose level." + " Argument is a comma-separated list of =." +@@ -60,6 +70,8 @@ GLOG_DEFINE_string(vmodule, "", "per-module verbose level." + + _START_GOOGLE_NAMESPACE_ + ++int32_t absl_proxy_v = 0; ++ + namespace glog_internal_namespace_ { + + // Used by logging_unittests.cc so can't make it static here. +@@ -132,7 +144,8 @@ static void VLOG2Initializer() { + // Can now parse --vmodule flag and initialize mapping of module-specific + // logging levels. + inited_vmodule = false; +- const char* vmodule = FLAGS_vmodule.c_str(); ++ string vmodule_str = FLAG(vmodule); ++ const char* vmodule = vmodule_str.c_str(); + const char* sep; + VModuleInfo* head = NULL; + VModuleInfo* tail = NULL; +@@ -164,7 +177,7 @@ static void VLOG2Initializer() { + + // This can be called very early, so we use SpinLock and RAW_VLOG here. + int SetVLOGLevel(const char* module_pattern, int log_level) { +- int result = FLAGS_v; ++ int result = FLAG(v); + size_t const pattern_len = strlen(module_pattern); + bool found = false; + { diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index a2c3b14d281..dea8eef8ab5 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -25879,6 +25879,8 @@ with pkgs; dr14_tmeter = callPackage ../applications/audio/dr14_tmeter { }; + dragonflydb = callPackage ../servers/nosql/dragonflydb { }; + dragonfly-reverb = callPackage ../applications/audio/dragonfly-reverb { }; drawing = callPackage ../applications/graphics/drawing { };