summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGerald Carter <jerry@samba.org>2005-11-17 17:41:02 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 11:05:26 -0500
commit70cac98b6e1871cf93b379a4834de1778853de86 (patch)
tree473421497e007ccb7bd4fa74c978a74877278e9f
parent05f7bec525484b7a13ba0f80fd684cd1f9b1d66b (diff)
downloadsamba-70cac98b6e1871cf93b379a4834de1778853de86.tar.gz
samba-70cac98b6e1871cf93b379a4834de1778853de86.tar.bz2
samba-70cac98b6e1871cf93b379a4834de1778853de86.zip
r11760: fix sequential reads in the eventlog; event viewer is behaving better now as well but needs more testing
(This used to be commit ba2f94aeae1f8e69d53fc360785adf222a8c9c6e)
-rw-r--r--source3/rpc_parse/parse_eventlog.c2
-rw-r--r--source3/rpc_server/srv_eventlog_nt.c186
2 files changed, 106 insertions, 82 deletions
diff --git a/source3/rpc_parse/parse_eventlog.c b/source3/rpc_parse/parse_eventlog.c
index 0f0b02748b..5e28a4aba5 100644
--- a/source3/rpc_parse/parse_eventlog.c
+++ b/source3/rpc_parse/parse_eventlog.c
@@ -294,7 +294,7 @@ BOOL eventlog_io_r_read_eventlog(const char *desc,
while(entry != NULL && record_written < record_total)
{
- DEBUG(10, ("eventlog_io_r_read_eventlog: writing record [%d] out of [%d].\n", record_written, record_total));
+ DEBUG(11, ("eventlog_io_r_read_eventlog: writing record [%d] out of [%d].\n", record_written, record_total));
/* Encode the actual eventlog record record */
diff --git a/source3/rpc_server/srv_eventlog_nt.c b/source3/rpc_server/srv_eventlog_nt.c
index 6413221031..0f0b73029a 100644
--- a/source3/rpc_server/srv_eventlog_nt.c
+++ b/source3/rpc_server/srv_eventlog_nt.c
@@ -28,6 +28,7 @@
typedef struct {
char *logname;
TDB_CONTEXT *tdb;
+ uint32 current_record;
uint32 num_records;
uint32 oldest_entry;
uint32 flags;
@@ -131,6 +132,45 @@ static BOOL elog_validate_logname( const char *name )
}
/********************************************************************
+********************************************************************/
+
+static BOOL get_num_records_hook( EVENTLOG_INFO * info )
+{
+ int next_record;
+ int oldest_record;
+
+ if ( !info->tdb ) {
+ DEBUG( 10, ( "No open tdb for %s\n", info->logname ) );
+ return False;
+ }
+
+ /* lock the tdb since we have to get 2 records */
+
+ tdb_lock_bystring( info->tdb, EVT_NEXT_RECORD, 1 );
+ next_record = tdb_fetch_int32( info->tdb, EVT_NEXT_RECORD);
+ oldest_record = tdb_fetch_int32( info->tdb, EVT_OLDEST_ENTRY);
+ tdb_unlock_bystring( info->tdb, EVT_NEXT_RECORD);
+
+ DEBUG( 8,
+ ( "Oldest Record %d; Next Record %d\n", oldest_record,
+ next_record ) );
+
+ info->num_records = ( next_record - oldest_record );
+ info->oldest_entry = oldest_record;
+
+ return True;
+}
+
+/********************************************************************
+ ********************************************************************/
+
+static BOOL get_oldest_entry_hook( EVENTLOG_INFO * info )
+{
+ /* it's the same thing */
+ return get_num_records_hook( info );
+}
+
+/********************************************************************
********************************************************************/
static NTSTATUS elog_open( pipes_struct * p, const char *logname, POLICY_HND *hnd )
@@ -199,6 +239,15 @@ static NTSTATUS elog_open( pipes_struct * p, const char *logname, POLICY_HND *hn
return NT_STATUS_NO_MEMORY;
}
+ /* set the initial current_record pointer */
+
+ if ( !get_oldest_entry_hook( elog ) ) {
+ DEBUG(3,("elog_open: Successfully opened eventlog but can't "
+ "get any information on internal records!\n"));
+ }
+
+ elog->current_record = elog->oldest_entry;
+
return NT_STATUS_OK;
}
@@ -398,45 +447,6 @@ static BOOL sync_eventlog_params( EVENTLOG_INFO *info )
}
/********************************************************************
-********************************************************************/
-
-static BOOL get_num_records_hook( EVENTLOG_INFO * info )
-{
- int next_record;
- int oldest_record;
-
- if ( !info->tdb ) {
- DEBUG( 10, ( "No open tdb for %s\n", info->logname ) );
- return False;
- }
-
- /* lock the tdb since we have to get 2 records */
-
- tdb_lock_bystring( info->tdb, EVT_NEXT_RECORD, 1 );
- next_record = tdb_fetch_int32( info->tdb, EVT_NEXT_RECORD);
- oldest_record = tdb_fetch_int32( info->tdb, EVT_OLDEST_ENTRY);
- tdb_unlock_bystring( info->tdb, EVT_NEXT_RECORD);
-
- DEBUG( 8,
- ( "Oldest Record %d; Next Record %d\n", oldest_record,
- next_record ) );
-
- info->num_records = ( next_record - oldest_record );
- info->oldest_entry = oldest_record;
-
- return True;
-}
-
-/********************************************************************
- ********************************************************************/
-
-static BOOL get_oldest_entry_hook( EVENTLOG_INFO * info )
-{
- /* it's the same thing */
- return get_num_records_hook( info );
-}
-
-/********************************************************************
********************************************************************/
static Eventlog_entry *read_package_entry( prs_struct * ps,
@@ -661,71 +671,85 @@ NTSTATUS _eventlog_read_eventlog( pipes_struct * p,
{
EVENTLOG_INFO *info = find_eventlog_info_by_hnd( p, &q_u->handle );
Eventlog_entry entry, *ee_new;
-
uint32 num_records_read = 0;
prs_struct *ps;
int bytes_left, record_number;
- TDB_CONTEXT *tdb;
-
info->flags = q_u->flags;
ps = &p->out_data.rdata;
+ uint32 elog_read_type, elog_read_dir;
bytes_left = q_u->max_read_size;
- tdb = info->tdb;
- if ( !tdb ) {
+
+ if ( !info->tdb )
return NT_STATUS_ACCESS_DENIED;
+
+ /* check for valid flags. Can't use the sequential and seek flags together */
+
+ elog_read_type = q_u->flags & (EVENTLOG_SEQUENTIAL_READ|EVENTLOG_SEEK_READ);
+ elog_read_dir = q_u->flags & (EVENTLOG_FORWARDS_READ|EVENTLOG_BACKWARDS_READ);
+
+ if ( elog_read_type == (EVENTLOG_SEQUENTIAL_READ|EVENTLOG_SEEK_READ)
+ || elog_read_dir == (EVENTLOG_FORWARDS_READ|EVENTLOG_BACKWARDS_READ) )
+ {
+ DEBUG(3,("_eventlog_read_eventlog: Invalid flags [0x%x] for ReadEventLog\n", q_u->flags));
+ return NT_STATUS_INVALID_PARAMETER;
}
- /* DEBUG(8,("Bytes left is %d\n",bytes_left)); */
+ /* a sequential read should ignore the offset */
- record_number = q_u->offset;
+ if ( elog_read_type & EVENTLOG_SEQUENTIAL_READ )
+ record_number = info->current_record;
+ else
+ record_number = q_u->offset;
while ( bytes_left > 0 ) {
- if ( get_eventlog_record
- ( ps, tdb, record_number, &entry ) ) {
- DEBUG( 8,
- ( "Retrieved record %d\n", record_number ) );
+
+ /* assume that when the record fetch fails, that we are done */
+
+ if ( !get_eventlog_record ( ps, info->tdb, record_number, &entry ) )
+ break;
+
+ DEBUG( 8, ( "Retrieved record %d\n", record_number ) );
- /* Now see if there is enough room to add */
- ee_new = read_package_entry( ps, q_u, r_u,&entry );
- if ( !ee_new )
- return NT_STATUS_NO_MEMORY;
-
- if ( r_u->num_bytes_in_resp + ee_new->record.length >
- q_u->max_read_size ) {
- r_u->bytes_in_next_record =
- ee_new->record.length;
-
- /* response would be too big to fit in client-size buffer */
+ /* Now see if there is enough room to add */
+
+ if ( !(ee_new = read_package_entry( ps, q_u, r_u,&entry )) )
+ return NT_STATUS_NO_MEMORY;
+
+ if ( r_u->num_bytes_in_resp + ee_new->record.length > q_u->max_read_size ) {
+ r_u->bytes_in_next_record = ee_new->record.length;
+
+ /* response would be too big to fit in client-size buffer */
- bytes_left = 0;
- break;
- }
+ bytes_left = 0;
+ break;
+ }
- add_record_to_resp( r_u, ee_new );
- bytes_left -= ee_new->record.length;
- ZERO_STRUCT( entry );
- num_records_read =
- r_u->num_records - num_records_read;
+ add_record_to_resp( r_u, ee_new );
+ bytes_left -= ee_new->record.length;
+ ZERO_STRUCT( entry );
+ num_records_read = r_u->num_records - num_records_read;
- DEBUG( 10,
- ( "_eventlog_read_eventlog: read [%d] records for a total of [%d] records using [%d] bytes out of a max of [%d].\n",
- num_records_read, r_u->num_records,
- r_u->num_bytes_in_resp,
- q_u->max_read_size ) );
- } else {
- DEBUG( 8, ( "get_eventlog_record returned NULL\n" ) );
- return NT_STATUS_NO_MEMORY; /* wrong error - but return one anyway */
- }
-
+ DEBUG( 10, ( "_eventlog_read_eventlog: read [%d] records for a total "
+ "of [%d] records using [%d] bytes out of a max of [%d].\n",
+ num_records_read, r_u->num_records,
+ r_u->num_bytes_in_resp,
+ q_u->max_read_size ) );
if ( info->flags & EVENTLOG_FORWARDS_READ )
record_number++;
else
record_number--;
+
+ /* update the eventlog record pointer */
+
+ info->current_record = record_number;
}
-
- return NT_STATUS_OK;
+
+ /* crazy by WinXP uses NT_STATUS_BUFFER_TOO_SMALL to
+ say when there are no more records */
+
+ return (num_records_read ? NT_STATUS_OK : NT_STATUS_BUFFER_TOO_SMALL);
}
/********************************************************************