Пример #1
0
static bool get_num_records_hook( EVENTLOG_INFO * info )
{
	int next_record;
	int oldest_record;

	if ( !info->etdb ) {
		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_with_timeout( ELOG_TDB_CTX(info->etdb), EVT_NEXT_RECORD, 1 );
	next_record = tdb_fetch_int32( ELOG_TDB_CTX(info->etdb), EVT_NEXT_RECORD);
	oldest_record = tdb_fetch_int32( ELOG_TDB_CTX(info->etdb), EVT_OLDEST_ENTRY);
	tdb_unlock_bystring( ELOG_TDB_CTX(info->etdb), 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;
}
Пример #2
0
PyObject *py_tdb_hnd_lock_bystring(PyObject *self, PyObject *args)
{
	tdb_hnd_object *obj = (tdb_hnd_object *)self;
	int result, timeout = 30;
	char *s;

        if (!obj->tdb) {
		PyErr_SetString(py_tdb_error, "tdb object has been closed"); 
		return NULL;
        }	

	if (!PyArg_ParseTuple(args, "s|i", &s, &timeout))
		return NULL;

	result = tdb_lock_bystring_with_timeout(obj->tdb, s, timeout);

	return PyInt_FromLong(result != -1);
}
Пример #3
0
struct named_mutex *grab_named_mutex(TALLOC_CTX *mem_ctx, const char *name,
                                     int timeout)
{
    struct named_mutex *result;

    result = talloc(mem_ctx, struct named_mutex);
    if (result == NULL) {
        DEBUG(0, ("talloc failed\n"));
        return NULL;
    }

    result->name = talloc_strdup(result, name);
    if (result->name == NULL) {
        DEBUG(0, ("talloc failed\n"));
        TALLOC_FREE(result);
        return NULL;
    }

    result->tdb = tdb_wrap_open(result, lock_path("mutex.tdb"), 0,
                                TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
    if (result->tdb == NULL) {
        DEBUG(1, ("Could not open mutex.tdb: %s\n",
                  strerror(errno)));
        TALLOC_FREE(result);
        return NULL;
    }

    if (tdb_lock_bystring_with_timeout(result->tdb->tdb, name,
                                       timeout) == -1) {
        DEBUG(1, ("Could not get the lock for %s\n", name));
        TALLOC_FREE(result);
        return NULL;
    }

    talloc_set_destructor(result, unlock_named_mutex);
    return result;
}
Пример #4
0
NTSTATUS evlog_push_record_tdb(TALLOC_CTX *mem_ctx,
			       TDB_CONTEXT *tdb,
			       struct eventlog_Record_tdb *r,
			       uint32_t *record_number)
{
	TDB_DATA kbuf, ebuf;
	DATA_BLOB blob;
	enum ndr_err_code ndr_err;
	int ret;

	if (!r) {
		return NT_STATUS_INVALID_PARAMETER;
	}

	if (!can_write_to_eventlog(tdb, r->size)) {
		return NT_STATUS_EVENTLOG_CANT_START;
	}

	/* need to read the record number and insert it into the entry here */

	/* lock */
	ret = tdb_lock_bystring_with_timeout(tdb, EVT_NEXT_RECORD, 1);
	if (ret == -1) {
		return NT_STATUS_LOCK_NOT_GRANTED;
	}

	/* read */
	r->record_number = tdb_fetch_int32(tdb, EVT_NEXT_RECORD);

	ndr_err = ndr_push_struct_blob(&blob, mem_ctx, NULL, r,
		      (ndr_push_flags_fn_t)ndr_push_eventlog_Record_tdb);
	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
		tdb_unlock_bystring(tdb, EVT_NEXT_RECORD);
		return ndr_map_error2ntstatus(ndr_err);
	}

	/* increment the record count */

	kbuf.dsize = sizeof(int32_t);
	kbuf.dptr = (uint8_t *)&r->record_number;

	ebuf.dsize = blob.length;
	ebuf.dptr  = blob.data;

	ret = tdb_store(tdb, kbuf, ebuf, 0);
	if (ret == -1) {
		tdb_unlock_bystring(tdb, EVT_NEXT_RECORD);
		return NT_STATUS_EVENTLOG_FILE_CORRUPT;
	}

	ret = tdb_store_int32(tdb, EVT_NEXT_RECORD, r->record_number + 1);
	if (ret == -1) {
		tdb_unlock_bystring(tdb, EVT_NEXT_RECORD);
		return NT_STATUS_EVENTLOG_FILE_CORRUPT;
	}
	tdb_unlock_bystring(tdb, EVT_NEXT_RECORD);

	if (record_number) {
		*record_number = r->record_number;
	}

	return NT_STATUS_OK;
}
Пример #5
0
static bool make_way_for_eventlogs( TDB_CONTEXT * the_tdb, int32_t needed,
				    bool whack_by_date )
{
	int32_t start_record, i, new_start;
	int32_t end_record;
	int32_t reclen, tresv1, trecnum, timegen, timewr;
	int nbytes, len, Retention, MaxSize;
	TDB_DATA key, ret;
	time_t current_time, exp_time;

	/* discard some eventlogs */

	/* read eventlogs from oldest_entry -- there can't be any discontinuity in recnos,
	   although records not necessarily guaranteed to have successive times */
	/* */

	/* lock */
	tdb_lock_bystring_with_timeout( the_tdb, EVT_NEXT_RECORD, 1 );
	/* read */
	end_record = tdb_fetch_int32( the_tdb, EVT_NEXT_RECORD );
	start_record = tdb_fetch_int32( the_tdb, EVT_OLDEST_ENTRY );
	Retention = tdb_fetch_int32( the_tdb, EVT_RETENTION );
	MaxSize = tdb_fetch_int32( the_tdb, EVT_MAXSIZE );

	time( &current_time );

	/* calculate ... */
	exp_time = current_time - Retention;	/* discard older than exp_time */

	/* todo - check for sanity in next_record */
	nbytes = 0;

	DEBUG( 3,
	       ( "MaxSize [%d] Retention [%d] Current Time [%u]  exp_time [%u]\n",
		 MaxSize, Retention, (unsigned int)current_time, (unsigned int)exp_time ) );
	DEBUG( 3,
	       ( "Start Record [%u] End Record [%u]\n",
		(unsigned int)start_record,
		(unsigned int)end_record ));

	for ( i = start_record; i < end_record; i++ ) {
		/* read a record, add the amt to nbytes */
		key.dsize = sizeof(int32_t);
		key.dptr = (unsigned char *)&i;
		ret = tdb_fetch( the_tdb, key );
		if ( ret.dsize == 0 ) {
			DEBUG( 8,
			       ( "Can't find a record for the key, record [%d]\n",
				 i ) );
			tdb_unlock_bystring( the_tdb, EVT_NEXT_RECORD );
			return False;
		}
		nbytes += ret.dsize;	/* note this includes overhead */

		len = tdb_unpack( ret.dptr, ret.dsize, "ddddd", &reclen,
				  &tresv1, &trecnum, &timegen, &timewr );
		if (len == -1) {
			DEBUG( 10,("make_way_for_eventlogs: tdb_unpack failed.\n"));
			tdb_unlock_bystring( the_tdb, EVT_NEXT_RECORD );
			SAFE_FREE( ret.dptr );
			return False;
		}

		DEBUG( 8,
		       ( "read record %u, record size is [%d], total so far [%d]\n",
			 (unsigned int)i, reclen, nbytes ) );

		SAFE_FREE( ret.dptr );

		/* note that other servers may just stop writing records when the size limit
		   is reached, and there are no records older than 'retention'. This doesn't
		   like a very useful thing to do, so instead we whack (as in sleeps with the
		   fishes) just enough records to fit the what we need.  This behavior could
		   be changed to 'match', if the need arises. */

		if ( !whack_by_date && ( nbytes >= needed ) )
			break;	/* done */
		if ( whack_by_date && ( timegen >= exp_time ) )
			break;	/* done */
	}

	DEBUG( 3,
	       ( "nbytes [%d] needed [%d] start_record is [%u], should be set to [%u]\n",
		 nbytes, needed, (unsigned int)start_record, (unsigned int)i ) );
	/* todo - remove eventlog entries here and set starting record to start_record... */
	new_start = i;
	if ( start_record != new_start ) {
		for ( i = start_record; i < new_start; i++ ) {
			key.dsize = sizeof(int32_t);
			key.dptr = (unsigned char *)&i;
			tdb_delete( the_tdb, key );
		}

		tdb_store_int32( the_tdb, EVT_OLDEST_ENTRY, new_start );
	}
	tdb_unlock_bystring( the_tdb, EVT_NEXT_RECORD );
	return True;
}