Adding support for registering a logger port/pid to capture BDB messages
This commit is contained in:
parent
d6374488eb
commit
22f33e0b0d
|
@ -50,6 +50,9 @@ static void* deadlock_check(void* arg);
|
||||||
static void* trickle_write(void* arg);
|
static void* trickle_write(void* arg);
|
||||||
static void* txn_checkpoint(void* arg);
|
static void* txn_checkpoint(void* arg);
|
||||||
|
|
||||||
|
static void bdb_errcall(const DB_ENV* dbenv, const char* errpfx, const char* msg);
|
||||||
|
static void bdb_msgcall(const DB_ENV* dbenv, const char* msg);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Global instance of DB_ENV; only a single one exists per O/S process.
|
* Global instance of DB_ENV; only a single one exists per O/S process.
|
||||||
*/
|
*/
|
||||||
|
@ -117,6 +120,15 @@ static unsigned int G_CHECKPOINT_INTERVAL = 60 * 60; /* Seconds between checkpoi
|
||||||
*/
|
*/
|
||||||
static int G_BDBERL_PIPE[2] = {-1, -1};
|
static int G_BDBERL_PIPE[2] = {-1, -1};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lock, port and pid reference for relaying BDB output into the SASL logger. READ lock
|
||||||
|
* is required to log data. WRITE lock is used when replacing the pid/port reference. If
|
||||||
|
* no pid/port is available, no callback is registered with BDB.
|
||||||
|
*/
|
||||||
|
static ErlDrvRWLock* G_LOG_RWLOCK = 0;
|
||||||
|
static ErlDrvTermData G_LOG_PID;
|
||||||
|
static ErlDrvPort G_LOG_PORT;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
@ -277,6 +289,11 @@ DRIVER_INIT(bdberl_drv)
|
||||||
// TODO: Make configurable/adjustable
|
// TODO: Make configurable/adjustable
|
||||||
G_TPOOL_GENERAL = bdberl_tpool_start(10);
|
G_TPOOL_GENERAL = bdberl_tpool_start(10);
|
||||||
G_TPOOL_TXNS = bdberl_tpool_start(10);
|
G_TPOOL_TXNS = bdberl_tpool_start(10);
|
||||||
|
|
||||||
|
// Initialize logging lock and refs
|
||||||
|
G_LOG_RWLOCK = erl_drv_rwlock_create("bdberl_drv: G_LOG_RWLOCK");
|
||||||
|
G_LOG_PORT = 0;
|
||||||
|
G_LOG_PID = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return &bdberl_drv_entry;
|
return &bdberl_drv_entry;
|
||||||
|
@ -358,6 +375,24 @@ static void bdberl_drv_stop(ErlDrvData handle)
|
||||||
close_database(d->dbrefs->dbref, 0, d);
|
close_database(d->dbrefs->dbref, 0, d);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If this port was registered as the endpoint for logging, go ahead and
|
||||||
|
// remove it. Note that we don't need to lock to check this since we only
|
||||||
|
// unregister if it's already initialized to this port.
|
||||||
|
if (G_LOG_PORT == d->port)
|
||||||
|
{
|
||||||
|
WRITE_LOCK(G_LOG_RWLOCK);
|
||||||
|
|
||||||
|
// Remove the references
|
||||||
|
G_LOG_PORT = 0;
|
||||||
|
G_LOG_PID = 0;
|
||||||
|
|
||||||
|
// Unregister with BDB -- MUST DO THIS WITH WRITE LOCK HELD!
|
||||||
|
G_DB_ENV->set_msgcall(G_DB_ENV, 0);
|
||||||
|
G_DB_ENV->set_errcall(G_DB_ENV, 0);
|
||||||
|
|
||||||
|
WRITE_UNLOCK(G_LOG_RWLOCK);
|
||||||
|
}
|
||||||
|
|
||||||
DBG("Stopped port: %p\r\n", d->port);
|
DBG("Stopped port: %p\r\n", d->port);
|
||||||
|
|
||||||
// Release the port instance data
|
// Release the port instance data
|
||||||
|
@ -400,6 +435,9 @@ static void bdberl_drv_finish()
|
||||||
erl_drv_rwlock_destroy(G_DATABASES_RWLOCK);
|
erl_drv_rwlock_destroy(G_DATABASES_RWLOCK);
|
||||||
hive_hash_destroy(G_DATABASES_NAMES);
|
hive_hash_destroy(G_DATABASES_NAMES);
|
||||||
|
|
||||||
|
// Release the logging rwlock
|
||||||
|
erl_drv_rwlock_destroy(G_LOG_RWLOCK);
|
||||||
|
|
||||||
DBG("DRIVER_FINISH\n");
|
DBG("DRIVER_FINISH\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -693,6 +731,25 @@ static int bdberl_drv_control(ErlDrvData handle, unsigned int cmd,
|
||||||
RETURN_INT(ERROR_INVALID_DBREF, outbuf);
|
RETURN_INT(ERROR_INVALID_DBREF, outbuf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
case CMD_REGISTER_LOGGER:
|
||||||
|
{
|
||||||
|
// If this port is not the current logger, make it so. Only one logger can be registered
|
||||||
|
// at a time.
|
||||||
|
if (G_LOG_PORT != d->port)
|
||||||
|
{
|
||||||
|
// Grab the write lock and update the global vars; also make sure to update BDB callbacks
|
||||||
|
// within the write lock to avoid race conditions.
|
||||||
|
WRITE_LOCK(G_LOG_RWLOCK);
|
||||||
|
|
||||||
|
G_LOG_PORT = d->port;
|
||||||
|
G_LOG_PID = driver_connected(d->port);
|
||||||
|
|
||||||
|
G_DB_ENV->set_msgcall(G_DB_ENV, &bdb_msgcall);
|
||||||
|
G_DB_ENV->set_errcall(G_DB_ENV, &bdb_errcall);
|
||||||
|
|
||||||
|
WRITE_UNLOCK(G_LOG_RWLOCK);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
*outbuf = 0;
|
*outbuf = 0;
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1532,3 +1589,30 @@ static void* txn_checkpoint(void* arg)
|
||||||
DBG("Checkpointer exiting.\r\n");
|
DBG("Checkpointer exiting.\r\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void bdb_errcall(const DB_ENV* dbenv, const char* errpfx, const char* msg)
|
||||||
|
{
|
||||||
|
READ_LOCK(G_LOG_RWLOCK);
|
||||||
|
if (G_LOG_PORT)
|
||||||
|
{
|
||||||
|
ErlDrvTermData response[] = { ERL_DRV_ATOM, driver_mk_atom("bdb_error_log"),
|
||||||
|
ERL_DRV_STRING, (ErlDrvTermData)msg, (ErlDrvUInt)strlen(msg),
|
||||||
|
ERL_DRV_TUPLE, 2};
|
||||||
|
driver_send_term(G_LOG_PORT, G_LOG_PID, response, sizeof(response) / sizeof(response[0]));
|
||||||
|
}
|
||||||
|
READ_UNLOCK(G_LOG_RWLOCK);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void bdb_msgcall(const DB_ENV* dbenv, const char* msg)
|
||||||
|
{
|
||||||
|
printf("msgcall: %s\n", msg);
|
||||||
|
READ_LOCK(G_LOG_RWLOCK);
|
||||||
|
if (G_LOG_PORT)
|
||||||
|
{
|
||||||
|
ErlDrvTermData response[] = { ERL_DRV_ATOM, driver_mk_atom("bdb_info_log"),
|
||||||
|
ERL_DRV_STRING, (ErlDrvTermData)msg, (ErlDrvUInt)strlen(msg),
|
||||||
|
ERL_DRV_TUPLE, 2};
|
||||||
|
driver_send_term(G_LOG_PORT, G_LOG_PID, response, sizeof(response) / sizeof(response[0]));
|
||||||
|
}
|
||||||
|
READ_UNLOCK(G_LOG_RWLOCK);
|
||||||
|
}
|
||||||
|
|
|
@ -45,7 +45,7 @@ static int bdberl_drv_control(ErlDrvData handle, unsigned int cmd,
|
||||||
#define CMD_PUT_COMMIT 14
|
#define CMD_PUT_COMMIT 14
|
||||||
#define CMD_REMOVE_DB 15
|
#define CMD_REMOVE_DB 15
|
||||||
#define CMD_TRUNCATE 16
|
#define CMD_TRUNCATE 16
|
||||||
|
#define CMD_REGISTER_LOGGER 17
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Command status values
|
* Command status values
|
||||||
|
|
Loading…
Reference in a new issue