fixed locking transient bug

This commit is contained in:
David Ribeiro Alves 2012-03-22 17:49:04 +00:00
parent 28bd62edfc
commit 1f31e96a9f
7 changed files with 39 additions and 29 deletions

View File

@ -158,7 +158,7 @@ public class VirtualBoxComputeServiceContextModule extends
bind(new TypeLiteral<Function<IMachine, SshClient>>() {
}).to(IMachineToSshClient.class);
bind(ExecutionType.class).toInstance(ExecutionType.GUI);
bind(ExecutionType.class).toInstance(ExecutionType.HEADLESS);
bind(LockType.class).toInstance(LockType.Write);
}

View File

@ -147,7 +147,7 @@ public class CreateAndInstallVm implements Function<MasterSpec, IMachine> {
.split(installationKeySequence), new StringToKeyCode());
for (List<Integer> scancodes : scancodelist) {
machineUtils.readLockMachineAndApplyToSession(vmName,new SendScancodes(scancodes));
machineUtils.sharedLockMachineAndApplyToSession(vmName,new SendScancodes(scancodes));
}
}

View File

@ -46,6 +46,7 @@ import org.jclouds.virtualbox.domain.NodeSpec;
import org.jclouds.virtualbox.domain.VmSpec;
import org.jclouds.virtualbox.statements.DeleteGShadowLock;
import org.jclouds.virtualbox.statements.SetIpAddress;
import org.jclouds.virtualbox.util.MachineController;
import org.jclouds.virtualbox.util.MachineUtils;
import org.virtualbox_4_1.CleanupMode;
import org.virtualbox_4_1.IMachine;
@ -83,23 +84,22 @@ public class NodeCreator implements Function<NodeSpec, NodeAndInitialCredentials
// TODO parameterize
public static final boolean USE_LINKED = true;
// TODO parameterize
public static final ExecutionType EXECUTION_TYPE = ExecutionType.HEADLESS;
private final Supplier<VirtualBoxManager> manager;
private final Function<CloneSpec, IMachine> cloner;
private final AtomicInteger nodePorts;
private final AtomicInteger nodeIps;
private MachineUtils machineUtils;
private final MachineUtils machineUtils;
private final MachineController machineController;
@Inject
public NodeCreator(Supplier<VirtualBoxManager> manager, Function<CloneSpec, IMachine> cloner,
MachineUtils machineUtils, RunScriptOnNode.Factory scriptRunnerFactory) {
MachineUtils machineUtils, RunScriptOnNode.Factory scriptRunnerFactory, MachineController machineController) {
this.manager = manager;
this.cloner = cloner;
this.nodePorts = new AtomicInteger(NODE_PORT_INIT);
this.nodeIps = new AtomicInteger(2);
this.machineUtils = machineUtils;
this.machineController = machineController;
}
@Override
@ -147,7 +147,7 @@ public class NodeCreator implements Function<NodeSpec, NodeAndInitialCredentials
IMachine cloned = cloner.apply(cloneSpec);
new LaunchMachineIfNotAlreadyRunning(manager.get(), EXECUTION_TYPE, "").apply(cloned);
machineController.ensureMachineIsLaunched(cloneVmSpec.getVmName());
// IMachineToNodeMetadata produces the final ip's but these need to be set before so we build a
// NodeMetadata just for the sake of running the gshadow and setip scripts

View File

@ -67,7 +67,7 @@ public class MachineController {
public void ensureMachineHasPowerDown(String vmName) {
while (!manager.get().getVBox().findMachine(vmName).getState().equals(MachineState.POWERED_OFF)) {
try {
machineUtils.writeLockMachineAndApplyToSession(vmName, new Function<ISession, Void>() {
machineUtils.sharedLockMachineAndApplyToSession(vmName, new Function<ISession, Void>() {
@Override
public Void apply(ISession session) {
IProgress powerDownProgress = session.getConsole().powerDown();

View File

@ -57,15 +57,12 @@ public class MachineUtils {
private final Supplier<VirtualBoxManager> manager;
private final Factory scriptRunner;
private final Supplier<NodeMetadata> host;
@Inject
public MachineUtils(Supplier<VirtualBoxManager> manager, RunScriptOnNode.Factory scriptRunner,
Supplier<NodeMetadata> host) {
public MachineUtils(Supplier<VirtualBoxManager> manager, RunScriptOnNode.Factory scriptRunner) {
super();
this.manager = manager;
this.scriptRunner = scriptRunner;
this.host = host;
}
public ListenableFuture<ExecResponse> runScriptOnNode(NodeMetadata metadata, Statement statement,
@ -100,10 +97,11 @@ public class MachineUtils {
});
}
/**
* Locks the machine and executes the given function using the machine matching the given id.
* The machine is write locked and modifications to the session that reflect on the machine can be done safely.
* Locks the machine and executes the given function using the machine matching the given id. The
* machine is write locked and modifications to the session that reflect on the machine can be
* done safely.
* <p/>
* Unlocks the machine before returning.
*
@ -116,10 +114,11 @@ public class MachineUtils {
public <T> T writeLockMachineAndApplyToSession(final String machineId, final Function<ISession, T> function) {
return lockSessionOnMachineAndApply(machineId, LockType.Write, function);
}
/**
* Locks the machine and executes the given function using the machine matching the given id.
* The machine is read locked, which means that settings can be read safely (but not changed) by function.
* Locks the machine and executes the given function using the machine matching the given id. The
* machine is read locked, which means that settings can be read safely (but not changed) by
* function.
* <p/>
* Unlocks the machine before returning.
*
@ -129,7 +128,7 @@ public class MachineUtils {
* the function to execute
* @return the result from applying the function to the machine.
*/
public <T> T readLockMachineAndApply(final String machineId, final Function<IMachine, T> function) {
public <T> T sharedLockMachineAndApply(final String machineId, final Function<IMachine, T> function) {
return lockSessionOnMachineAndApply(machineId, LockType.Shared, new Function<ISession, T>() {
@Override
@ -144,10 +143,11 @@ public class MachineUtils {
});
}
/**
* Locks the machine and executes the given function to the session using the machine matching the given id.
* The machine is read locked, which means that settings can be read safely (but not changed) by function.
* Locks the machine and executes the given function to the session using the machine matching
* the given id. The machine is read locked, which means that settings can be read safely (but
* not changed) by function.
* <p/>
* Unlocks the machine before returning.
*
@ -157,10 +157,9 @@ public class MachineUtils {
* the function to execute
* @return the result from applying the function to the machine.
*/
public <T> T readLockMachineAndApplyToSession(final String machineId, final Function<ISession, T> function) {
public <T> T sharedLockMachineAndApplyToSession(final String machineId, final Function<ISession, T> function) {
return lockSessionOnMachineAndApply(machineId, LockType.Shared, function);
}
/**
* Locks the machine and executes the given function using the current session. Since the machine
@ -183,11 +182,14 @@ public class MachineUtils {
int retries = 5;
int count = 0;
ISession session;
long time = System.currentTimeMillis();
while (true) {
try {
session = manager.get().getSessionObject();
IMachine immutableMachine = manager.get().getVBox().findMachine(machineId);
session = manager.get().getSessionObject();
immutableMachine.lockMachine(session, type);
System.err.println("ACQUIRED LOCK ["+time+"]");
print();
break;
} catch (VBoxException e) {
VBoxException vbex = Throwables2.getFirstThrowableOfType(e, VBoxException.class);
@ -195,7 +197,7 @@ public class MachineUtils {
return null;
}
count++;
logger.warn("Could not lock machine (try %i of %i). Error: %s", retries, count, e.getMessage());
logger.warn(e, "Could not lock machine (try %d of %d). Error: %s", count, retries, e.getMessage());
if (count == retries) {
throw new RuntimeException(String.format("error locking %s with %s lock: %s", machineId, type,
e.getMessage()), e);
@ -213,6 +215,14 @@ public class MachineUtils {
type, e.getMessage()), e);
} finally {
session.unlockMachine();
System.err.println("RELEASED LOCK ["+time+"]");
print();
}
}
void print() {
for (StackTraceElement element : Thread.currentThread().getStackTrace()){
System.err.println(element.toString());
}
}

View File

@ -142,7 +142,7 @@ public class CreateAndInstallVmLiveTest extends BaseVirtualBoxClientLiveTest {
String vboxVersion = Iterables.get(
Splitter.on('r').split(context.getProviderSpecificContext().getBuildVersion()), 0);
assertEquals(vboxVersion, machineUtils.readLockMachineAndApplyToSession(machine.getName(),
assertEquals(vboxVersion, machineUtils.sharedLockMachineAndApplyToSession(machine.getName(),
new Function<ISession, String>() {
@Override
public String apply(ISession session) {

View File

@ -110,7 +110,7 @@ public class GuestAdditionsInstallerLiveTest extends
machineUtils.applyForMachine(machine.getName(),
new LaunchMachineIfNotAlreadyRunning(manager.get(),
ExecutionType.GUI, ""));
assertTrue(machineUtils.readLockMachineAndApplyToSession(
assertTrue(machineUtils.sharedLockMachineAndApplyToSession(
machine.getName(),
new Function<ISession, Boolean>() {
@Override