summaryrefslogtreecommitdiff
path: root/source3/rpc_server/srv_eventlog_lib.c
diff options
context:
space:
mode:
authorGerald Carter <jerry@samba.org>2005-11-17 20:08:59 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 11:05:26 -0500
commit5251618c7fff7635a4b64072f88eaf5e4e25761e (patch)
tree71005176976553554ba598799e8dca8155a09683 /source3/rpc_server/srv_eventlog_lib.c
parent70cac98b6e1871cf93b379a4834de1778853de86 (diff)
downloadsamba-5251618c7fff7635a4b64072f88eaf5e4e25761e.tar.gz
samba-5251618c7fff7635a4b64072f88eaf5e4e25761e.tar.bz2
samba-5251618c7fff7635a4b64072f88eaf5e4e25761e.zip
r11761: * fix clearing of event logs by truncating the tdb.
This feature got broken in some of the other updates. Now each open handle stores an pointer to an open tdb data structure (not the tdb pointer itself). Clearing can be done with a simple elog_close_tdb( elog, True ) to force a close and then calling elog_open_tdb( logname, True ) to force an tdb truncate. Permissions on existing tdbs are maintained which is important. * We don't currently handle backup. Haven't looked at the format of a backuped up eventlog to know what the deal is. (This used to be commit 2df34c9403446d12f1ceeac38cbda5d3ba805b02)
Diffstat (limited to 'source3/rpc_server/srv_eventlog_lib.c')
-rw-r--r--source3/rpc_server/srv_eventlog_lib.c107
1 files changed, 59 insertions, 48 deletions
diff --git a/source3/rpc_server/srv_eventlog_lib.c b/source3/rpc_server/srv_eventlog_lib.c
index b21c2a2529..ec5edf2f34 100644
--- a/source3/rpc_server/srv_eventlog_lib.c
+++ b/source3/rpc_server/srv_eventlog_lib.c
@@ -24,14 +24,7 @@
/* maintain a list of open eventlog tdbs with reference counts */
-struct elog_open_tdb {
- struct elog_open_tdb *prev, *next;
- char *name;
- TDB_CONTEXT *tdb;
- int ref_count;
-};
-
-static struct elog_open_tdb *open_elog_list;
+static ELOG_TDB *open_elog_list;
/********************************************************************
Init an Eventlog TDB, and return it. If null, something bad
@@ -317,14 +310,14 @@ BOOL can_write_to_eventlog( TDB_CONTEXT * tdb, int32 needed )
/*******************************************************************
*******************************************************************/
-TDB_CONTEXT *elog_open_tdb( char *logname )
+ELOG_TDB *elog_open_tdb( char *logname, BOOL force_clear )
{
- TDB_CONTEXT *tdb;
+ TDB_CONTEXT *tdb = NULL;
uint32 vers_id;
- struct elog_open_tdb *ptr;
+ ELOG_TDB *ptr;
char *tdbfilename;
pstring tdbpath;
- struct elog_open_tdb *tdb_node;
+ ELOG_TDB *tdb_node = NULL;
char *eventlogdir;
/* first see if we have an open context */
@@ -332,7 +325,19 @@ TDB_CONTEXT *elog_open_tdb( char *logname )
for ( ptr=open_elog_list; ptr; ptr=ptr->next ) {
if ( strequal( ptr->name, logname ) ) {
ptr->ref_count++;
- return ptr->tdb;
+
+ /* trick to alow clearing of the eventlog tdb.
+ The force_clear flag should imply that someone
+ has done a force close. So make sure the tdb
+ is NULL. If this is a normal open, then just
+ return the existing reference */
+
+ if ( force_clear ) {
+ SMB_ASSERT( ptr->tdb == NULL );
+ break;
+ }
+ else
+ return ptr;
}
}
@@ -348,27 +353,41 @@ TDB_CONTEXT *elog_open_tdb( char *logname )
pstrcpy( tdbpath, tdbfilename );
SAFE_FREE( tdbfilename );
- DEBUG(7,("elog_open_tdb: Opening %s...\n", tdbpath ));
+ DEBUG(7,("elog_open_tdb: Opening %s...(force_clear == %s)\n",
+ tdbpath, force_clear?"True":"False" ));
+
+ /* the tdb wasn't already open or this is a forced clear open */
- tdb = tdb_open_log( tdbpath, 0, TDB_DEFAULT, O_RDWR , 0 );
- if ( tdb ) {
- vers_id = tdb_fetch_int32( tdb, EVT_VERSION );
+ if ( !force_clear ) {
- if ( vers_id != EVENTLOG_DATABASE_VERSION_V1 ) {
- DEBUG(1,("elog_open_tdb: Invalid version [%d] on file [%s].\n",
- vers_id, tdbpath));
- tdb_close( tdb );
- tdb = elog_init_tdb( tdbpath );
+ tdb = tdb_open_log( tdbpath, 0, TDB_DEFAULT, O_RDWR , 0 );
+ if ( tdb ) {
+ vers_id = tdb_fetch_int32( tdb, EVT_VERSION );
+
+ if ( vers_id != EVENTLOG_DATABASE_VERSION_V1 ) {
+ DEBUG(1,("elog_open_tdb: Invalid version [%d] on file [%s].\n",
+ vers_id, tdbpath));
+ tdb_close( tdb );
+ tdb = elog_init_tdb( tdbpath );
+ }
}
}
- else {
+
+ if ( !tdb )
tdb = elog_init_tdb( tdbpath );
- }
/* if we got a valid context, then add it to the list */
if ( tdb ) {
- if ( !(tdb_node = TALLOC_ZERO_P( NULL, struct elog_open_tdb )) ) {
+ /* on a forced clear, just reset the tdb context if we already
+ have an open entry in the list */
+
+ if ( ptr ) {
+ ptr->tdb = tdb;
+ return ptr;
+ }
+
+ if ( !(tdb_node = TALLOC_ZERO_P( NULL, ELOG_TDB)) ) {
DEBUG(0,("elog_open_tdb: talloc() failure!\n"));
tdb_close( tdb );
return NULL;
@@ -381,42 +400,34 @@ TDB_CONTEXT *elog_open_tdb( char *logname )
DLIST_ADD( open_elog_list, tdb_node );
}
- return tdb;
+ return tdb_node;
}
/*******************************************************************
Wrapper to handle reference counts to the tdb
*******************************************************************/
-int elog_close_tdb( TDB_CONTEXT *tdb )
+int elog_close_tdb( ELOG_TDB *etdb, BOOL force_close )
{
- struct elog_open_tdb *ptr;
+ TDB_CONTEXT *tdb;
- if ( !tdb )
+ if ( !etdb )
return 0;
- /* See if we can just decrement the ref_count.
- Just compare pointer values (not names ) */
-
- for ( ptr=open_elog_list; ptr; ptr=ptr->next ) {
- if ( tdb == ptr->tdb ) {
- ptr->ref_count--;
- break;
- }
- }
+ etdb->ref_count--;
- /* if we have a NULL pointer; it means we are trying to
- close a tdb not in the list of open eventlogs */
-
- SMB_ASSERT( ptr != NULL );
- if ( !ptr )
+ SMB_ASSERT( etdb->ref_count >= 0 );
+
+ if ( etdb->ref_count == 0 ) {
+ tdb = etdb->tdb;
+ DLIST_REMOVE( open_elog_list, etdb );
+ TALLOC_FREE( etdb );
return tdb_close( tdb );
+ }
- SMB_ASSERT( ptr->ref_count >= 0 );
-
- if ( ptr->ref_count == 0 ) {
- DLIST_REMOVE( open_elog_list, ptr );
- TALLOC_FREE( ptr );
+ if ( force_close ) {
+ tdb = etdb->tdb;
+ etdb->tdb = NULL;
return tdb_close( tdb );
}