summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Adam <obnox@samba.org>2008-01-14 18:31:11 +0100
committerGünther Deschner <gd@samba.org>2008-01-14 19:38:01 +0100
commitd35bda0ffd5bea57087dba9a6da8c20df8fa165c (patch)
tree40be9067b2d4fb2090d53c1da1466848d47e0af3
parent36a7316bfc9d7582ccd908f2b9d96e0fe983e884 (diff)
downloadsamba-d35bda0ffd5bea57087dba9a6da8c20df8fa165c.tar.gz
samba-d35bda0ffd5bea57087dba9a6da8c20df8fa165c.tar.bz2
samba-d35bda0ffd5bea57087dba9a6da8c20df8fa165c.zip
Add detection for need of update to the registry db.
This only detects if the tdb sequence number has changed since the data has last been read. Michael (This used to be commit 3f081ebeadf30a7943723703ecae479e0412c60c)
-rw-r--r--source3/include/reg_objects.h4
-rw-r--r--source3/registry/reg_api.c8
-rw-r--r--source3/registry/reg_db.c29
-rw-r--r--source3/registry/reg_frontend_hilvl.c29
-rw-r--r--source3/registry/reg_printing.c2
-rw-r--r--source3/registry/reg_shares.c2
-rw-r--r--source3/registry/reg_smbconf.c4
7 files changed, 72 insertions, 6 deletions
diff --git a/source3/include/reg_objects.h b/source3/include/reg_objects.h
index f6cf9cccb7..23a14e6757 100644
--- a/source3/include/reg_objects.h
+++ b/source3/include/reg_objects.h
@@ -61,6 +61,7 @@ struct registry_value {
typedef struct {
uint32 num_values;
REGISTRY_VALUE **values;
+ int seqnum;
} REGVAL_CTR;
/* container for registry subkey names */
@@ -68,6 +69,7 @@ typedef struct {
typedef struct {
uint32 num_subkeys;
char **subkeys;
+ int seqnum;
} REGSUBKEY_CTR;
/*
@@ -128,6 +130,8 @@ typedef struct {
struct security_descriptor **psecdesc);
WERROR (*set_secdesc)(const char *key,
struct security_descriptor *sec_desc);
+ bool (*subkeys_need_update)(REGSUBKEY_CTR *subkeys);
+ bool (*values_need_update)(REGVAL_CTR *values);
} REGISTRY_OPS;
typedef struct {
diff --git a/source3/registry/reg_api.c b/source3/registry/reg_api.c
index bb410e646b..8bbdb6abd3 100644
--- a/source3/registry/reg_api.c
+++ b/source3/registry/reg_api.c
@@ -27,7 +27,9 @@
static WERROR fill_value_cache(struct registry_key *key)
{
if (key->values != NULL) {
- return WERR_OK;
+ if (!reg_values_need_update(key->key, key->values)) {
+ return WERR_OK;
+ }
}
if (!(key->values = TALLOC_ZERO_P(key, REGVAL_CTR))) {
@@ -44,7 +46,9 @@ static WERROR fill_value_cache(struct registry_key *key)
static WERROR fill_subkey_cache(struct registry_key *key)
{
if (key->subkeys != NULL) {
- return WERR_OK;
+ if (!reg_subkeys_need_update(key->key, key->subkeys)) {
+ return WERR_OK;
+ }
}
if (!(key->subkeys = TALLOC_ZERO_P(key, REGSUBKEY_CTR))) {
diff --git a/source3/registry/reg_db.c b/source3/registry/reg_db.c
index f50a41816c..c4bfc2b6c9 100644
--- a/source3/registry/reg_db.c
+++ b/source3/registry/reg_db.c
@@ -622,7 +622,15 @@ int regdb_fetch_keys(const char *key, REGSUBKEY_CTR *ctr)
}
strupper_m(path);
+ if (tdb_read_lock_bystring_with_timeout(tdb_reg->tdb, path, 10) == -1) {
+ return 0;
+ }
+
dbuf = tdb_fetch_bystring(tdb_reg->tdb, path);
+ ctr->seqnum = regdb_get_seqnum();
+
+ tdb_read_unlock_bystring(tdb_reg->tdb, path);
+
buf = dbuf.dptr;
buflen = dbuf.dsize;
@@ -750,7 +758,14 @@ int regdb_fetch_values( const char* key, REGVAL_CTR *values )
return 0;
}
+ if (tdb_read_lock_bystring_with_timeout(tdb_reg->tdb, keystr, 10) == -1) {
+ return 0;
+ }
+
data = tdb_fetch_bystring(tdb_reg->tdb, keystr);
+ values->seqnum = regdb_get_seqnum();
+
+ tdb_read_unlock_bystring(tdb_reg->tdb, keystr);
if (!data.dptr) {
/* all keys have zero values by default */
@@ -907,6 +922,16 @@ static WERROR regdb_set_secdesc(const char *key,
return err;
}
+bool regdb_subkeys_need_update(REGSUBKEY_CTR *subkeys)
+{
+ return (regdb_get_seqnum() != subkeys->seqnum);
+}
+
+bool regdb_values_need_update(REGVAL_CTR *values)
+{
+ return (regdb_get_seqnum() != values->seqnum);
+}
+
/*
* Table of function pointers for default access
*/
@@ -918,5 +943,7 @@ REGISTRY_OPS regdb_ops = {
regdb_store_values,
NULL,
regdb_get_secdesc,
- regdb_set_secdesc
+ regdb_set_secdesc,
+ regdb_subkeys_need_update,
+ regdb_values_need_update
};
diff --git a/source3/registry/reg_frontend_hilvl.c b/source3/registry/reg_frontend_hilvl.c
index a4b78b24c0..73fcf87e17 100644
--- a/source3/registry/reg_frontend_hilvl.c
+++ b/source3/registry/reg_frontend_hilvl.c
@@ -214,3 +214,32 @@ WERROR regkey_set_secdesc(REGISTRY_KEY *key,
return WERR_ACCESS_DENIED;
}
+
+/**
+ * Check whether the in-memory version of the subkyes of a
+ * registry key needs update from disk.
+ */
+bool reg_subkeys_need_update(REGISTRY_KEY *key, REGSUBKEY_CTR *subkeys)
+{
+ if (key->hook && key->hook->ops && key->hook->ops->subkeys_need_update)
+ {
+ return key->hook->ops->subkeys_need_update(subkeys);
+ }
+
+ return false;
+}
+
+/**
+ * Check whether the in-memory version of the values of a
+ * registry key needs update from disk.
+ */
+bool reg_values_need_update(REGISTRY_KEY *key, REGVAL_CTR *values)
+{
+ if (key->hook && key->hook->ops && key->hook->ops->values_need_update)
+ {
+ return key->hook->ops->values_need_update(values);
+ }
+
+ return false;
+}
+
diff --git a/source3/registry/reg_printing.c b/source3/registry/reg_printing.c
index 2ca74f7c16..5be0796002 100644
--- a/source3/registry/reg_printing.c
+++ b/source3/registry/reg_printing.c
@@ -1266,5 +1266,5 @@ REGISTRY_OPS printing_ops = {
regprint_fetch_reg_values,
regprint_store_reg_keys,
regprint_store_reg_values,
- NULL, NULL, NULL
+ NULL, NULL, NULL, NULL, NULL
};
diff --git a/source3/registry/reg_shares.c b/source3/registry/reg_shares.c
index 178f23e21c..4ac6e1d151 100644
--- a/source3/registry/reg_shares.c
+++ b/source3/registry/reg_shares.c
@@ -159,7 +159,7 @@ REGISTRY_OPS shares_reg_ops = {
shares_value_info,
shares_store_subkey,
shares_store_value,
- NULL, NULL, NULL
+ NULL, NULL, NULL, NULL, NULL
};
diff --git a/source3/registry/reg_smbconf.c b/source3/registry/reg_smbconf.c
index 116cde936e..8dfb745a7e 100644
--- a/source3/registry/reg_smbconf.c
+++ b/source3/registry/reg_smbconf.c
@@ -271,5 +271,7 @@ REGISTRY_OPS smbconf_reg_ops = {
smbconf_store_values,
smbconf_reg_access_check,
smbconf_get_secdesc,
- smbconf_set_secdesc
+ smbconf_set_secdesc,
+ NULL,
+ NULL
};