mirror of
https://github.com/samba-team/samba.git
synced 2025-01-26 10:04:02 +03:00
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)
This commit is contained in:
parent
05f7bec525
commit
70cac98b6e
@ -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 */
|
||||
|
||||
|
@ -28,6 +28,7 @@
|
||||
typedef struct {
|
||||
char *logname;
|
||||
TDB_CONTEXT *tdb;
|
||||
uint32 current_record;
|
||||
uint32 num_records;
|
||||
uint32 oldest_entry;
|
||||
uint32 flags;
|
||||
@ -130,6 +131,45 @@ static BOOL elog_validate_logname( const char *name )
|
||||
return False;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
********************************************************************/
|
||||
|
||||
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 );
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
********************************************************************/
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -397,45 +446,6 @@ static BOOL sync_eventlog_params( EVENTLOG_INFO *info )
|
||||
return True;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
********************************************************************/
|
||||
|
||||
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 );
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
********************************************************************/
|
||||
|
||||
@ -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;
|
||||
/* Now see if there is enough room to add */
|
||||
|
||||
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 */
|
||||
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;
|
||||
}
|
||||
|
||||
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 */
|
||||
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;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
|
Loading…
x
Reference in New Issue
Block a user