Add back C library implementations for fdb_database_open_tenant and 3 other methods (#12593)

This allows 7.x python libraries to load these methods. It does this on startup to set up python/C API stuff, regardless
of whether the API user actually invokes this functionality (which was experimental and is now removed).

More details: rdar://166307379

Testing:
ctest -R c_api
ctest -R python

20251211-224723-gglass-17ed16f020aa18de compressed=True data_size=35311862 duration=5560013 ended=100000 fail_fast=1000 max_runs=100000 pass=100000 priority=100 remaining=0 runtime=1:01:01 sanity=False started=100000 stopped=20251211-234824 submitted=20251211-224723 timeout=5400 username=gglass
This commit is contained in:
gxglass
2025-12-12 09:34:27 -08:00
committed by GitHub
parent a34f5a46a7
commit df96a141f5
3 changed files with 99 additions and 0 deletions

View File

@@ -413,6 +413,33 @@ extern "C" DLLEXPORT void fdb_database_destroy(FDBDatabase* d) {
CATCH_AND_DIE(DB(d)->delref(););
}
// Define these symbols so that older client bindings (in particular,
// python) can load them at startup. Nobody should be calling this
// stuff in 8.0.0+ because it has always been experimental and is now
// deleted.
extern "C" DLLEXPORT fdb_error_t fdb_database_open_tenant(FDBDatabase* d,
uint8_t const* tenant_name,
int tenant_name_length,
FDBTenant** out_tenant) {
fprintf(stderr, "Unexpected call to removed functionality [fdb_database_open_tenant]\n");
abort();
}
extern "C" DLLEXPORT fdb_error_t fdb_tenant_create_transaction(FDBTenant* tenant, FDBTransaction** out_transaction) {
fprintf(stderr, "Unexpected call to removed functionality [fdb_tenant_create_transaction]\n");
abort();
}
extern "C" DLLEXPORT WARN_UNUSED_RESULT FDBFuture* fdb_tenant_get_id(FDBTenant* tenant) {
fprintf(stderr, "Unexpected call to removed functionality [fdb_tenant_get_id]\n");
abort();
}
extern "C" DLLEXPORT void fdb_tenant_destroy(FDBTenant* tenant) {
fprintf(stderr, "Unexpected call to removed functionality [fdb_tenant_destroy]\n");
abort();
}
extern "C" DLLEXPORT fdb_error_t fdb_database_create_transaction(FDBDatabase* d, FDBTransaction** out_transaction) {
CATCH_AND_RETURN(Reference<ITransaction> tr = DB(d)->createTransaction();
if (g_api_version <= 15) tr->setOption(FDBTransactionOptions::ACCESS_SYSTEM_KEYS);

View File

@@ -376,6 +376,25 @@ DLLEXPORT WARN_UNUSED_RESULT fdb_error_t fdb_database_set_option(FDBDatabase* d,
DLLEXPORT WARN_UNUSED_RESULT fdb_error_t fdb_database_create_transaction(FDBDatabase* d,
FDBTransaction** out_transaction);
/*
* Dummy versions of tenant-related functions are needed in the FDB C library
* because 7.x python bindings always load these functions on startup.
* (In 8.0+, users should not be invoking this deleted experimental
* functionality directly.)
*/
typedef struct FDB_tenant FDBTenant;
DLLEXPORT WARN_UNUSED_RESULT fdb_error_t fdb_database_open_tenant(FDBDatabase* d,
uint8_t const* tenant_name,
int tenant_name_length,
FDBTenant** out_tenant);
DLLEXPORT WARN_UNUSED_RESULT fdb_error_t fdb_tenant_create_transaction(FDBTenant* tenant,
FDBTransaction** out_transaction);
DLLEXPORT WARN_UNUSED_RESULT FDBFuture* fdb_tenant_get_id(FDBTenant* tenant);
DLLEXPORT void fdb_tenant_destroy(FDBTenant* tenant);
DLLEXPORT WARN_UNUSED_RESULT FDBFuture* fdb_database_reboot_worker(FDBDatabase* db,
uint8_t const* address,
int address_length,

View File

@@ -1302,6 +1302,25 @@ class Database(_TransactionCreator):
def _set_option(self, option, param, length):
self.capi.fdb_database_set_option(self.dpointer, option, param, length)
# XXX Adding this back temporarily to test C bindings changes to ensure
# that 7.x tenant-having python libraries can pass startup with 8.0.0
# libfdb_c.so. Client code that actually calls tenant related APIs will
# of course not obtain useful functionality. Returning `None` here seems
# both necessary and sufficient to ensure that clients don't think that
# they are able to obtain tenant-related functionality.
#
# TODO(gglass): remove once we think the C library has been fixed
# up. We don't want to ship this stuff in 8.0.0 python bindings
# as that would perpetuate these unwanted dependencies on the C
# library.
def open_tenant(self, name):
tname = name # this is a bug
pointer = ctypes.c_void_p()
self.capi.fdb_database_open_tenant(
self.dpointer, tname, len(tname), ctypes.byref(pointer)
)
return None
def create_transaction(self):
pointer = ctypes.c_void_p()
self.capi.fdb_database_create_transaction(self.dpointer, ctypes.byref(pointer))
@@ -1653,6 +1672,27 @@ def init_c_api():
_capi.fdb_database_destroy.argtypes = [ctypes.c_void_p]
_capi.fdb_database_destroy.restype = None
# XXX Adding this back temporarily to test C bindings changes to put
# this stuff back in, to avoid breaking 7.x tenant-having python libraries
# that want to load these symbols on process startup.
#
# TODO(gglass): remove once we think the C library has been fixed
# up. We don't want to ship this stuff in 8.0.0 python bindings
# as that would perpetuate these unwanted dependencies on the C
# library. Alternatively, only initialize this stuff in a non-default
# mode to be used only by internal testing with the very specific
# goal of ensuring that the C library has symbols to satisfy
# 7.x python client libraries. Like "SIMULATE_7X_PYTHON_BINDINGS"
# mode.
_capi.fdb_database_open_tenant.argtypes = [
ctypes.c_void_p,
ctypes.c_void_p,
ctypes.c_int,
ctypes.POINTER(ctypes.c_void_p),
]
_capi.fdb_database_open_tenant.restype = ctypes.c_int
_capi.fdb_database_open_tenant.errcheck = check_error_code
_capi.fdb_database_create_transaction.argtypes = [
ctypes.c_void_p,
ctypes.POINTER(ctypes.c_void_p),
@@ -1672,6 +1712,19 @@ def init_c_api():
_capi.fdb_database_get_client_status.argtypes = [ctypes.c_void_p]
_capi.fdb_database_get_client_status.restype = ctypes.c_void_p
_capi.fdb_tenant_destroy.argtypes = [ctypes.c_void_p]
_capi.fdb_tenant_destroy.restype = None
_capi.fdb_tenant_get_id.argtypes = [ctypes.c_void_p]
_capi.fdb_tenant_get_id.restype = ctypes.c_void_p
_capi.fdb_tenant_create_transaction.argtypes = [
ctypes.c_void_p,
ctypes.POINTER(ctypes.c_void_p),
]
_capi.fdb_tenant_create_transaction.restype = ctypes.c_int
_capi.fdb_tenant_create_transaction.errcheck = check_error_code
_capi.fdb_transaction_destroy.argtypes = [ctypes.c_void_p]
_capi.fdb_transaction_destroy.restype = None