1471
1472
* Decode the payload, and grab our settings
1473
1474
if(decode_cleanruv_payload(extop_payload, &payload)){
1474
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "Abort cleanAllRUV task: failed to decode payload. Aborting ext op\n");
1475
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "Abort CleanAllRUV Task: failed to decode payload. Aborting ext op\n");
1475
1476
return LDAP_OPERATIONS_ERROR;
1477
1478
rid = atoi(ldap_utf8strtok_r(payload, ":", &iter));
1478
1479
repl_root = ldap_utf8strtok_r(iter, ":", &iter);
1479
1480
certify_all = ldap_utf8strtok_r(iter, ":", &iter);
1481
if(!is_cleaned_rid(rid) || is_task_aborted(rid)){
1482
if(!is_cleaned_rid(rid) || !is_pre_cleaned_rid(rid) || is_task_aborted(rid)){
1482
1483
/* This replica has already been aborted, or was never cleaned, or already finished cleaning */
1485
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "Abort cleanAllRUV task: aborting cleanallruv task for rid(%d)\n", rid);
1486
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "Abort CleanAllRUV Task: aborting cleanallruv task for rid(%d)\n", rid);
1488
1489
* Get the node, so we can get the replica and its agreements
1490
1491
if((mtnode_ext = replica_config_get_mtnode_by_dn(repl_root)) == NULL){
1491
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "Abort cleanAllRUV task: failed to get replication node "
1492
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "Abort CleanAllRUV Task: failed to get replication node "
1492
1493
"from (%s), aborting operation\n", repl_root);
1493
1494
rc = LDAP_OPERATIONS_ERROR;
1496
1497
if (mtnode_ext->replica){
1497
1498
object_acquire (mtnode_ext->replica);
1499
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "Abort cleanAllRUV task: replica is missing from (%s), "
1501
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "Abort CleanAllRUV Task: replica is missing from (%s), "
1500
1502
"aborting operation\n",repl_root);
1501
1503
rc = LDAP_OPERATIONS_ERROR;
1504
1506
r = (Replica*)object_get_data (mtnode_ext->replica);
1506
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "Abort cleanAllRUV task: replica is NULL, aborting task\n");
1508
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "Abort CleanAllRUV Task: replica is NULL, aborting task\n");
1507
1509
rc = LDAP_OPERATIONS_ERROR;
1592
1596
if (NULL == extop_oid || strcmp(extop_oid, REPL_CLEANRUV_OID) != 0 ||
1593
1597
NULL == extop_payload || NULL == extop_payload->bv_val){
1594
1598
/* something is wrong, error out */
1596
1599
goto free_and_return;
1599
1602
* Decode the payload
1601
1604
if(decode_cleanruv_payload(extop_payload, &payload)){
1602
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: failed to decode payload. Aborting ext op\n");
1605
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "CleanAllRUV Task: failed to decode payload. Aborting ext op\n");
1604
1606
goto free_and_return;
1606
1608
rid = atoi(ldap_utf8strtok_r(payload, ":", &iter));
1607
1609
repl_root = ldap_utf8strtok_r(iter, ":", &iter);
1608
1610
csnstr = ldap_utf8strtok_r(iter, ":", &iter);
1611
force = ldap_utf8strtok_r(iter, ":", &iter);
1609
1615
maxcsn = csn_new();
1610
1616
csn_init_by_string(maxcsn, csnstr);
1612
1618
* If we already cleaned this server, just return success
1614
if(is_cleaned_rid(rid)){
1620
if(is_cleaned_rid(rid) || is_pre_cleaned_rid(rid) || is_task_aborted(rid)){
1615
1621
csn_free(&maxcsn);
1617
1623
goto free_and_return;
1621
1626
* Get the node, so we can get the replica and its agreements
1623
1628
if((mtnode_ext = replica_config_get_mtnode_by_dn(repl_root)) == NULL){
1624
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: failed to get replication node "
1629
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "CleanAllRUV Task: failed to get replication node "
1625
1630
"from (%s), aborting operation\n", repl_root);
1627
1631
goto free_and_return;
1630
1634
if (mtnode_ext->replica){
1631
1635
object_acquire (mtnode_ext->replica);
1632
1636
release_it = 1;
1634
if (mtnode_ext->replica == NULL){
1635
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: replica is missing from (%s), "
1638
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "CleanAllRUV Task: replica is missing from (%s), "
1636
1639
"aborting operation\n",repl_root);
1637
rc = LDAP_OPERATIONS_ERROR;
1638
1640
goto free_and_return;
1641
1643
r = (Replica*)object_get_data (mtnode_ext->replica);
1643
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: replica is NULL, aborting task\n");
1645
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "CleanAllRUV Task: replica is NULL, aborting task\n");
1645
1646
goto free_and_return;
1713
1723
/* free everything */
1714
1724
object_release(ruv_obj);
1716
if (mtnode_ext->replica && release_it)
1717
object_release (mtnode_ext->replica);
1719
1726
* This read-only replica has no easy way to tell when it's safe to release the rid.
1720
1727
* So we won't release it, not until a server restart.
1722
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: You must restart the server if you want to reuse rid(%d).\n", rid);
1723
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: Successfully cleaned rid(%d).\n", rid);
1729
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "CleanAllRUV Task: You must restart the server if you want to reuse rid(%d).\n", rid);
1730
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "CleanAllRUV Task: Successfully cleaned rid(%d).\n", rid);
1726
1734
free_and_return:
1727
if(rc && release_it){
1728
if (mtnode_ext->replica)
1729
object_release (mtnode_ext->replica);
1735
if(release_it && mtnode_ext && mtnode_ext->replica) {
1736
object_release (mtnode_ext->replica);
1733
1739
slapi_ch_free_string(&payload);
1736
1742
* Craft a message so we know this replica supports the task
1738
1744
if ((resp_bere = der_alloc())){
1740
ber_int_t response = 1;
1742
ber_printf(resp_bere, "{e}", response);
1743
ber_flatten(resp_bere, &resp_bval);
1744
slapi_pblock_set(pb, SLAPI_EXT_OP_RET_VALUE, resp_bval);
1745
slapi_send_ldap_result(pb, LDAP_SUCCESS, NULL, NULL, 0, NULL);
1747
if (NULL != resp_bere)
1749
ber_free(resp_bere, 1);
1752
if (NULL != resp_bval)
1754
ber_bvfree(resp_bval);
1745
ber_printf(resp_bere, "{s}", CLEANRUV_ACCEPTED);
1746
ber_flatten(resp_bere, &resp_bval);
1747
slapi_pblock_set(pb, SLAPI_EXT_OP_RET_VALUE, resp_bval);
1748
slapi_send_ldap_result(pb, LDAP_SUCCESS, NULL, NULL, 0, NULL);
1750
if (NULL != resp_bere)
1752
ber_free(resp_bere, 1);
1755
if (NULL != resp_bval)
1757
ber_bvfree(resp_bval);
1759
/* tell extendop code that we have already sent the result */
1760
rc = SLAPI_PLUGIN_EXTENDED_SENT_RESULT;
1762
rc = LDAP_OPERATIONS_ERROR;
1769
* Get the max csn for the designated repl area
1772
multimaster_extop_cleanruv_get_maxcsn(Slapi_PBlock *pb)
1774
Slapi_PBlock *search_pb = NULL;
1775
Slapi_Entry **entries = NULL;
1776
struct berval *resp_bval = NULL;
1777
struct berval *extop_payload;
1778
BerElement *resp_bere = NULL;
1779
char **ruv_elements = NULL;
1780
char *extop_oid = NULL;
1781
char *ruv_part = NULL;
1782
char *base_dn = NULL;
1783
char *payload = NULL;
1784
char *maxcsn = NULL;
1785
char *filter = NULL;
1786
char *ridstr = NULL;
1792
int rc = LDAP_OPERATIONS_ERROR;
1795
slapi_pblock_get(pb, SLAPI_EXT_OP_REQ_OID, &extop_oid);
1796
slapi_pblock_get(pb, SLAPI_EXT_OP_REQ_VALUE, &extop_payload);
1798
if (NULL == extop_oid || strcmp(extop_oid, REPL_CLEANRUV_GET_MAXCSN_OID) != 0 ||
1799
NULL == extop_payload || NULL == extop_payload->bv_val){
1800
/* something is wrong, error out */
1801
goto free_and_return;
1804
* Decode the payload
1806
if(decode_cleanruv_payload(extop_payload, &payload)){
1807
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "CleanAllRUV Get MaxCSN Task: failed to decode payload. Aborting ext op\n");
1808
goto free_and_return;
1810
rid = atoi(ldap_utf8strtok_r(payload, ":", &iter));
1811
base_dn = ldap_utf8strtok_r(iter, ":", &iter);
1813
* Get the maxruv from the database tombstone entry
1815
filter = "(&(nsuniqueid=ffffffff-ffffffff-ffffffff-ffffffff)(objectclass=nstombstone))";
1816
attrs[0] = "nsds50ruv";
1818
ridstr = slapi_ch_smprintf("{replica %d ldap", rid);
1820
search_pb = slapi_pblock_new();
1821
slapi_search_internal_set_pb(search_pb, base_dn, LDAP_SCOPE_SUBTREE, filter, attrs, 0, NULL, NULL, repl_get_plugin_identity(PLUGIN_MULTIMASTER_REPLICATION), 0);
1822
slapi_search_internal_pb (search_pb);
1823
slapi_pblock_get(search_pb, SLAPI_PLUGIN_INTOP_RESULT, &res);
1825
if ( LDAP_SUCCESS == res ) {
1826
slapi_pblock_get(search_pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &entries);
1827
if (NULL == entries || entries[0] == NULL) {
1828
/* Hmmm, no tombstpne! Error out */
1830
/* find the right ruv element, and find the maxcsn */
1831
ruv_elements = slapi_entry_attr_get_charray(entries[0],attrs[0]);
1832
for(i = 0; ruv_elements && ruv_elements[i] ; i++){
1833
if(strstr(ruv_elements[i], ridstr)){
1834
/* get the max csn */
1835
ruv_part = ldap_utf8strtok_r(ruv_elements[i], " ", &iter);
1836
for(part_count = 1; ruv_part && part_count < 5; part_count++){
1837
ruv_part = ldap_utf8strtok_r(iter, " ", &iter);
1839
if(part_count == 5 && ruv_part){/* we have the maxcsn */
1840
maxcsn = slapi_ch_strdup(ruv_part);
1845
slapi_ch_array_free(ruv_elements);
1848
/* internal search failed */
1849
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "CleanAllRUV Get MaxCSN Task: internal search failed (%d)\n", res);
1852
maxcsn = slapi_ch_strdup(CLEANRUV_NO_MAXCSN);
1855
* Send the extended op response
1857
if ((resp_bere = der_alloc())){
1858
ber_printf(resp_bere, "{s}", maxcsn);
1859
ber_flatten(resp_bere, &resp_bval);
1860
slapi_pblock_set(pb, SLAPI_EXT_OP_RET_VALUE, resp_bval);
1861
slapi_send_ldap_result(pb, LDAP_SUCCESS, NULL, NULL, 0, NULL);
1863
if (NULL != resp_bere)
1865
ber_free(resp_bere, 1);
1868
if (NULL != resp_bval)
1870
ber_bvfree(resp_bval);
1872
/* tell extendop code that we have already sent the result */
1873
rc = SLAPI_PLUGIN_EXTENDED_SENT_RESULT;
1875
rc = LDAP_OPERATIONS_ERROR;
1879
slapi_free_search_results_internal(search_pb);
1880
slapi_pblock_destroy(search_pb);
1881
slapi_ch_free_string(&payload);
1882
slapi_ch_free_string(&maxcsn);
1883
slapi_ch_free_string(&ridstr);
1889
* Search cn=config for the cleanallruv attributes (clean & abort)
1892
multimaster_extop_cleanruv_check_status(Slapi_PBlock *pb)
1894
Slapi_PBlock *search_pb = NULL;
1895
Slapi_Entry **entries = NULL;
1896
struct berval *resp_bval = NULL;
1897
struct berval *extop_payload;
1898
BerElement *resp_bere = NULL;
1899
char *response = NULL;
1900
char *filter = NULL;
1903
int rc = LDAP_OPERATIONS_ERROR;
1905
slapi_pblock_get(pb, SLAPI_EXT_OP_REQ_OID, &extop_oid);
1906
slapi_pblock_get(pb, SLAPI_EXT_OP_REQ_VALUE, &extop_payload);
1908
if (NULL == extop_oid || strcmp(extop_oid, REPL_CLEANRUV_CHECK_STATUS_OID) != 0 ||
1909
NULL == extop_payload || NULL == extop_payload->bv_val){
1910
/* something is wrong, error out */
1911
goto free_and_return;
1914
* Decode the payload - which should just be a filter
1916
if(decode_cleanruv_payload(extop_payload, &filter)){
1917
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "CleanAllRUV Check Status Task: failed to decode payload. Aborting ext op\n");
1918
goto free_and_return;
1921
search_pb = slapi_pblock_new();
1922
slapi_search_internal_set_pb(search_pb, "cn=config", LDAP_SCOPE_SUBTREE,
1923
filter, NULL, 0, NULL, NULL, repl_get_plugin_identity(PLUGIN_MULTIMASTER_REPLICATION), 0);
1924
slapi_search_internal_pb (search_pb);
1925
slapi_pblock_get(search_pb, SLAPI_PLUGIN_INTOP_RESULT, &res);
1926
if ( LDAP_SUCCESS == res ) {
1927
slapi_pblock_get(search_pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &entries);
1928
if (NULL == entries || entries[0] == NULL) {
1929
/* cleaning task has finished, send repsonse */
1930
response = CLEANRUV_FINISHED;
1932
response = CLEANRUV_CLEANING;
1935
* Send the extended op response
1937
if ((resp_bere = der_alloc())){
1938
ber_printf(resp_bere, "{s}", response);
1939
ber_flatten(resp_bere, &resp_bval);
1940
slapi_pblock_set(pb, SLAPI_EXT_OP_RET_VALUE, resp_bval);
1941
slapi_send_ldap_result(pb, LDAP_SUCCESS, NULL, NULL, 0, NULL);
1943
if (NULL != resp_bere)
1945
ber_free(resp_bere, 1);
1948
if (NULL != resp_bval)
1950
ber_bvfree(resp_bval);
1952
/* tell extendop code that we have already sent the result */
1953
rc = SLAPI_PLUGIN_EXTENDED_SENT_RESULT;
1959
slapi_free_search_results_internal(search_pb);
1960
slapi_pblock_destroy(search_pb);
1961
slapi_ch_free_string(&filter);
1762
1968
* This plugin entry point is a noop entry