Exemple #1
0
bool
api::isVolumeSyncedUpTo(const vd::VolumeId& vol_id,
                        const vd::TLogId& tlog_id)
{
    SharedVolumePtr v = VolManager::get()->findVolume_(vol_id);
    return v->isSyncedToBackendUpTo(tlog_id);
}
TEST_P(OwnerTagTest, constant_tag)
{
    auto ns(make_random_namespace());
    SharedVolumePtr v = newVolume(*ns);

    const VolumeConfig cfg = v->get_config();
    destroyVolume(v,
                  DeleteLocalData::F,
                  RemoveVolumeCompletely::F);

    v = localRestart(ns->ns());

    EXPECT_EQ(cfg.owner_tag_,
              v->get_config().owner_tag_);

    destroyVolume(v,
                  DeleteLocalData::T,
                  RemoveVolumeCompletely::F);

    restartVolume(cfg);
    v = getVolume(cfg.id_);

    EXPECT_EQ(cfg.owner_tag_,
              v->get_config().owner_tag_);
}
Exemple #3
0
void
api::setFOCTimeout(const vd::VolumeId& volName,
                   const boost::chrono::seconds timeout)
{
    SharedVolumePtr v = VolManager::get()->findVolume_(volName);
    v->setFOCTimeout(timeout);
}
TEST_P(OwnerTagTest, changing_tag)
{
    auto ns(make_random_namespace());
    SharedVolumePtr v = newVolume(*ns);

    const VolumeConfig cfg = v->get_config();
    destroyVolume(v,
                  DeleteLocalData::T,
                  RemoveVolumeCompletely::F);

    const OwnerTag new_tag(new_owner_tag());
    EXPECT_NE(cfg.owner_tag_,
              new_tag);

    {
        fungi::ScopedLock l(VolManager::get()->mgmtMutex_);
        VolManager::get()->backend_restart(cfg.getNS(),
                                           new_tag,
                                           PrefetchVolumeData::F,
                                           IgnoreFOCIfUnreachable::F);
    }

    v = getVolume(cfg.id_);

    EXPECT_EQ(new_tag,
              v->get_config().owner_tag_);
}
Exemple #5
0
void
api::setFailOverCacheConfig(const vd::VolumeId& volName,
                            const boost::optional<vd::FailOverCacheConfig>& maybe_foc_config)
{
    SharedVolumePtr v = VolManager::get()->findVolume_(volName);
    v->setFailOverCacheConfig(maybe_foc_config);
}
Exemple #6
0
bool
api::isVolumeSynced(const vd::VolumeId& volName)
{

    SharedVolumePtr v = VolManager::get()->findVolume_(volName);
    return v->isSyncedToBackend();
}
Exemple #7
0
bool
api::isVolumeSyncedUpTo(const vd::VolumeId& volName,
                        const vd::SnapshotName& snapshotName)
{
    SharedVolumePtr v = VolManager::get()->findVolume_(volName);
    return v->isSyncedToBackendUpTo(snapshotName);
}
TEST_P(DtlCheckerTest, auto_recovery)
{
    auto ns_ptr = make_random_namespace();

    const backend::Namespace& ns = ns_ptr->ns();

    SharedVolumePtr v = newVolume("vol1",
                          ns);

    const auto port = get_next_foc_port();
    ASSERT_THROW(v->setFailOverCacheConfig(FailOverCacheConfig(FailOverCacheTestSetup::host(),
                                                               port,
                                                               GetParam().foc_mode())),
                 fungi::IOException);

    ASSERT_EQ(VolumeFailOverState::DEGRADED,
              v->getVolumeFailOverState());

    auto foc_ctx(start_one_foc());
    ASSERT_EQ(port,
              foc_ctx->port());

    boost::this_thread::sleep_for(2 * dtl_check_interval_);

    ASSERT_EQ(VolumeFailOverState::OK_SYNC,
              v->getVolumeFailOverState());
}
Exemple #9
0
uint64_t
api::getSnapshotBackendSize(const vd::VolumeId& volName,
                            const vd::SnapshotName& snapName)
{
    SharedVolumePtr v = VolManager::get()->findVolume_(volName);
    return v->getSnapshotBackendSize(snapName);
}
Exemple #10
0
void
api::showSnapshots(const VolumeId& volName,
                   std::list<vd::SnapshotName>& l)
{
    SharedVolumePtr v = VolManager::get()->findVolume_(volName);
    v->listSnapshots(l);
}
TEST_P(BigReadWriteTest, bigReadsOnFull)
{
    auto ns_ptr = make_random_namespace();
    SharedVolumePtr v = newVolume(VolumeId("volume1"),
                          ns_ptr->ns());

    SCOPED_BLOCK_BACKEND(*v);

    size_t csz = v->getClusterSize();
    size_t lba_size = v->getLBASize();

    const std::string pattern(csz,'a');
    size_t scoMul = v->getSCOMultiplier();
    for(size_t i = 0;i < 50*scoMul; ++i)
    {
        writeToVolume(*v, i* csz / lba_size, csz, pattern);
    }

    // Stop here to manually delete sco's to check error handling
    for(size_t i = 0; i < scoMul; ++i)
    {
        checkVolume(*v,0, csz*scoMul, pattern);
    }

}
Exemple #12
0
uint64_t
api::getSnapshotSCOCount(const vd::VolumeId& volName,
                         const vd::SnapshotName& snapid)
{
    SharedVolumePtr v = VolManager::get()->findVolume_(volName);
    return v->getSnapshotSCOCount(snapid);
}
Exemple #13
0
boost::optional<be::Garbage>
api::applyScrubbingWork(const vd::VolumeId& volName,
                        const scrubbing::ScrubReply& scrub_reply,
                        const vd::ScrubbingCleanup cleanup)
{
    SharedVolumePtr v = VolManager::get()->findVolume_(volName);
    return v->applyScrubbingWork(scrub_reply,
                                 cleanup);
}
TEST_P(SnapshotRestoreTest, snapshot_restoration_on_a_clone)
{
    const auto wrns_parent(make_random_namespace());
    const std::string parent_name(wrns_parent->ns().str());

    SharedVolumePtr parent = newVolume(VolumeId(parent_name),
                               be::Namespace(parent_name));

    const std::string pattern1("before-parent-snapshot");

    writeToVolume(*parent,
                  0,
                  parent->getClusterSize(),
                  pattern1);

    const SnapshotName parent_snap("parent-snapshot");
    parent->createSnapshot(parent_snap);

    waitForThisBackendWrite(*parent);

    const auto wrns_clone(make_random_namespace());
    const std::string clone_name(wrns_clone->ns().str());

    SharedVolumePtr clone = createClone(clone_name,
                                be::Namespace(clone_name),
                                be::Namespace(parent_name),
                                parent_snap);

    const std::string pattern2("before-clone-snapshot");

    writeToVolume(*clone,
                  0,
                  clone->getClusterSize(),
                  pattern2);

    const SnapshotName clone_snap("clone-snapshot");
    clone->createSnapshot(clone_snap);

    waitForThisBackendWrite(*clone);

    const std::string pattern3("after-clone-snapshot");

    writeToVolume(*clone,
                  0,
                  clone->getClusterSize(),
                  pattern3);

    checkVolume(*clone,
                0,
                clone->getClusterSize(),
                pattern3);

    restoreSnapshot(*clone,
                    clone_snap);

    checkVolume(*clone,
                0,
                clone->getClusterSize(),
                pattern2);
}
TEST_P(SnapshotRestoreTest, TestFailOver)
{
    auto foc_ctx(start_one_foc());
    auto ns_ptr = make_random_namespace();
    SharedVolumePtr v = newVolume(VolumeId("volume1"),
                          ns_ptr->ns(),
                          VolumeSize((1 << 18) * 512),
                          SCOMultiplier(1));

    v->setFailOverCacheConfig(foc_ctx->config(GetParam().foc_mode()));

    VolumeConfig cfg = v->get_config();
    v->createSnapshot(SnapshotName("snap0"));

    for(int i = 0; i < 5; ++i)
    {
        writeToVolume(*v,
                      0,
                      4096,
                      "a");
    }


    waitForThisBackendWrite(*v);
    v->restoreSnapshot(SnapshotName("snap0"));

    for(int i = 0; i < 7; ++i)
    {
        writeToVolume(*v,
                      8,
                      4096,
                      "d");
    }

    flushFailOverCache(*v);
    destroyVolume(v,
                  DeleteLocalData::T,
                  RemoveVolumeCompletely::F);

    SharedVolumePtr v1 = 0;
    v1 = getVolume(VolumeId("volume1"));
    ASSERT_FALSE(v1);
    restartVolume(cfg);
    v1 = getVolume(VolumeId("volume1"));

    ASSERT_TRUE(v1 != nullptr);
    checkVolume(*v1,0,4096, "\0");
    checkVolume(*v1,8,4096, "d");
    checkCurrentBackendSize(*v1);
}
TEST_P(BigReadWriteTest, bigReadsOnEmpty)
{
    auto ns_ptr = make_random_namespace();

    SharedVolumePtr v = newVolume(VolumeId("volume1"),
                          ns_ptr->ns());

    size_t csz = v->getClusterSize();
    const std::string pattern(csz,'\0');
    size_t scoMul = v->getSCOMultiplier();

    for(size_t i = 0; i < scoMul; ++i)
    {
        checkVolume(*v,0, csz*scoMul, pattern);
    }
}
TEST_P(BigReadWriteTest, OneBigWriteOneBigRead)
{
    auto ns_ptr = make_random_namespace();

    SharedVolumePtr v = newVolume(VolumeId("volume1"),
                                  ns_ptr->ns());

    SCOPED_BLOCK_BACKEND(*v);

    size_t csz = v->getClusterSize();

    const std::string pattern(csz,'a');
    size_t scoMul = v->getSCOMultiplier();
    writeToVolume(*v, 0, csz * scoMul, pattern);

    // Stop here to manually delete sco's to check error handling
    checkVolume(*v,0, csz*scoMul, pattern);

}
TEST_P(SnapshotRestoreTest, RestoreAndWriteAgain1)
{
    auto ns_ptr = make_random_namespace();
    SharedVolumePtr v = newVolume(VolumeId("volume1"),
                          ns_ptr->ns(),
                          VolumeSize(1 << 26),
                          SCOMultiplier(1));

    const std::string pattern("e-manual");

    v->createSnapshot(SnapshotName("snap1"));
    waitForThisBackendWrite(*v);

    writeToVolume(*v, 0, 5 * 4096, pattern);
    waitForThisBackendWrite(*v);

    restoreSnapshot(*v,"snap1");

    writeToVolume(*v, 0, 4*4096, pattern);
    waitForThisBackendWrite(*v);
    checkCurrentBackendSize(*v);
}
TEST_P(SnapshotRestoreTest, HaltOnError)
{
    auto ns_ptr = make_random_namespace();
    SharedVolumePtr v = newVolume(VolumeId("volume1"),
                          ns_ptr->ns());

    const std::string pattern1("blah");

    const TLogId tlog_id(v->getSnapshotManagement().getCurrentTLogId());

    writeToVolume(*v, 0, 4096, pattern1);
    v->createSnapshot(SnapshotName("snap1"));
    waitForThisBackendWrite(*v);

    EXPECT_THROW(restoreSnapshot(*v, "snap42"),
                 std::exception);
    EXPECT_FALSE(v->is_halted());

    v->getBackendInterface()->remove(boost::lexical_cast<std::string>(tlog_id));
    EXPECT_THROW(restoreSnapshot(*v, "snap1"),
                 std::exception);
    EXPECT_TRUE(v->is_halted());
}
Exemple #20
0
uint64_t
api::getTLogUsed(const vd::VolumeId& volName)
{
    SharedVolumePtr v = VolManager::get()->findVolume_(volName);
    return v->getTLogUsed();
}
    void
    test_after_tlog(bool failover)
    {
        const auto wrns(make_random_namespace());

        SharedVolumePtr v = make_volume(*wrns);

        const std::string pattern1("Hairdresser On Fire");

        {
            SCOPED_BLOCK_BACKEND(*v);

            writeToVolume(*v,
                          v->getClusterMultiplier() * CachePage::capacity(),
                          v->getClusterSize(),
                          pattern1);
        }

        v->scheduleBackendSync();
        waitForThisBackendWrite(*v);

        const std::string pattern2("Such A Little Thing Makes Such A Big Difference");

        writeToVolume(*v,
                      2 * v->getClusterMultiplier() * CachePage::capacity(),
                      v->getClusterSize(),
                      pattern2);

        const auto ncfgs(node_configs());

        if (failover)
        {
            mds_manager_->stop_one(ncfgs[0]);

            checkVolume(*v,
                        0,
                        v->getClusterSize(),
                        "");
        }
        else
        {
            const std::vector<MDSNodeConfig> ncfgs2{ ncfgs[1],
                                                     ncfgs[0] };

            v->updateMetaDataBackendConfig(MDSMetaDataBackendConfig(ncfgs2,
                                                                    ApplyRelocationsToSlaves::T));
        }

        check_config(*v,
                     ncfgs,
                     true);

        checkVolume(*v,
                    v->getClusterMultiplier() * CachePage::capacity(),
                    v->getClusterSize(),
                    pattern1);

        checkVolume(*v,
                    2 * v->getClusterMultiplier() * CachePage::capacity(),
                    v->getClusterSize(),
                    pattern2);

        destroyVolume(v,
                      DeleteLocalData::F,
                      RemoveVolumeCompletely::F);

        v = localRestart(wrns->ns());

        check_config(*v,
                     ncfgs,
                     true);

        checkVolume(*v,
                    v->getClusterMultiplier() * CachePage::capacity(),
                    v->getClusterSize(),
                    pattern1);

        checkVolume(*v,
                    2 * v->getClusterMultiplier() * CachePage::capacity(),
                    v->getClusterSize(),
                    pattern2);
    }
Exemple #22
0
void
api::startPrefetching(const vd::VolumeId& volName)
{
    SharedVolumePtr v = VolManager::get()->findVolume_(volName);
    v->startPrefetch();
}
Exemple #23
0
uint64_t
api::getCurrentBackendSize(const vd::VolumeId& volName)
{
    SharedVolumePtr v = VolManager::get()->findVolume_(volName);
    return v->getCurrentBackendSize();
}
Exemple #24
0
vd::TLogId
api::scheduleBackendSync(const vd::VolumeId& volName)
{
    SharedVolumePtr v = VolManager::get()->findVolume_(volName);
    return v->scheduleBackendSync();
}
Exemple #25
0
bool
api::checkVolumeConsistency(const vd::VolumeId& volName)
{
    SharedVolumePtr v = VolManager::get()->findVolume_(volName);
    return v->checkConsistency();
}
Exemple #26
0
uint64_t
api::getCurrentSCOCount(const vd::VolumeId& volName)
{
    SharedVolumePtr v = VolManager::get()->findVolume_(volName);
    return  v->getSnapshotSCOCount();
}
    void
    test_before_tlog(bool failover)
    {
        const auto wrns(make_random_namespace());

        SharedVolumePtr v = make_volume(*wrns);

        const auto ncfgs(node_configs());
        const std::string pattern("King Leer");

        {
            SCOPED_BLOCK_BACKEND(*v);

            writeToVolume(*v,
                          v->getClusterMultiplier() * CachePage::capacity(),
                          v->getClusterSize(),
                          pattern);

            if (failover)
            {
                mds_manager_->stop_one(ncfgs[0]);

                checkVolume(*v,
                            0,
                            v->getClusterSize(),
                            "");
            }
            else
            {
                const std::vector<MDSNodeConfig> ncfgs2{ ncfgs[1],
                                                         ncfgs[0] };

                v->updateMetaDataBackendConfig(MDSMetaDataBackendConfig(ncfgs2,
                                                                        ApplyRelocationsToSlaves::T));
            }

            check_config(*v,
                         ncfgs,
                         true);

            checkVolume(*v,
                        v->getClusterMultiplier() * CachePage::capacity(),
                        v->getClusterSize(),
                        pattern);
        }

        destroyVolume(v,
                      DeleteLocalData::F,
                      RemoveVolumeCompletely::F);

        v = localRestart(wrns->ns());

        check_config(*v,
                     ncfgs,
                     true);

        checkVolume(*v,
                    v->getClusterMultiplier() * CachePage::capacity(),
                    v->getClusterSize(),
                    pattern);
    }
Exemple #28
0
vd::VolumeFailOverState
api::getFailOverMode(const vd::VolumeId& volName)
{
    SharedVolumePtr v = VolManager::get()->findVolume_(volName);
    return v->getVolumeFailOverState();
}
TEST_P(SimpleBackupRestoreTest, rollback_to_previous_snap_if_snapshot_didnt_make_it)
{
    auto ns_ptr = make_random_namespace();

    const backend::Namespace& nspace = ns_ptr->ns();

    // const Namespace nspace;
    const VolumeId vid("backup");


    auto wov = newWriteOnlyVolume(vid,
                                  nspace,
                                  BackupRole::WanBackupBase);
    ASSERT_TRUE(wov);

    const auto cfg(wov->get_config());

    const std::string pattern("a mysteriously returning message");
    const size_t size = 1024 * 1024;
    writeToVolume(*wov, 0, size, pattern);
    const SnapshotName snap("snap");
    wov->createSnapshot(snap);
    waitForThisBackendWrite(*wov);
    const std::string pattern2("a mysteriously disappearing message");
    writeToVolume(*wov, 0, size, pattern2);
    wov->scheduleBackendSync();
    waitForThisBackendWrite(*wov);
    {
        SCOPED_DESTROY_WRITE_ONLY_VOLUME_UNBLOCK_BACKEND_FOR_BACKEND_RESTART(wov, 3);
        wov->createSnapshot(SnapshotName("snap2"));

        const SnapshotPersistor& sp =
            wov->getSnapshotManagement().getSnapshotPersistor();
        SnapshotManagement::writeSnapshotPersistor(sp,
                                                   cm_->newBackendInterface(nspace));
    }

    const fs::path
        cfg_file(make_config_file(nspace,
                                  MaybeString(),
                                  MaybeString(),
                                  MaybeBackupRole(BackupRole::WanBackupNormal)));

    bu::Restore(cfg_file,
                false,
                youtils::GracePeriod(boost::posix_time::seconds(2)))();
    {
        fungi::ScopedLock l(api::getManagementMutex());
        api::backend_restart(nspace,
                             new_owner_tag(),
                             PrefetchVolumeData::T,
                             IgnoreFOCIfUnreachable::T);
    }

    SharedVolumePtr v = getVolume(vid);
    checkVolume(*v, 0, size, pattern);
    std::list<SnapshotName> snaps;
    v->listSnapshots(snaps);
    EXPECT_EQ(1U, snaps.size());
    EXPECT_EQ(snap, snaps.front());
}
Exemple #30
0
boost::optional<vd::FailOverCacheConfig>
api::getFailOverCacheConfig(const vd::VolumeId& volName)
{
    SharedVolumePtr v = VolManager::get()->findVolume_(volName);
    return v->getFailOverCacheConfig();
}