diff options
author | Jakub Hrozek <jhrozek@redhat.com> | 2016-05-23 18:18:00 +0200 |
---|---|---|
committer | Jakub Hrozek <jhrozek@redhat.com> | 2016-06-23 13:47:07 +0200 |
commit | a257259b05d62ebe548b6c798a3aa03a97dbc0c2 (patch) | |
tree | af4cc3c4e1e109bcf25b673ce06beb85a2a4536d /src/db/sysdb.c | |
parent | dd285415d7a8d8376207960cfa3e977524c3b98c (diff) | |
download | sssd-a257259b05d62ebe548b6c798a3aa03a97dbc0c2.tar.gz sssd-a257259b05d62ebe548b6c798a3aa03a97dbc0c2.tar.xz sssd-a257259b05d62ebe548b6c798a3aa03a97dbc0c2.zip |
SYSDB: If modifyTimestamp is the same, only update the TS cache
Resolves:
https://fedorahosted.org/sssd/ticket/2602
If the entry being saved contains the original modifyTimestamp attribute
and the modifyTimestamp attribute is the same as the one we already
saved to the timestamp cache, only the expire timestamps in the
asynchronous timestamp cache will be bumped and the sysdb code will
avoid writes to the main cache completely. If the modifyTimestamp is
either missing or differs, we assume the entry had changed and do a full
write to the main cache.
Also amends the generic sysdb_set_attrs* and similar functions that
their results is also reflected in the timestamps cache.
Reviewed-by: Sumit Bose <sbose@redhat.com>
Diffstat (limited to 'src/db/sysdb.c')
-rw-r--r-- | src/db/sysdb.c | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/src/db/sysdb.c b/src/db/sysdb.c index 81b731a0d..1224e96ad 100644 --- a/src/db/sysdb.c +++ b/src/db/sysdb.c @@ -1524,6 +1524,42 @@ errno_t sysdb_msg2attrs(TALLOC_CTX *mem_ctx, size_t count, return EOK; } +struct ldb_message *sysdb_attrs2msg(TALLOC_CTX *mem_ctx, + struct ldb_dn *entry_dn, + struct sysdb_attrs *attrs, + int mod_op) +{ + struct ldb_message *msg; + errno_t ret; + + msg = ldb_msg_new(mem_ctx); + if (msg == NULL) { + ret = ENOMEM; + goto done; + } + + msg->dn = entry_dn; + + msg->elements = talloc_array(msg, struct ldb_message_element, attrs->num); + if (msg->elements == NULL) { + ret = ENOMEM; + goto done; + } + + for (int i = 0; i < attrs->num; i++) { + msg->elements[i] = attrs->a[i]; + msg->elements[i].flags = mod_op; + } + msg->num_elements = attrs->num; + + ret = EOK; +done: + if (ret != EOK) { + talloc_zfree(msg); + } + return msg; +} + int sysdb_compare_usn(const char *a, const char *b) { size_t len_a; @@ -1715,3 +1751,43 @@ bool is_ts_ldb_dn(struct ldb_dn *dn) return false; } + +bool sysdb_msg_attrs_modts_differs(struct ldb_message *old_entry, + struct sysdb_attrs *new_entry) +{ + const char *old_entry_ts_attr = NULL; + const char *new_entry_ts_attr = NULL; + errno_t ret; + + old_entry_ts_attr = ldb_msg_find_attr_as_string(old_entry, + SYSDB_ORIG_MODSTAMP, + NULL); + if (old_entry_ts_attr == NULL) { + /* we didn't know the originalModifyTimestamp earlier. Regardless + * of whether the new_entry has the timestamp, we should do + * a comparison of the attributes + */ + return true; + } + + if (new_entry == NULL) { + return false; + } + + ret = sysdb_attrs_get_string(new_entry, SYSDB_ORIG_MODSTAMP, + &new_entry_ts_attr); + if (ret != EOK) { + /* Nothing to compare against in the new entry either, do + * a comparison of the attributes + */ + return true; + } + + if (old_entry_ts_attr != NULL + && new_entry_ts_attr != NULL + && strcmp(old_entry_ts_attr, new_entry_ts_attr) == 0) { + return false; + } + + return true; +} |