diff options
author | Volker Lendecke <vlendec@samba.org> | 2006-11-22 16:53:28 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 12:16:01 -0500 |
commit | 7a192590514fe8adebf4cdf51dc96c48d5225329 (patch) | |
tree | 2ac142fd2df71ebe11c21e1f8714aa2c4fd4589e | |
parent | ca70f53930df64b6a2fcb563b4ffa84d99a01741 (diff) | |
download | samba-7a192590514fe8adebf4cdf51dc96c48d5225329.tar.gz samba-7a192590514fe8adebf4cdf51dc96c48d5225329.tar.bz2 samba-7a192590514fe8adebf4cdf51dc96c48d5225329.zip |
r19841: Wrap regdb_store_keys and regdb_store_values in tdb transactions
(This used to be commit 5ec737922041b723b9e60c08049ace5fa2fa5dec)
-rw-r--r-- | source3/lib/util_tdb.c | 8 | ||||
-rw-r--r-- | source3/registry/reg_db.c | 70 |
2 files changed, 60 insertions, 18 deletions
diff --git a/source3/lib/util_tdb.c b/source3/lib/util_tdb.c index e847c79369..4db39095a6 100644 --- a/source3/lib/util_tdb.c +++ b/source3/lib/util_tdb.c @@ -302,6 +302,14 @@ int tdb_store_bystring(TDB_CONTEXT *tdb, const char *keystr, TDB_DATA data, int return tdb_store(tdb, key, data, flags); } +int tdb_trans_store_bystring(TDB_CONTEXT *tdb, const char *keystr, + TDB_DATA data, int flags) +{ + TDB_DATA key = make_tdb_data(keystr, strlen(keystr)+1); + + return tdb_trans_store(tdb, key, data, flags); +} + /**************************************************************************** Fetch a buffer using a null terminated string key. Don't forget to call free() on the result dptr. diff --git a/source3/registry/reg_db.c b/source3/registry/reg_db.c index df0664a304..2afecffec7 100644 --- a/source3/registry/reg_db.c +++ b/source3/registry/reg_db.c @@ -366,15 +366,20 @@ BOOL regdb_store_keys( const char *key, REGSUBKEY_CTR *ctr ) { int num_subkeys, i; pstring path; - REGSUBKEY_CTR *subkeys, *old_subkeys; + REGSUBKEY_CTR *subkeys = NULL, *old_subkeys = NULL; char *oldkeyname; + if ( tdb_transaction_start( tdb_reg ) == -1 ) { + DEBUG(0, ("regdb_store_keys: tdb_transaction_start failed\n")); + return False; + } + /* fetch a list of the old subkeys so we can determine if any were * deleted */ if ( !(old_subkeys = TALLOC_ZERO_P( ctr, REGSUBKEY_CTR )) ) { DEBUG(0,("regdb_store_keys: talloc() failure!\n")); - return False; + goto fail; } regdb_fetch_keys( key, old_subkeys ); @@ -383,8 +388,8 @@ BOOL regdb_store_keys( const char *key, REGSUBKEY_CTR *ctr ) if ( !regdb_store_keys_internal( key, ctr ) ) { DEBUG(0,("regdb_store_keys: Failed to store new subkey list " - "for parent [%s}\n", key )); - return False; + "for parent [%s]\n", key )); + goto fail; } /* now delete removed keys */ @@ -392,15 +397,30 @@ BOOL regdb_store_keys( const char *key, REGSUBKEY_CTR *ctr ) num_subkeys = regsubkey_ctr_numkeys( old_subkeys ); for ( i=0; i<num_subkeys; i++ ) { oldkeyname = regsubkey_ctr_specific_key( old_subkeys, i ); - if ( !regsubkey_ctr_key_exists( ctr, oldkeyname ) ) { - pstr_sprintf( path, "%s%c%s", key, '/', oldkeyname ); - normalize_reg_path( path ); - tdb_delete_bystring( tdb_reg, path ); - pstr_sprintf( path, "%s/%s/%s", VALUE_PREFIX, key, - oldkeyname ); - normalize_reg_path( path ); - tdb_delete_bystring( tdb_reg, path ); + + if ( regsubkey_ctr_key_exists( ctr, oldkeyname ) ) { + /* + * It's still around, don't delete + */ + + continue; + } + + pstr_sprintf( path, "%s/%s", key, oldkeyname ); + normalize_reg_path( path ); + if (tdb_delete_bystring( tdb_reg, path ) == -1) { + DEBUG(1, ("Deleting %s failed\n", path)); + goto fail; } + + pstr_sprintf( path, "%s/%s/%s", VALUE_PREFIX, key, + oldkeyname ); + normalize_reg_path( path ); + + /* + * Ignore errors here, we might have no values around + */ + tdb_delete_bystring( tdb_reg, path ); } TALLOC_FREE( old_subkeys ); @@ -409,12 +429,12 @@ BOOL regdb_store_keys( const char *key, REGSUBKEY_CTR *ctr ) num_subkeys = regsubkey_ctr_numkeys( ctr ); for ( i=0; i<num_subkeys; i++ ) { - pstr_sprintf( path, "%s%c%s", key, '/', + pstr_sprintf( path, "%s/%s", key, regsubkey_ctr_specific_key( ctr, i ) ); if ( !(subkeys = TALLOC_ZERO_P( ctr, REGSUBKEY_CTR )) ) { DEBUG(0,("regdb_store_keys: talloc() failure!\n")); - return False; + goto fail; } if ( regdb_fetch_keys( path, subkeys ) == -1 ) { @@ -422,15 +442,29 @@ BOOL regdb_store_keys( const char *key, REGSUBKEY_CTR *ctr ) if ( !regdb_store_keys_internal( path, subkeys ) ) { DEBUG(0,("regdb_store_keys: Failed to store " "new record for key [%s}\n", path )); - TALLOC_FREE( subkeys ); - return False; + goto fail; } } TALLOC_FREE( subkeys ); } - + + if (tdb_transaction_commit( tdb_reg ) == -1) { + DEBUG(0, ("regdb_store_keys: Could not commit transaction\n")); + return False; + } + return True; + + fail: + TALLOC_FREE( old_subkeys ); + TALLOC_FREE( subkeys ); + + if (tdb_transaction_cancel( tdb_reg ) == -1) { + smb_panic("regdb_store_keys: tdb_transaction_cancel failed\n"); + } + + return False; } @@ -620,7 +654,7 @@ BOOL regdb_store_values( const char *key, REGVAL_CTR *values ) pstr_sprintf( keystr, "%s/%s", VALUE_PREFIX, key ); normalize_reg_path( keystr ); - ret = tdb_store_bystring(tdb_reg, keystr, data, TDB_REPLACE); + ret = tdb_trans_store_bystring(tdb_reg, keystr, data, TDB_REPLACE); SAFE_FREE( data.dptr ); |