mirror of
https://github.com/lwip-tcpip/lwip.git
synced 2025-02-22 03:40:48 +00:00
Removed TDB code, which we cannot port, because it needs a filesystem.
About multilink support. Multilink uses Samba TDB (Trivial Database Library), which we cannot port, for the above reason. We have to choose between doing a memory-shared TDB-clone, or dropping multilink support at all.
This commit is contained in:
parent
1a1deb5d58
commit
1d7efce0dc
@ -30,6 +30,17 @@
|
||||
|
||||
#include "lwip/opt.h"
|
||||
|
||||
/* Multilink support
|
||||
*
|
||||
* Multilink uses Samba TDB (Trivial Database Library), which
|
||||
* we cannot port, because it needs a filesystem.
|
||||
*
|
||||
* We have to choose between doing a memory-shared TDB-clone,
|
||||
* or dropping multilink support at all.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_MULTILINK
|
||||
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
@ -593,3 +604,4 @@ str_to_epdisc(ep, str)
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif /* HAVE_MULTILINK */
|
||||
|
@ -109,10 +109,6 @@
|
||||
#include "ecp.h"
|
||||
#include "pathnames.h"
|
||||
|
||||
#ifdef USE_TDB
|
||||
#include "tdb.h"
|
||||
#endif
|
||||
|
||||
#if CBCP_SUPPORT
|
||||
#include "cbcp.h"
|
||||
#endif
|
||||
@ -153,10 +149,6 @@ int ppp_session_number; /* Session number, for channels with such a
|
||||
concept (eg PPPoE) */
|
||||
int childwait_done; /* have timed out waiting for children */
|
||||
|
||||
#ifdef USE_TDB
|
||||
TDB_CONTEXT *pppdb; /* database for storing status etc. */
|
||||
#endif
|
||||
|
||||
char db_key[32];
|
||||
|
||||
int (*holdoff_hook) __P((void)) = NULL;
|
||||
@ -247,13 +239,6 @@ static void forget_child __P((int pid, int status));
|
||||
static int reap_kids __P((void));
|
||||
static void childwait_end __P((void *));
|
||||
|
||||
#ifdef USE_TDB
|
||||
static void update_db_entry __P((void));
|
||||
static void add_db_key __P((const char *));
|
||||
static void delete_db_key __P((const char *));
|
||||
static void cleanup_db __P((void));
|
||||
#endif
|
||||
|
||||
static void handle_events __P((void));
|
||||
void print_link_stats __P((void));
|
||||
|
||||
@ -430,20 +415,6 @@ int ppp_oldmain() {
|
||||
*/
|
||||
linux_sys_init();
|
||||
|
||||
#ifdef USE_TDB
|
||||
pppdb = tdb_open(_PATH_PPPDB, 0, 0, O_RDWR|O_CREAT, 0644);
|
||||
if (pppdb != NULL) {
|
||||
slprintf(db_key, sizeof(db_key), "pppd%d", getpid());
|
||||
update_db_entry();
|
||||
} else {
|
||||
warn("Warning: couldn't open ppp database %s", _PATH_PPPDB);
|
||||
if (multilink) {
|
||||
warn("Warning: disabling multilink");
|
||||
multilink = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Detach ourselves from the terminal, if required,
|
||||
* and identify who is running us.
|
||||
@ -1184,12 +1155,6 @@ cleanup()
|
||||
if (the_channel->cleanup)
|
||||
(*the_channel->cleanup)();
|
||||
remove_pidfiles();
|
||||
|
||||
#ifdef USE_TDB
|
||||
if (pppdb != NULL)
|
||||
cleanup_db();
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
@ -1566,9 +1531,6 @@ safe_fork(int infd, int outfd, int errfd)
|
||||
|
||||
/* Executing in the child */
|
||||
sys_close();
|
||||
#ifdef USE_TDB
|
||||
tdb_close(pppdb);
|
||||
#endif
|
||||
|
||||
/* make sure infd, outfd and errfd won't get tromped on below */
|
||||
if (infd == 1 || infd == 2)
|
||||
@ -1864,17 +1826,8 @@ script_setenv(var, value, iskey)
|
||||
if (script_env != 0) {
|
||||
for (i = 0; (p = script_env[i]) != 0; ++i) {
|
||||
if (strncmp(p, var, varl) == 0 && p[varl] == '=') {
|
||||
#ifdef USE_TDB
|
||||
if (p[-1] && pppdb != NULL)
|
||||
delete_db_key(p);
|
||||
#endif
|
||||
free(p-1);
|
||||
script_env[i] = newstring;
|
||||
#ifdef USE_TDB
|
||||
if (iskey && pppdb != NULL)
|
||||
add_db_key(newstring);
|
||||
update_db_entry();
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -1900,14 +1853,6 @@ script_setenv(var, value, iskey)
|
||||
|
||||
script_env[i] = newstring;
|
||||
script_env[i+1] = 0;
|
||||
|
||||
#ifdef USE_TDB
|
||||
if (pppdb != NULL) {
|
||||
if (iskey)
|
||||
add_db_key(newstring);
|
||||
update_db_entry();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1926,138 +1871,10 @@ script_unsetenv(var)
|
||||
return;
|
||||
for (i = 0; (p = script_env[i]) != 0; ++i) {
|
||||
if (strncmp(p, var, vl) == 0 && p[vl] == '=') {
|
||||
#ifdef USE_TDB
|
||||
if (p[-1] && pppdb != NULL)
|
||||
delete_db_key(p);
|
||||
#endif
|
||||
free(p-1);
|
||||
while ((script_env[i] = script_env[i+1]) != 0)
|
||||
++i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#ifdef USE_TDB
|
||||
if (pppdb != NULL)
|
||||
update_db_entry();
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Any arbitrary string used as a key for locking the database.
|
||||
* It doesn't matter what it is as long as all pppds use the same string.
|
||||
*/
|
||||
#define PPPD_LOCK_KEY "pppd lock"
|
||||
|
||||
/*
|
||||
* lock_db - get an exclusive lock on the TDB database.
|
||||
* Used to ensure atomicity of various lookup/modify operations.
|
||||
*/
|
||||
void lock_db()
|
||||
{
|
||||
#ifdef USE_TDB
|
||||
TDB_DATA key;
|
||||
|
||||
key.dptr = PPPD_LOCK_KEY;
|
||||
key.dsize = strlen(key.dptr);
|
||||
tdb_chainlock(pppdb, key);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* unlock_db - remove the exclusive lock obtained by lock_db.
|
||||
*/
|
||||
void unlock_db()
|
||||
{
|
||||
#ifdef USE_TDB
|
||||
TDB_DATA key;
|
||||
|
||||
key.dptr = PPPD_LOCK_KEY;
|
||||
key.dsize = strlen(key.dptr);
|
||||
tdb_chainunlock(pppdb, key);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef USE_TDB
|
||||
/*
|
||||
* update_db_entry - update our entry in the database.
|
||||
*/
|
||||
static void
|
||||
update_db_entry()
|
||||
{
|
||||
TDB_DATA key, dbuf;
|
||||
int vlen, i;
|
||||
char *p, *q, *vbuf;
|
||||
|
||||
if (script_env == NULL)
|
||||
return;
|
||||
vlen = 0;
|
||||
for (i = 0; (p = script_env[i]) != 0; ++i)
|
||||
vlen += strlen(p) + 1;
|
||||
vbuf = malloc(vlen + 1);
|
||||
if (vbuf == 0)
|
||||
novm("database entry");
|
||||
q = vbuf;
|
||||
for (i = 0; (p = script_env[i]) != 0; ++i)
|
||||
q += slprintf(q, vbuf + vlen - q, "%s;", p);
|
||||
|
||||
key.dptr = db_key;
|
||||
key.dsize = strlen(db_key);
|
||||
dbuf.dptr = vbuf;
|
||||
dbuf.dsize = vlen;
|
||||
if (tdb_store(pppdb, key, dbuf, TDB_REPLACE))
|
||||
error("tdb_store failed: %s", tdb_errorstr(pppdb));
|
||||
|
||||
if (vbuf)
|
||||
free(vbuf);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* add_db_key - add a key that we can use to look up our database entry.
|
||||
*/
|
||||
static void
|
||||
add_db_key(str)
|
||||
const char *str;
|
||||
{
|
||||
TDB_DATA key, dbuf;
|
||||
|
||||
key.dptr = (char *) str;
|
||||
key.dsize = strlen(str);
|
||||
dbuf.dptr = db_key;
|
||||
dbuf.dsize = strlen(db_key);
|
||||
if (tdb_store(pppdb, key, dbuf, TDB_REPLACE))
|
||||
error("tdb_store key failed: %s", tdb_errorstr(pppdb));
|
||||
}
|
||||
|
||||
/*
|
||||
* delete_db_key - delete a key for looking up our database entry.
|
||||
*/
|
||||
static void
|
||||
delete_db_key(str)
|
||||
const char *str;
|
||||
{
|
||||
TDB_DATA key;
|
||||
|
||||
key.dptr = (char *) str;
|
||||
key.dsize = strlen(str);
|
||||
tdb_delete(pppdb, key);
|
||||
}
|
||||
|
||||
/*
|
||||
* cleanup_db - delete all the entries we put in the database.
|
||||
*/
|
||||
static void
|
||||
cleanup_db()
|
||||
{
|
||||
TDB_DATA key;
|
||||
int i;
|
||||
char *p;
|
||||
|
||||
key.dptr = db_key;
|
||||
key.dsize = strlen(db_key);
|
||||
tdb_delete(pppdb, key);
|
||||
for (i = 0; (p = script_env[i]) != 0; ++i)
|
||||
if (p[-1])
|
||||
delete_db_key(p);
|
||||
}
|
||||
#endif /* USE_TDB */
|
||||
|
@ -1,476 +0,0 @@
|
||||
/*
|
||||
Unix SMB/CIFS implementation.
|
||||
|
||||
trivial database library
|
||||
|
||||
Copyright (C) Anton Blanchard 2001
|
||||
|
||||
** NOTE! The following LGPL license applies to the tdb
|
||||
** library. This does NOT imply that all of Samba is released
|
||||
** under the LGPL
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "lwip/opt.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <sys/stat.h>
|
||||
#include <time.h>
|
||||
#include <signal.h>
|
||||
#include "tdb.h"
|
||||
#include "spinlock.h"
|
||||
|
||||
#define DEBUG
|
||||
|
||||
#ifdef USE_SPINLOCKS
|
||||
|
||||
/*
|
||||
* ARCH SPECIFIC
|
||||
*/
|
||||
|
||||
#if defined(SPARC_SPINLOCKS)
|
||||
|
||||
static inline int __spin_trylock(spinlock_t *lock)
|
||||
{
|
||||
unsigned int result;
|
||||
|
||||
asm volatile("ldstub [%1], %0"
|
||||
: "=r" (result)
|
||||
: "r" (lock)
|
||||
: "memory");
|
||||
|
||||
return (result == 0) ? 0 : EBUSY;
|
||||
}
|
||||
|
||||
static inline void __spin_unlock(spinlock_t *lock)
|
||||
{
|
||||
asm volatile("":::"memory");
|
||||
*lock = 0;
|
||||
}
|
||||
|
||||
static inline void __spin_lock_init(spinlock_t *lock)
|
||||
{
|
||||
*lock = 0;
|
||||
}
|
||||
|
||||
static inline int __spin_is_locked(spinlock_t *lock)
|
||||
{
|
||||
return (*lock != 0);
|
||||
}
|
||||
|
||||
#elif defined(POWERPC_SPINLOCKS)
|
||||
|
||||
static inline int __spin_trylock(spinlock_t *lock)
|
||||
{
|
||||
unsigned int result;
|
||||
|
||||
__asm__ __volatile__(
|
||||
"1: lwarx %0,0,%1\n\
|
||||
cmpwi 0,%0,0\n\
|
||||
li %0,0\n\
|
||||
bne- 2f\n\
|
||||
li %0,1\n\
|
||||
stwcx. %0,0,%1\n\
|
||||
bne- 1b\n\
|
||||
isync\n\
|
||||
2:" : "=&r"(result)
|
||||
: "r"(lock)
|
||||
: "cr0", "memory");
|
||||
|
||||
return (result == 1) ? 0 : EBUSY;
|
||||
}
|
||||
|
||||
static inline void __spin_unlock(spinlock_t *lock)
|
||||
{
|
||||
asm volatile("eieio":::"memory");
|
||||
*lock = 0;
|
||||
}
|
||||
|
||||
static inline void __spin_lock_init(spinlock_t *lock)
|
||||
{
|
||||
*lock = 0;
|
||||
}
|
||||
|
||||
static inline int __spin_is_locked(spinlock_t *lock)
|
||||
{
|
||||
return (*lock != 0);
|
||||
}
|
||||
|
||||
#elif defined(INTEL_SPINLOCKS)
|
||||
|
||||
static inline int __spin_trylock(spinlock_t *lock)
|
||||
{
|
||||
int oldval;
|
||||
|
||||
asm volatile("xchgl %0,%1"
|
||||
: "=r" (oldval), "=m" (*lock)
|
||||
: "0" (0)
|
||||
: "memory");
|
||||
|
||||
return oldval > 0 ? 0 : EBUSY;
|
||||
}
|
||||
|
||||
static inline void __spin_unlock(spinlock_t *lock)
|
||||
{
|
||||
asm volatile("":::"memory");
|
||||
*lock = 1;
|
||||
}
|
||||
|
||||
static inline void __spin_lock_init(spinlock_t *lock)
|
||||
{
|
||||
*lock = 1;
|
||||
}
|
||||
|
||||
static inline int __spin_is_locked(spinlock_t *lock)
|
||||
{
|
||||
return (*lock != 1);
|
||||
}
|
||||
|
||||
#elif defined(MIPS_SPINLOCKS) && defined(sgi) && (_COMPILER_VERSION >= 730)
|
||||
|
||||
/* Implement spinlocks on IRIX using the MIPSPro atomic fetch operations. See
|
||||
* sync(3) for the details of the intrinsic operations.
|
||||
*
|
||||
* "sgi" and "_COMPILER_VERSION" are always defined by MIPSPro.
|
||||
*/
|
||||
|
||||
#ifdef STANDALONE
|
||||
|
||||
/* MIPSPro 7.3 has "__inline" as an extension, but not "inline. */
|
||||
#define inline __inline
|
||||
|
||||
#endif /* STANDALONE */
|
||||
|
||||
/* Returns 0 if the lock is acquired, EBUSY otherwise. */
|
||||
static inline int __spin_trylock(spinlock_t *lock)
|
||||
{
|
||||
unsigned int val;
|
||||
val = __lock_test_and_set(lock, 1);
|
||||
return val == 0 ? 0 : EBUSY;
|
||||
}
|
||||
|
||||
static inline void __spin_unlock(spinlock_t *lock)
|
||||
{
|
||||
__lock_release(lock);
|
||||
}
|
||||
|
||||
static inline void __spin_lock_init(spinlock_t *lock)
|
||||
{
|
||||
__lock_release(lock);
|
||||
}
|
||||
|
||||
/* Returns 1 if the lock is held, 0 otherwise. */
|
||||
static inline int __spin_is_locked(spinlock_t *lock)
|
||||
{
|
||||
unsigned int val;
|
||||
val = __add_and_fetch(lock, 0);
|
||||
return val;
|
||||
}
|
||||
|
||||
#elif defined(MIPS_SPINLOCKS)
|
||||
|
||||
static inline unsigned int load_linked(unsigned long addr)
|
||||
{
|
||||
unsigned int res;
|
||||
|
||||
__asm__ __volatile__("ll\t%0,(%1)"
|
||||
: "=r" (res)
|
||||
: "r" (addr));
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static inline unsigned int store_conditional(unsigned long addr, unsigned int value)
|
||||
{
|
||||
unsigned int res;
|
||||
|
||||
__asm__ __volatile__("sc\t%0,(%2)"
|
||||
: "=r" (res)
|
||||
: "0" (value), "r" (addr));
|
||||
return res;
|
||||
}
|
||||
|
||||
static inline int __spin_trylock(spinlock_t *lock)
|
||||
{
|
||||
unsigned int mw;
|
||||
|
||||
do {
|
||||
mw = load_linked(lock);
|
||||
if (mw)
|
||||
return EBUSY;
|
||||
} while (!store_conditional(lock, 1));
|
||||
|
||||
asm volatile("":::"memory");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void __spin_unlock(spinlock_t *lock)
|
||||
{
|
||||
asm volatile("":::"memory");
|
||||
*lock = 0;
|
||||
}
|
||||
|
||||
static inline void __spin_lock_init(spinlock_t *lock)
|
||||
{
|
||||
*lock = 0;
|
||||
}
|
||||
|
||||
static inline int __spin_is_locked(spinlock_t *lock)
|
||||
{
|
||||
return (*lock != 0);
|
||||
}
|
||||
|
||||
#else
|
||||
#error Need to implement spinlock code in spinlock.c
|
||||
#endif
|
||||
|
||||
/*
|
||||
* OS SPECIFIC
|
||||
*/
|
||||
|
||||
static void yield_cpu(void)
|
||||
{
|
||||
struct timespec tm;
|
||||
|
||||
#ifdef USE_SCHED_YIELD
|
||||
sched_yield();
|
||||
#else
|
||||
/* Linux will busy loop for delays < 2ms on real time tasks */
|
||||
tm.tv_sec = 0;
|
||||
tm.tv_nsec = 2000000L + 1;
|
||||
nanosleep(&tm, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
static int this_is_smp(void)
|
||||
{
|
||||
#if defined(HAVE_SYSCONF) && defined(SYSCONF_SC_NPROC_ONLN)
|
||||
return (sysconf(_SC_NPROC_ONLN) > 1) ? 1 : 0;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* GENERIC
|
||||
*/
|
||||
|
||||
static int smp_machine = 0;
|
||||
|
||||
static inline void __spin_lock(spinlock_t *lock)
|
||||
{
|
||||
int ntries = 0;
|
||||
|
||||
while(__spin_trylock(lock)) {
|
||||
while(__spin_is_locked(lock)) {
|
||||
if (smp_machine && ntries++ < MAX_BUSY_LOOPS)
|
||||
continue;
|
||||
yield_cpu();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void __read_lock(tdb_rwlock_t *rwlock)
|
||||
{
|
||||
int ntries = 0;
|
||||
|
||||
while(1) {
|
||||
__spin_lock(&rwlock->lock);
|
||||
|
||||
if (!(rwlock->count & RWLOCK_BIAS)) {
|
||||
rwlock->count++;
|
||||
__spin_unlock(&rwlock->lock);
|
||||
return;
|
||||
}
|
||||
|
||||
__spin_unlock(&rwlock->lock);
|
||||
|
||||
while(rwlock->count & RWLOCK_BIAS) {
|
||||
if (smp_machine && ntries++ < MAX_BUSY_LOOPS)
|
||||
continue;
|
||||
yield_cpu();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void __write_lock(tdb_rwlock_t *rwlock)
|
||||
{
|
||||
int ntries = 0;
|
||||
|
||||
while(1) {
|
||||
__spin_lock(&rwlock->lock);
|
||||
|
||||
if (rwlock->count == 0) {
|
||||
rwlock->count |= RWLOCK_BIAS;
|
||||
__spin_unlock(&rwlock->lock);
|
||||
return;
|
||||
}
|
||||
|
||||
__spin_unlock(&rwlock->lock);
|
||||
|
||||
while(rwlock->count != 0) {
|
||||
if (smp_machine && ntries++ < MAX_BUSY_LOOPS)
|
||||
continue;
|
||||
yield_cpu();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void __write_unlock(tdb_rwlock_t *rwlock)
|
||||
{
|
||||
__spin_lock(&rwlock->lock);
|
||||
|
||||
#ifdef DEBUG
|
||||
if (!(rwlock->count & RWLOCK_BIAS))
|
||||
fprintf(stderr, "bug: write_unlock\n");
|
||||
#endif
|
||||
|
||||
rwlock->count &= ~RWLOCK_BIAS;
|
||||
__spin_unlock(&rwlock->lock);
|
||||
}
|
||||
|
||||
static void __read_unlock(tdb_rwlock_t *rwlock)
|
||||
{
|
||||
__spin_lock(&rwlock->lock);
|
||||
|
||||
#ifdef DEBUG
|
||||
if (!rwlock->count)
|
||||
fprintf(stderr, "bug: read_unlock\n");
|
||||
|
||||
if (rwlock->count & RWLOCK_BIAS)
|
||||
fprintf(stderr, "bug: read_unlock\n");
|
||||
#endif
|
||||
|
||||
rwlock->count--;
|
||||
__spin_unlock(&rwlock->lock);
|
||||
}
|
||||
|
||||
/* TDB SPECIFIC */
|
||||
|
||||
/* lock a list in the database. list -1 is the alloc list */
|
||||
int tdb_spinlock(TDB_CONTEXT *tdb, int list, int rw_type)
|
||||
{
|
||||
tdb_rwlock_t *rwlocks;
|
||||
|
||||
if (!tdb->map_ptr) return -1;
|
||||
rwlocks = (tdb_rwlock_t *)((char *)tdb->map_ptr + tdb->header.rwlocks);
|
||||
|
||||
switch(rw_type) {
|
||||
case F_RDLCK:
|
||||
__read_lock(&rwlocks[list+1]);
|
||||
break;
|
||||
|
||||
case F_WRLCK:
|
||||
__write_lock(&rwlocks[list+1]);
|
||||
break;
|
||||
|
||||
default:
|
||||
return TDB_ERRCODE(TDB_ERR_LOCK, -1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* unlock the database. */
|
||||
int tdb_spinunlock(TDB_CONTEXT *tdb, int list, int rw_type)
|
||||
{
|
||||
tdb_rwlock_t *rwlocks;
|
||||
|
||||
if (!tdb->map_ptr) return -1;
|
||||
rwlocks = (tdb_rwlock_t *)((char *)tdb->map_ptr + tdb->header.rwlocks);
|
||||
|
||||
switch(rw_type) {
|
||||
case F_RDLCK:
|
||||
__read_unlock(&rwlocks[list+1]);
|
||||
break;
|
||||
|
||||
case F_WRLCK:
|
||||
__write_unlock(&rwlocks[list+1]);
|
||||
break;
|
||||
|
||||
default:
|
||||
return TDB_ERRCODE(TDB_ERR_LOCK, -1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tdb_create_rwlocks(int fd, unsigned int hash_size)
|
||||
{
|
||||
unsigned size, i;
|
||||
tdb_rwlock_t *rwlocks;
|
||||
|
||||
size = TDB_SPINLOCK_SIZE(hash_size);
|
||||
rwlocks = malloc(size);
|
||||
if (!rwlocks)
|
||||
return -1;
|
||||
|
||||
for(i = 0; i < hash_size+1; i++) {
|
||||
__spin_lock_init(&rwlocks[i].lock);
|
||||
rwlocks[i].count = 0;
|
||||
}
|
||||
|
||||
/* Write it out (appending to end) */
|
||||
if (write(fd, rwlocks, size) != size) {
|
||||
free(rwlocks);
|
||||
return -1;
|
||||
}
|
||||
smp_machine = this_is_smp();
|
||||
free(rwlocks);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tdb_clear_spinlocks(TDB_CONTEXT *tdb)
|
||||
{
|
||||
tdb_rwlock_t *rwlocks;
|
||||
unsigned i;
|
||||
|
||||
if (tdb->header.rwlocks == 0) return 0;
|
||||
if (!tdb->map_ptr) return -1;
|
||||
|
||||
/* We're mmapped here */
|
||||
rwlocks = (tdb_rwlock_t *)((char *)tdb->map_ptr + tdb->header.rwlocks);
|
||||
for(i = 0; i < tdb->header.hash_size+1; i++) {
|
||||
__spin_lock_init(&rwlocks[i].lock);
|
||||
rwlocks[i].count = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
int tdb_create_rwlocks(int fd, unsigned int hash_size) { return 0; }
|
||||
int tdb_spinlock(TDB_CONTEXT *tdb, int list, int rw_type) { return -1; }
|
||||
int tdb_spinunlock(TDB_CONTEXT *tdb, int list, int rw_type) { return -1; }
|
||||
|
||||
/* Non-spinlock version: remove spinlock pointer */
|
||||
int tdb_clear_spinlocks(TDB_CONTEXT *tdb)
|
||||
{
|
||||
tdb_off off = (tdb_off)((char *)&tdb->header.rwlocks
|
||||
- (char *)&tdb->header);
|
||||
|
||||
tdb->header.rwlocks = 0;
|
||||
if (lseek(tdb->fd, off, SEEK_SET) != off
|
||||
|| write(tdb->fd, (void *)&tdb->header.rwlocks,
|
||||
sizeof(tdb->header.rwlocks))
|
||||
!= sizeof(tdb->header.rwlocks))
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
@ -1,59 +0,0 @@
|
||||
#ifndef __SPINLOCK_H__
|
||||
#define __SPINLOCK_H__
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include "tdb.h"
|
||||
|
||||
#ifdef USE_SPINLOCKS
|
||||
|
||||
#define RWLOCK_BIAS 0x1000UL
|
||||
|
||||
/* OS SPECIFIC */
|
||||
#define MAX_BUSY_LOOPS 1000
|
||||
#undef USE_SCHED_YIELD
|
||||
|
||||
/* ARCH SPECIFIC */
|
||||
/* We should make sure these are padded to a cache line */
|
||||
#if defined(SPARC_SPINLOCKS)
|
||||
typedef volatile char spinlock_t;
|
||||
#elif defined(POWERPC_SPINLOCKS)
|
||||
typedef volatile unsigned long spinlock_t;
|
||||
#elif defined(INTEL_SPINLOCKS)
|
||||
typedef volatile int spinlock_t;
|
||||
#elif defined(MIPS_SPINLOCKS)
|
||||
typedef volatile unsigned long spinlock_t;
|
||||
#else
|
||||
#error Need to implement spinlock code in spinlock.h
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
spinlock_t lock;
|
||||
volatile int count;
|
||||
} tdb_rwlock_t;
|
||||
|
||||
int tdb_spinlock(TDB_CONTEXT *tdb, int list, int rw_type);
|
||||
int tdb_spinunlock(TDB_CONTEXT *tdb, int list, int rw_type);
|
||||
int tdb_create_rwlocks(int fd, unsigned int hash_size);
|
||||
int tdb_clear_spinlocks(TDB_CONTEXT *tdb);
|
||||
|
||||
#define TDB_SPINLOCK_SIZE(hash_size) (((hash_size) + 1) * sizeof(tdb_rwlock_t))
|
||||
|
||||
#else /* !USE_SPINLOCKS */
|
||||
#if 0
|
||||
#define tdb_create_rwlocks(fd, hash_size) 0
|
||||
#define tdb_spinlock(tdb, list, rw_type) (-1)
|
||||
#define tdb_spinunlock(tdb, list, rw_type) (-1)
|
||||
#else
|
||||
int tdb_spinlock(TDB_CONTEXT *tdb, int list, int rw_type);
|
||||
int tdb_spinunlock(TDB_CONTEXT *tdb, int list, int rw_type);
|
||||
int tdb_create_rwlocks(int fd, unsigned int hash_size);
|
||||
#endif
|
||||
int tdb_clear_spinlocks(TDB_CONTEXT *tdb);
|
||||
#define TDB_SPINLOCK_SIZE(hash_size) 0
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
2011
src/netif/ppp/tdb.c
2011
src/netif/ppp/tdb.c
File diff suppressed because it is too large
Load Diff
@ -1,164 +0,0 @@
|
||||
#ifndef __TDB_H__
|
||||
#define __TDB_H__
|
||||
|
||||
/*
|
||||
Unix SMB/CIFS implementation.
|
||||
|
||||
trivial database library
|
||||
|
||||
Copyright (C) Andrew Tridgell 1999-2004
|
||||
|
||||
** NOTE! The following LGPL license applies to the tdb
|
||||
** library. This does NOT imply that all of Samba is released
|
||||
** under the LGPL
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef PRINTF_ATTRIBUTE
|
||||
/** Use gcc attribute to check printf fns. a1 is the 1-based index of
|
||||
* the parameter containing the format, and a2 the index of the first
|
||||
* argument. Note that some gcc 2.x versions don't handle this
|
||||
* properly **/
|
||||
#if (__GNUC__ >= 3)
|
||||
#define PRINTF_ATTRIBUTE(a1, a2) __attribute__ ((format (__printf__, a1, a2)))
|
||||
#else
|
||||
#define PRINTF_ATTRIBUTE(a1, a2)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* flags to tdb_store() */
|
||||
#define TDB_REPLACE 1
|
||||
#define TDB_INSERT 2
|
||||
#define TDB_MODIFY 3
|
||||
|
||||
/* flags for tdb_open() */
|
||||
#define TDB_DEFAULT 0 /* just a readability place holder */
|
||||
#define TDB_CLEAR_IF_FIRST 1
|
||||
#define TDB_INTERNAL 2 /* don't store on disk */
|
||||
#define TDB_NOLOCK 4 /* don't do any locking */
|
||||
#define TDB_NOMMAP 8 /* don't use mmap */
|
||||
#define TDB_CONVERT 16 /* convert endian (internal use) */
|
||||
#define TDB_BIGENDIAN 32 /* header is big-endian (internal use) */
|
||||
|
||||
#define TDB_ERRCODE(code, ret) ((tdb->ecode = (code)), ret)
|
||||
|
||||
/* error codes */
|
||||
enum TDB_ERROR {TDB_SUCCESS=0, TDB_ERR_CORRUPT, TDB_ERR_IO, TDB_ERR_LOCK,
|
||||
TDB_ERR_OOM, TDB_ERR_EXISTS, TDB_ERR_NOLOCK, TDB_ERR_LOCK_TIMEOUT,
|
||||
TDB_ERR_NOEXIST};
|
||||
|
||||
#ifndef u32
|
||||
#define u32 unsigned
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
char *dptr;
|
||||
size_t dsize;
|
||||
} TDB_DATA;
|
||||
|
||||
typedef u32 tdb_len;
|
||||
typedef u32 tdb_off;
|
||||
|
||||
/* this is stored at the front of every database */
|
||||
struct tdb_header {
|
||||
char magic_food[32]; /* for /etc/magic */
|
||||
u32 version; /* version of the code */
|
||||
u32 hash_size; /* number of hash entries */
|
||||
tdb_off rwlocks;
|
||||
tdb_off reserved[31];
|
||||
};
|
||||
|
||||
struct tdb_lock_type {
|
||||
u32 count;
|
||||
u32 ltype;
|
||||
};
|
||||
|
||||
struct tdb_traverse_lock {
|
||||
struct tdb_traverse_lock *next;
|
||||
u32 off;
|
||||
u32 hash;
|
||||
};
|
||||
|
||||
/* this is the context structure that is returned from a db open */
|
||||
typedef struct tdb_context {
|
||||
char *name; /* the name of the database */
|
||||
void *map_ptr; /* where it is currently mapped */
|
||||
int fd; /* open file descriptor for the database */
|
||||
tdb_len map_size; /* how much space has been mapped */
|
||||
int read_only; /* opened read-only */
|
||||
struct tdb_lock_type *locked; /* array of chain locks */
|
||||
enum TDB_ERROR ecode; /* error code for last tdb error */
|
||||
struct tdb_header header; /* a cached copy of the header */
|
||||
u32 flags; /* the flags passed to tdb_open */
|
||||
struct tdb_traverse_lock travlocks; /* current traversal locks */
|
||||
struct tdb_context *next; /* all tdbs to avoid multiple opens */
|
||||
dev_t device; /* uniquely identifies this tdb */
|
||||
ino_t inode; /* uniquely identifies this tdb */
|
||||
void (*log_fn)(struct tdb_context *tdb, int level, const char *, ...) PRINTF_ATTRIBUTE(3,4); /* logging function */
|
||||
u32 (*hash_fn)(TDB_DATA *key);
|
||||
int open_flags; /* flags used in the open - needed by reopen */
|
||||
} TDB_CONTEXT;
|
||||
|
||||
typedef int (*tdb_traverse_func)(TDB_CONTEXT *, TDB_DATA, TDB_DATA, void *);
|
||||
typedef void (*tdb_log_func)(TDB_CONTEXT *, int , const char *, ...);
|
||||
typedef u32 (*tdb_hash_func)(TDB_DATA *key);
|
||||
|
||||
TDB_CONTEXT *tdb_open(const char *name, int hash_size, int tdb_flags,
|
||||
int open_flags, mode_t mode);
|
||||
TDB_CONTEXT *tdb_open_ex(const char *name, int hash_size, int tdb_flags,
|
||||
int open_flags, mode_t mode,
|
||||
tdb_log_func log_fn,
|
||||
tdb_hash_func hash_fn);
|
||||
|
||||
int tdb_reopen(TDB_CONTEXT *tdb);
|
||||
int tdb_reopen_all(void);
|
||||
void tdb_logging_function(TDB_CONTEXT *tdb, tdb_log_func);
|
||||
enum TDB_ERROR tdb_error(TDB_CONTEXT *tdb);
|
||||
const char *tdb_errorstr(TDB_CONTEXT *tdb);
|
||||
TDB_DATA tdb_fetch(TDB_CONTEXT *tdb, TDB_DATA key);
|
||||
int tdb_delete(TDB_CONTEXT *tdb, TDB_DATA key);
|
||||
int tdb_store(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, int flag);
|
||||
int tdb_append(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA new_dbuf);
|
||||
int tdb_close(TDB_CONTEXT *tdb);
|
||||
TDB_DATA tdb_firstkey(TDB_CONTEXT *tdb);
|
||||
TDB_DATA tdb_nextkey(TDB_CONTEXT *tdb, TDB_DATA key);
|
||||
int tdb_traverse(TDB_CONTEXT *tdb, tdb_traverse_func fn, void *);
|
||||
int tdb_exists(TDB_CONTEXT *tdb, TDB_DATA key);
|
||||
int tdb_lockkeys(TDB_CONTEXT *tdb, u32 number, TDB_DATA keys[]);
|
||||
void tdb_unlockkeys(TDB_CONTEXT *tdb);
|
||||
int tdb_lockall(TDB_CONTEXT *tdb);
|
||||
void tdb_unlockall(TDB_CONTEXT *tdb);
|
||||
|
||||
/* Low level locking functions: use with care */
|
||||
void tdb_set_lock_alarm(sig_atomic_t *palarm);
|
||||
int tdb_chainlock(TDB_CONTEXT *tdb, TDB_DATA key);
|
||||
int tdb_chainunlock(TDB_CONTEXT *tdb, TDB_DATA key);
|
||||
|
||||
/* Debug functions. Not used in production. */
|
||||
void tdb_dump_all(TDB_CONTEXT *tdb);
|
||||
int tdb_printfreelist(TDB_CONTEXT *tdb);
|
||||
|
||||
extern TDB_DATA tdb_null;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* tdb.h */
|
Loading…
x
Reference in New Issue
Block a user