repl5_mtnode_ext.c 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. /** BEGIN COPYRIGHT BLOCK
  2. * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
  3. * Copyright (C) 2005 Red Hat, Inc.
  4. * All rights reserved.
  5. *
  6. * License: GPL (version 3 or any later version).
  7. * See LICENSE for details.
  8. * END COPYRIGHT BLOCK **/
  9. #ifdef HAVE_CONFIG_H
  10. #include <config.h>
  11. #endif
  12. /* repl5_replica.c */
  13. #include "repl5.h"
  14. #include "cl5_api.h"
  15. /* global data */
  16. static DataList *root_list;
  17. /*
  18. * Mapping tree node extension management. Node stores replica object
  19. */
  20. void
  21. multimaster_mtnode_extension_init()
  22. {
  23. /* Initialize list that store node roots. It is used during
  24. plugin startup to create replica objects */
  25. root_list = dl_new();
  26. dl_init(root_list, 0);
  27. }
  28. void
  29. multimaster_mtnode_free_replica_object(const Slapi_DN *root)
  30. {
  31. mapping_tree_node *mtnode;
  32. multimaster_mtnode_extension *ext;
  33. /* In some cases, root can be an empty SDN */
  34. /* Othertimes, a bug is setting root to 0x8, and I can't see where... */
  35. if (root != NULL) {
  36. mtnode = slapi_get_mapping_tree_node_by_dn(root);
  37. if (mtnode != NULL) {
  38. ext = (multimaster_mtnode_extension *)repl_con_get_ext(REPL_CON_EXT_MTNODE, mtnode);
  39. if (ext != NULL && ext->replica != NULL) {
  40. object_release(ext->replica);
  41. }
  42. }
  43. }
  44. }
  45. void
  46. multimaster_mtnode_extension_destroy()
  47. {
  48. /* First iterate over the list to free the replica infos */
  49. /* dl_cleanup (root_list, (FREEFN)multimaster_mtnode_free_replica_object); */
  50. dl_cleanup(root_list, (FREEFN)slapi_sdn_free);
  51. dl_free(&root_list);
  52. }
  53. /* This function loops over the list of node roots, constructing replica objects
  54. where exist */
  55. void
  56. multimaster_mtnode_construct_replicas()
  57. {
  58. Slapi_DN *root;
  59. int cookie;
  60. Replica *r;
  61. mapping_tree_node *mtnode;
  62. multimaster_mtnode_extension *ext;
  63. for (root = dl_get_first(root_list, &cookie); root;
  64. root = dl_get_next(root_list, &cookie)) {
  65. r = replica_new(root);
  66. if (r) {
  67. mtnode = slapi_get_mapping_tree_node_by_dn(root);
  68. if (mtnode == NULL) {
  69. slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name,
  70. "multimaster_mtnode_construct_replicas: "
  71. "failed to locate mapping tree node for %s\n",
  72. slapi_sdn_get_dn(root));
  73. continue;
  74. }
  75. ext = (multimaster_mtnode_extension *)repl_con_get_ext(REPL_CON_EXT_MTNODE, mtnode);
  76. if (ext == NULL) {
  77. slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, "multimaster_mtnode_construct_replicas: "
  78. "failed to locate replication extension of mapping tree node for %s\n",
  79. slapi_sdn_get_dn(root));
  80. continue;
  81. }
  82. ext->replica = object_new(r, replica_destroy);
  83. if (replica_add_by_name(replica_get_name(r), ext->replica) != 0) {
  84. if (ext->replica) {
  85. object_release(ext->replica);
  86. ext->replica = NULL;
  87. }
  88. }
  89. }
  90. }
  91. }
  92. void *
  93. multimaster_mtnode_extension_constructor(void *object, void *parent __attribute__((unused)))
  94. {
  95. mapping_tree_node *node;
  96. const Slapi_DN *root;
  97. multimaster_mtnode_extension *ext;
  98. ext = (multimaster_mtnode_extension *)slapi_ch_calloc(1, sizeof(multimaster_mtnode_extension));
  99. node = (mapping_tree_node *)object;
  100. /* replica can be attached only to local public data */
  101. if (slapi_mapping_tree_node_is_set(node, SLAPI_MTN_LOCAL) &&
  102. !slapi_mapping_tree_node_is_set(node, SLAPI_MTN_PRIVATE)) {
  103. root = slapi_get_mapping_tree_node_root(node);
  104. /* ONREPL - we don't create replica object here because
  105. we can't fully initialize replica here since backends
  106. are not yet started. Instead, replica objects are created
  107. during replication plugin startup */
  108. if (root != NULL && !slapi_sdn_isempty(root)) {
  109. /* for now just store node root in the root list */
  110. dl_add(root_list, slapi_sdn_dup(root));
  111. }
  112. }
  113. return ext;
  114. }
  115. void
  116. multimaster_mtnode_extension_destructor(void *ext, void *object __attribute__((unused)), void *parent __attribute__((unused)))
  117. {
  118. if (ext) {
  119. multimaster_mtnode_extension *mtnode_ext = (multimaster_mtnode_extension *)ext;
  120. if (mtnode_ext->replica) {
  121. object_release(mtnode_ext->replica);
  122. mtnode_ext->replica = NULL;
  123. }
  124. slapi_ch_free((void **)&ext);
  125. }
  126. }
  127. Object *
  128. replica_get_replica_from_dn(const Slapi_DN *dn)
  129. {
  130. mapping_tree_node *mtnode;
  131. multimaster_mtnode_extension *ext;
  132. if (dn == NULL)
  133. return NULL;
  134. mtnode = slapi_get_mapping_tree_node_by_dn(dn);
  135. if (mtnode == NULL) {
  136. slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, "replica_get_replica_from_dn: "
  137. "failed to locate mapping tree node for %s\n",
  138. slapi_sdn_get_dn(dn));
  139. return NULL;
  140. }
  141. ext = (multimaster_mtnode_extension *)repl_con_get_ext(REPL_CON_EXT_MTNODE, mtnode);
  142. if (ext == NULL) {
  143. slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, "replica_get_replica_from_dn: "
  144. "failed to locate replication extension of mapping tree node for %s\n",
  145. slapi_sdn_get_dn(dn));
  146. return NULL;
  147. }
  148. if (ext->replica)
  149. object_acquire(ext->replica);
  150. return ext->replica;
  151. }
  152. Object *
  153. replica_get_replica_for_op(Slapi_PBlock *pb)
  154. {
  155. Slapi_DN *sdn = NULL;
  156. Object *repl_obj = NULL;
  157. if (pb) {
  158. /* get replica generation for this operation */
  159. slapi_pblock_get(pb, SLAPI_TARGET_SDN, &sdn);
  160. if (NULL == sdn) {
  161. goto bail;
  162. }
  163. repl_obj = replica_get_replica_from_dn(sdn);
  164. }
  165. bail:
  166. return repl_obj;
  167. }
  168. Object *
  169. replica_get_for_backend(const char *be_name)
  170. {
  171. Slapi_Backend *be;
  172. const Slapi_DN *suffix;
  173. Object *r_obj;
  174. be = slapi_be_select_by_instance_name(be_name);
  175. if (NULL == be)
  176. return NULL;
  177. suffix = slapi_be_getsuffix(be, 0);
  178. r_obj = replica_get_replica_from_dn(suffix);
  179. return r_obj;
  180. }