From a5770c1ce1539c0eace71f8deece3c65f2bb027d Mon Sep 17 00:00:00 2001 From: Yoni Fogel Date: Tue, 11 Jun 2013 19:44:52 -0700 Subject: [PATCH] refs #25. Makes product name configurable via db_env_set_toku_product_name --- buildheader/make_tdb.cc | 1 + ft/ft-ops.cc | 2 + ft/ft.cc | 89 +++++++++++++++++++++++++++++++++++++++++ ft/ft.h | 17 ++++++++ ft/logger.cc | 2 +- ft/logger.h | 1 - ft/recover.cc | 40 ++++++------------ src/export.map | 1 + src/ydb.cc | 78 ++++++++++-------------------------- src/ydb.h | 1 - src/ydb_db.cc | 11 ++--- src/ydb_env_func.cc | 19 +++++++++ src/ydb_env_func.h | 2 + 13 files changed, 172 insertions(+), 92 deletions(-) diff --git a/buildheader/make_tdb.cc b/buildheader/make_tdb.cc index 432c55ca204..8ecb33fec84 100644 --- a/buildheader/make_tdb.cc +++ b/buildheader/make_tdb.cc @@ -819,6 +819,7 @@ int main (int argc, char *const argv[] __attribute__((__unused__))) { printf("void db_env_enable_engine_status(bool) %s;\n", VISIBLE); printf("void db_env_set_flusher_thread_callback (void (*)(int, void*), void*) %s;\n", VISIBLE); printf("void db_env_set_num_bucket_mutexes(uint32_t) %s;\n", VISIBLE); + printf("int db_env_set_toku_product_name(const char*) %s;\n", VISIBLE); printf("#if defined(__cplusplus) || defined(__cilkplusplus)\n}\n#endif\n"); printf("#endif\n"); diff --git a/ft/ft-ops.cc b/ft/ft-ops.cc index 37617a82fc2..bf09eca7178 100644 --- a/ft/ft-ops.cc +++ b/ft/ft-ops.cc @@ -6220,6 +6220,8 @@ exit: return r; } + + void toku_ft_layer_destroy(void) { toku_mutex_destroy(&ft_open_close_lock); toku_ft_serialize_layer_destroy(); diff --git a/ft/ft.cc b/ft/ft.cc index 7aaaa79004e..ed2d851f6c6 100644 --- a/ft/ft.cc +++ b/ft/ft.cc @@ -1081,3 +1081,92 @@ void toku_ft_get_garbage(FT ft, uint64_t *total_space, uint64_t *used_space) { *used_space = info.used_space; } + +#if !defined(TOKUDB_REVISION) +#error +#endif + + + +#define xstr(X) str(X) +#define str(X) #X +#define static_version_string xstr(DB_VERSION_MAJOR) "." \ + xstr(DB_VERSION_MINOR) "." \ + xstr(DB_VERSION_PATCH) " build " \ + xstr(TOKUDB_REVISION) +struct toku_product_name_strings_struct toku_product_name_strings; + +char toku_product_name[TOKU_MAX_PRODUCT_NAME_LENGTH]; +void +tokudb_update_product_name_strings(void) { + //DO ALL STRINGS HERE.. maybe have a separate FT layer version as well + { // Version string + int n = snprintf(toku_product_name_strings.db_version, + sizeof(toku_product_name_strings.db_version), + "%s %s", toku_product_name, static_version_string); + assert(n >= 0); + assert((unsigned)n < sizeof(toku_product_name_strings.db_version)); + } + { + int n = snprintf(toku_product_name_strings.fileopsdirectory, + sizeof(toku_product_name_strings.fileopsdirectory), + "%s.directory", toku_product_name); + assert(n >= 0); + assert((unsigned)n < sizeof(toku_product_name_strings.fileopsdirectory)); + } + { + int n = snprintf(toku_product_name_strings.environmentdictionary, + sizeof(toku_product_name_strings.environmentdictionary), + "%s.environment", toku_product_name); + assert(n >= 0); + assert((unsigned)n < sizeof(toku_product_name_strings.environmentdictionary)); + } + { + int n = snprintf(toku_product_name_strings.rollback_cachefile, + sizeof(toku_product_name_strings.rollback_cachefile), + "%s.rollback", toku_product_name); + assert(n >= 0); + assert((unsigned)n < sizeof(toku_product_name_strings.rollback_cachefile)); + } + { + int n = snprintf(toku_product_name_strings.single_process_lock, + sizeof(toku_product_name_strings.single_process_lock), + "__%s_lock_dont_delete_me", toku_product_name); + assert(n >= 0); + assert((unsigned)n < sizeof(toku_product_name_strings.single_process_lock)); + } +} +#undef xstr +#undef str + +int +toku_single_process_lock(const char *lock_dir, const char *which, int *lockfd) { + if (!lock_dir) + return ENOENT; + int namelen=strlen(lock_dir)+strlen(which); + char lockfname[namelen+sizeof("/_") + strlen(toku_product_name_strings.single_process_lock)]; + + int l = snprintf(lockfname, sizeof(lockfname), "%s/%s_%s", + lock_dir, toku_product_name_strings.single_process_lock, which); + assert(l+1 == (signed)(sizeof(lockfname))); + *lockfd = toku_os_lock_file(lockfname); + if (*lockfd < 0) { + int e = get_error_errno(); + fprintf(stderr, "Couldn't start tokudb because some other tokudb process is using the same directory [%s] for [%s]\n", lock_dir, which); + return e; + } + return 0; +} + +int +toku_single_process_unlock(int *lockfd) { + int fd = *lockfd; + *lockfd = -1; + if (fd>=0) { + int r = toku_os_unlock_file(fd); + if (r != 0) + return get_error_errno(); + } + return 0; +} + diff --git a/ft/ft.h b/ft/ft.h index ab9d0dfc609..1289ee69513 100644 --- a/ft/ft.h +++ b/ft/ft.h @@ -198,4 +198,21 @@ int get_num_cores(void); struct toku_thread_pool *get_ft_pool(void); void dump_bad_block(unsigned char *vp, uint64_t size); +int toku_single_process_lock(const char *lock_dir, const char *which, int *lockfd); + +int toku_single_process_unlock(int *lockfd); + +void tokudb_update_product_name_strings(void); +#define TOKU_MAX_PRODUCT_NAME_LENGTH (256) +extern char toku_product_name[TOKU_MAX_PRODUCT_NAME_LENGTH]; + +struct toku_product_name_strings_struct { + char db_version[sizeof(toku_product_name) + sizeof("1.2.3 build ") + 256]; + char environmentdictionary[sizeof(toku_product_name) + sizeof(".environment")]; + char fileopsdirectory[sizeof(toku_product_name) + sizeof(".directory")]; + char single_process_lock[sizeof(toku_product_name) + sizeof("___lock_dont_delete_me")]; + char rollback_cachefile[sizeof(toku_product_name) + sizeof(".rollback")]; +}; + +extern struct toku_product_name_strings_struct toku_product_name_strings; #endif diff --git a/ft/logger.cc b/ft/logger.cc index cc9351b0ba8..052017cb937 100644 --- a/ft/logger.cc +++ b/ft/logger.cc @@ -289,7 +289,7 @@ toku_logger_open_rollback(TOKULOGGER logger, CACHETABLE cachetable, bool create) FT_HANDLE t = NULL; // Note, there is no DB associated with this BRT. toku_ft_handle_create(&t); - int r = toku_ft_handle_open(t, ROLLBACK_CACHEFILE_NAME, create, create, cachetable, NULL_TXN); + int r = toku_ft_handle_open(t, toku_product_name_strings.rollback_cachefile, create, create, cachetable, NULL_TXN); assert_zero(r); logger->rollback_cachefile = t->ft->cf; toku_logger_initialize_rollback_cache(logger, t->ft); diff --git a/ft/logger.h b/ft/logger.h index 2908b846479..994c7cbe4ae 100644 --- a/ft/logger.h +++ b/ft/logger.h @@ -102,7 +102,6 @@ enum { TOKU_LOG_VERSION = FT_LAYOUT_VERSION, TOKU_LOG_MIN_SUPPORTED_VERSION = FT_LAYOUT_MIN_SUPPORTED_VERSION, }; -#define ROLLBACK_CACHEFILE_NAME "tokudb.rollback" int toku_logger_create (TOKULOGGER *resultp); int toku_logger_open (const char *directory, TOKULOGGER logger); diff --git a/ft/recover.cc b/ft/recover.cc index 768369950ce..858de323bfd 100644 --- a/ft/recover.cc +++ b/ft/recover.cc @@ -97,8 +97,6 @@ PATENT RIGHTS GRANT: #include "checkpoint.h" #include "txn_manager.h" -static const char recovery_lock_file[] = "/__tokudb_recoverylock_dont_delete_me"; - int tokudb_recovery_trace = 0; // turn on recovery tracing, default off. //#define DO_VERIFY_COUNTS @@ -500,13 +498,13 @@ static int toku_recover_fassociate (struct logtype_fassociate *l, RECOVER_ENV re // If rollback file, specify which checkpointed version of file we need (not just the latest) // because we cannot use a rollback log that is later than the last complete checkpoint. See #3113. { - bool rollback_file = (0==strcmp(fname, ROLLBACK_CACHEFILE_NAME)); + bool rollback_file = (0==strcmp(fname, toku_product_name_strings.rollback_cachefile)); LSN max_acceptable_lsn = MAX_LSN; if (rollback_file) { max_acceptable_lsn = renv->ss.checkpoint_begin_lsn; FT_HANDLE t; toku_ft_handle_create(&t); - r = toku_ft_handle_open_recovery(t, ROLLBACK_CACHEFILE_NAME, false, false, renv->ct, (TOKUTXN)NULL, l->filenum, max_acceptable_lsn); + r = toku_ft_handle_open_recovery(t, toku_product_name_strings.rollback_cachefile, false, false, renv->ct, (TOKUTXN)NULL, l->filenum, max_acceptable_lsn); renv->logger->rollback_cachefile = t->ft->cf; toku_logger_initialize_rollback_cache(renv->logger, t->ft); } else { @@ -826,7 +824,7 @@ static int toku_recover_fcreate (struct logtype_fcreate *l, RECOVER_ENV renv) { return r; } } - assert(0!=strcmp(iname, ROLLBACK_CACHEFILE_NAME)); //Creation of rollback cachefile never gets logged. + assert(0!=strcmp(iname, toku_product_name_strings.rollback_cachefile)); //Creation of rollback cachefile never gets logged. toku_free(iname_in_cwd); toku_free(iname); @@ -854,7 +852,7 @@ static int toku_recover_fopen (struct logtype_fopen *l, RECOVER_ENV renv) { TOKUTXN txn = NULL; char *fname = fixup_fname(&l->iname); - assert(0!=strcmp(fname, ROLLBACK_CACHEFILE_NAME)); //Rollback cachefile can be opened only via fassociate. + assert(0!=strcmp(fname, toku_product_name_strings.rollback_cachefile)); //Rollback cachefile can be opened only via fassociate. r = internal_recover_fopen_or_fcreate(renv, must_create, 0, &l->iname, l->filenum, l->treeflags, txn, 0, 0, TOKU_DEFAULT_COMPRESSION_METHOD, MAX_LSN); toku_free(fname); @@ -910,7 +908,7 @@ static int toku_recover_fclose (struct logtype_fclose *l, RECOVER_ENV renv) { char *iname = fixup_fname(&l->iname); assert(strcmp(tuple->iname, iname) == 0); // verify that file_map has same iname as log entry - if (0!=strcmp(iname, ROLLBACK_CACHEFILE_NAME)) { + if (0!=strcmp(iname, toku_product_name_strings.rollback_cachefile)) { //Rollback cachefile is closed manually at end of recovery, not here toku_ft_handle_close_recovery(tuple->ft_handle, l->lsn); } @@ -1569,35 +1567,21 @@ static int do_recovery(RECOVER_ENV renv, const char *env_dir, const char *log_di int toku_recover_lock(const char *lock_dir, int *lockfd) { - if (!lock_dir) - return ENOENT; - int namelen=strlen(lock_dir); - char lockfname[namelen+sizeof(recovery_lock_file)]; - - int l = snprintf(lockfname, sizeof(lockfname), "%s%s", lock_dir, recovery_lock_file); - assert(l+1 == (signed)(sizeof(lockfname))); - *lockfd = toku_os_lock_file(lockfname); - if (*lockfd < 0) { - int e = get_error_errno(); - fprintf(stderr, "Couldn't run recovery because some other process holds the recovery lock %s\n", lockfname); - return e; + int e = toku_single_process_lock(lock_dir, "recovery", lockfd); + if (e != 0 && e != ENOENT) { + fprintf(stderr, "Couldn't run recovery because some other process holds the recovery lock\n"); } - return 0; + return e; } int toku_recover_unlock(int lockfd) { - int r = toku_os_unlock_file(lockfd); - if (r != 0) { - return get_error_errno(); - } - return 0; + int lockfd_copy = lockfd; + return toku_single_process_unlock(&lockfd_copy); } - - int tokudb_recover(DB_ENV *env, - prepared_txn_callback_t prepared_txn_callback, + prepared_txn_callback_t prepared_txn_callback, keep_cachetable_callback_t keep_cachetable_callback, TOKULOGGER logger, const char *env_dir, const char *log_dir, diff --git a/src/export.map b/src/export.map index 62537c63d1b..5e5352e4e78 100644 --- a/src/export.map +++ b/src/export.map @@ -28,6 +28,7 @@ db_env_enable_engine_status; db_env_set_flusher_thread_callback; db_env_set_num_bucket_mutexes; + db_env_set_toku_product_name; read_partitioned_counter; diff --git a/src/ydb.cc b/src/ydb.cc index cac5305667f..ff4868fdb0d 100644 --- a/src/ydb.cc +++ b/src/ydb.cc @@ -229,50 +229,18 @@ ydb_layer_get_status(DB_ENV* env, YDB_LAYER_STATUS statp) { static DB_ENV * volatile most_recent_env; // most recently opened env, used for engine status on crash. Note there are likely to be races on this if you have multiple threads creating and closing environments in parallel. We'll declare it volatile since at least that helps make sure the compiler doesn't optimize away certain code (e.g., if while debugging, you write a code that spins on most_recent_env, you'd like to compiler not to optimize your code away.) -const char * environmentdictionary = "tokudb.environment"; -const char * fileopsdirectory = "tokudb.directory"; - static int env_get_iname(DB_ENV* env, DBT* dname_dbt, DBT* iname_dbt); static int toku_maybe_get_engine_status_text (char* buff, int buffsize); // for use by toku_assert static void toku_maybe_set_env_panic(int code, const char * msg); // for use by toku_assert -static const char single_process_lock_file[] = "/__tokudb_lock_dont_delete_me_"; - -static int -single_process_lock(const char *lock_dir, const char *which, int *lockfd) { - if (!lock_dir) - return ENOENT; - int namelen=strlen(lock_dir)+strlen(which); - char lockfname[namelen+sizeof(single_process_lock_file)]; - - int l = snprintf(lockfname, sizeof(lockfname), "%s%s%s", lock_dir, single_process_lock_file, which); - assert(l+1 == (signed)(sizeof(lockfname))); - *lockfd = toku_os_lock_file(lockfname); - if (*lockfd < 0) { - int e = get_error_errno(); - fprintf(stderr, "Couldn't start tokudb because some other tokudb process is using the same directory [%s] for [%s]\n", lock_dir, which); - return e; - } - return 0; -} - -static int -single_process_unlock(int *lockfd) { - int fd = *lockfd; - *lockfd = -1; - if (fd>=0) { - int r = toku_os_unlock_file(fd); - if (r != 0) - return get_error_errno(); - } - return 0; -} - int toku_ydb_init(void) { int r = 0; //Lower level must be initialized first. r = toku_ft_layer_init(); + if (r!=0) goto exit; + r = db_env_set_toku_product_name("tokudb"); +exit: return r; } @@ -751,7 +719,7 @@ validate_env(DB_ENV * env, bool * valid_newenv, bool need_rollback_cachefile) { char* path = NULL; // Test for persistent environment - path = toku_construct_full_name(2, env->i->dir, environmentdictionary); + path = toku_construct_full_name(2, env->i->dir, toku_product_name_strings.environmentdictionary); assert(path); r = toku_stat(path, &buf); if (r == 0) { @@ -772,7 +740,7 @@ validate_env(DB_ENV * env, bool * valid_newenv, bool need_rollback_cachefile) { // Test for existence of rollback cachefile if it is expected to exist if (r == 0 && need_rollback_cachefile) { - path = toku_construct_full_name(2, env->i->dir, ROLLBACK_CACHEFILE_NAME); + path = toku_construct_full_name(2, env->i->dir, toku_product_name_strings.rollback_cachefile); assert(path); r = toku_stat(path, &buf); if (r == 0) { @@ -797,7 +765,7 @@ validate_env(DB_ENV * env, bool * valid_newenv, bool need_rollback_cachefile) { // Test for fileops directory if (r == 0) { - path = toku_construct_full_name(2, env->i->dir, fileopsdirectory); + path = toku_construct_full_name(2, env->i->dir, toku_product_name_strings.fileopsdirectory); assert(path); r = toku_stat(path, &buf); if (r == 0) { @@ -856,13 +824,13 @@ ydb_maybe_upgrade_env (DB_ENV *env, LSN * last_lsn_of_clean_shutdown_read_from_l static void unlock_single_process(DB_ENV *env) { int r; - r = single_process_unlock(&env->i->envdir_lockfd); + r = toku_single_process_unlock(&env->i->envdir_lockfd); lazy_assert_zero(r); - r = single_process_unlock(&env->i->datadir_lockfd); + r = toku_single_process_unlock(&env->i->datadir_lockfd); lazy_assert_zero(r); - r = single_process_unlock(&env->i->logdir_lockfd); + r = toku_single_process_unlock(&env->i->logdir_lockfd); lazy_assert_zero(r); - r = single_process_unlock(&env->i->tmpdir_lockfd); + r = toku_single_process_unlock(&env->i->tmpdir_lockfd); lazy_assert_zero(r); } @@ -934,13 +902,13 @@ env_open(DB_ENV * env, const char *home, uint32_t flags, int mode) { env_setup_real_log_dir(env); env_setup_real_tmp_dir(env); - r = single_process_lock(env->i->dir, "environment", &env->i->envdir_lockfd); + r = toku_single_process_lock(env->i->dir, "environment", &env->i->envdir_lockfd); if (r!=0) goto cleanup; - r = single_process_lock(env->i->real_data_dir, "data", &env->i->datadir_lockfd); + r = toku_single_process_lock(env->i->real_data_dir, "data", &env->i->datadir_lockfd); if (r!=0) goto cleanup; - r = single_process_lock(env->i->real_log_dir, "logs", &env->i->logdir_lockfd); + r = toku_single_process_lock(env->i->real_log_dir, "logs", &env->i->logdir_lockfd); if (r!=0) goto cleanup; - r = single_process_lock(env->i->real_tmp_dir, "temp", &env->i->tmpdir_lockfd); + r = toku_single_process_lock(env->i->real_tmp_dir, "temp", &env->i->tmpdir_lockfd); if (r!=0) goto cleanup; bool need_rollback_cachefile; @@ -961,7 +929,7 @@ env_open(DB_ENV * env, const char *home, uint32_t flags, int mode) { if (upgrade_in_progress) { // Delete old rollback file. There was a clean shutdown, so it has nothing useful, // and there is no value in upgrading it. It is simpler to just create a new one. - char* rollback_filename = toku_construct_full_name(2, env->i->dir, ROLLBACK_CACHEFILE_NAME); + char* rollback_filename = toku_construct_full_name(2, env->i->dir, toku_product_name_strings.rollback_cachefile); assert(rollback_filename); r = unlink(rollback_filename); if (r != 0) { @@ -1057,7 +1025,7 @@ env_open(DB_ENV * env, const char *home, uint32_t flags, int mode) { assert_zero(r); r = db_use_builtin_key_cmp(env->i->persistent_environment); assert_zero(r); - r = toku_db_open_iname(env->i->persistent_environment, txn, environmentdictionary, DB_CREATE, mode); + r = toku_db_open_iname(env->i->persistent_environment, txn, toku_product_name_strings.environmentdictionary, DB_CREATE, mode); assert_zero(r); if (newenv) { // create new persistent_environment @@ -1092,7 +1060,7 @@ env_open(DB_ENV * env, const char *home, uint32_t flags, int mode) { assert_zero(r); r = db_use_builtin_key_cmp(env->i->directory); assert_zero(r); - r = toku_db_open_iname(env->i->directory, txn, fileopsdirectory, DB_CREATE, mode); + r = toku_db_open_iname(env->i->directory, txn, toku_product_name_strings.fileopsdirectory, DB_CREATE, mode); assert_zero(r); } if (using_txns) { @@ -1225,6 +1193,7 @@ env_close(DB_ENV * env, uint32_t flags) { unlock_single_process(env); toku_free(env->i); toku_free(env); + toku_sync_fetch_and_add(&tokudb_num_envs, -1); if (flags != 0) { r = EINVAL; } @@ -2261,6 +2230,8 @@ env_get_cursor_for_directory(DB_ENV* env, DB_TXN* txn, DBC** c) { return toku_db_cursor(env->i->directory, txn, c, 0); } +int tokudb_num_envs = 0; + static int toku_env_create(DB_ENV ** envp, uint32_t flags) { int r = ENOSYS; @@ -2374,6 +2345,7 @@ toku_env_create(DB_ENV ** envp, uint32_t flags) { *envp = result; r = 0; + toku_sync_fetch_and_add(&tokudb_num_envs, 1); cleanup: if (r!=0) { if (result) { @@ -2761,13 +2733,7 @@ db_version(int *major, int *minor, int *patch) { *minor = DB_VERSION_MINOR; if (patch) *patch = DB_VERSION_PATCH; -#if defined(TOKUDB_REVISION) -#define xstr(X) str(X) -#define str(X) #X - return "tokudb " xstr(DB_VERSION_MAJOR) "." xstr(DB_VERSION_MINOR) "." xstr(DB_VERSION_PATCH) " build " xstr(TOKUDB_REVISION); -#else -#error -#endif + return toku_product_name_strings.db_version; } // HACK: To ensure toku_pthread_yield gets included in the .so diff --git a/src/ydb.h b/src/ydb.h index 53e68970e98..96fcba6113c 100644 --- a/src/ydb.h +++ b/src/ydb.h @@ -114,5 +114,4 @@ extern "C" uint64_t toku_test_get_latest_lsn(DB_ENV *env) __attribute__((__visib // test-only function extern "C" int toku_test_get_checkpointing_user_data_status(void) __attribute__((__visibility__("default"))); - #endif diff --git a/src/ydb_db.cc b/src/ydb_db.cc index 24c3c76c46e..07b4ce4a31a 100644 --- a/src/ydb_db.cc +++ b/src/ydb_db.cc @@ -167,16 +167,17 @@ create_iname(DB_ENV *env, uint64_t id1, uint64_t id2, char *hint, const char *ma 8 + // hex file format version 24 + // hex id (normally the txnid's parent and child) 8 + // hex value of n if non-neg - sizeof("_B___.tokudb")]; // extra pieces + sizeof("_B___.") + // extra pieces + strlen(toku_product_name)]; if (n < 0) bytes = snprintf(inamebase, sizeof(inamebase), - "%s_%" PRIx64 "_%" PRIx64 "_%" PRIx32 ".tokudb", - hint, id1, id2, FT_LAYOUT_VERSION); + "%s_%" PRIx64 "_%" PRIx64 "_%" PRIx32 ".%s", + hint, id1, id2, FT_LAYOUT_VERSION, toku_product_name); else { invariant(strlen(mark) == 1); bytes = snprintf(inamebase, sizeof(inamebase), - "%s_%" PRIx64 "_%" PRIx64 "_%" PRIx32 "_%s_%" PRIx32 ".tokudb", - hint, id1, id2, FT_LAYOUT_VERSION, mark, n); + "%s_%" PRIx64 "_%" PRIx64 "_%" PRIx32 "_%s_%" PRIx32 ".%s", + hint, id1, id2, FT_LAYOUT_VERSION, mark, n, toku_product_name); } assert(bytes>0); assert(bytes<=(int)sizeof(inamebase)-1); diff --git a/src/ydb_env_func.cc b/src/ydb_env_func.cc index 11b0c5e5bd9..2190dace55e 100644 --- a/src/ydb_env_func.cc +++ b/src/ydb_env_func.cc @@ -93,6 +93,7 @@ PATENT RIGHTS GRANT: #include #include +#include #include #include #include @@ -225,3 +226,21 @@ db_env_set_num_bucket_mutexes(uint32_t num_mutexes) { toku_pair_list_set_lock_size(num_mutexes); } +int +db_env_set_toku_product_name(const char *name) { + if (tokudb_num_envs > 0) { + return EINVAL; + } + if (!name || strlen(name) < 1) { + return EINVAL; + } + if (strlen(name) >= sizeof(toku_product_name)) { + return ENAMETOOLONG; + } + if (strncmp(toku_product_name, name, sizeof(toku_product_name))) { + strcpy(toku_product_name, name); + tokudb_update_product_name_strings(); + } + return 0; +} + diff --git a/src/ydb_env_func.h b/src/ydb_env_func.h index 9ebad8d8862..8e57088d8bd 100644 --- a/src/ydb_env_func.h +++ b/src/ydb_env_func.h @@ -105,4 +105,6 @@ void setup_dlmalloc(void) __attribute__((__visibility__("default"))); // Test-only function void toku_env_increase_last_xid(DB_ENV *env, uint64_t increment); +extern int tokudb_num_envs; + #endif