Fix race condition in default superuser setup; patch by Sylvain Lebresne and Aleksey Yeschenko for CASSANDRA-5049
Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/26e71c1c Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/26e71c1c Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/26e71c1c Branch: refs/heads/trunk Commit: 26e71c1ce476b74f7fc209d829b5d7e3896ff6c8 Parents: 35a653c Author: Aleksey Yeschenko <alek...@apache.org> Authored: Mon Dec 10 22:36:05 2012 +0300 Committer: Aleksey Yeschenko <alek...@apache.org> Committed: Mon Dec 10 22:36:05 2012 +0300 ---------------------------------------------------------------------- src/java/org/apache/cassandra/auth/Auth.java | 35 ++++++-------- .../apache/cassandra/service/StorageService.java | 8 +++- 2 files changed, 22 insertions(+), 21 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cassandra/blob/26e71c1c/src/java/org/apache/cassandra/auth/Auth.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/auth/Auth.java b/src/java/org/apache/cassandra/auth/Auth.java index 45b4435..a1ba3df 100644 --- a/src/java/org/apache/cassandra/auth/Auth.java +++ b/src/java/org/apache/cassandra/auth/Auth.java @@ -17,8 +17,6 @@ */ package org.apache.cassandra.auth; -import java.util.concurrent.TimeUnit; - import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -28,7 +26,6 @@ import org.apache.cassandra.cql3.UntypedResultSet; import org.apache.cassandra.cql3.QueryProcessor; import org.apache.cassandra.exceptions.RequestExecutionException; import org.apache.cassandra.service.MigrationManager; -import org.apache.cassandra.service.StorageService; public class Auth { @@ -116,25 +113,23 @@ public class Auth // register a custom MigrationListener for permissions cleanup after dropped keyspaces/cfs. MigrationManager.instance.register(new MigrationListener()); + } - // schedule seeding a superuser in RING_DELAY milliseconds. - Runnable runnable = new Runnable() + /** + * Sets up default superuser. + */ + public static void setupSuperuser() + { + try { - public void run() - { - try - { - // insert a default superuser if AUTH_KS.USERS_CF is empty. - if (QueryProcessor.process(String.format("SELECT * FROM %s.%s", AUTH_KS, USERS_CF)).isEmpty()) - insertUser(DEFAULT_SUPERUSER_NAME, true); - } - catch (RequestExecutionException e) - { - logger.warn("Skipping default superuser setup: some nodes are not ready"); - } - } - }; - StorageService.tasks.schedule(runnable, StorageService.RING_DELAY, TimeUnit.MILLISECONDS); + // insert a default superuser if AUTH_KS.USERS_CF is empty. + if (QueryProcessor.process(String.format("SELECT * FROM %s.%s", AUTH_KS, USERS_CF)).isEmpty()) + insertUser(DEFAULT_SUPERUSER_NAME, true); + } + catch (RequestExecutionException e) + { + logger.warn("Skipping default superuser setup: some nodes are not ready"); + } } // we only worry about one character ('). Make sure it's properly escaped. http://git-wip-us.apache.org/repos/asf/cassandra/blob/26e71c1c/src/java/org/apache/cassandra/service/StorageService.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/service/StorageService.java b/src/java/org/apache/cassandra/service/StorageService.java index e5550f9..08dc5fc 100644 --- a/src/java/org/apache/cassandra/service/StorageService.java +++ b/src/java/org/apache/cassandra/service/StorageService.java @@ -37,6 +37,7 @@ import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.apache.cassandra.auth.Auth; import org.apache.cassandra.concurrent.DebuggableScheduledThreadPoolExecutor; import org.apache.cassandra.concurrent.Stage; import org.apache.cassandra.concurrent.StageManager; @@ -62,7 +63,6 @@ import org.apache.cassandra.net.IAsyncResult; import org.apache.cassandra.net.MessageOut; import org.apache.cassandra.net.MessagingService; import org.apache.cassandra.net.ResponseVerbHandler; -import org.apache.cassandra.service.AntiEntropyService.RepairFuture; import org.apache.cassandra.service.AntiEntropyService.TreeRequestVerbHandler; import org.apache.cassandra.streaming.*; import org.apache.cassandra.thrift.Constants; @@ -738,6 +738,9 @@ public class StorageService implements IEndpointStateChangeSubscriber, StorageSe Gossiper.instance.replacedEndpoint(existing); logger.info("Startup completed! Now serving reads."); assert tokenMetadata.sortedTokens().size() > 0; + + // setup default superuser (if needed). + Auth.setupSuperuser(); } else { @@ -775,6 +778,9 @@ public class StorageService implements IEndpointStateChangeSubscriber, StorageSe isSurveyMode = false; logger.info("Leaving write survey mode and joining ring at operator request"); assert tokenMetadata.sortedTokens().size() > 0; + + // setup default superuser (if needed). + Auth.setupSuperuser(); } }