2010-05-21 12:07:41 +09:30
/*
libctdb local tdb access code
Copyright ( C ) Andrew Tridgell 2006
Copyright ( C ) Rusty Russell 2010
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation ; either version 3 of the License , or
( at your option ) any later version .
This program 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 General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program ; if not , see < http : //www.gnu.org/licenses/>.
*/
# include <ctdb.h>
# include <tdb.h>
# include <stdlib.h>
# include <stdbool.h>
# include <string.h>
2010-06-08 18:10:36 +09:30
# include <errno.h>
2010-05-21 12:07:41 +09:30
# include <ctdb_protocol.h> // For struct ctdb_ltdb_header
# include "local_tdb.h"
/*
fetch a record from the ltdb , separating out the header information
and returning the body of the record . The caller should free ( ) the
header when done , rather than the ( optional ) data - > dptr .
*/
struct ctdb_ltdb_header * ctdb_local_fetch ( struct tdb_context * tdb ,
TDB_DATA key , TDB_DATA * data )
{
TDB_DATA rec ;
rec = tdb_fetch ( tdb , key ) ;
if ( rec . dsize < sizeof ( struct ctdb_ltdb_header ) ) {
free ( rec . dptr ) ;
return NULL ;
}
if ( data ) {
data - > dsize = rec . dsize - sizeof ( struct ctdb_ltdb_header ) ;
data - > dptr = rec . dptr + sizeof ( struct ctdb_ltdb_header ) ;
}
return ( struct ctdb_ltdb_header * ) rec . dptr ;
}
/*
2010-06-08 18:10:36 +09:30
write a record to a normal database : 1 on success , 0 if noop , - 1 on fail .
errno = EIO = > tdb error .
2010-05-21 12:07:41 +09:30
*/
int ctdb_local_store ( struct tdb_context * tdb , TDB_DATA key ,
struct ctdb_ltdb_header * header , TDB_DATA data )
{
TDB_DATA rec ;
int ret ;
2010-06-08 18:10:36 +09:30
TDB_DATA old ;
2010-05-21 12:07:41 +09:30
2010-06-08 18:10:36 +09:30
old = tdb_fetch ( tdb , key ) ;
if ( old . dsize < sizeof ( * header ) ) {
errno = EIO ;
2010-05-21 12:07:41 +09:30
return - 1 ;
}
2010-06-08 18:10:36 +09:30
/* Debugging check: we have lock and should not change hdr. */
if ( memcmp ( old . dptr , header , sizeof ( * header ) ) ! = 0 ) {
free ( old . dptr ) ;
errno = EINVAL ;
return - 1 ;
}
2010-05-21 12:07:41 +09:30
2010-06-08 18:10:36 +09:30
/* Optimize out the nothing-changed case. */
if ( old . dsize = = sizeof ( * header ) + data . dsize
& & memcmp ( old . dptr + sizeof ( * header ) , data . dptr , data . dsize ) = = 0 ) {
free ( old . dptr ) ;
return 0 ;
}
2010-05-21 12:07:41 +09:30
2010-06-08 18:10:36 +09:30
rec . dsize = sizeof ( * header ) + data . dsize ;
rec . dptr = malloc ( rec . dsize ) ;
if ( ! rec . dptr ) {
2010-05-21 12:07:41 +09:30
free ( old . dptr ) ;
2010-06-08 18:10:36 +09:30
errno = ENOMEM ;
return - 1 ;
2010-05-21 12:07:41 +09:30
}
2010-06-21 14:45:37 +09:30
memcpy ( rec . dptr , header , sizeof ( * header ) ) ;
memcpy ( rec . dptr + sizeof ( * header ) , data . dptr , data . dsize ) ;
2010-06-08 18:10:36 +09:30
2010-05-21 12:07:41 +09:30
ret = tdb_store ( tdb , key , rec , TDB_REPLACE ) ;
2010-06-08 18:10:36 +09:30
free ( old . dptr ) ;
2010-05-21 12:07:41 +09:30
free ( rec . dptr ) ;
2010-06-08 18:10:36 +09:30
if ( ret ! = 0 ) {
errno = EIO ;
return - 1 ;
}
return 1 ;
2010-05-21 12:07:41 +09:30
}