~ubuntu-branches/ubuntu/saucy/389-ds-base/saucy

« back to all changes in this revision

Viewing changes to ldap/servers/plugins/replication/repl_extop.c

  • Committer: Package Import Robot
  • Author(s): Timo Aaltonen
  • Date: 2013-02-06 18:06:31 UTC
  • mfrom: (11.1.1 raring-proposed)
  • Revision ID: package-import@ubuntu.com-20130206180631-h6ldv3k506hmm46e
Tags: 1.3.0.2-0ubuntu2
debian/*: Fix time stamps due to clock skew (FTBFS).

Show diffs side-by-side

added added

removed removed

Lines of Context:
906
906
 
907
907
        /* remove this code once ticket 374 is fixed */
908
908
#ifdef ENABLE_TEST_TICKET_374
 
909
#include <unistd.h>
909
910
        if (getenv("SLAPD_TEST_TICKET_374") && (opid > 20)) {
910
911
                int i = 0;
911
912
                int max = 480 * 5;
1445
1446
int
1446
1447
multimaster_extop_abort_cleanruv(Slapi_PBlock *pb)
1447
1448
{
1448
 
        multimaster_mtnode_extension *mtnode_ext;
 
1449
        multimaster_mtnode_extension *mtnode_ext = NULL;
 
1450
        int release_it = 0;
1449
1451
        PRThread *thread = NULL;
1450
1452
        cleanruv_data *data;
1451
1453
        Replica *r;
1452
1454
        ReplicaId rid;
1453
 
        CSN *maxcsn;
1454
 
        struct berval *extop_payload;
 
1455
        struct berval *extop_payload = NULL;
1455
1456
        char *extop_oid;
1456
1457
        char *repl_root;
1457
1458
        char *payload = NULL;
1458
1459
        char *certify_all;
1459
1460
        char *iter;
1460
 
        int rc = 0;
 
1461
        int rc = LDAP_SUCCESS;
1461
1462
 
1462
1463
        slapi_pblock_get(pb, SLAPI_EXT_OP_REQ_OID, &extop_oid);
1463
1464
        slapi_pblock_get(pb, SLAPI_EXT_OP_REQ_VALUE, &extop_payload);
1464
1465
 
1465
 
        if (NULL == extop_oid || strcmp(extop_oid, REPL_CLEANRUV_OID) != 0 ||
 
1466
        if (NULL == extop_oid || strcmp(extop_oid, REPL_ABORT_CLEANRUV_OID) != 0 ||
1466
1467
                NULL == extop_payload || NULL == extop_payload->bv_val){
1467
1468
                /* something is wrong, error out */
1468
1469
                return LDAP_OPERATIONS_ERROR;
1471
1472
         *  Decode the payload, and grab our settings
1472
1473
         */
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;
1476
1477
        }
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);
1480
1481
 
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 */
1483
1484
                goto out;
1484
1485
        } else {
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);
1486
1487
        }
1487
1488
        /*
1488
1489
         *  Get the node, so we can get the replica and its agreements
1489
1490
         */
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;
1494
1495
                goto out;
1495
1496
        }
1496
1497
        if (mtnode_ext->replica){
1497
1498
                object_acquire (mtnode_ext->replica);
 
1499
                release_it = 1;
1498
1500
        } else {
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;
1502
1504
                goto out;
1503
1505
        }
1504
1506
        r = (Replica*)object_get_data (mtnode_ext->replica);
1505
1507
        if(r == NULL){
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;
1508
1510
                goto out;
1509
1511
        }
1512
1514
         */
1513
1515
        data = (cleanruv_data*)slapi_ch_calloc(1, sizeof(cleanruv_data));
1514
1516
        if (data == NULL) {
1515
 
                slapi_log_error( SLAPI_LOG_REPL, repl_plugin_name, "Abort cleanAllRUV task: failed to allocate "
 
1517
                slapi_log_error( SLAPI_LOG_REPL, repl_plugin_name, "Abort CleanAllRUV Task: failed to allocate "
1516
1518
                        "abort_cleanruv_data.  Aborting task.\n");
1517
1519
                rc = LDAP_OPERATIONS_ERROR;
1518
1520
                goto out;
1519
1521
        }
1520
1522
        data->repl_obj = mtnode_ext->replica; /* released in replica_abort_task_thread() */
 
1523
        release_it = 0; /* thread owns it now */
1521
1524
        data->replica = r;
1522
1525
        data->task = NULL;
1523
1526
        data->payload = slapi_ch_bvdup(extop_payload);
1525
1528
        data->repl_root = slapi_ch_strdup(repl_root);
1526
1529
        data->certify = slapi_ch_strdup(certify_all);
1527
1530
        /*
1528
 
         *  Stop the cleaning, and delete the rid
 
1531
         *  Set the aborted rid and stop the cleaning
1529
1532
         */
1530
 
        maxcsn = replica_get_cleanruv_maxcsn(r, rid);
1531
 
        delete_cleaned_rid(r, rid, maxcsn);
1532
 
        csn_free(&maxcsn);
1533
1533
        add_aborted_rid(rid, r, repl_root);
1534
1534
        stop_ruv_cleaning();
1535
1535
        /*
1539
1539
                        (void *)data, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD,
1540
1540
                        PR_UNJOINABLE_THREAD, SLAPD_DEFAULT_THREAD_STACKSIZE);
1541
1541
        if (thread == NULL) {
1542
 
                if(mtnode_ext->replica){
1543
 
                        object_release(mtnode_ext->replica);
1544
 
                }
1545
 
                slapi_log_error( SLAPI_LOG_REPL, repl_plugin_name, "Abort cleanAllRUV task: unable to create abort "
 
1542
                slapi_log_error( SLAPI_LOG_REPL, repl_plugin_name, "Abort CleanAllRUV Task: unable to create abort "
1546
1543
                        "thread.  Aborting task.\n");
 
1544
                release_it = 1; /* have to release mtnode_ext->replica now */
1547
1545
                slapi_ch_free_string(&data->repl_root);
1548
1546
                slapi_ch_free_string(&data->certify);
 
1547
                ber_bvfree(data->payload);
 
1548
                slapi_ch_free((void **)&data);
1549
1549
                rc = LDAP_OPERATIONS_ERROR;
1550
1550
        }
1551
1551
 
1552
1552
out:
 
1553
        if (release_it && mtnode_ext && mtnode_ext->replica) {
 
1554
                object_release(mtnode_ext->replica);
 
1555
        }
1553
1556
    slapi_ch_free_string(&payload);
1554
1557
 
1555
1558
        return rc;
1569
1572
int
1570
1573
multimaster_extop_cleanruv(Slapi_PBlock *pb)
1571
1574
{
1572
 
        multimaster_mtnode_extension *mtnode_ext;
 
1575
        multimaster_mtnode_extension *mtnode_ext = NULL;
1573
1576
        PRThread *thread = NULL;
1574
1577
        Replica *r = NULL;
1575
1578
        cleanruv_data *data = NULL;
1577
1580
        struct berval *extop_payload;
1578
1581
        struct berval *resp_bval = NULL;
1579
1582
        BerElement *resp_bere = NULL;
1580
 
        char *extop_oid;
1581
 
        char *repl_root;
1582
1583
        char *payload = NULL;
1583
1584
        char *csnstr = NULL;
 
1585
        char *force = NULL;
 
1586
        char *extop_oid;
 
1587
        char *repl_root;
1584
1588
        char *iter;
1585
1589
        int release_it = 0;
1586
1590
        int rid = 0;
1587
 
        int rc = 0;
 
1591
        int rc = LDAP_OPERATIONS_ERROR;
1588
1592
 
1589
1593
        slapi_pblock_get(pb, SLAPI_EXT_OP_REQ_OID, &extop_oid);
1590
1594
        slapi_pblock_get(pb, SLAPI_EXT_OP_REQ_VALUE, &extop_payload);
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 */
1595
 
                rc = -1;
1596
1599
                goto free_and_return;
1597
1600
        }
1598
1601
        /*
1599
1602
         *  Decode the payload
1600
1603
         */
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");
1603
 
                rc = -1;
 
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;
1605
1607
        }
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);
 
1612
        if(force == NULL){
 
1613
                force = "no";
 
1614
        }
1609
1615
        maxcsn = csn_new();
1610
1616
        csn_init_by_string(maxcsn, csnstr);
1611
1617
        /*
1612
1618
         *  If we already cleaned this server, just return success
1613
1619
         */
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);
1616
 
                rc = 1;
 
1622
                rc = LDAP_SUCCESS;
1617
1623
                goto free_and_return;
1618
1624
        }
1619
 
 
1620
1625
        /*
1621
1626
         *  Get the node, so we can get the replica and its agreements
1622
1627
         */
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);
1626
 
                rc = -1;
1627
1631
                goto free_and_return;
1628
1632
        }
1629
1633
 
1630
1634
        if (mtnode_ext->replica){
1631
1635
                object_acquire (mtnode_ext->replica);
1632
1636
                release_it = 1;
1633
 
        }
1634
 
        if (mtnode_ext->replica == NULL){
1635
 
                slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: replica is missing from (%s), "
 
1637
        } else {
 
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;
1639
1641
        }
1640
1642
 
1641
1643
        r = (Replica*)object_get_data (mtnode_ext->replica);
1642
1644
        if(r == NULL){
1643
 
                slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: replica is NULL, aborting task\n");
1644
 
                rc = -1;
 
1645
                slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "CleanAllRUV Task: replica is NULL, aborting task\n");
1645
1646
                goto free_and_return;
1646
1647
        }
1647
1648
 
1651
1652
                 *
1652
1653
                 *  This will also release mtnode_ext->replica
1653
1654
                 */
1654
 
                slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: launching cleanAllRUV thread...\n");
 
1655
                slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "CleanAllRUV Task: launching cleanAllRUV thread...\n");
1655
1656
                data = (cleanruv_data*)slapi_ch_calloc(1, sizeof(cleanruv_data));
1656
1657
                if (data == NULL) {
1657
 
                        slapi_log_error( SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: failed to allocate "
 
1658
                        slapi_log_error( SLAPI_LOG_FATAL, repl_plugin_name, "CleanAllRUV Task: failed to allocate "
1658
1659
                                "cleanruv_Data\n");
1659
 
                        rc = -1;
1660
1660
                        goto free_and_return;
1661
1661
                }
1662
1662
                data->repl_obj = mtnode_ext->replica;
1665
1665
                data->task = NULL;
1666
1666
                data->maxcsn = maxcsn;
1667
1667
                data->payload = slapi_ch_bvdup(extop_payload);
 
1668
                data->force = slapi_ch_strdup(force);
 
1669
                data->repl_root = slapi_ch_strdup(repl_root);
1668
1670
 
1669
1671
                thread = PR_CreateThread(PR_USER_THREAD, replica_cleanallruv_thread_ext,
1670
1672
                                (void *)data, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD,
1671
1673
                                PR_UNJOINABLE_THREAD, SLAPD_DEFAULT_THREAD_STACKSIZE);
1672
1674
                if (thread == NULL) {
1673
 
                    rc = -1;
1674
 
                        slapi_log_error( SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: unable to create cleanAllRUV "
 
1675
                        slapi_log_error( SLAPI_LOG_FATAL, repl_plugin_name, "CleanAllRUV Task: unable to create cleanAllRUV "
1675
1676
                                "monitoring thread.  Aborting task.\n");
 
1677
                        ber_bvfree(data->payload);
 
1678
                        data->payload = NULL;
 
1679
                        slapi_ch_free_string(&data->force);
 
1680
                        slapi_ch_free_string(&data->repl_root);
 
1681
                        slapi_ch_free((void **)&data);
 
1682
                } else {
 
1683
                        release_it = 0; /* thread will release data->repl_obj == mtnode_ext->replica */
 
1684
                        maxcsn = NULL; /* thread owns it now */
 
1685
                        rc = LDAP_SUCCESS;
1676
1686
                }
1677
1687
        } else { /* this is a read-only consumer */
1678
1688
                /*
1689
1699
                                /* we've already been cleaned */
1690
1700
                                break;
1691
1701
                        }
1692
 
                        slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: checking if we're caught up...\n");
1693
 
                        if(ruv_covers_csn_cleanallruv(ruv,maxcsn) || csn_get_replicaid(maxcsn) == 0){
 
1702
                        slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "CleanAllRUV Task: checking if we're caught up...\n");
 
1703
                        if(ruv_covers_csn_cleanallruv(ruv,maxcsn) || csn_get_replicaid(maxcsn) == 0|| strcmp(force,"yes") == 0){
1694
1704
                                /* We are caught up */
1695
1705
                                break;
1696
1706
                        } else {
1697
1707
                                char csnstr[CSN_STRSIZE];
1698
1708
                                csn_as_string(maxcsn, PR_FALSE, csnstr);
1699
 
                                slapi_log_error( SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: not ruv caught up maxcsn(%s)\n", csnstr);
 
1709
                                slapi_log_error( SLAPI_LOG_FATAL, repl_plugin_name, "CleanAllRUV Task: not ruv caught up maxcsn(%s)\n", csnstr);
1700
1710
                        }
1701
1711
                        DS_Sleep(PR_SecondsToInterval(5));
1702
1712
                }
1703
 
                slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: we're caught up...\n");
 
1713
                slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "CleanAllRUV Task: we're caught up...\n");
1704
1714
                /*
1705
1715
                 *  Set cleaned rid in memory only - does not survive a server restart
1706
1716
                 */
1712
1722
 
1713
1723
                /* free everything */
1714
1724
                object_release(ruv_obj);
1715
 
                csn_free(&maxcsn);
1716
 
                if (mtnode_ext->replica && release_it)
1717
 
                        object_release (mtnode_ext->replica);
1718
1725
                /*
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.
1721
1728
                 */
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);
 
1731
                rc = LDAP_SUCCESS;
1724
1732
        }
1725
1733
 
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);
1730
1737
        }
1731
 
        if(rc)
1732
 
            csn_free(&maxcsn);
 
1738
        csn_free(&maxcsn);
1733
1739
        slapi_ch_free_string(&payload);
1734
1740
 
1735
1741
        /*
1736
1742
         *   Craft a message so we know this replica supports the task
1737
1743
         */
1738
1744
        if ((resp_bere = der_alloc())){
1739
 
 
1740
 
                ber_int_t response = 1;
1741
 
 
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);
1746
 
                /* resp_bere */
1747
 
                if (NULL != resp_bere)
1748
 
                {
1749
 
                        ber_free(resp_bere, 1);
1750
 
                }
1751
 
                /* resp_bval */
1752
 
                if (NULL != resp_bval)
1753
 
                {
1754
 
                        ber_bvfree(resp_bval);
1755
 
                }
1756
 
        }
1757
 
 
1758
 
        return rc;
1759
 
}
 
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);
 
1749
                /* resp_bere */
 
1750
                if (NULL != resp_bere)
 
1751
                {
 
1752
                        ber_free(resp_bere, 1);
 
1753
                }
 
1754
                /* resp_bval */
 
1755
                if (NULL != resp_bval)
 
1756
                {
 
1757
                        ber_bvfree(resp_bval);
 
1758
                }
 
1759
                /* tell extendop code that we have already sent the result */
 
1760
                rc = SLAPI_PLUGIN_EXTENDED_SENT_RESULT;
 
1761
        } else {
 
1762
                rc = LDAP_OPERATIONS_ERROR;
 
1763
        }
 
1764
 
 
1765
        return rc;
 
1766
}
 
1767
 
 
1768
/*
 
1769
 *  Get the max csn for the designated repl area
 
1770
 */
 
1771
int
 
1772
multimaster_extop_cleanruv_get_maxcsn(Slapi_PBlock *pb)
 
1773
{
 
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;
 
1787
        char *iter = NULL;
 
1788
        char *attrs[2];
 
1789
        int part_count = 0;
 
1790
        int rid = 0;
 
1791
        int res = 0;
 
1792
        int rc = LDAP_OPERATIONS_ERROR;
 
1793
        int i = 0;
 
1794
 
 
1795
        slapi_pblock_get(pb, SLAPI_EXT_OP_REQ_OID, &extop_oid);
 
1796
        slapi_pblock_get(pb, SLAPI_EXT_OP_REQ_VALUE, &extop_payload);
 
1797
 
 
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;
 
1802
        }
 
1803
        /*
 
1804
         *  Decode the payload
 
1805
         */
 
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;
 
1809
        }
 
1810
        rid = atoi(ldap_utf8strtok_r(payload, ":", &iter));
 
1811
        base_dn = ldap_utf8strtok_r(iter, ":", &iter);
 
1812
        /*
 
1813
         *  Get the maxruv from the database tombstone entry
 
1814
         */
 
1815
        filter = "(&(nsuniqueid=ffffffff-ffffffff-ffffffff-ffffffff)(objectclass=nstombstone))";
 
1816
        attrs[0] = "nsds50ruv";
 
1817
        attrs[1] = NULL;
 
1818
        ridstr = slapi_ch_smprintf("{replica %d ldap", rid);
 
1819
 
 
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);
 
1824
 
 
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 */
 
1829
                } else {
 
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);
 
1838
                                        }
 
1839
                                        if(part_count == 5 && ruv_part){/* we have the maxcsn */
 
1840
                                                maxcsn = slapi_ch_strdup(ruv_part);
 
1841
                                                break;
 
1842
                                        }
 
1843
                                }
 
1844
                        }
 
1845
                        slapi_ch_array_free(ruv_elements);
 
1846
                }
 
1847
        } else {
 
1848
                /* internal search failed */
 
1849
                slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "CleanAllRUV Get MaxCSN Task: internal search failed (%d)\n", res);
 
1850
        }
 
1851
        if(maxcsn == NULL){
 
1852
                maxcsn = slapi_ch_strdup(CLEANRUV_NO_MAXCSN);
 
1853
        }
 
1854
        /*
 
1855
         *  Send the extended op response
 
1856
         */
 
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);
 
1862
                /* resp_bere */
 
1863
                if (NULL != resp_bere)
 
1864
                {
 
1865
                        ber_free(resp_bere, 1);
 
1866
                }
 
1867
                /* resp_bval */
 
1868
                if (NULL != resp_bval)
 
1869
                {
 
1870
                        ber_bvfree(resp_bval);
 
1871
                }
 
1872
                /* tell extendop code that we have already sent the result */
 
1873
                rc = SLAPI_PLUGIN_EXTENDED_SENT_RESULT;
 
1874
        } else {
 
1875
                rc = LDAP_OPERATIONS_ERROR;
 
1876
        }
 
1877
 
 
1878
free_and_return:
 
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);
 
1884
 
 
1885
        return rc;
 
1886
}
 
1887
 
 
1888
/*
 
1889
 *  Search cn=config for the cleanallruv attributes (clean & abort)
 
1890
 */
 
1891
int
 
1892
multimaster_extop_cleanruv_check_status(Slapi_PBlock *pb)
 
1893
{
 
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;
 
1901
        char *extop_oid;
 
1902
        int res = 0;
 
1903
        int rc = LDAP_OPERATIONS_ERROR;
 
1904
 
 
1905
        slapi_pblock_get(pb, SLAPI_EXT_OP_REQ_OID, &extop_oid);
 
1906
        slapi_pblock_get(pb, SLAPI_EXT_OP_REQ_VALUE, &extop_payload);
 
1907
 
 
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;
 
1912
        }
 
1913
        /*
 
1914
         *  Decode the payload - which should just be a filter
 
1915
         */
 
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;
 
1919
        }
 
1920
 
 
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;
 
1931
                } else {
 
1932
                        response = CLEANRUV_CLEANING;
 
1933
                }
 
1934
                /*
 
1935
                 *  Send the extended op response
 
1936
                 */
 
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);
 
1942
                        /* resp_bere */
 
1943
                        if (NULL != resp_bere)
 
1944
                        {
 
1945
                                ber_free(resp_bere, 1);
 
1946
                        }
 
1947
                        /* resp_bval */
 
1948
                        if (NULL != resp_bval)
 
1949
                        {
 
1950
                                ber_bvfree(resp_bval);
 
1951
                        }
 
1952
                        /* tell extendop code that we have already sent the result */
 
1953
                        rc = SLAPI_PLUGIN_EXTENDED_SENT_RESULT;
 
1954
                }
 
1955
        }
 
1956
 
 
1957
free_and_return:
 
1958
 
 
1959
        slapi_free_search_results_internal(search_pb);
 
1960
        slapi_pblock_destroy(search_pb);
 
1961
        slapi_ch_free_string(&filter);
 
1962
 
 
1963
        return rc;
 
1964
}
 
1965
 
1760
1966
 
1761
1967
/*
1762
1968
 * This plugin entry point is a noop entry