/** BEGIN COPYRIGHT BLOCK * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission. * Copyright (C) 2005 Red Hat, Inc. * All rights reserved. * * License: GPL (version 3 or any later version). * See LICENSE for details. * END COPYRIGHT BLOCK **/ #ifdef HAVE_CONFIG_H #include #endif /* repl5_replica.c */ #include "repl5.h" #include "cl5_api.h" /* global data */ static DataList *root_list; /* * Mapping tree node extension management. Node stores replica object */ void multimaster_mtnode_extension_init() { /* Initialize list that store node roots. It is used during plugin startup to create replica objects */ root_list = dl_new(); dl_init(root_list, 0); } void multimaster_mtnode_free_replica_object(const Slapi_DN *root) { mapping_tree_node *mtnode; multimaster_mtnode_extension *ext; /* In some cases, root can be an empty SDN */ /* Othertimes, a bug is setting root to 0x8, and I can't see where... */ if (root != NULL) { mtnode = slapi_get_mapping_tree_node_by_dn(root); if (mtnode != NULL) { ext = (multimaster_mtnode_extension *)repl_con_get_ext(REPL_CON_EXT_MTNODE, mtnode); if (ext != NULL && ext->replica != NULL) { object_release(ext->replica); } } } } void multimaster_mtnode_extension_destroy() { /* First iterate over the list to free the replica infos */ /* dl_cleanup (root_list, (FREEFN)multimaster_mtnode_free_replica_object); */ dl_cleanup(root_list, (FREEFN)slapi_sdn_free); dl_free(&root_list); } /* This function loops over the list of node roots, constructing replica objects where exist */ void multimaster_mtnode_construct_replicas() { Slapi_DN *root; int cookie; Replica *r; mapping_tree_node *mtnode; multimaster_mtnode_extension *ext; for (root = dl_get_first(root_list, &cookie); root; root = dl_get_next(root_list, &cookie)) { r = replica_new(root); if (r) { mtnode = slapi_get_mapping_tree_node_by_dn(root); if (mtnode == NULL) { slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, "multimaster_mtnode_construct_replicas: " "failed to locate mapping tree node for %s\n", slapi_sdn_get_dn(root)); continue; } ext = (multimaster_mtnode_extension *)repl_con_get_ext(REPL_CON_EXT_MTNODE, mtnode); if (ext == NULL) { slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, "multimaster_mtnode_construct_replicas: " "failed to locate replication extension of mapping tree node for %s\n", slapi_sdn_get_dn(root)); continue; } ext->replica = object_new(r, replica_destroy); if (replica_add_by_name(replica_get_name(r), ext->replica) != 0) { if (ext->replica) { object_release(ext->replica); ext->replica = NULL; } } } } } void * multimaster_mtnode_extension_constructor(void *object, void *parent __attribute__((unused))) { mapping_tree_node *node; const Slapi_DN *root; multimaster_mtnode_extension *ext; ext = (multimaster_mtnode_extension *)slapi_ch_calloc(1, sizeof(multimaster_mtnode_extension)); node = (mapping_tree_node *)object; /* replica can be attached only to local public data */ if (slapi_mapping_tree_node_is_set(node, SLAPI_MTN_LOCAL) && !slapi_mapping_tree_node_is_set(node, SLAPI_MTN_PRIVATE)) { root = slapi_get_mapping_tree_node_root(node); /* ONREPL - we don't create replica object here because we can't fully initialize replica here since backends are not yet started. Instead, replica objects are created during replication plugin startup */ if (root != NULL && !slapi_sdn_isempty(root)) { /* for now just store node root in the root list */ dl_add(root_list, slapi_sdn_dup(root)); } } return ext; } void multimaster_mtnode_extension_destructor(void *ext, void *object __attribute__((unused)), void *parent __attribute__((unused))) { if (ext) { multimaster_mtnode_extension *mtnode_ext = (multimaster_mtnode_extension *)ext; if (mtnode_ext->replica) { object_release(mtnode_ext->replica); mtnode_ext->replica = NULL; } slapi_ch_free((void **)&ext); } } Object * replica_get_replica_from_dn(const Slapi_DN *dn) { mapping_tree_node *mtnode; multimaster_mtnode_extension *ext; if (dn == NULL) return NULL; mtnode = slapi_get_mapping_tree_node_by_dn(dn); if (mtnode == NULL) { slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, "replica_get_replica_from_dn: " "failed to locate mapping tree node for %s\n", slapi_sdn_get_dn(dn)); return NULL; } ext = (multimaster_mtnode_extension *)repl_con_get_ext(REPL_CON_EXT_MTNODE, mtnode); if (ext == NULL) { slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, "replica_get_replica_from_dn: " "failed to locate replication extension of mapping tree node for %s\n", slapi_sdn_get_dn(dn)); return NULL; } if (ext->replica) object_acquire(ext->replica); return ext->replica; } Object * replica_get_replica_for_op(Slapi_PBlock *pb) { Slapi_DN *sdn = NULL; Object *repl_obj = NULL; if (pb) { /* get replica generation for this operation */ slapi_pblock_get(pb, SLAPI_TARGET_SDN, &sdn); if (NULL == sdn) { goto bail; } repl_obj = replica_get_replica_from_dn(sdn); } bail: return repl_obj; } Object * replica_get_for_backend(const char *be_name) { Slapi_Backend *be; const Slapi_DN *suffix; Object *r_obj; be = slapi_be_select_by_instance_name(be_name); if (NULL == be) return NULL; suffix = slapi_be_getsuffix(be, 0); r_obj = replica_get_replica_from_dn(suffix); return r_obj; }