1
0

cl5_test.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840
  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. /* cl5_test.c - changelog test cases */
  13. #include "cl5_test.h"
  14. #include "slapi-plugin.h"
  15. #include "cl5.h"
  16. #define REPLICA_ROOT "dc=example,dc=com" /* replica root */
  17. #define OP_COUNT 4 /* number of ops generated at a time */
  18. #define MOD_COUNT 5
  19. #define VALUE_COUNT 5
  20. #define ENTRY_COUNT 50
  21. #define CL_DN "cn=changelog5,cn=config"
  22. #define INSTANCE_ATTR "nsslapd-instancedir"
  23. #define REPLICA_OC "nsds5Replica"
  24. #define REPLICA_RDN "cn=replica"
  25. static void testBasic ();
  26. static void testBackupRestore ();
  27. static void testIteration ();
  28. static void testTrimming ();
  29. static void testPerformance ();
  30. static void testPerformanceMT ();
  31. static void testLDIF ();
  32. static void testAll ();
  33. static int configureChangelog ();
  34. static int configureReplica ();
  35. static int populateChangelogOp ();
  36. static int populateChangelog (int entryCount, CSN ***csnList);
  37. static int processEntries (int entryCount, CSN **csnList);
  38. static void clearCSNList (CSN ***csnList, int count);
  39. static void threadMain (void *data);
  40. static char* getBaseDir (const char *dir);
  41. static LDAPMod **buildMods ();
  42. void testChangelog (TestType type)
  43. {
  44. switch (type)
  45. {
  46. case TEST_BASIC: testBasic ();
  47. break;
  48. case TEST_BACKUP_RESTORE: testBackupRestore ();
  49. break;
  50. case TEST_ITERATION: testIteration ();
  51. break;
  52. case TEST_TRIMMING: testTrimming ();
  53. break;
  54. case TEST_PERFORMANCE: testPerformance ();
  55. break;
  56. case TEST_PERFORMANCE_MT: testPerformanceMT ();
  57. break;
  58. case TEST_LDIF: testLDIF ();
  59. break;
  60. case TEST_ALL: testAll ();
  61. break;
  62. default: printf ("Taste case %d is not supported\n", type);
  63. }
  64. }
  65. /* tests Open/Close, normal recovery, read/write/remove
  66. of an entry */
  67. static void testBasic ()
  68. {
  69. int rc = 0;
  70. slapi_log_error(SLAPI_LOG_FATAL, LOG_ERR, repl_plugin_name_cl, "Starting basic test ...\n");
  71. /* ONREPL - we can't run the tests from the startup code because
  72. operations can't be issued until all plugins are started. So,
  73. instead, we do it when changelog is created
  74. rc = configureChangelog (); */
  75. if (rc == 0)
  76. {
  77. rc = configureReplica ();
  78. if (rc == 0)
  79. {
  80. rc = populateChangelogOp ();
  81. }
  82. }
  83. if (rc == 0)
  84. slapi_log_error(SLAPI_LOG_FATAL, LOG_ERR, repl_plugin_name_cl,
  85. "Basic test completed successfully\n");
  86. else
  87. slapi_log_error(SLAPI_LOG_FATAL, LOG_ERR, repl_plugin_name_cl,
  88. "Basic test failed\n");
  89. }
  90. static void testBackupRestore ()
  91. {
  92. char *dir;
  93. int rc = -1;
  94. char *baseDir;
  95. char bkDir [MAXPATHLEN];
  96. slapi_log_error(SLAPI_LOG_FATAL, LOG_ERR, repl_plugin_name_cl, "Starting backup and recovery test ...\n");
  97. dir = cl5GetDir ();
  98. if (dir)
  99. {
  100. baseDir = getBaseDir (dir);
  101. PR_snprintf (bkDir, sizeof(bkDir), "%s/clbackup", baseDir);
  102. slapi_ch_free ((void**)&baseDir);
  103. rc = cl5Backup (bkDir, NULL);
  104. if (rc == CL5_SUCCESS)
  105. {
  106. cl5Close ();
  107. rc = cl5Restore (dir, bkDir, NULL);
  108. if (rc == CL5_SUCCESS)
  109. rc = cl5Open (dir, NULL);
  110. /* PR_RmDir (bkDir);*/
  111. }
  112. }
  113. if (rc == CL5_SUCCESS)
  114. slapi_log_error(SLAPI_LOG_FATAL, LOG_ERR, repl_plugin_name_cl,
  115. "Backup and Restore test completed successfully\n");
  116. else
  117. slapi_log_error(SLAPI_LOG_FATAL, LOG_ERR, repl_plugin_name_cl,
  118. "Backup and Restore test failed\n");
  119. }
  120. static void testIteration ()
  121. {
  122. Object *r_obj;
  123. Slapi_DN *r_root;
  124. Replica *r;
  125. char *replGen;
  126. RUV *ruv;
  127. CL5ReplayIterator *it = NULL;
  128. slapi_operation_parameters op;
  129. int rc;
  130. int i;
  131. slapi_log_error(SLAPI_LOG_FATAL, LOG_ERR, repl_plugin_name_cl, "Starting iteration test ...\n");
  132. /* get replica object */
  133. r_root = slapi_sdn_new_dn_byval(REPLICA_ROOT);
  134. r_obj = replica_get_replica_from_dn (r_root);
  135. slapi_sdn_free (&r_root);
  136. if (r_obj == NULL)
  137. {
  138. slapi_log_error(SLAPI_LOG_FATAL, LOG_ERR, repl_plugin_name_cl, "replica is not configured for (%s)\n",
  139. REPLICA_ROOT);
  140. return;
  141. }
  142. slapi_log_error(SLAPI_LOG_FATAL, LOG_ERR, repl_plugin_name_cl, "Starting first iteration pass ...\n");
  143. /* configure empty consumer ruv */
  144. r = (Replica*)object_get_data (r_obj);
  145. PR_ASSERT (r);
  146. replGen = replica_get_generation (r);
  147. ruv_init_new (replGen, 0, NULL, &ruv);
  148. /* create replay iterator */
  149. rc = cl5CreateReplayIterator (r_obj, ruv, &it);
  150. if (it)
  151. {
  152. i = 0;
  153. while ((rc = cl5GetNextOperationToReplay (it, &op)) == CL5_SUCCESS)
  154. {
  155. ruv_set_csns (ruv, op.csn, NULL);
  156. operation_parameters_done (&op);
  157. i ++;
  158. }
  159. }
  160. if (it)
  161. cl5DestroyReplayIterator (&it);
  162. if (rc == CL5_NOTFOUND)
  163. {
  164. if (i == 0) /* success */
  165. slapi_log_error(SLAPI_LOG_FATAL, LOG_ERR, repl_plugin_name_cl, "First iteration pass completed "
  166. "successfully: no changes to replay\n");
  167. else /* incorrect number of entries traversed */
  168. slapi_log_error(SLAPI_LOG_FATAL, LOG_ERR, repl_plugin_name_cl, "First iteration pass failed: "
  169. "traversed %d entries; expected none\n", i);
  170. }
  171. else /* general error */
  172. slapi_log_error(SLAPI_LOG_FATAL, LOG_ERR, repl_plugin_name_cl, "First iteration pass failed\n");
  173. slapi_log_error(SLAPI_LOG_FATAL, LOG_ERR, repl_plugin_name_cl, "Starting second iteration pass ...\n");
  174. /* add some entries */
  175. populateChangelogOp ();
  176. /* create replay iterator */
  177. rc = cl5CreateReplayIterator (r_obj, ruv, &it);
  178. if (it)
  179. {
  180. i = 0;
  181. while ((rc = cl5GetNextOperationToReplay (it, &op)) == CL5_SUCCESS)
  182. {
  183. ruv_set_csns (ruv, op.csn, NULL);
  184. operation_parameters_done (&op);
  185. i ++;
  186. }
  187. }
  188. if (it)
  189. cl5DestroyReplayIterator (&it);
  190. if (rc == CL5_NOTFOUND)
  191. {
  192. if (i == OP_COUNT) /* success */
  193. slapi_log_error(SLAPI_LOG_FATAL, LOG_ERR, repl_plugin_name_cl, "Second iteration pass completed "
  194. "successfully: %d entries traversed\n", i);
  195. else /* incorrect number of entries traversed */
  196. slapi_log_error(SLAPI_LOG_FATAL, LOG_ERR, repl_plugin_name_cl, "Second iteration pass failed: "
  197. "traversed %d entries; expected %d\n", i, OP_COUNT);
  198. }
  199. else /* general error */
  200. slapi_log_error(SLAPI_LOG_FATAL, LOG_ERR, repl_plugin_name_cl, "Second iteration pass failed\n");
  201. slapi_log_error(SLAPI_LOG_FATAL, LOG_ERR, repl_plugin_name_cl, "Starting third iteration pass ...\n");
  202. /* add more entries */
  203. populateChangelogOp ();
  204. /* create replay iterator */
  205. rc = cl5CreateReplayIterator (r_obj, ruv, &it);
  206. if (it)
  207. {
  208. i = 0;
  209. while ((rc = cl5GetNextOperationToReplay (it, &op)) == CL5_SUCCESS)
  210. {
  211. ruv_set_csns (ruv, op.csn, NULL);
  212. operation_parameters_done (&op);
  213. i ++;
  214. }
  215. }
  216. if (it)
  217. cl5DestroyReplayIterator (&it);
  218. if (rc == CL5_NOTFOUND)
  219. {
  220. if (i == OP_COUNT) /* success */
  221. slapi_log_error(SLAPI_LOG_FATAL, LOG_ERR, repl_plugin_name_cl, "Third iteration pass completed "
  222. "successfully: %d entries traversed\n", i);
  223. else /* incorrect number of entries traversed */
  224. slapi_log_error(SLAPI_LOG_FATAL, LOG_ERR, repl_plugin_name_cl, "Third iteration pass failed: "
  225. "traversed %d entries; expected %d\n", i, OP_COUNT);
  226. }
  227. else /* general error */
  228. slapi_log_error(SLAPI_LOG_FATAL, LOG_ERR, repl_plugin_name_cl, "Second iteration pass failed\n");
  229. slapi_log_error(SLAPI_LOG_FATAL, LOG_ERR, repl_plugin_name_cl, "Iteration test is complete\n");
  230. ruv_destroy (&ruv);
  231. object_release (r_obj);
  232. slapi_ch_free ((void**)&replGen);
  233. }
  234. static void testTrimming ()
  235. {
  236. PRIntervalTime interval;
  237. int count;
  238. int rc;
  239. slapi_log_error(SLAPI_LOG_FATAL, LOG_ERR, repl_plugin_name_cl, "Starting trimming test ...\n");
  240. rc = populateChangelog (200, NULL);
  241. if (rc == 0)
  242. {
  243. interval = PR_SecondsToInterval(2);
  244. DS_Sleep (interval);
  245. rc = populateChangelog (300, NULL);
  246. if (rc == 0)
  247. rc = cl5ConfigTrimming (300, "1d", CHANGELOGDB_COMPACT_INTERVAL, CHANGELOGDB_TRIM_INTERVAL);
  248. interval = PR_SecondsToInterval(300); /* 5 min is default trimming interval */
  249. slapi_log_error(SLAPI_LOG_FATAL, LOG_ERR, repl_plugin_name_cl,
  250. "Trimming test: sleeping for 5 minutes until trimming kicks in\n");
  251. DS_Sleep (interval);
  252. count = cl5GetOperationCount (NULL);
  253. }
  254. if (rc == 0 && count == 300)
  255. {
  256. slapi_log_error(SLAPI_LOG_FATAL, LOG_ERR, repl_plugin_name_cl,
  257. "Trimming test completed successfully: changelog contains 300 entries\n");
  258. }
  259. else if (rc == 0)
  260. {
  261. slapi_log_error(SLAPI_LOG_FATAL, LOG_ERR, repl_plugin_name_cl,
  262. "Trimming test failed: changelog contains %d entries; expected - 300\n",
  263. count);
  264. }
  265. else /* general failure */
  266. slapi_log_error(SLAPI_LOG_FATAL, LOG_ERR, repl_plugin_name_cl, "Trimming test failed\n");
  267. }
  268. static void testPerformance ()
  269. {
  270. PRTime starttime, endtime, totaltime;
  271. int entryCount = 5000;
  272. CSN **csnList = NULL;
  273. int rc;
  274. starttime = PR_Now();
  275. rc = populateChangelog (entryCount, &csnList);
  276. endtime = PR_Now();
  277. totaltime = (endtime - starttime) / 1000; /* ms */
  278. slapi_log_error(SLAPI_LOG_FATAL, LOG_ERR, repl_plugin_name_cl, "Write performance:\n"
  279. "entry count - %d, total time - %ldms\n"
  280. "latency = %d msec\nthroughput = %d entry/sec\n",
  281. entryCount, totaltime,
  282. totaltime / entryCount, entryCount * 1000 / totaltime);
  283. starttime = endtime;
  284. rc = processEntries (entryCount, csnList);
  285. endtime = PR_Now();
  286. totaltime = (endtime - starttime) / 1000; /* ms */
  287. slapi_log_error(SLAPI_LOG_FATAL, LOG_ERR, repl_plugin_name_cl, "Read performance:\n"
  288. "entry count - %d, total time - %ld\n"
  289. "latency = %d msec\nthroughput = %d entry/sec\n",
  290. entryCount, totaltime,
  291. totaltime / entryCount, entryCount * 1000 / totaltime);
  292. clearCSNList (&csnList, entryCount);
  293. }
  294. static int threadsLeft;
  295. static void testPerformanceMT ()
  296. {
  297. PRTime starttime, endtime, totaltime;
  298. int entryCount = 200;
  299. int threadCount = 10;
  300. int entryTotal;
  301. int i;
  302. PRIntervalTime interval;
  303. interval = PR_MillisecondsToInterval(100);
  304. threadsLeft = threadCount * 2;
  305. entryTotal = threadCount * entryCount;
  306. starttime = PR_Now();
  307. for (i = 0; i < threadCount; i++)
  308. {
  309. PR_CreateThread(PR_USER_THREAD, threadMain, (void*)&entryCount,
  310. PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD,
  311. PR_UNJOINABLE_THREAD, 0);
  312. }
  313. while (threadsLeft > 5)
  314. DS_Sleep (interval);
  315. endtime = PR_Now();
  316. totaltime = (endtime - starttime) / 1000; /* ms */
  317. slapi_log_error(SLAPI_LOG_FATAL, LOG_ERR, repl_plugin_name_cl, "Write performance:\n"
  318. "entry count - %d, total time - %ld\n"
  319. "latency = %d msec per entry\nthroughput = %d entry/sec\n",
  320. entryCount, totaltime,
  321. totaltime / entryTotal, entryTotal * 1000 / totaltime);
  322. starttime = endtime;
  323. while (threadsLeft != 0)
  324. DS_Sleep (interval);
  325. endtime = PR_Now();
  326. totaltime = (endtime - starttime) / 1000; /* ms */
  327. slapi_log_error(SLAPI_LOG_FATAL, LOG_ERR, repl_plugin_name_cl, "Read performance:\n"
  328. "entry count - %d, total time - %ld\n"
  329. "latency = %d msec per entry\nthroughput = %d entry/sec\n",
  330. entryCount, totaltime,
  331. totaltime / entryTotal, entryTotal * 1000 / totaltime);
  332. }
  333. static void testLDIF ()
  334. {
  335. char *clDir = cl5GetDir ();
  336. int rc;
  337. char *baseDir;
  338. char ldifFile [MAXPATHLEN];
  339. slapi_log_error(SLAPI_LOG_FATAL, LOG_ERR, repl_plugin_name_cl, "Starting LDIF test ...\n");
  340. baseDir = getBaseDir (clDir);
  341. PR_snprintf (ldifFile, sizeof(ldifFile), "%s/cl5.ldif", baseDir);
  342. slapi_ch_free ((void**)&baseDir);
  343. rc = populateChangelog (ENTRY_COUNT, NULL);
  344. if (rc == CL5_SUCCESS)
  345. {
  346. rc = cl5ExportLDIF (ldifFile, NULL);
  347. if (rc == CL5_SUCCESS)
  348. {
  349. cl5Close();
  350. rc = cl5ImportLDIF (clDir, ldifFile, NULL);
  351. if (rc == CL5_SUCCESS)
  352. cl5Open(clDir, NULL);
  353. }
  354. }
  355. PR_Delete (ldifFile);
  356. if (rc == CL5_SUCCESS)
  357. slapi_log_error(SLAPI_LOG_FATAL, LOG_ERR, repl_plugin_name_cl,
  358. "LDIF test completed successfully\n");
  359. else
  360. slapi_log_error(SLAPI_LOG_FATAL, LOG_ERR, repl_plugin_name_cl, "LDIF test failed\n");
  361. }
  362. static void testAll ()
  363. {
  364. testBasic ();
  365. testIteration ();
  366. testBackupRestore ();
  367. testLDIF ();
  368. /* testTrimming ();*/
  369. #if 0
  370. /* xxxPINAKI */
  371. /* these tests are not working correctly...the call to db->put() */
  372. /* just hangs forever */
  373. slapi_log_error(SLAPI_LOG_FATAL, LOG_ERR, repl_plugin_name_cl,
  374. "Starting single threaded performance measurement ...\n");
  375. testPerformance ();
  376. slapi_log_error(SLAPI_LOG_FATAL, LOG_ERR, repl_plugin_name_cl,
  377. "Starting multi threaded performance measurement ...\n");
  378. testPerformanceMT ();
  379. #endif
  380. }
  381. static int populateChangelog (int entryCount, CSN ***csnList)
  382. {
  383. CSN *csn;
  384. int i;
  385. slapi_operation_parameters op;
  386. int rc;
  387. char *uniqueid;
  388. if (csnList)
  389. {
  390. (*csnList) = (CSN**)slapi_ch_calloc (entryCount, sizeof (CSN*));
  391. }
  392. /* generate entries */
  393. for (i = 0; i < entryCount; i++)
  394. {
  395. /* ONREPL need to get replica object
  396. rc = csnGetNewCSNForRepl (&csn);
  397. if (rc != CL5_SUCCESS) */
  398. return -1;
  399. if (csnList)
  400. (*csnList) [i] = csn_dup (csn);
  401. memset (&op, 0, sizeof (op));
  402. op.csn = csn;
  403. slapi_uniqueIDGenerateString(&uniqueid);
  404. op.target_address.uniqueid = uniqueid;
  405. op.target_address.dn = slapi_ch_strdup ("cn=entry,dc=example,dc=com");
  406. if (i % 5 == 0)
  407. {
  408. op.operation_type = SLAPI_OPERATION_MODRDN;
  409. op.p.p_modrdn.modrdn_deloldrdn = 1;
  410. op.p.p_modrdn.modrdn_newrdn = slapi_ch_strdup("cn=entry2,dc=example,dc=com");
  411. op.p.p_modrdn.modrdn_newsuperior_address.dn = NULL;
  412. op.p.p_modrdn.modrdn_newsuperior_address.uniqueid = NULL;
  413. op.p.p_modrdn.modrdn_mods = buildMods ();
  414. }
  415. else if (i % 4 == 0)
  416. {
  417. op.operation_type = SLAPI_OPERATION_DELETE;
  418. }
  419. else if (i % 3 == 0)
  420. {
  421. op.operation_type = SLAPI_OPERATION_ADD;
  422. op.p.p_add.target_entry = slapi_entry_alloc ();
  423. slapi_entry_set_dn (op.p.p_add.target_entry, slapi_ch_strdup(op.target_address.dn));
  424. slapi_entry_set_uniqueid (op.p.p_add.target_entry, slapi_ch_strdup(op.target_address.uniqueid));
  425. slapi_entry_attr_set_charptr(op.p.p_add.target_entry, "objectclass", "top");
  426. slapi_entry_attr_set_charptr(op.p.p_add.target_entry, "cn", "entry");
  427. }
  428. else
  429. {
  430. op.operation_type = SLAPI_OPERATION_MODIFY;
  431. op.p.p_modify.modify_mods = buildMods ();
  432. }
  433. /* ONREPL rc = cl5WriteOperation (&op, 1);*/
  434. operation_parameters_done (&op);
  435. if (rc != CL5_SUCCESS)
  436. return -1;
  437. }
  438. slapi_log_error(SLAPI_LOG_FATAL, LOG_ERR, repl_plugin_name_cl,
  439. "Successfully populated changelog with %d entries\n", entryCount);
  440. return 0;
  441. }
  442. static int processEntries (int entryCount, CSN **csnList)
  443. {
  444. int i;
  445. int rc = 0;
  446. slapi_operation_parameters op;
  447. for (i = 0; i < entryCount; i++)
  448. {
  449. memset (&op, 0, sizeof (op));
  450. op.csn = csn_dup (csnList [i]);
  451. /* rc = cl5GetOperation (&op);*/
  452. if (rc != CL5_SUCCESS)
  453. return -1;
  454. operation_parameters_done (&op);
  455. }
  456. slapi_log_error(SLAPI_LOG_FATAL, LOG_ERR, repl_plugin_name_cl,
  457. "Successfully read %d entries from the changelog\n", entryCount);
  458. return 0;
  459. }
  460. void clearCSNList (CSN ***csnList, int count)
  461. {
  462. int i;
  463. for (i = 0; i < count; i++)
  464. {
  465. csn_free (&((*csnList)[i]));
  466. }
  467. slapi_ch_free ((void**)csnList);
  468. }
  469. static void threadMain (void *data)
  470. {
  471. int entryCount = *(int*)data;
  472. CSN **csnList;
  473. populateChangelog (entryCount, &csnList);
  474. PR_AtomicDecrement (&threadsLeft);
  475. processEntries (entryCount, csnList);
  476. PR_AtomicDecrement (&threadsLeft);
  477. clearCSNList (&csnList, entryCount);
  478. }
  479. static char* getBaseDir (const char *dir)
  480. {
  481. char *baseDir = slapi_ch_strdup (dir);
  482. char *ch;
  483. ch = &(baseDir [strlen (dir) - 2]);
  484. while (ch >= baseDir && *ch != '\\' && *ch != '/')
  485. ch --;
  486. if (ch >= baseDir)
  487. {
  488. *ch = '\0';
  489. }
  490. return baseDir;
  491. }
  492. static LDAPMod **buildMods ()
  493. {
  494. Slapi_Mods smods;
  495. Slapi_Mod smod;
  496. LDAPMod **mods;
  497. struct berval bv;
  498. int j, k;
  499. slapi_mods_init (&smods, MOD_COUNT);
  500. for (j = 0; j < MOD_COUNT; j++)
  501. {
  502. slapi_mod_init (&smod, VALUE_COUNT);
  503. slapi_mod_set_operation (&smod, LDAP_MOD_ADD | LDAP_MOD_BVALUES);
  504. slapi_mod_set_type (&smod, "attr");
  505. for (k = 0; k < VALUE_COUNT; k++)
  506. {
  507. bv.bv_val = "bvalue";
  508. bv.bv_len = strlen (bv.bv_val) + 1;
  509. slapi_mod_add_value (&smod, &bv);
  510. }
  511. slapi_mods_add_smod (&smods, &smod);
  512. /* ONREPL slapi_mod_done (&smod); */
  513. }
  514. mods = slapi_mods_get_ldapmods_passout (&smods);
  515. slapi_mods_done (&smods);
  516. return mods;
  517. }
  518. /* Format:
  519. dn: cn=changelog5,cn=config
  520. objectclass: top
  521. objectclass: extensibleObject
  522. cn: changelog5
  523. nsslapd-changelogDir: d:/netscape/server4/slapd-elf/cl5 */
  524. static int configureChangelog ()
  525. {
  526. Slapi_PBlock *pb = slapi_pblock_new ();
  527. Slapi_Entry *e = slapi_entry_alloc ();
  528. int rc;
  529. char *attrs[] = {INSTANCE_ATTR, NULL};
  530. Slapi_Entry **entries;
  531. char cl_dir [256];
  532. char *str = NULL;
  533. /* set changelog dn */
  534. slapi_entry_set_dn (e, slapi_ch_strdup (CL_DN));
  535. /* set object classes */
  536. slapi_entry_add_string(e, "objectclass", "top");
  537. slapi_entry_add_string(e, "objectclass", "extensibleObject");
  538. /* get directory instance dir */
  539. slapi_search_internal_set_pb (pb, "cn=config", LDAP_SCOPE_BASE, "objectclass=*",
  540. attrs, 0, NULL, NULL,
  541. repl_get_plugin_identity (PLUGIN_MULTIMASTER_REPLICATION), 0);
  542. slapi_search_internal_pb (pb);
  543. slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT, &rc);
  544. if (rc != LDAP_SUCCESS)
  545. {
  546. slapi_log_error(SLAPI_LOG_FATAL, LOG_ERR, repl_plugin_name_cl, "failed to get server instance "
  547. "directory; LDAP error - %d\n", rc);
  548. rc = -1;
  549. goto done;
  550. }
  551. slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &entries);
  552. str = slapi_entry_attr_get_charptr(entries[0], INSTANCE_ATTR);
  553. PR_snprintf (cl_dir, sizeof(cl_dir), "%s/%s", str, "cl5db");
  554. slapi_ch_free((void **)&str);
  555. slapi_entry_add_string (e, CONFIG_CHANGELOG_DIR_ATTRIBUTE, cl_dir);
  556. slapi_free_search_results_internal(pb);
  557. slapi_pblock_destroy (pb);
  558. pb = slapi_pblock_new ();
  559. slapi_add_entry_internal_set_pb (pb, e, NULL,
  560. repl_get_plugin_identity (PLUGIN_MULTIMASTER_REPLICATION), 0);
  561. slapi_add_internal_pb (pb);
  562. slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT, &rc);
  563. if (rc != LDAP_SUCCESS)
  564. {
  565. slapi_log_error(SLAPI_LOG_FATAL, LOG_ERR, repl_plugin_name_cl, "failed to add changelog "
  566. "configuration entry; LDAP error - %d\n", rc);
  567. rc = -1;
  568. }
  569. else
  570. rc = 0;
  571. done:
  572. slapi_pblock_destroy (pb);
  573. return rc;
  574. }
  575. #define DN_SIZE 1024
  576. /* Format:
  577. dn: cn=replica,cn="o=NetscapeRoot",cn= mapping tree,cn=config
  578. objectclass: top
  579. objectclass: nsds5Replica
  580. objectclass: extensibleObject
  581. nsds5ReplicaRoot: o=NetscapeRoot
  582. nsds5ReplicaId: 2
  583. nsds5flags: 1
  584. cn: replica
  585. */
  586. static int configureReplica ()
  587. {
  588. Slapi_PBlock *pb = slapi_pblock_new ();
  589. Slapi_Entry *e = slapi_entry_alloc ();
  590. int rc;
  591. char dn [DN_SIZE];
  592. /* set changelog dn */
  593. PR_snprintf (dn, sizeof(dn), "%s,cn=\"%s\",%s", REPLICA_RDN, REPLICA_ROOT,
  594. slapi_get_mapping_tree_config_root ());
  595. slapi_entry_set_dn (e, slapi_ch_strdup (dn));
  596. /* set object classes */
  597. slapi_entry_add_string(e, "objectclass", "top");
  598. slapi_entry_add_string(e, "objectclass", REPLICA_OC);
  599. slapi_entry_add_string(e, "objectclass", "extensibleObject");
  600. /* set other attributes */
  601. slapi_entry_add_string (e, attr_replicaRoot, REPLICA_ROOT);
  602. slapi_entry_add_string (e, attr_replicaId, "1");
  603. slapi_entry_add_string (e, attr_flags, "1");
  604. slapi_add_entry_internal_set_pb (pb, e, NULL,
  605. repl_get_plugin_identity (PLUGIN_MULTIMASTER_REPLICATION), 0);
  606. slapi_add_internal_pb (pb);
  607. slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT, &rc);
  608. if (rc != LDAP_SUCCESS)
  609. {
  610. slapi_log_error(SLAPI_LOG_FATAL, LOG_ERR, repl_plugin_name_cl, "failed to add replica for (%s) "
  611. "configuration entry; LDAP error - %d\n", REPLICA_ROOT, rc);
  612. rc = -1;
  613. }
  614. else
  615. rc = 0;
  616. slapi_pblock_destroy (pb);
  617. return rc;
  618. }
  619. /* generates one of each ldap operations */
  620. static int populateChangelogOp ()
  621. {
  622. Slapi_PBlock *pb = slapi_pblock_new ();
  623. Slapi_Entry *e = slapi_entry_alloc ();
  624. int rc;
  625. char dn [DN_SIZE], newrdn [64];
  626. LDAPMod *mods[2];
  627. Slapi_Mod smod;
  628. struct berval bv;
  629. time_t cur_time;
  630. /* add entry */
  631. cur_time = time(NULL);
  632. PR_snprintf (dn, sizeof(dn), "cn=%s,%s", ctime(&cur_time), REPLICA_ROOT);
  633. slapi_entry_set_dn (e, slapi_ch_strdup (dn));
  634. slapi_entry_add_string(e, "objectclass", "top");
  635. slapi_entry_add_string(e, "objectclass", "extensibleObject");
  636. slapi_entry_add_string (e, "mail", "[email protected]");
  637. slapi_add_entry_internal_set_pb (pb, e, NULL,
  638. repl_get_plugin_identity (PLUGIN_MULTIMASTER_REPLICATION), 0);
  639. slapi_add_internal_pb (pb);
  640. slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT, &rc);
  641. slapi_pblock_destroy (pb);
  642. if (rc != LDAP_SUCCESS)
  643. {
  644. slapi_log_error(SLAPI_LOG_FATAL, LOG_ERR, repl_plugin_name_cl, "failed to add entry (%s); "
  645. "LDAP error - %d\n", dn, rc);
  646. return -1;
  647. }
  648. /* modify entry */
  649. pb = slapi_pblock_new ();
  650. slapi_mod_init (&smod, 1);
  651. slapi_mod_set_type (&smod, "mail");
  652. slapi_mod_set_operation (&smod, LDAP_MOD_REPLACE | LDAP_MOD_BVALUES);
  653. bv.bv_val = "[email protected]";
  654. bv.bv_len = strlen (bv.bv_val);
  655. slapi_mod_add_value(&smod, &bv);
  656. mods[0] = (LDAPMod*)slapi_mod_get_ldapmod_byref(&smod);
  657. mods[1] = NULL;
  658. slapi_modify_internal_set_pb (pb, dn, mods, NULL, NULL,
  659. repl_get_plugin_identity (PLUGIN_MULTIMASTER_REPLICATION), 0);
  660. slapi_modify_internal_pb (pb);
  661. slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT, &rc);
  662. slapi_mod_done (&smod);
  663. slapi_pblock_destroy (pb);
  664. if (rc != LDAP_SUCCESS)
  665. {
  666. slapi_log_error(SLAPI_LOG_FATAL, LOG_ERR, repl_plugin_name_cl, "failed to modify entry (%s); "
  667. "LDAP error - %d\n", dn, rc);
  668. return -1;
  669. }
  670. /* rename entry */
  671. pb = slapi_pblock_new ();
  672. cur_time = time (NULL);
  673. PR_snprintf (newrdn, sizeof(newrdn), "cn=renamed%s", ctime(&cur_time));
  674. slapi_rename_internal_set_pb_ext (pb, dn, newrdn, NULL, 1, NULL, NULL,
  675. repl_get_plugin_identity (PLUGIN_MULTIMASTER_REPLICATION), 0);
  676. slapi_modrdn_internal_pb (pb);
  677. slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT, &rc);
  678. slapi_pblock_destroy (pb);
  679. if (rc != LDAP_SUCCESS)
  680. {
  681. slapi_log_error(SLAPI_LOG_FATAL, LOG_ERR, repl_plugin_name_cl, "failed to rename entry (%s); "
  682. "LDAP error - %d\n", dn, rc);
  683. return -1;
  684. }
  685. /* delete the entry */
  686. pb = slapi_pblock_new ();
  687. PR_snprintf (dn, sizeof(dn), "%s,%s", newrdn, REPLICA_ROOT);
  688. slapi_delete_internal_set_pb (pb, dn, NULL, NULL,
  689. repl_get_plugin_identity (PLUGIN_MULTIMASTER_REPLICATION), 0);
  690. slapi_delete_internal_pb (pb);
  691. slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT, &rc);
  692. slapi_pblock_destroy (pb);
  693. if (rc != LDAP_SUCCESS)
  694. {
  695. slapi_log_error(SLAPI_LOG_FATAL, LOG_ERR, repl_plugin_name_cl, "failed to delete entry (%s); "
  696. "LDAP error - %d\n", dn, rc);
  697. return -1;
  698. }
  699. return 0;
  700. }