public void notifyOfDowngradedLocks(bladeLockType readToAdd, bladeLockType writeToAdd) { permittedAccessRead = bladeLockCollection.clearField(permittedAccessRead, readToAdd); permittedAccessWrite = bladeLockCollection.clearField(permittedAccessWrite, writeToAdd); foreach (string lockName in bladeLockCollection.getLockNames()) { bladeLockType lockType = (bladeLockType)Enum.Parse(typeof(bladeLockType), lockName); // We are downgrading if we previously held a writer lock, and now hold a reader lock. bool releasingWrite = ((int)writeToAdd & (int)lockType) != 0; bool releasingRead = ((int)readToAdd & (int)lockType) != 0; bool downgradingWriteToRead = releasingWrite && !releasingRead; if (releasingWrite) { // Flush anything we are no longer holding a write lock on to the DB. createOrUpdateInDB(getPermittedFieldsIncludingInheritors(lockType)); } if (downgradingWriteToRead) { // We should make sure we set the read lock if we're downgrading permittedAccessRead |= lockType; } } }
private new static List <string> getPermittedFields(bladeLockType lockType) { List <string> toRet = new List <string>(); if (lockType.HasFlag(bladeLockType.lockIPAddresses)) { toRet.Add("iscsiIP"); toRet.Add("bladeIP"); toRet.Add("iLOIP"); } if (lockType.HasFlag(bladeLockType.lockvmDeployState)) { toRet.Add("vmDeployState"); } if (lockType.HasFlag(bladeLockType.lockBIOS)) { toRet.Add("currentlyHavingBIOSDeployed"); toRet.Add("lastDeployedBIOS"); } if (lockType.HasFlag(bladeLockType.lockOwnership)) { toRet.Add("currentlyBeingAVMServer"); } return(toRet.Distinct().ToList()); }
private new static List <string> getPermittedFields(bladeLockType lockType) { List <string> toRet = new List <string>(); if ((lockType & bladeLockType.lockIPAddresses) != bladeLockType.lockNone) { toRet.Add("iscsiIP"); toRet.Add("VMIP"); } if ((lockType & bladeLockType.lockVirtualHW) != bladeLockType.lockNone) { toRet.Add("vmConfigKey"); toRet.Add("eth0MAC"); toRet.Add("eth1MAC"); toRet.Add("cpuCount"); toRet.Add("memoryMB"); } if ((lockType & bladeLockType.lockOwnership) != bladeLockType.lockNone) { toRet.Add("parentBladeID"); toRet.Add("parentBladeIP"); toRet.Add("indexOnServer"); toRet.Add("isWaitingForResources"); } return(toRet.Distinct().ToList()); }
public bladeSpec createBladeSpec(string newBladeIP, string newISCSIIP, string newILOIP, ushort newILOPort, bool newCurrentlyHavingBIOSDeployed, VMDeployStatus newVMDeployState, string newCurrentBIOS, bladeLockType permittedAccess) { return(new bladeSpec(newBladeIP, newISCSIIP, newILOIP, newILOPort, newCurrentlyHavingBIOSDeployed, newVMDeployState, newCurrentBIOS, permittedAccess)); }
public void acquire(bladeLockType readTypes, bladeLockType writeTypes) { if (!tryAcquire(readTypes, writeTypes)) { throw new Exception(".."); } return; debugmsg(Thread.CurrentThread.ManagedThreadId + " bladeLockCollection for blade " + _name + " acquiring " + readTypes + " / " + writeTypes); debugmsg(Thread.CurrentThread.ManagedThreadId + Environment.StackTrace); DateTime deadline = DateTime.Now + TimeSpan.FromSeconds(10); while (true) { if (tryAcquire(readTypes, writeTypes)) { break; } if (DateTime.Now > deadline) { throw new ApplicationException("can't lock"); } Thread.Sleep(TimeSpan.FromSeconds(1)); } debugmsg(Thread.CurrentThread.ManagedThreadId + " bladeLockCollection acquisition for blade " + _name + " finished"); }
public List <string> getPermittedFields(bladeLockType lockType) { List <string> toRet = new List <string>(); if (lockType.HasFlag(bladeLockType.lockIPAddresses)) { toRet.Add("kernelDebugPort"); } if (lockType.HasFlag(bladeLockType.lockVirtualHW)) { toRet.Add("kernelDebugKey"); toRet.Add("friendlyName"); toRet.Add("availableUsersCSV"); } if (lockType.HasFlag(bladeLockType.lockOwnership)) { toRet.Add("state"); toRet.Add("currentOwner"); toRet.Add("nextOwner"); } if (lockType.HasFlag(bladeLockType.lockSnapshot)) { toRet.Add("currentSnapshot"); } toRet.Add("lastKeepAlive"); return(toRet.Distinct().ToList()); }
public void notifyOfUpgradedLocks(bladeLockType readToAdd, bladeLockType writeToAdd) { foreach (string lockName in bladeLockCollection.getLockNames()) { bladeLockType lockType = (bladeLockType)Enum.Parse(typeof(bladeLockType), lockName); bool previouslyHeldRead = ((int)permittedAccessRead & (int)lockType) != 0; bool addingRead = ((int)readToAdd & (int)lockType) != 0; bool addingWrite = ((int)writeToAdd & (int)lockType) != 0; if (previouslyHeldRead) { addingRead = false; } // If we are adding a read lock, we must get clean data from the DB. We don't need to do this for a write lock if // we already held the read lock, since no-one could've changed it. if (addingRead | (!previouslyHeldRead && addingWrite)) { updateFieldFromDB(getPermittedFieldsIncludingInheritors(lockType)); } } // Writer locks imply reader locks permittedAccessRead |= readToAdd | writeToAdd; permittedAccessWrite |= writeToAdd; }
public override List <string> getPermittedFieldsIncludingInheritors(bladeLockType lockType) { List <string> toRet = getPermittedFields(lockType); toRet.AddRange(base.getPermittedFields(lockType)); return(toRet.Distinct().ToList()); }
public bladeSpec createBladeSpec(string newBladeIP, string newISCSIIP, string newILOIP, ushort newKernelDebugPort, bool newCurrentlyHavingBIOSDeployed, VMDeployStatus newvmDeployState, string newCurrentBIOS, string newDebugKey, string newFriendlyName, bladeLockType permittedAccessRead, bladeLockType permittedAccessWrite) { return(new bladeSpec(null, newBladeIP, newISCSIIP, newILOIP, newKernelDebugPort, newCurrentlyHavingBIOSDeployed, newvmDeployState, newCurrentBIOS, newDebugKey, newFriendlyName, permittedAccessRead, permittedAccessWrite)); }
public bladeSpec(SQLiteConnection conn, SQLiteDataReader reader, bladeLockType permittedAccessRead, bladeLockType permittedAccessWrite) : base(conn, reader, permittedAccessRead, permittedAccessWrite) { parseFromDBRow(reader); ESXiUsername = Settings.Default.esxiUsername; ESXiPassword = Settings.Default.esxiPassword; iLoUsername = Settings.Default.iloUsername; iLoPassword = Settings.Default.iloPassword; }
public lockableOwnership(string bladeIP, bladeLockType readLocks, bladeLockType writeLocks) { IPAddress = bladeIP; _readLocks = readLocks; _writeLocks = writeLocks; specOwnership = null; allocationStack = Environment.StackTrace; acquire(); }
public void release(bladeLockType readTypes, bladeLockType writeTypes) { debugmsg(Thread.CurrentThread.ManagedThreadId + " bladeLockCollection release for blade " + _name + " releasing " + readTypes + " / " + writeTypes); debugmsg(Thread.CurrentThread.ManagedThreadId + Environment.StackTrace); foreach (string lockTypeName in getLockNames()) { bladeLockType lockType = (bladeLockType)Enum.Parse(typeof(bladeLockType), lockTypeName); bool willReleaseReadLock = (((int)readTypes & (int)lockType) != 0); bool willReleaseWriteLock = (((int)writeTypes & (int)lockType) != 0); debugmsg(lockTypeName + " releasing " + willReleaseReadLock + "/" + willReleaseWriteLock + " : current access " + locksForThisBlade[lockTypeName].IsReaderLockHeld + "/" + locksForThisBlade[lockTypeName].IsWriterLockHeld); if (willReleaseWriteLock) { _writeTakenList[lockTypeName].threadID = -1; // We will downgrade the lock if neccessary. if (willReleaseReadLock) { // We are releasing the whole lock. debugmsg(Thread.CurrentThread.ManagedThreadId + " bladeLockCollection release for blade " + _name + lockTypeName + " downgrading"); locksForThisBlade[lockTypeName].DowngradeFromWriterLock(); debugmsg(Thread.CurrentThread.ManagedThreadId + " bladeLockCollection release for blade " + _name + lockTypeName + " releasing reader lock"); locksForThisBlade[lockTypeName].ReleaseReaderLock(); // The read lock is now not taken by this thread. takenLockInfo tmp; _readTakenList[lockTypeName].TryRemove(Thread.CurrentThread.ManagedThreadId, out tmp); } else { debugmsg(Thread.CurrentThread.ManagedThreadId + " bladeLockCollection release for blade " + _name + lockTypeName + " downgrading (!willReleaseReaderLock)"); locksForThisBlade[lockTypeName].DowngradeFromWriterLock(); takenLockInfo tmp; _readTakenList[lockTypeName].TryRemove(Thread.CurrentThread.ManagedThreadId, out tmp); } } else { // Only release a read lock if we aren't releasing the whole write lock. if (willReleaseReadLock) { takenLockInfo tmp; _readTakenList[lockTypeName].TryRemove(Thread.CurrentThread.ManagedThreadId, out tmp); debugmsg(Thread.CurrentThread.ManagedThreadId + " bladeLockCollection release for blade " + _name + " " + lockTypeName + " releasing reader lock (!willReleaseWriterLock)"); locksForThisBlade[lockTypeName].ReleaseReaderLock(); } } } debugmsg(Thread.CurrentThread.ManagedThreadId + " bladeLockCollection release for blade " + _name + " finished"); }
public void upgradeLocks(bladeLockType readToAdd, bladeLockType writeToAdd) { if (_isDisposed) { return; } _bladeLockStatus[specOwnership.kernelDebugAddress].acquire(readToAdd, writeToAdd); _readLocks |= readToAdd | writeToAdd; _writeLocks |= writeToAdd; specOwnership.notifyOfUpgradedLocks(readToAdd, writeToAdd); }
public bladeLockCollection(string name, bladeLockType readLocks, bladeLockType writeLocks) { _name = name; foreach (string lockTypeName in getLockNames()) { locksForThisBlade.TryAdd(lockTypeName, new nonDeadlockingRWLock()); _readTakenList.TryAdd(lockTypeName, new ConcurrentDictionary <int, takenLockInfo>()); _writeTakenList.TryAdd(lockTypeName, new takenLockInfo()); } debugmsg(Thread.CurrentThread.ManagedThreadId + " bladeLockCollection for blade " + _name + " constructed"); acquire(readLocks, writeLocks); }
protected bladeOwnership(SQLiteConnection conn, SQLiteDataReader reader, bladeLockType permittedAccessRead, bladeLockType permittedAccessWrite) { this.conn = conn; this.permittedAccessRead = permittedAccessRead; this.permittedAccessWrite = permittedAccessWrite; if (permittedAccessRead.HasFlag(bladeLockType.lockVirtualHW)) { _availableUsersCSV = makeUsersCSV(new[] { new userDesc(Settings.Default.vmUsername, Settings.Default.vmPassword) }); } parseFromDBRow(reader); }
protected bladeOwnership(SQLiteConnection conn, string newFriendlyName, ushort newDebugPort, string newDebugKey, bladeLockType permittedAccessRead, bladeLockType permittedAccessWrite) { this.conn = conn; _state = bladeStatus.unused; _friendlyName = newFriendlyName; _kernelDebugPort = newDebugPort; _kernelDebugKey = newDebugKey; this.permittedAccessRead = permittedAccessRead; this.permittedAccessWrite = permittedAccessWrite; if (permittedAccessRead.HasFlag(bladeLockType.lockVirtualHW)) { _availableUsersCSV = makeUsersCSV(new[] { new userDesc(Settings.Default.vmUsername, Settings.Default.vmPassword) }); } }
public vmSpec(SQLiteConnection conn, string IP, bladeLockType readLock, bladeLockType writeLock, bool writeToDBImmediately = true) : base(conn, IP, 0, "a.b.c.d", readLock, writeLock) { vmConfigKey = null; VMIP = IP; if (writeToDBImmediately) { createOrUpdateInDB(new List <string>() { "vmConfigKey", "VMIP" }); } }
public void downgradeLocks(bladeLockType readToRelease, bladeLockType writeToRelease) { if (_isDisposed) { return; } specOwnership.notifyOfDowngradedLocks(readToRelease, writeToRelease); _readLocks = bladeLockCollection.clearField(_readLocks, readToRelease); _writeLocks = bladeLockCollection.clearField(_writeLocks, writeToRelease); // Set any read locks that are being downgraded (ie, writes that we not also releasing reads of) _readLocks |= writeToRelease & (~readToRelease); _bladeLockStatus[specOwnership.kernelDebugAddress].downgrade(readToRelease, writeToRelease); }
public bool assertLocks(bladeLockType read, bladeLockType write) { foreach (string lockTypeName in getLockNames()) { int lockBitMask = (int)Enum.Parse(typeof(bladeLockType), lockTypeName); bool readRequested = ((int)read & lockBitMask) != 0; bool writeRequested = ((int)write & lockBitMask) != 0; if (writeRequested) { if (!locksForThisBlade[lockTypeName].IsWriterLockHeld) { return(false); } } else { if (locksForThisBlade[lockTypeName].IsWriterLockHeld) { return(false); } if (readRequested) { if (!locksForThisBlade[lockTypeName].IsReaderLockHeld) { return(false); } } else { if (locksForThisBlade[lockTypeName].IsReaderLockHeld) { return(false); } } } } return(true); }
private bool tryAcquire(bladeLockType readTypes, bladeLockType writeTypes) { List <string> succededLocks = new List <string>(); foreach (string lockTypeName in getLockNames()) { bool didTake; try { didTake = attemptToTakeSingleLock(readTypes, writeTypes, lockTypeName); } catch (Exception e) { // this is a little tricky, because we need to release any locks we have taken before we return, but since // attemptToTakeSingleLock failed, we have not taken all requested locks. Note that attemptToTakeSingleLock // will undo the _current_ call if it throws. foreach (string lockToRelease in getLockNames()) { if (!succededLocks.Contains(lockToRelease) || lockTypeName == lockToRelease) { // We did not set this one, so clear it from the collection. readTypes &= ~((bladeLockType)(Enum.Parse(typeof(bladeLockType), lockToRelease))); writeTypes &= ~((bladeLockType)(Enum.Parse(typeof(bladeLockType), lockToRelease))); } } release(readTypes, writeTypes); //if (e is ApplicationException) // return false; throw; } if (didTake) { succededLocks.Add(lockTypeName); } } return(true); }
public bladeSpec(SQLiteConnection conn, string newBladeIP, string newISCSIIP, string newILOIP, ushort newKernelDebugPort, bool newCurrentlyHavingBIOSDeployed, VMDeployStatus newvmDeployState, string newCurrentBIOS, string newKernelDebugKey, string newFriendlyName, bladeLockType permittedAccessRead, bladeLockType permittedAccessWrite) : base(conn, newFriendlyName, newKernelDebugPort, newKernelDebugKey, permittedAccessRead, permittedAccessWrite) { _iscsiIP = newISCSIIP; _bladeIP = newBladeIP; _iLOIP = newILOIP; _currentlyHavingBIOSDeployed = newCurrentlyHavingBIOSDeployed; _lastDeployedBIOS = newCurrentBIOS; _vmDeployState = newvmDeployState; ESXiUsername = Settings.Default.esxiUsername; ESXiPassword = Settings.Default.esxiPassword; iLoUsername = Settings.Default.iloUsername; iLoPassword = Settings.Default.iloPassword; }
public lockableVMSpec getVMByIP(string bladeName, bladeLockType readLock, bladeLockType writeLock) { // We need to lock IP addressess, since we're searching by them. readLock = readLock | bladeLockType.lockIPAddresses; lockableVMSpec toRet = new lockableVMSpec(bladeName, readLock, writeLock); try { string sqlCommand = "select * from bladeOwnership " + "join VMConfiguration on ownershipKey = VMConfiguration.ownershipID " + "where VMConfiguration.VMIP = $VMIP"; using (SQLiteCommand cmd = new SQLiteCommand(sqlCommand, conn)) { cmd.Parameters.AddWithValue("$VMIP", bladeName); using (SQLiteDataReader reader = cmd.ExecuteReader()) { if (reader.Read()) { toRet.setSpec(new vmSpec(conn, reader, readLock, writeLock)); return(toRet); } // No records returned. toRet.Dispose(); return(null); } } } catch (Exception) { toRet.Dispose(); throw; } }
public disposingList <lockableBladeSpec> getAllBladeInfo(Func <bladeSpec, bool> filter, bladeLockType lockTypeRead, bladeLockType lockTypeWrite, bool permitAccessDuringBIOS = false, bool permitAccessDuringDeployment = false, int max = Int32.MaxValue) { disposingList <lockableBladeSpec> toRet = new disposingList <lockableBladeSpec>(); foreach (string bladeIP in getAllBladeIP()) { lockableBladeSpec blade = getBladeByIP(bladeIP, lockTypeRead, lockTypeWrite, true, true); // Filter out anything as requested if (!filter(blade.spec)) { blade.Dispose(); continue; } // Filter out anything we don't have access to right now, due to BIOS or VM deployments if ((!permitAccessDuringDeployment) && blade.spec.vmDeployState != VMDeployStatus.notBeingDeployed && blade.spec.vmDeployState != VMDeployStatus.failed && blade.spec.vmDeployState != VMDeployStatus.readyForDeployment) { blade.Dispose(); continue; } if ((!permitAccessDuringBIOS) && blade.spec.currentlyHavingBIOSDeployed) { blade.Dispose(); continue; } // Have we hit our maximum yet? if (toRet.Count == max) { blade.Dispose(); continue; } // Otherwise, okay. toRet.Add(blade); } return(toRet); }
public abstract List <string> getPermittedFieldsIncludingInheritors(bladeLockType lockType);
public disposingList <lockableVMSpec> getAllVMInfo(Func <vmSpec, bool> filter, bladeLockType lockTypeRead, bladeLockType lockTypeWrite) { disposingList <lockableVMSpec> toRet = new disposingList <lockableVMSpec>(); foreach (string bladeIP in getAllVMIP()) { lockableVMSpec VM = getVMByIP(bladeIP, lockTypeRead, lockTypeWrite); if (filter(VM.spec)) { toRet.Add(VM); } else { VM.Dispose(); } } return(toRet); }
public vmSpec(SQLiteConnection conn, string friendlyName, VMSoftwareSpec debugSpec, bladeLockType readLock, bladeLockType writeLock) : base(conn, friendlyName, debugSpec, readLock, writeLock) { vmConfigKey = null; }
// FIXME: code duplication public lockableBladeSpec getBladeByIP(string IP, bladeLockType readLock, bladeLockType writeLock, bool permitAccessDuringBIOS = false, bool permitAccessDuringDeployment = false) { bladeLockType origReadLock = readLock | writeLock; readLock = origReadLock; // We need to lock IP addressess, since we're searching by them. readLock = readLock | bladeLockType.lockIPAddresses; readLock = readLock | bladeLockType.lockvmDeployState; readLock = readLock | bladeLockType.lockBIOS; lockableBladeSpec toRet = null; try { toRet = new lockableBladeSpec(IP, readLock, writeLock); string sqlCommand = "select * from bladeOwnership " + "join bladeConfiguration on ownershipKey = bladeConfiguration.ownershipID " + "where bladeIP = $bladeIP"; using (SQLiteCommand cmd = new SQLiteCommand(sqlCommand, conn)) { cmd.Parameters.AddWithValue("$bladeIP", IP); using (SQLiteDataReader reader = cmd.ExecuteReader()) { if (reader.Read()) { bladeSpec newSpec = new bladeSpec(conn, reader, readLock, writeLock); toRet.setSpec(newSpec); if ((!permitAccessDuringDeployment) && newSpec.vmDeployState != VMDeployStatus.notBeingDeployed && newSpec.vmDeployState != VMDeployStatus.failed && newSpec.vmDeployState != VMDeployStatus.readyForDeployment) { throw new Exception("Attempt to access blade during VM deployment"); } if ((!permitAccessDuringBIOS) && newSpec.currentlyHavingBIOSDeployed) { throw new Exception("Attempt to access blade during BIOS deployment"); } if ((origReadLock & bladeLockType.lockvmDeployState) == 0 && (writeLock & bladeLockType.lockvmDeployState) == 0) { toRet.downgradeLocks(bladeLockType.lockvmDeployState, bladeLockType.lockNone); } if ((origReadLock & bladeLockType.lockBIOS) == 0 && (writeLock & bladeLockType.lockBIOS) == 0) { toRet.downgradeLocks(bladeLockType.lockBIOS, bladeLockType.lockNone); } leakCheckerInspector.monitorDisposable(toRet); return(toRet); } // No records returned. throw new bladeNotFoundException(); } } } catch (Exception) { if (toRet != null) { toRet.Dispose(); } throw; } }
public vmSpec(SQLiteConnection conn, SQLiteDataReader reader, bladeLockType readLock, bladeLockType writeLock) : base(conn, reader, readLock, writeLock) { parseFromDBRow(reader); }
public disposingListOfBladesAndVMs getBladesAndVMs(Func <bladeSpec, bool> BladeFilter, Func <vmSpec, bool> VMFilter, bladeLockType lockTypeRead, bladeLockType lockTypeWrite, bool permitAccessDuringBIOS = false, bool permitAccessDuringDeployment = false) { disposingListOfBladesAndVMs toRet = new disposingListOfBladesAndVMs(); toRet.blades = getAllBladeInfo(BladeFilter, lockTypeRead, lockTypeWrite, permitAccessDuringBIOS, permitAccessDuringDeployment); toRet.VMs = getAllVMInfo(VMFilter, lockTypeRead, lockTypeWrite); return(toRet); }
public disposingList <lockableVMSpec> getVMByVMServerIP(lockableBladeSpec blade, bladeLockType readLock, bladeLockType writeLock) { disposingList <lockableVMSpec> toRet = new disposingList <lockableVMSpec>(); if ((blade.getCurrentLocks().read & bladeLockType.lockVMCreation) == 0) { throw new Exception("lockVMCreation required on vmserver passed to getVMByVMServerIP"); } // We need to lock IP addressess on the VMs, since we lock by them. readLock = readLock | bladeLockType.lockIPAddresses; // Since we hold lockVMCreation, we can assume no new VMs will be added or removed to/from this blade. We assume that // VM IP addresses will never change, except during initialization, when they go from null - we just drop any with a // NULL IP address. Dictionary <string, lockableVMSpec> VMNames = new Dictionary <string, lockableVMSpec>(); string sqlCommand = "select VMIP from vmConfiguration " + "join bladeConfiguration on parentbladeID = bladeConfigKey " + "where bladeIP = $vmServerIP"; using (SQLiteCommand cmd = new SQLiteCommand(sqlCommand, conn)) { cmd.Parameters.AddWithValue("$vmServerIP", blade.spec.bladeIP); using (SQLiteDataReader reader = cmd.ExecuteReader()) { while (reader.Read()) { string VMName = reader[0].ToString(); if (!String.IsNullOrEmpty(VMName)) { VMNames.Add(VMName, new lockableVMSpec(VMName, readLock, writeLock)); } } } } try { // Now read each from the DB, now that we hold the lock for each. foreach (KeyValuePair <string, lockableVMSpec> kvp in VMNames) { string vmName = kvp.Key; lockableVMSpec vmSpec = kvp.Value; string sql_getVM = "select bladeOwnership.*, vmConfiguration.* from vmConfiguration " + " join bladeOwnership on bladeOwnership.ownershipKey = vmConfiguration.ownershipID " + " join bladeConfiguration on parentbladeID = bladeConfigKey " + " where VMIP = $vmIP"; using (SQLiteCommand cmd = new SQLiteCommand(sql_getVM, conn)) { cmd.Parameters.AddWithValue("$vmIP", vmName); using (SQLiteDataReader reader = cmd.ExecuteReader()) { if (!reader.Read()) { throw new Exception("VM disappeared, even though we hold lockVMCreation on the parent!"); } vmSpec.setSpec(new vmSpec(conn, reader, readLock, writeLock)); toRet.Add(vmSpec); } } } } catch (Exception) { foreach (KeyValuePair <string, lockableVMSpec> kvp in VMNames) { kvp.Value.Dispose(); } throw; } return(toRet); }