Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

merge to stable-23-3 #671

Merged
merged 7 commits into from
Mar 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions cloud/blockstore/libs/service/auth_scheme.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ TPermissionList GetRequestPermissions(
perms("reallocatedisk", {EPermission::Update}),
perms("rebindvolumes", {EPermission::Update}),
perms("setuserid", {EPermission::Update}),
perms("cms", {EPermission::Update}),

// Delete
perms("deletecheckpointdata", {EPermission::Delete}),
Expand Down
12 changes: 8 additions & 4 deletions cloud/blockstore/libs/storage/disk_agent/disk_agent_state.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -765,16 +765,20 @@ void TDiskAgentState::AcquireDevices(
const TString& diskId,
ui32 volumeGeneration)
{
CheckError(DeviceClient->AcquireDevices(
auto [updated, error] = DeviceClient->AcquireDevices(
uuids,
clientId,
now,
accessMode,
mountSeqNumber,
diskId,
volumeGeneration));
volumeGeneration);

UpdateSessionCache(*DeviceClient);
CheckError(error);

if (updated) {
UpdateSessionCache(*DeviceClient);
}
}

void TDiskAgentState::ReleaseDevices(
Expand Down Expand Up @@ -887,7 +891,7 @@ void TDiskAgentState::RestoreSessions(TDeviceClient& client) const
std::make_move_iterator(session.MutableDeviceIds()->begin()),
std::make_move_iterator(session.MutableDeviceIds()->end()));

const auto error = client.AcquireDevices(
const auto [_, error] = client.AcquireDevices(
uuids,
session.GetClientId(),
TInstant::MicroSeconds(session.GetLastActivityTs()),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1707,7 +1707,7 @@ Y_UNIT_TEST_SUITE(TDiskAgentStateTest)
UNIT_ASSERT_VALUES_EQUAL(0, session.GetMountSeqNumber());
UNIT_ASSERT_VALUES_EQUAL("vol0", session.GetDiskId());
UNIT_ASSERT_VALUES_EQUAL(1001, session.GetVolumeGeneration());
UNIT_ASSERT_VALUES_EQUAL(2, session.GetLastActivityTs());
UNIT_ASSERT_VALUES_EQUAL(0, session.GetLastActivityTs());
UNIT_ASSERT(session.GetReadOnly());
}

Expand All @@ -1724,7 +1724,7 @@ Y_UNIT_TEST_SUITE(TDiskAgentStateTest)
UNIT_ASSERT_VALUES_EQUAL(0, session.GetMountSeqNumber());
UNIT_ASSERT_VALUES_EQUAL("vol1", session.GetDiskId());
UNIT_ASSERT_VALUES_EQUAL(2000, session.GetVolumeGeneration());
UNIT_ASSERT_VALUES_EQUAL(3, session.GetLastActivityTs());
UNIT_ASSERT_VALUES_EQUAL(0, session.GetLastActivityTs());
UNIT_ASSERT(session.GetReadOnly());
}

Expand All @@ -1743,7 +1743,7 @@ Y_UNIT_TEST_SUITE(TDiskAgentStateTest)

// VolumeGeneration was updated by reader-1
UNIT_ASSERT_VALUES_EQUAL(1001, session.GetVolumeGeneration());
UNIT_ASSERT_VALUES_EQUAL(1, session.GetLastActivityTs());
UNIT_ASSERT_VALUES_EQUAL(0, session.GetLastActivityTs());
UNIT_ASSERT(!session.GetReadOnly());
}
}
Expand Down
24 changes: 20 additions & 4 deletions cloud/blockstore/libs/storage/disk_agent/model/device_client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ TVector<NProto::TDiskAgentDeviceSession> TDeviceClient::GetSessions() const
session.SetDiskId(state->DiskId);
session.SetVolumeGeneration(state->VolumeGeneration);
session.SetMountSeqNumber(ws.MountSeqNumber);
session.SetLastActivityTs(ws.LastActivityTs.MicroSeconds());
}
*session.AddDeviceIds() = id;
}
Expand All @@ -52,7 +51,6 @@ TVector<NProto::TDiskAgentDeviceSession> TDeviceClient::GetSessions() const
session.SetDiskId(state->DiskId);
session.SetVolumeGeneration(state->VolumeGeneration);
session.SetMountSeqNumber(rs.MountSeqNumber);
session.SetLastActivityTs(rs.LastActivityTs.MicroSeconds());
}
*session.AddDeviceIds() = id;
}
Expand All @@ -74,7 +72,7 @@ TVector<NProto::TDiskAgentDeviceSession> TDeviceClient::GetSessions() const
return r;
}

NCloud::NProto::TError TDeviceClient::AcquireDevices(
TResultOrError<bool> TDeviceClient::AcquireDevices(
const TVector<TString>& uuids,
const TString& clientId,
TInstant now,
Expand Down Expand Up @@ -124,6 +122,8 @@ NCloud::NProto::TError TDeviceClient::AcquireDevices(
}
}

bool somethingHasChanged = false;

// acquire devices
for (const auto& uuid: uuids) {
TDeviceState& ds = *GetDeviceState(uuid);
Expand All @@ -138,6 +138,10 @@ NCloud::NProto::TError TDeviceClient::AcquireDevices(
}
);

if (ds.DiskId != diskId || ds.VolumeGeneration != volumeGeneration) {
somethingHasChanged = true;
}

ds.DiskId = diskId;
ds.VolumeGeneration = volumeGeneration;

Expand All @@ -146,12 +150,16 @@ NCloud::NProto::TError TDeviceClient::AcquireDevices(
ds.WriterSession = {};
STORAGE_INFO("Device %s was released by client %s for writing.",
uuid.Quote().c_str(), clientId.c_str());

somethingHasChanged = true;
}

if (s == ds.ReaderSessions.end()) {
ds.ReaderSessions.push_back({clientId, now});
STORAGE_INFO("Device %s was acquired by client %s for reading.",
uuid.Quote().c_str(), clientId.c_str());

somethingHasChanged = true;
} else if (now > s->LastActivityTs) {
s->LastActivityTs = now;
}
Expand All @@ -160,11 +168,19 @@ NCloud::NProto::TError TDeviceClient::AcquireDevices(
ds.ReaderSessions.erase(s);
STORAGE_INFO("Device %s was released by client %s for reading.",
uuid.Quote().c_str(), clientId.c_str());

somethingHasChanged = true;
}

if (ds.WriterSession.Id != clientId) {
STORAGE_INFO("Device %s was acquired by client %s for writing.",
uuid.Quote().c_str(), clientId.c_str());

somethingHasChanged = true;
}

if (ds.WriterSession.MountSeqNumber != mountSeqNumber) {
somethingHasChanged = true;
}

ds.WriterSession.Id = clientId;
Expand All @@ -174,7 +190,7 @@ NCloud::NProto::TError TDeviceClient::AcquireDevices(
}
}

return {};
return {somethingHasChanged};
}

NCloud::NProto::TError TDeviceClient::ReleaseDevices(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
#include <cloud/blockstore/config/disk.pb.h>
#include <cloud/blockstore/public/api/protos/volume.pb.h>

#include <cloud/storage/core/libs/common/error.h>
#include <cloud/storage/core/libs/diagnostics/logging.h>
#include <cloud/storage/core/protos/error.pb.h>

#include <util/datetime/base.h>
#include <util/generic/hash.h>
Expand Down Expand Up @@ -55,7 +55,9 @@ class TDeviceClient final
TDeviceClient(TDeviceClient&&) noexcept = delete;
TDeviceClient& operator=(TDeviceClient&&) noexcept = delete;

NCloud::NProto::TError AcquireDevices(
// returns `true` if any session has been updated
// (excluding `LastActivityTs` field) or a new one has been added.
TResultOrError<bool> AcquireDevices(
const TVector<TString>& uuids,
const TString& clientId,
TInstant now,
Expand Down
98 changes: 88 additions & 10 deletions cloud/blockstore/libs/storage/disk_agent/model/device_client_ut.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ auto AcquireDevices(TDeviceClient& client, const TAcquireParamsBuilder& builder)
builder.AccessMode,
builder.MountSeqNumber,
builder.DiskId,
builder.VolumeGeneration);
builder.VolumeGeneration).GetError();
}

////////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -618,9 +618,7 @@ Y_UNIT_TEST_SUITE(TDeviceClientTest)
UNIT_ASSERT_VALUES_EQUAL("writer", session.GetClientId());
UNIT_ASSERT_VALUES_EQUAL(1, session.GetVolumeGeneration());
UNIT_ASSERT(!session.GetReadOnly());
UNIT_ASSERT_VALUES_EQUAL(
TInstant::Seconds(42),
TInstant::MicroSeconds(session.GetLastActivityTs()));
UNIT_ASSERT_VALUES_EQUAL(0, session.GetLastActivityTs());
UNIT_ASSERT_VALUES_EQUAL(2, session.DeviceIdsSize());
UNIT_ASSERT_VALUES_EQUAL("uuid1", session.GetDeviceIds(0));
UNIT_ASSERT_VALUES_EQUAL("uuid2", session.GetDeviceIds(1));
Expand All @@ -644,9 +642,7 @@ Y_UNIT_TEST_SUITE(TDeviceClientTest)
UNIT_ASSERT_VALUES_EQUAL("reader", session.GetClientId());
UNIT_ASSERT_VALUES_EQUAL(2, session.GetVolumeGeneration());
UNIT_ASSERT(session.GetReadOnly());
UNIT_ASSERT_VALUES_EQUAL(
TInstant::Seconds(100),
TInstant::MicroSeconds(session.GetLastActivityTs()));
UNIT_ASSERT_VALUES_EQUAL(0, session.GetLastActivityTs());
UNIT_ASSERT_VALUES_EQUAL(2, session.DeviceIdsSize());
UNIT_ASSERT_VALUES_EQUAL("uuid1", session.GetDeviceIds(0));
UNIT_ASSERT_VALUES_EQUAL("uuid2", session.GetDeviceIds(1));
Expand All @@ -657,15 +653,97 @@ Y_UNIT_TEST_SUITE(TDeviceClientTest)
UNIT_ASSERT_VALUES_EQUAL("writer", session.GetClientId());
UNIT_ASSERT_VALUES_EQUAL(2, session.GetVolumeGeneration());
UNIT_ASSERT(!session.GetReadOnly());
UNIT_ASSERT_VALUES_EQUAL(
TInstant::Seconds(42),
TInstant::MicroSeconds(session.GetLastActivityTs()));
UNIT_ASSERT_VALUES_EQUAL(0, session.GetLastActivityTs());
UNIT_ASSERT_VALUES_EQUAL(2, session.DeviceIdsSize());
UNIT_ASSERT_VALUES_EQUAL("uuid1", session.GetDeviceIds(0));
UNIT_ASSERT_VALUES_EQUAL("uuid2", session.GetDeviceIds(1));
}
}
}

Y_UNIT_TEST_F(TestShouldAcquire, TFixture)
{
auto client = CreateClient({
.Devices = {"uuid1", "uuid2"}
});

UNIT_ASSERT_VALUES_EQUAL(0, client.GetSessions().size());

{
auto [updated, error] = client.AcquireDevices(
{"uuid2", "uuid1"}, // uuids
"writer", // ClientId
TInstant::Seconds(10), // now
NProto::VOLUME_ACCESS_READ_WRITE,
1, // MountSeqNumber
"vol0", // DiskId
1 // VolumeGeneration
);

UNIT_ASSERT_C(!HasError(error), error);
UNIT_ASSERT(updated); // new write session
}

{
auto [updated, error] = client.AcquireDevices(
{"uuid2", "uuid1"}, // uuids
"writer", // ClientId
TInstant::Seconds(100), // now
NProto::VOLUME_ACCESS_READ_WRITE,
1, // MountSeqNumber
"vol0", // DiskId
1 // VolumeGeneration
);

UNIT_ASSERT_C(!HasError(error), error);
UNIT_ASSERT(!updated);
}

{
auto [updated, error] = client.AcquireDevices(
{"uuid2", "uuid1"}, // uuids
"writer", // ClientId
TInstant::Seconds(200), // now
NProto::VOLUME_ACCESS_READ_WRITE,
1, // MountSeqNumber
"vol0", // DiskId
2 // volumeGeneration
);

UNIT_ASSERT_C(!HasError(error), error);
UNIT_ASSERT(updated); // new volumeGeneration
}

{
auto [updated, error] = client.AcquireDevices(
{"uuid2", "uuid1"}, // uuids
"reader", // ClientId
TInstant::Seconds(300), // now
NProto::VOLUME_ACCESS_READ_ONLY,
1, // MountSeqNumber
"vol0", // DiskId
3 // VolumeGeneration
);

UNIT_ASSERT_C(!HasError(error), error);
UNIT_ASSERT(updated); // new read session
}

{
auto [updated, error] = client.AcquireDevices(
{"uuid2", "uuid1"}, // uuids
"reader2", // ClientId
TInstant::Seconds(300), // now
NProto::VOLUME_ACCESS_READ_ONLY,
1, // MountSeqNumber
"vol0", // DiskId
3 // VolumeGeneration
);

UNIT_ASSERT_C(!HasError(error), error);
UNIT_ASSERT(updated); // new read session
}
}
}

} // namespace NCloud::NBlockStore::NStorage
Original file line number Diff line number Diff line change
Expand Up @@ -754,6 +754,15 @@ NProto::TError TDiskRegistryState::ValidateAgent(
<< "all agent devices should come from the same rack, mismatch: "
<< rack << " != " << device.GetRack());
}

if (device.GetState() != NProto::DEVICE_STATE_ONLINE &&
device.GetState() != NProto::DEVICE_STATE_ERROR)
{
return MakeError(E_ARGUMENT, TStringBuilder()
<< "unexpected state of the device " << device.GetDeviceUUID()
<< ": " << NProto::EDeviceState_Name(device.GetState())
<< " (" << static_cast<ui32>(device.GetState()) << ")");
}
}

return {};
Expand Down
Loading