mirror of
https://github.com/apple/foundationdb.git
synced 2025-06-02 19:25:52 +08:00
More carefully validate tenant increments to avoid overflows
This commit is contained in:
parent
dbcab0b1bd
commit
3881f1ccc6
@ -77,17 +77,16 @@ bool tenantMapChanging(MutationRef const& mutation, KeyRangeRef const& tenantMap
|
||||
return false;
|
||||
}
|
||||
|
||||
// validates whether the lastTenantId and the nextTenantId share the same 2 byte prefix
|
||||
bool nextTenantIdPrefixMatches(int64_t lastTenantId, int64_t nextTenantId) {
|
||||
if (getTenantIdPrefix(nextTenantId) != getTenantIdPrefix(lastTenantId)) {
|
||||
TraceEvent(g_network->isSimulated() ? SevWarnAlways : SevError, "TenantIdPrefixMismatch")
|
||||
.detail("CurrentTenantId", lastTenantId)
|
||||
.detail("NewTenantId", nextTenantId)
|
||||
.detail("CurrentTenantIdPrefix", getTenantIdPrefix(lastTenantId))
|
||||
.detail("NewTenantIdPrefix", getTenantIdPrefix(nextTenantId));
|
||||
return false;
|
||||
// validates whether the the ID created by adding delta to baseID is a valid ID in the same tenant prefix
|
||||
int64_t computeNextTenantId(int64_t baseId, int64_t delta) {
|
||||
if ((baseId & 0xFFFFFFFFFFFF) + delta > 0xFFFFFFFFFFFF) {
|
||||
TraceEvent(g_network->isSimulated() ? SevWarnAlways : SevError, "NoMoreTenantIds")
|
||||
.detail("LastTenantId", baseId)
|
||||
.detail("TenantIdPrefix", getTenantIdPrefix(baseId));
|
||||
throw cluster_no_capacity();
|
||||
}
|
||||
return true;
|
||||
|
||||
return baseId + delta;
|
||||
}
|
||||
|
||||
// returns the maximum allowable tenant id in which the 2 byte prefix is not overriden
|
||||
|
@ -2603,10 +2603,7 @@ struct CreateTenantImpl {
|
||||
ASSERT(tenantIdPrefix.present());
|
||||
lastId = tenantIdPrefix.get() << 48;
|
||||
}
|
||||
if (!TenantAPI::nextTenantIdPrefixMatches(lastId.get(), lastId.get() + 1)) {
|
||||
throw cluster_no_capacity();
|
||||
}
|
||||
self->tenantEntry.setId(lastId.get() + 1);
|
||||
self->tenantEntry.setId(TenantAPI::computeNextTenantId(lastId.get(), 1));
|
||||
ManagementClusterMetadata::tenantMetadata().lastTenantId.set(tr, self->tenantEntry.id);
|
||||
|
||||
self->tenantEntry.tenantState = MetaclusterAPI::TenantState::REGISTERING;
|
||||
|
@ -127,7 +127,7 @@ TenantMode tenantModeForClusterType(ClusterType clusterType, TenantMode tenantMo
|
||||
int64_t extractTenantIdFromMutation(MutationRef m);
|
||||
int64_t extractTenantIdFromKeyRef(StringRef s);
|
||||
bool tenantMapChanging(MutationRef const& mutation, KeyRangeRef const& tenantMapRange);
|
||||
bool nextTenantIdPrefixMatches(int64_t lastTenantId, int64_t nextTenantId);
|
||||
int64_t computeNextTenantId(int64_t tenantId, int64_t delta);
|
||||
int64_t getMaxAllowableTenantId(int64_t curTenantId);
|
||||
int64_t getTenantIdPrefix(int64_t tenantId);
|
||||
|
||||
@ -230,14 +230,13 @@ Future<int64_t> getNextTenantId(Transaction tr) {
|
||||
// Shift by 6 bytes to make the prefix the first two bytes of the tenant id
|
||||
lastId = tenantIdPrefix << 48;
|
||||
}
|
||||
int64_t tenantId = lastId.get() + 1;
|
||||
|
||||
int64_t delta = 1;
|
||||
if (BUGGIFY) {
|
||||
tenantId += deterministicRandom()->randomSkewedUInt32(1, 1e9);
|
||||
delta += deterministicRandom()->randomSkewedUInt32(1, 1e9);
|
||||
}
|
||||
if (!TenantAPI::nextTenantIdPrefixMatches(lastId.get(), tenantId)) {
|
||||
throw cluster_no_capacity();
|
||||
}
|
||||
return tenantId;
|
||||
|
||||
return TenantAPI::computeNextTenantId(lastId.get(), delta);
|
||||
}
|
||||
|
||||
ACTOR template <class DB>
|
||||
|
@ -134,17 +134,18 @@ private:
|
||||
TenantMetadata::tenantCount().getD(&ryw->getTransaction(), Snapshot::False, 0);
|
||||
int64_t _nextId = wait(TenantAPI::getNextTenantId(&ryw->getTransaction()));
|
||||
state int64_t nextId = _nextId;
|
||||
ASSERT(nextId > 0);
|
||||
ASSERT(nextId >= 0);
|
||||
|
||||
state std::vector<Future<bool>> createFutures;
|
||||
int itrCount = 0;
|
||||
for (auto const& [tenant, config] : tenants) {
|
||||
if (!TenantAPI::nextTenantIdPrefixMatches(nextId - 1, nextId)) {
|
||||
throw cluster_no_capacity();
|
||||
createFutures.push_back(createTenant(ryw, tenant, config, nextId, tenantGroupNetTenantDelta));
|
||||
if (++itrCount < tenants.size()) {
|
||||
nextId = TenantAPI::computeNextTenantId(nextId, 1);
|
||||
}
|
||||
createFutures.push_back(createTenant(ryw, tenant, config, nextId++, tenantGroupNetTenantDelta));
|
||||
}
|
||||
|
||||
TenantMetadata::lastTenantId().set(&ryw->getTransaction(), nextId - 1);
|
||||
TenantMetadata::lastTenantId().set(&ryw->getTransaction(), nextId);
|
||||
wait(waitForAll(createFutures));
|
||||
|
||||
state int numCreatedTenants = 0;
|
||||
|
Loading…
x
Reference in New Issue
Block a user