Ejemplo n.º 1
0
def TestCreateDisk(vm1):
    """ Creating disk with various combination of capacityInBytes and capacityInKB.
    """
    Log("Add a new disk with capacityInKB greater than capacityInBytes.")
    # server must consider capacityInBytes
    cspec = Vim.Vm.ConfigSpec()
    cspec = vmconfig.AddScsiCtlr(cspec, cfgInfo = vm1.config)
    capacityKB = 4 * 1024
    vmconfig.AddScsiDisk(cspec, cfgInfo = vm1.config,
                         capacity = capacityKB)
    vm.Reconfigure(vm1, cspec)
    # Server must always return "capacityInBytes"
    devices = vmconfig.CheckDevice(vm1.config, Vim.Vm.Device.VirtualDisk,
                                   {"capacityInKB": capacityKB,
                                    "capacityInBytes": (capacityKB * 1024)})
    if len(devices) != 1:
       raise Exception("Failed to find new disk!")

    Log("Add a new disk with capacityInBytes bigger than capacityInKB.")
    cspec = Vim.Vm.ConfigSpec()
    capacityBytes = (capacityKB * 1024) + SECTOR_SIZE
    vmconfig.AddScsiDisk(cspec, cfgInfo = vm1.GetConfig(), capacity = capacityKB,
                         capacityInBytes = capacityBytes)
    vm.Reconfigure(vm1, cspec)
    devices = vmconfig.CheckDevice(vm1.config, Vim.Vm.Device.VirtualDisk,
                                   {"capacityInKB": capacityKB,
                                    "capacityInBytes": capacityBytes})
    if len(devices) != 1:
       raise Exception("Capacity did not match expected values!")

    cspec = Vim.Vm.ConfigSpec()
    # server must consider capacityInBytes
    capacityBytes = 2*capacityKB*1024 - SECTOR_SIZE
    vmconfig.AddScsiDisk(cspec, cfgInfo = vm1.config, capacity = capacityKB,
                         capacityInBytes = capacityBytes)
    vm.Reconfigure(vm1, cspec)
    devices = vmconfig.CheckDevice(vm1.config, Vim.Vm.Device.VirtualDisk,
                                   {"capacityInKB": (2 * capacityKB)-1,
                                    "capacityInBytes": capacityBytes})
    if len(devices) != 1:
       raise Exception("Capacity did not match expected values!")

    Log("Removing virtual disks from VM.")
    devices = vmconfig.CheckDevice(vm1.config, Vim.Vm.Device.VirtualDisk)
    fileOp = Vim.Vm.Device.VirtualDeviceSpec.FileOperation.destroy
    cspec = Vim.Vm.ConfigSpec()
    for device in devices:
       vmconfig.RemoveDeviceFromSpec(cspec, device, fileOp)
    vm.Reconfigure(vm1, cspec)
Ejemplo n.º 2
0
    def __init__(self,
                 vmIn,
                 vStorageObject,
                 datastore,
                 fullTest=True,
                 powerOn=False):
        if not vmIn:
            self.vm = createDummyVm(datastore.name)
        else:
            self.vm = vmIn
            Logger("VMTest, vm = %s\n" % (self.vm.name))
        self.vsobj = vStorageObject
        self.ds = datastore
        self.fullTest = fullTest

        if self.vm != vm1 and not fullTest:
            # VM with one scsi controller and disk
            cspec = Vim.Vm.ConfigSpec()
            cspec = vmconfig.AddScsiCtlr(cspec, cfgInfo=self.vm.config)
            capacityKB = 10 * 1024
            # Add eager-zeroed disk so it can be enabled multi-writter
            vmconfig.AddScsiDisk(cspec,
                                 cfgInfo=self.vm.config,
                                 capacity=capacityKB,
                                 datastorename=self.ds.name,
                                 thin=False,
                                 scrub=True)
            InvokeAndTrack(self.vm.Reconfigure, cspec)

        if powerOn:
            Logger("Powering on VM ")
            vm.PowerOn(self.vm)
            time.sleep(2)
Ejemplo n.º 3
0
def TestWithSnapshot(vm1):
    """ Verify that it is not possible to extend delta disk by changing
        capacityInBytes.
    """
    cspec = Vim.Vm.ConfigSpec()
    vmconfig.AddScsiDisk(cspec, cfgInfo = vm1.config)
    vm.Reconfigure(vm1, cspec)
    devices = vmconfig.CheckDevice(vm1.config, Vim.Vm.Device.VirtualDisk)
    if len(devices) != 1:
       raise Exception("Failed to find new disk!")

    # attempt to extend a disk with a parent
    Log("Creating a snapshot on the VM for negative disk extend test.")
    vm.CreateSnapshot(vm1, "dummy snapshot", "dummy desc", False, False)
    Log("Attempting to extend disk size of delta disk.")
    disk = vmconfig.CheckDevice(vm1.config, Vim.Vm.Device.VirtualDisk)[0]
    cspec = Vim.Vm.ConfigSpec()
    disk.capacityInBytes = disk.capacityInBytes + 1024
    vmconfig.AddDeviceToSpec(cspec, disk, Vim.Vm.Device.VirtualDeviceSpec.Operation.edit)
    task = vm1.Reconfigure(cspec)
    try:
       WaitForTask(task)
    except Exception as e:
       Log("Hit an exception extending delta disk as expected" + str(e))
    else:
       raise Exception("Error: Extending delta disk was allowed!")

    Log("Removing all snapshots on the VM.")
    vm.RemoveAllSnapshots(vm1)
Ejemplo n.º 4
0
def getObjMapping(vmName, desc):
    Log("\nCreating VM object ID map on %s\n" % (desc))
    vmRef = CreateQuickDummy(vmName, datastoreName=vvolDsName, \
                             vmxVersion="vmx-13")

    cspec = Vim.Vm.ConfigSpec()
    cspec = vmconfig.AddScsiCtlr(cspec, cfgInfo=vmRef.config)
    capacityKB = 5 * 1024
    vmconfig.AddScsiDisk(cspec,
                         cfgInfo=vmRef.config,
                         capacity=capacityKB,
                         datastorename=vvolDsName,
                         thin=True,
                         scrub=False)
    InvokeAndTrack(vmRef.Reconfigure, cspec)

    vmRefs.append(vmRef)

    vm.PowerOn(vmRef)

    ssName = ("ss-%s" % random.randint(1, 1000))
    vm.CreateSnapshot(vmRef, ssName, "snaphost", memory=True, quiesce=False)

    global dstVmxId
    dstVmxId = []

    vmMap = {}
    for f1 in vmRef.layoutEx.file:
        if f1.type == "config":
            lastIdx = f1.name.rfind(".")

            lastIdx1 = f1.name.rfind("/")
            uuid = f1.name[f1.name.rfind("rfc4122."):lastIdx1]

        elif f1.backingObjectId:
            lastIdx = f1.name.rfind(".")
            uuid = f1.backingObjectId

        else:
            continue

        fname = vmName + f1.name[lastIdx:]
        vmMap[fname] = uuid
        Log("\n   adding %s - %s\n" % (fname, uuid))

        if fname.find(".vmx") != -1:
            dstVmxId.append(uuid)

    # Unregister VM to assume only vvol objects exists
    vm.PowerOff(vmRef)
    vmRef.Unregister()

    return vmMap
Ejemplo n.º 5
0
def AddDiskExternalDir(vm1, pathBase, datastore):
    diskDir = pathBase + '-disk'
    CreateDirectory(diskDir)
    cspec = Vim.Vm.ConfigSpec()
    diskRelPath = re.sub(r'\[.*\]\s*', '', diskDir) + '/testDisk.vmdk'
    cspec = vmconfig.AddScsiCtlr(cspec)
    vmconfig.AddScsiDisk(cspec,
                         datastorename=datastore,
                         fileName=diskRelPath,
                         thin=True,
                         createNamedFile=True)
    vm.Reconfigure(vm1, cspec)
    devices = vmconfig.CheckDevice(vm1.GetConfig(), Vim.Vm.Device.VirtualDisk)
    if len(devices) < 2:
        raise Exception('Failed to find added disk')
    return devices[1], diskDir
Ejemplo n.º 6
0
def TestEditDisk(vm1):
    """ Test reconfigures of capacityInBytes and capacityInKB when both are set
        and differ.
    """
    Log("Adding a new disk.")
    cspec = Vim.Vm.ConfigSpec()
    vmconfig.AddScsiDisk(cspec, cfgInfo = vm1.config)
    vm.Reconfigure(vm1, cspec)
    devices = vmconfig.CheckDevice(vm1.config, Vim.Vm.Device.VirtualDisk)
    if len(devices) != 1:
       raise Exception("Failed to find new disk!")

    disk = devices[0]
    Log("Increase disk size by 4MB setting capacityInBytes")
    cspec = Vim.Vm.ConfigSpec()
    newCapacity = disk.capacityInBytes + 4 * 1024 * 1024 + SECTOR_SIZE
    newCapacityKB = (newCapacity - SECTOR_SIZE) / 1024
    disk.capacityInBytes = newCapacity
    vmconfig.AddDeviceToSpec(cspec, disk, Vim.Vm.Device.VirtualDeviceSpec.Operation.edit)
    vm.Reconfigure(vm1, cspec)
    devices = vmconfig.CheckDevice(vm1.config, Vim.Vm.Device.VirtualDisk,
                                   {"capacityInBytes": newCapacity,
                                    "capacityInKB": newCapacityKB})
    if len(devices) != 1:
       raise Exception("Failed to find the disk with updated capacity: " +  str(len(devices)))

    Log("Atempt to increase only capacityInKB.")
    newCapacityKB = newCapacityKB + 4*1024
    disk.capacityInKB = newCapacityKB
    cspec = Vim.Vm.ConfigSpec()
    vmconfig.AddDeviceToSpec(cspec, disk, Vim.Vm.Device.VirtualDeviceSpec.Operation.edit)
    vm.Reconfigure(vm1, cspec)
    devices = vmconfig.CheckDevice(vm1.config, Vim.Vm.Device.VirtualDisk,
                                   {"capacityInKB": newCapacityKB})
    if len(devices) != 1:
       raise Exception("Failed to find the disk with updated capacity: " +  str(len(devices)))

    Log("Removing virtual disk from VM")
    cspec = Vim.Vm.ConfigSpec()
    fileOp = Vim.Vm.Device.VirtualDeviceSpec.FileOperation.destroy
    vmconfig.RemoveDeviceFromSpec(cspec, devices[0], fileOp)
    vm.Reconfigure(vm1, cspec)
Ejemplo n.º 7
0
    def attachDiskEx(self):
        id = self.vsobj.config.id

        # On a VM w/o controller
        task = self.vm.AttachDisk(id, self.ds)
        CheckTaskState(task, Vim.Fault.MissingController)

        # VM with one scsi controller and disk
        cspec = Vim.Vm.ConfigSpec()
        cspec = vmconfig.AddScsiCtlr(cspec, cfgInfo=self.vm.config)
        capacityKB = 10 * 1024

        vmconfig.AddScsiDisk(cspec,
                             cfgInfo=self.vm.config,
                             capacity=capacityKB,
                             datastorename=self.ds.name)
        InvokeAndTrack(self.vm.Reconfigure, cspec)

        disk = vmconfig.CheckDevice(self.vm.config,
                                    Vim.Vm.Device.VirtualDisk)[0]
        ctlrKey = disk.controllerKey
        unitNumber = disk.unitNumber

        task = self.vm.AttachDisk(id, self.ds, -99)
        CheckTaskState(task, Vim.Fault.InvalidController)

        task = self.vm.AttachDisk(id, self.ds, ctlrKey, unitNumber)
        CheckTaskState(task, Vmodl.Fault.InvalidArgument)

        task = self.vm.AttachDisk(id, self.ds)
        CheckTaskState(task, None)
        checkVmDisk(self.vsobj, self.vm, True)

        # VM with two SCSI controllers
        if self.vm != vm1:
            cspec = Vim.Vm.ConfigSpec()
            cspec = vmconfig.AddScsiCtlr(cspec, cfgInfo=self.vm.config)
            InvokeAndTrack(self.vm.Reconfigure, cspec)

            task = self.vm.AttachDisk(id, self.ds)
            CheckTaskState(task, Vim.Fault.MissingController)
Ejemplo n.º 8
0
def createTest(baseDiskFileName):
    """
   Creates a new VM with a delta disk
   pointing to an already existing base disk.
   Also checks the results.
   """

    print("Running create test")

    vmName = "linkedCloneTest2"
    cspec = vm.CreateDefaultSpec(vmName)

    vmconfig.AddScsiDisk(cspec)

    vmFolder = vm.GetVmFolder()
    resPool = vm.GetResourcePool()

    createTask = vmFolder.CreateVm(cspec, resPool)
    WaitForTask(createTask)

    print("createTest succeeded")
Ejemplo n.º 9
0
def testPromoteDisks(si, numDisks, numiter, backingType, vmxVersion, ds1, ds2,
                     status, resultsArray):
    for i in range(numiter):
        bigClock = StopWatch()
        try:
            try:
                vm1Name = "Parent" + str(i)
                vm1 = folder.Find(vm1Name)
                if vm1 != None:
                    Log("Cleaning up old vm with name: " + vm1Name)
                    vm1.Destroy()

                # Create a simple vm with numDisks on ds1
                vm1 = vm.CreateQuickDummy(vm1Name, numScsiDisks=numDisks, \
                                          datastoreName=ds1, diskSizeInMB=1, \
                                          vmxVersion=vmxVersion, \
                                          backingType=backingType)
                Log("Created parent VM1 --" + vm1Name)

                vm1DirName = vm1.config.files.snapshotDirectory

                # Create snapshot
                vm.CreateSnapshot(vm1, "S1", "S1 is the first snaphost", \
                                  False, False)
                snapshotInfo = vm1.GetSnapshot()
                S1Snapshot = snapshotInfo.GetCurrentSnapshot()
                Log("Created Snapshot S1 for VM1")

                # Get the name of the parent disks
                disks = vmconfig.CheckDevice(S1Snapshot.GetConfig(), \
                                             Vim.Vm.Device.VirtualDisk)

                if len(disks) != numDisks:
                    raise Exception("Failed to find parent disks")

                parentDisks = [None] * len(disks)
                for i in range(len(disks)):
                    parentDisks[i] = disks[i].GetBacking().GetFileName()

                # Create a VM2 on ds2 that is linked off S1
                vm2Name = "LinkedClone" + str(i)
                configSpec = vmconfig.CreateDefaultSpec(name=vm2Name,
                                                        datastoreName=ds2)
                configSpec = vmconfig.AddScsiCtlr(configSpec)
                configSpec = vmconfig.AddScsiDisk(configSpec,
                                                  datastorename=ds2,
                                                  capacity=1024,
                                                  backingType=backingType)
                configSpec.SetVersion(vmxVersion)
                childDiskBacking = configSpec.GetDeviceChange()[1].\
                                   GetDevice().GetBacking()
                parentBacking = GetBackingInfo(backingType)
                parentBacking.SetFileName(parentDisks[0])
                childDiskBacking.SetParent(parentBacking)
                childDiskBacking.SetDeltaDiskFormat("redoLogFormat")

                resPool = invt.GetResourcePool()
                vmFolder = invt.GetVmFolder()
                vimutil.InvokeAndTrack(vmFolder.CreateVm, configSpec, resPool)

                vm2 = folder.Find(vm2Name)
                Log("Created child VM2 --" + vm2Name)

                vm2DirName = vm2.config.files.snapshotDirectory

                # create delta disks off VM1 on VM2
                Log("Adding delta disks off VM1 to VM2")
                configSpec = Vim.Vm.ConfigSpec()
                for i in range(len(parentDisks)):
                    configSpec = vmconfig.AddScsiDisk(configSpec, \
                                                      datastorename = ds2, \
                                                      cfgInfo = vm2.GetConfig(), \
                                                      backingType = backingType)
                    SetDeltaDiskBacking(configSpec, i, parentDisks[i])

                vimutil.InvokeAndTrack(vm2.Reconfigure, configSpec)

                Log("Power (on) vm1")
                vm.PowerOn(vm1)
                time.sleep(5)

                Log("Power (on) vm2")
                vm.PowerOn(vm2)
                time.sleep(5)

                # prepare promoteDisksSpec
                diskList = GetVirtualDisks(vm2)
                promoteDisksSpec = [None] * len(diskList)
                for i in range(len(diskList)):
                    promoteDisksSpec[i]=vim.host.LowLevelProvisioningManager.\
                                        PromoteDisksSpec()
                    promoteDisksSpec[i].SetNumLinks(1)
                    promoteDisksSpec[i].SetOffsetFromBottom(0)
                    diskId = diskList[i].GetKey()
                    promoteDisksSpec[i].SetDiskId(diskId)

                Log("Calling LLPM PromoteDisks")
                llpm = invt.GetLLPM()
                try:
                    task = llpm.PromoteDisks(vm2, promoteDisksSpec)
                    WaitForTask(task)
                except Exception as e:
                    print(e)
                    Log("Caught exception : " + str(e))
                    status = "FAIL"

                status = "PASS"

                Log("Destroying VMs")
                vm.PowerOff(vm2)
                time.sleep(5)
                vm.PowerOff(vm1)
                time.sleep(5)

                vm2.Destroy()
                vm1.Destroy()

            finally:
                bigClock.finish("iteration " + str(i))

        except Exception as e:
            Log("Caught exception : " + str(e))
            status = "FAIL"

        Log("TEST RUN COMPLETE: " + status)
        resultsArray.append(status)

    Log("Results for each iteration: ")
    for i in range(len(resultsArray)):
        Log("Iteration " + str(i) + ": " + resultsArray[i])
Ejemplo n.º 10
0
def main():
   supportedArgs = [ (["h:", "host="], "localhost", "Host name", "host"),
                     (["u:", "user="******"root", "User name", "user"),
                     (["p:", "pwd="], "ca$hc0w", "Password", "pwd"),
                     (["v:", "vmname="], "Hw7ReconfigTest", "Name of the virtual machine", "vmname"),
                     (["i:", "numiter="], "1", "Number of iterations", "iter") ]

   supportedToggles = [ (["usage", "help"], False, "Show usage information", "usage"),
                        (["runall", "r"], True, "Run all the tests", "runall"),
                        (["nodelete"], False, "Dont delete vm on completion", "nodelete") ]

   args = arguments.Arguments(sys.argv, supportedArgs, supportedToggles)
   if args.GetKeyValue("usage") == True:
      args.Usage()
      sys.exit(0)

   # Connect
   si = Connect(host=args.GetKeyValue("host"),
                user=args.GetKeyValue("user"),
                pwd=args.GetKeyValue("pwd"),
                version="vim.version.version9")
   atexit.register(Disconnect, si)


   # Process command line
   vmname = args.GetKeyValue("vmname")
   numiter = int(args.GetKeyValue("iter"))
   runall = args.GetKeyValue("runall")
   noDelete = args.GetKeyValue("nodelete")
   status = "PASS"

   for i in range(numiter):
       bigClock = StopWatch()
       vm1 = None
       try:
           ## Cleanup old VMs
	   vm1 = folder.Find(vmname)
	   if vm1 != None:
	      vm1.Destroy()

	   Log("Creating virtual machine")
	   vm1 = vm.CreateQuickDummy(vmname, 1, diskSizeInMB = 4096)

	   devices = vmconfig.CheckDevice(vm1.GetConfig(), Vim.Vm.Device.VirtualDisk)
	   if len(devices) < 1:
	         raise Exception("Failed to find added disk!")
	   cspec = Vim.Vm.ConfigSpec()
	   for i in range(0, len(devices)) :
	       disk = devices[i]
	       backing = disk.GetBacking()
	       backing.SetEagerlyScrub(True)
	       disk.SetBacking(backing)
	       vmconfig.AddDeviceToSpec(cspec, disk, Vim.Vm.Device.VirtualDeviceSpec.Operation.edit)

	   Log("Scrubbing existing disks of the VM")
	   task = vm1.Reconfigure(cspec)
	   WaitForTask(task)

	   Log("Add a new scrubbed disk to the VM")
	   cspec = Vim.Vm.ConfigSpec()
	   cspec = vmconfig.AddScsiCtlr(cspec)
	   vmconfig.AddScsiDisk(cspec, capacity = 128 * 1024, scrub = True)
	   #task = vm1.Reconfigure(cspec)
	   #WaitForTask(task)

       except Exception as e:
           status = "FAIL"
           Log("Caught exception : " + str(e))
   Log("TEST RUN COMPLETE: " + status)
Ejemplo n.º 11
0
def testLinkedClone(si, numiter, deltaDiskFormat, backingType, vmxVersion, ds1, ds2, status, resultsArray):
   for i in range(numiter):
      bigClock = StopWatch()
      try:
         try:
            vm1Name = "LinkedParent_" + str(i)
            vm1 = folder.Find(vm1Name)
            if vm1 != None:
               Log("Cleaning up old vm with name: " + vm1Name)
               vm1.Destroy()

            # Create a simple vm with nothing but two disk on ds1
            vm1 = vm.CreateQuickDummy(vm1Name, numScsiDisks=2, \
                                      datastoreName=ds1, diskSizeInMB=1, \
                                      vmxVersion=vmxVersion, \
                                      backingType=backingType)
            Log("Created parent VM1 --" + vm1Name + "with Native snapshotting"
              + " capability set to " + str(vm1.IsNativeSnapshotCapable()))

            vm1DirName = vm1.config.files.snapshotDirectory

            # Create snapshots

            # S1, S1C1, S1C1C1 and S1C2
            vm.CreateSnapshot(vm1, "S1", "S1 is the first snaphost", \
                              False, False)
            snapshotInfo = vm1.GetSnapshot()
            S1Snapshot = snapshotInfo.GetCurrentSnapshot()
            Log("Create Snapshot S1 for VM1")

            vm.CreateSnapshot(vm1, "S1-C1", "S1-C1 is the first child of S1",\
                              False, False)

            snapshotInfo = vm1.GetSnapshot()
            S1C1Snapshot = snapshotInfo.GetCurrentSnapshot()
            Log("Create Snapshot S1C1 for VM1")

            vm.CreateSnapshot(vm1, "S1-C1-C1", \
                              "S1-C1-C1 is the grand child of S1", \
                              False, False)
            snapshotInfo = vm1.GetSnapshot()
            S1C1C1Snapshot = snapshotInfo.GetCurrentSnapshot()
            Log("Create Snapshot S1C1C1 for VM1")

            # revert to S1
            vimutil.InvokeAndTrack(S1Snapshot.Revert)
            Log("Reverted VM1 to Snapshot S1C1")

            vm.CreateSnapshot(vm1, "S1-C2", \
                              "S1-C2 is the second child of S1", False, False)

            snapshotInfo = vm1.GetSnapshot()
            S1C2Snapshot = snapshotInfo.GetCurrentSnapshot()
            Log("Create Snapshot S1C2 for VM1")

            # revert to S1C1C1, so it is the current snapshot
            vimutil.InvokeAndTrack(S1C1C1Snapshot.Revert)
            Log("Reverted VM1 to Snapshot S1C1C1")

            # Get the name of the parent disks
            disks = vmconfig.CheckDevice(S1C2Snapshot.GetConfig(), \
                                         Vim.Vm.Device.VirtualDisk)

            if len(disks) != 2:
               raise Exception("Failed to find parent disk1")

            parentDisk1 = disks[0].GetBacking().GetFileName()

            disks = vmconfig.CheckDevice(S1C1C1Snapshot.GetConfig(), Vim.Vm.Device.VirtualDisk)

            if len(disks) != 2:
               raise Exception("Failed to find parent disk2")

            parentDisk2 = disks[1].GetBacking().GetFileName()

            # Create a VM2 on ds2 that is linked off S1C2
            vm2Name = "LinkedChild1_" + str(i)
            configSpec = vmconfig.CreateDefaultSpec(name = vm2Name, datastoreName = ds2)
            configSpec = vmconfig.AddScsiCtlr(configSpec)
            configSpec = vmconfig.AddScsiDisk(configSpec, datastorename = ds2, capacity = 1024, backingType = backingType)
            configSpec.SetVersion(vmxVersion)
            childDiskBacking = configSpec.GetDeviceChange()[1].GetDevice().GetBacking()
            parentBacking = GetBackingInfo(backingType)
            parentBacking.SetFileName(parentDisk1)
            childDiskBacking.SetParent(parentBacking)
            childDiskBacking.SetDeltaDiskFormat(deltaDiskFormat)

            resPool = invt.GetResourcePool()
            vmFolder = invt.GetVmFolder()
            vimutil.InvokeAndTrack(vmFolder.CreateVm, configSpec, resPool)

            vm2 = folder.Find(vm2Name)
            Log("Created child VM2 --" + vm2Name)

            vm2DirName = vm2.config.files.snapshotDirectory

            # Create a VM3 on ds2 that is linked off S1C1C1
            vm3Name = "LinkedChild2_" + str(i)
            configSpec.SetName(vm3Name)
            parentBacking.SetFileName(parentDisk2)

            vimutil.InvokeAndTrack(vmFolder.CreateVm, configSpec, resPool)
            vm3 = folder.Find(vm3Name)
            Log("Created child VM3 --" + vm3Name)

            vm3DirName = vm3.config.files.snapshotDirectory

            # Create snapshot VM3S1 for VM3
            vm.CreateSnapshot(vm3, "VM3S1", "VM3S1 is VM3 snaphost", False, False)
            Log("Create Snapshot VM3S1 for VM3")

            # Create snapshot VM3S2 for VM3
            vm.CreateSnapshot(vm3, "VM3S2", "VM3S2 is VM3 snaphost", False, False)
            Log("Create Snapshot VM3S2 for VM3")
            snapshotInfo = vm3.GetSnapshot()
            VM3S2Snapshot = snapshotInfo.GetCurrentSnapshot()

            # get the disk name of VM3S2 so it can be configured as a
            # parent disk for VM2
            disks = vmconfig.CheckDevice(VM3S2Snapshot.GetConfig(), Vim.Vm.Device.VirtualDisk)

            if len(disks) != 1:
               raise Exception("Failed to find parent disk2")

            parentDisk3 = disks[0].GetBacking().GetFileName()

            # create a delta disk off VM3S2 on VM2
            Log("Adding delta disk off VM3S2 to VM2")
            configSpec = Vim.Vm.ConfigSpec()
            configSpec = vmconfig.AddScsiDisk(configSpec, \
                                              datastorename = ds2, \
                                              cfgInfo = vm2.GetConfig(), \
                                              backingType = backingType)
            childDiskBacking = configSpec.GetDeviceChange()[0].GetDevice().GetBacking()
            parentBacking = GetBackingInfo(backingType)
            parentBacking.SetFileName(parentDisk3)
            childDiskBacking.SetParent(parentBacking)
            childDiskBacking.SetDeltaDiskFormat(deltaDiskFormat)

            vimutil.InvokeAndTrack(vm2.Reconfigure, configSpec)

            Log("Power cycle VM1...")
            PowerCycle(vm1)
            Log("Power cycle VM2...")
            PowerCycle(vm2)
            Log("Power cycle VM3...")
            PowerCycle(vm3)

            Log("OP1: delete VM1.S1C2, then power cycle VM2")
            vimutil.InvokeAndTrack(S1C2Snapshot.Remove, True)
            PowerCycle(vm2)

            Log("OP2: destroy VM2, power cycle VM1")
            vimutil.InvokeAndTrack(vm2.Destroy)
            PowerCycle(vm1)

            Log("then recreate VM2 with just disk1")
            configSpec = vmconfig.CreateDefaultSpec(name = vm2Name, \
                                                    datastoreName = ds2)
            configSpec = vmconfig.AddScsiCtlr(configSpec)
            configSpec = vmconfig.AddScsiDisk(configSpec, datastorename = ds2, \
                                              capacity = 1024, \
                                              backingType = backingType)
            configSpec.SetVersion(vmxVersion)
            childDiskBacking = configSpec.GetDeviceChange()[1].GetDevice().GetBacking()
            parentBacking = GetBackingInfo(backingType)
            parentBacking.SetFileName(parentDisk1)
            childDiskBacking.SetParent(parentBacking)
            childDiskBacking.SetDeltaDiskFormat(deltaDiskFormat)

            resPool = invt.GetResourcePool()
            vmFolder = invt.GetVmFolder()
            vimutil.InvokeAndTrack(vmFolder.CreateVm, configSpec, resPool)
            vm2 = folder.Find(vm2Name)
            Log("ReCreated child VM2 --" + vm2Name)

            Log("OP3: delete VM3S2, power cycle VM1, revert to S1C1")
            vimutil.InvokeAndTrack(VM3S2Snapshot.Remove, True)
            vimutil.InvokeAndTrack(S1C1Snapshot.Revert)
            PowerCycle(vm1)

            llpm = si.RetrieveInternalContent().GetLlProvisioningManager()

            Log("OP4: refresh VM2 disk and destroy the disk and its parent")
            llpm.ReloadDisks(vm2, ['currentConfig', 'snapshotConfig'])

            disks = vmconfig.CheckDevice(vm2.GetConfig(), \
                                         Vim.Vm.Device.VirtualDisk)
            diskChain1 = disks[0]
            diskChain1.backing.parent.parent = None
            configSpec = Vim.Vm.ConfigSpec()
            configSpec = vmconfig.RemoveDeviceFromSpec(configSpec, \
                                                       diskChain1,
                                                       "destroy")
            configSpec.files = vm2.config.files
            llpm.ReconfigVM(configSpec)
            Log("verify only the immediate parent is deleted")
            PowerCycle(vm1)

            Log("OP5: destroy VM1, power cycle VM3")
            vimutil.InvokeAndTrack(vm1.Destroy)
            PowerCycle(vm3)

            Log("OP6: Consolidate VM3 disk chain")
            disks = vmconfig.CheckDevice(vm3.GetConfig(), \
                                         Vim.Vm.Device.VirtualDisk)

            shouldHaveFailed = 0
            try:
               task = llpm.ConsolidateDisks(vm3, disks)
               WaitForTask(task)
            except Exception as e:
               shouldHaveFailed = 1
               Log("Hit an exception when trying to consolidate cross " \
                   "snapshot point.")

            if shouldHaveFailed != 1:
               raise Exception("Error: allowed consolidation to merge snapshot")

            diskchain1 = disks[0]
            diskchain1.backing.parent.parent = None

            disks = vmconfig.CheckDevice(vm3.GetConfig(), \
                                         Vim.Vm.Device.VirtualDisk)
            diskchain2 = disks[0]
            diskchain2.backing = diskchain2.backing.parent.parent

            disks = []
            disks.append(diskchain1)
            disks.append(diskchain2)

            vimutil.InvokeAndTrack(llpm.ConsolidateDisks, vm3, disks)
            PowerCycle(vm3)

            Log("OP7: destroy VM2, no orphaned disks/files should have left")
            vimutil.InvokeAndTrack(vm2.Destroy)

            Log("Delete snapshot of VM3, and delete the disk with all parent."
                "then destroy vM3, no orphaned disks/files should have left")

            disks = vmconfig.CheckDevice(vm3.GetConfig(), \
                                         Vim.Vm.Device.VirtualDisk)
            diskChain1 = disks[0]
            configSpec = Vim.Vm.ConfigSpec()
            configSpec = vmconfig.RemoveDeviceFromSpec(configSpec, \
                                                       diskChain1,
                                                       "destroy")
            configSpec.files = vm3.config.files
            vimutil.InvokeAndTrack(llpm.ReconfigVM, configSpec)
            vimutil.InvokeAndTrack(vm3.Destroy)

            hostSystem = host.GetHostSystem(si)
            b = hostSystem.GetDatastoreBrowser()

            shouldHaveFailed = 0

            try:
               vimutil.InvokeAndTrack(b.Search, vm1DirName)
            except Vim.Fault.FileNotFound:
               Log("Caught " + vm1DirName + "Not found as expected")
               shouldHaveFailed += 1

            try:
               vimutil.InvokeAndTrack(b.Search, vm2DirName)
            except Vim.Fault.FileNotFound:
               Log("Caught " + vm2DirName + "Not found as expected")
               shouldHaveFailed += 1

            try:
               vimutil.InvokeAndTrack(b.Search, vm3DirName)
            except Vim.Fault.FileNotFound:
               Log("Caught " + vm3DirName + "Not found as expected")
               shouldHaveFailed += 1

            if shouldHaveFailed != 3:
               Log("Failed, orphaned disks left")
               raise Exception("orphaned disks")

            status = "PASS"

         finally:
            bigClock.finish("iteration " + str(i))

      except Exception as e:
         Log("Caught exception : " + str(e))
         status = "FAIL"

      Log("TEST RUN COMPLETE: " + status)
      resultsArray.append(status)

   Log("Results for each iteration: ")
   for i in range(len(resultsArray)):
      Log("Iteration " + str(i) + ": " + resultsArray[i])
Ejemplo n.º 12
0
def main():
   supportedArgs = [ (["h:", "host="], "localhost", "Host name", "host"),
                     (["u:", "user="******"root", "User name", "user"),
                     (["p:", "pwd="], "ca$hc0w", "Password", "pwd"),
                     (["v:", "vmname="], "CreateTest", "Name of the virtual machine", "vmname")]
   supportedToggles = [(["usage", "help"], False, "Show usage information", "usage")]

   args = arguments.Arguments(sys.argv, supportedArgs, supportedToggles)
   if args.GetKeyValue("usage") == True:
      args.Usage()
      sys.exit(0)

   # Connect
   si = Connect(args.GetKeyValue("host"), 443,
                args.GetKeyValue("user"), args.GetKeyValue("pwd"))
   atexit.register(Disconnect, si)

   # Process command line
   vmname = args.GetKeyValue("vmname")

   # Cleanup from previous runs.
   vm1 = folder.Find(vmname)
   if vm1 != None:
      vm1.Destroy()

   # Create vms
   envBrowser = invt.GetEnv()
   config = vm.CreateQuickDummySpec(vmname)
   cfgOption = envBrowser.QueryConfigOption(None, None)
   cfgTarget = envBrowser.QueryConfigTarget(None)
   NIC_DIFFERENCE = 7

   config = vmconfig.AddNic(config, cfgOption, cfgTarget, unitNumber = NIC_DIFFERENCE + 0)
   config = vmconfig.AddNic(config, cfgOption, cfgTarget, unitNumber = NIC_DIFFERENCE + 2)
   config = vmconfig.AddNic(config, cfgOption, cfgTarget, unitNumber = NIC_DIFFERENCE + 3)
   config = vmconfig.AddNic(config, cfgOption, cfgTarget, unitNumber = NIC_DIFFERENCE + 4)
   config = vmconfig.AddNic(config, cfgOption, cfgTarget)
   config = vmconfig.AddNic(config, cfgOption, cfgTarget, unitNumber = NIC_DIFFERENCE + 6)
   config = vmconfig.AddNic(config, cfgOption, cfgTarget, unitNumber = NIC_DIFFERENCE + 7)
   config = vmconfig.AddNic(config, cfgOption, cfgTarget, unitNumber = NIC_DIFFERENCE + 8)
   config = vmconfig.AddNic(config, cfgOption, cfgTarget, unitNumber = NIC_DIFFERENCE + 9)
   config = vmconfig.AddScsiCtlr(config, cfgOption, cfgTarget, unitNumber = 3)
   config = vmconfig.AddScsiDisk(config, cfgOption, cfgTarget, unitNumber = 0)
   isofile = "[] /usr/lib/vmware/isoimages/linux.iso"
   config = vmconfig.AddCdrom(config, cfgOption, cfgTarget, unitNumber = 0, isoFilePath=isofile)
   image = "[] /vmimages/floppies/vmscsi.flp"
   config = vmconfig.AddFloppy(config, cfgOption, cfgTarget, unitNumber = 0, type="image", backingName=image)
   config = vmconfig.AddFloppy(config, cfgOption, cfgTarget, unitNumber = 1, type="image", backingName=image)
   backing = Vim.Vm.Device.VirtualSerialPort.FileBackingInfo()
   backing.SetFileName("[]")
   config = vmconfig.AddSerial(config, backing)

   try:
      vmFolder = invt.GetVmFolder()
      vimutil.InvokeAndTrack(vmFolder.CreateVm, config, invt.GetResourcePool(), None)
   except Exception as e:
      raise

   vm1 = folder.Find(vmname)
   printNicUnitNumbers(vm1, "Test 1: Creating a vm with lots of nics")

   cspec = Vim.Vm.ConfigSpec()
   cspec = vmconfig.AddNic(cspec, cfgOption, cfgTarget)
   task = vm1.Reconfigure(cspec)
   WaitForTask(task)
   printNicUnitNumbers(vm1, "Test 2: Added a nic")


   cspec = Vim.Vm.ConfigSpec()
   cspec = vmconfig.AddNic(cspec, cfgOption, cfgTarget)
   task = vm1.Reconfigure(cspec)
   try:
      WaitForTask(task)
   except Vim.Fault.TooManyDevices as e:
      print("Caught too many devices as expected")
   nics = printNicUnitNumbers(vm1, "Test 3: Added too many nics")


   cspec = Vim.Vm.ConfigSpec()
   uni = nics[4].GetUnitNumber()
   cspec = vmconfig.RemoveDeviceFromSpec(cspec, nics[0])
   cspec = vmconfig.RemoveDeviceFromSpec(cspec, nics[2])
   cspec = vmconfig.RemoveDeviceFromSpec(cspec, nics[4])
   cspec = vmconfig.RemoveDeviceFromSpec(cspec, nics[5])
   cspec = vmconfig.RemoveDeviceFromSpec(cspec, nics[6])
   cspec = vmconfig.AddNic(cspec, cfgOption, cfgTarget)
   task = vm1.Reconfigure(cspec)
   WaitForTask(task)
   printNicUnitNumbers(vm1, "Test 4: Removed a bunch of nics")

   cspec = Vim.Vm.ConfigSpec()
   cspec = vmconfig.AddNic(cspec, cfgOption, cfgTarget, unitNumber = NIC_DIFFERENCE - 2)
   task = vm1.Reconfigure(cspec)
   WaitForTask(task)
   printNicUnitNumbers(vm1, "Test 5: Added a nic with slot incorrectly specified")

   cspec = Vim.Vm.ConfigSpec()
   cspec = vmconfig.AddNic(cspec, cfgOption, cfgTarget, unitNumber = uni)
   cspec = vmconfig.AddScsiCtlr(cspec, cfgOption, cfgTarget, unitNumber = 4)
   cspec = vmconfig.AddScsiDisk(cspec, cfgOption, cfgTarget, unitNumber = 1)
   task = vm1.Reconfigure(cspec)
   WaitForTask(task)
   printNicUnitNumbers(vm1, "Test 6: Added a nic with a slot correctly specified")

   cspec = Vim.Vm.ConfigSpec()
   cspec = vmconfig.AddNic(cspec, cfgOption, cfgTarget, unitNumber = uni)
   task = vm1.Reconfigure(cspec)
   try:
      WaitForTask(task)
   except Vim.Fault.InvalidDeviceSpec as e:
      print("Exception caught for adding same nic twice")
   printNicUnitNumbers(vm1, "Test 7: Added a nic with s slot specified to be an occupied slot")
   vm1.Destroy()
Ejemplo n.º 13
0
def getObjMapping(vmName, desc, target=False):
    Log("\nCreating VM object ID map on %s\n" % (desc))
    vmRef = CreateQuickDummy(vmName, datastoreName=vvolDsName, \
                             vmxVersion="vmx-13")

    cspec = Vim.Vm.ConfigSpec()
    cspec = vmconfig.AddScsiCtlr(cspec, cfgInfo=vmRef.config)
    capacityKB = 5 * 1024
    vmconfig.AddScsiDisk(cspec,
                         cfgInfo=vmRef.config,
                         capacity=capacityKB,
                         datastorename=vvolDsName,
                         thin=True,
                         scrub=False)
    InvokeAndTrack(vmRef.Reconfigure, cspec)

    vmRefs.append(vmRef)

    vm.PowerOn(vmRef)

    ssName = ("ss-%s" % random.randint(1, 1000))
    vm.CreateSnapshot(vmRef, ssName, "snaphost", memory=True, quiesce=False)

    lc1Name = vmName.replace('-', '-lc1-')
    lc1Ref = CreateLinkedClone(vmRef, lc1Name, ssName)

    lc2Name = vmName.replace('-', '-lc2-')
    lc2Ref = CreateLinkedClone(vmRef, lc2Name, ssName)

    global dstVmxId
    dstVmxId = []

    vmConfigId = None
    lc1ConfigId = None
    lc2ConfigId = None
    if target:
        tgtName = vmName + '-tgt'
        tgtPath = DsNsMgrMkdir(vvolDs, tgtName)
        vmConfigId = tgtPath[tgtPath.rfind('/') + 1:]

        lc1TgtName = lc1Name + '-tgt'
        lc1TgtPath = DsNsMgrMkdir(vvolDs, lc1TgtName)
        lc1ConfigId = lc1TgtPath[lc1TgtPath.rfind('/') + 1:]

        lc2TgtName = lc2Name + '-tgt'
        lc2TgtPath = DsNsMgrMkdir(vvolDs, lc2TgtName)
        lc2ConfigId = lc2TgtPath[lc2TgtPath.rfind('/') + 1:]

    vmMap1 = {}
    addObjMappingForVm(vmName, vmRef, vmMap1, vmConfigId)
    addObjMappingForVm(lc1Name, lc1Ref, vmMap1, lc1ConfigId)

    vmMap2 = {}
    addObjMappingForVm(vmName, vmRef, vmMap2, vmConfigId)
    addObjMappingForVm(lc2Name, lc2Ref, vmMap2, lc2ConfigId)

    # Unregister VM to assume only vvol objects exists
    vm.PowerOff(vmRef)
    vmRef.Unregister()
    lc1Ref.Unregister()
    lc2Ref.Unregister()

    # returns the vmMap and a list of VMs created
    return [vmMap1, vmMap2], [vmName, lc1Name, lc2Name]
Ejemplo n.º 14
0
def test(si, delta, backingType, vmxVersion, ds):
    suffix = ''.join(
        random.choice(string.letters + string.digits) for i in xrange(8))

    vm1Name = '-'.join(['LinkedParent', suffix])
    print('Creating %s VM on %s' % (vm1Name, ds))
    task.WaitForTasks(
        [vm1.Destroy() for vm1 in folder.GetVmAll() if vm1.name == vm1Name])
    vm1 = vm.CreateQuickDummy(vm1Name,
                              numScsiDisks=1,
                              datastoreName=ds,
                              diskSizeInMB=1,
                              vmxVersion=vmxVersion,
                              backingType=backingType)
    vm1DirName = vm1.config.files.snapshotDirectory

    print('Creating Snapshot S1 for %s' % vm1Name)
    vm.CreateSnapshot(vm1, 'S1', '', False, False)
    s1 = vm1.snapshot.currentSnapshot

    disks = vmconfig.CheckDevice(s1.config, vim.vm.Device.VirtualDisk)
    if len(disks) != 1:
        raise Exception('Failed to find parent disk from snapshot')

    parent = disks[0].backing

    vm2Name = '-'.join(['LinkedChild', suffix])
    print('Creating %s VM on %s' % (vm2Name, ds))
    task.WaitForTasks(
        [vm2.Destroy() for vm2 in folder.GetVmAll() if vm2.name == vm2Name])
    vm2 = vm.CreateQuickDummy(vm2Name, datastoreName=ds, vmxVersion=vmxVersion)
    vm2DirName = vm2.config.files.snapshotDirectory

    configSpec = vim.vm.ConfigSpec()
    configSpec = vmconfig.AddScsiCtlr(configSpec)
    configSpec = vmconfig.AddScsiDisk(configSpec,
                                      datastorename=ds,
                                      capacity=1024,
                                      backingType=backingType)
    child = configSpec.deviceChange[1].device.backing
    child.parent = parent
    child.deltaDiskFormat = delta

    # this edit is expected to fail
    configSpec = vmconfig.AddFloppy(
        configSpec,
        type="image",
        backingName=
        "[] /these/are/not/the/floppy/images/you/are/looking/for.flp")
    floppy = configSpec.deviceChange[2].device
    floppy.backing = None

    print('Reconfigure %s (1) adding a disk backed by snapshot of %s and (2) '
          'adding floppy backed by non-existent image. Expecting a failure' %
          (vm2Name, vm1Name))
    try:
        vm.Reconfigure(vm2, configSpec)
    except Exception as e:
        pass
    else:
        raise Exception(
            'Expected exception during %s reconfigure. But it succeeded instead'
            % vm2Name)

    print('Destroying %s' % vm2Name)
    vm.Destroy(vm2)
    print('Destroying %s' % vm1Name)
    vm.Destroy(vm1)

    hostSystem = host.GetHostSystem(si)
    datastoreBrowser = hostSystem.GetDatastoreBrowser()

    try:
        task.WaitForTask(datastoreBrowser.Search(vm1DirName))
    except vim.fault.FileNotFound:
        pass
    else:
        raise Exception(
            "Expected that '%s' will be gone but it still present" %
            vm1DirName)

    try:
        task.WaitForTask(datastoreBrowser.Search(vm2DirName))
    except vim.fault.FileNotFound:
        pass
    else:
        raise Exception(
            "Expected that '%s' will be gone but it still present" %
            vm2DirName)
Ejemplo n.º 15
0
def TestLinkedClone(vm1, datastore=None):
    if datastore is None:
        vm1Path = vm1.GetSummary().GetConfig().GetVmPathName()
        m = re.search(r'\[(.+)\]', vm1Path)
        datastore = m.group(1)
    baseName = vm1.GetConfig().GetName()
    parentName = 'LinkedParent_' + baseName
    vmP = folder.Find(parentName)
    if vmP != None:
        Log('Destroying old parent VM %s' % parentName)
        vmP.Destroy()
    # Create parent VM
    vmP = vm.CreateQuickDummy(parentName,
                              numScsiDisks=2,
                              datastoreName=datastore,
                              diskSizeInMB=1)
    # Create snapshots
    # S1 -> S1C1 -> S1C1C1
    #   `-> S1C2
    S1Snapshot = TakeSnapshot(vmP, 'S1', 'S1 is the first snaphost')
    Log('Create Snapshot S1 for parent VM')

    S1C1Snapshot = TakeSnapshot(vmP, 'S1-C1', 'S1-C1 is the first child of S1')
    Log('Create Snapshot S1C1 for parent VM')

    S1C1C1Snapshot = TakeSnapshot(vmP, 'S1-C1-C1',
                                  'S1-C1-C1 is the grand child of S1')
    Log('Create Snapshot S1C1C1 for parent VM')

    # Revert to S1
    vimutil.InvokeAndTrack(S1Snapshot.Revert)
    Log('Reverted parent VM to Snapshot S1')

    S1C2Snapshot = TakeSnapshot(vmP, 'S1-C2',
                                'S1-C2 is the second child of S1')
    Log('Create Snapshot S1C2 for parent VM')

    # Revert to S1C1C1, so it is the current snapshot
    vimutil.InvokeAndTrack(S1C1C1Snapshot.Revert)
    Log('Reverted parent VM to Snapshot S1C1C1')

    # Get the name of the parent disks
    disks = vmconfig.CheckDevice(S1C2Snapshot.GetConfig(),
                                 Vim.Vm.Device.VirtualDisk)
    if len(disks) != 2:
        raise Exception('Failed to find parent disk1')
    parentDisk1 = disks[0].GetBacking().GetFileName()
    disks = vmconfig.CheckDevice(S1C1C1Snapshot.GetConfig(),
                                 Vim.Vm.Device.VirtualDisk)
    if len(disks) != 2:
        raise Exception('Failed to find parent disk2')
    parentDisk2 = disks[1].GetBacking().GetFileName()

    # Create a VMC1 whose first disk is linked off S1C2
    child1Name = 'LinkedChild1_' + baseName
    vmC1 = folder.Find(child1Name)
    if vmC1 != None:
        Log('Destroying old child VM %s' % child1Name)
        vmC1.Destroy()

    configSpec = vmconfig.CreateDefaultSpec(name=child1Name,
                                            datastoreName=datastore)
    configSpec = vmconfig.AddScsiCtlr(configSpec)
    configSpec = vmconfig.AddScsiDisk(configSpec,
                                      datastorename=datastore,
                                      capacity=1024)
    SetDeltaDiskBacking(configSpec, 1, parentDisk1)
    resPool = invt.GetResourcePool()
    vmFolder = invt.GetVmFolder()
    vimutil.InvokeAndTrack(vmFolder.CreateVm, configSpec, resPool)
    vmC1 = folder.Find(child1Name)
    vmC1DirName = vmC1.config.files.snapshotDirectory
    Log('Created child VM %s' % child1Name)

    # Create a VMC2 that is linked off S1C1C1
    child2Name = 'LinkedChild2_' + baseName
    vmC2 = folder.Find(child2Name)
    if vmC2 != None:
        Log('Destroying old child VM %s' % child2Name)
        vmC2.Destroy()
    configSpec.SetName(child2Name)
    SetDeltaDiskBacking(configSpec, 1, parentDisk2)
    vimutil.InvokeAndTrack(vmFolder.CreateVm, configSpec, resPool)
    vmC2 = folder.Find(child2Name)
    vmC2DirName = vmC2.config.files.snapshotDirectory
    Log('Created child VM %s' % child2Name)

    # Create snapshot VMC2S1 for VMC2
    TakeSnapshot(vmC2, 'VMC2S1', 'VMC2S1 is VMC2 snaphost')
    Log('Create Snapshot VMC2S1 for VMC2')

    # Create snapshot VMC2S2 for VMC2
    VMC2S2Snapshot = TakeSnapshot(vmC2, 'VMC2S2', 'VMC2S2 is VMC2 snaphost')
    Log('Create Snapshot VMC2S2 for VMC2')

    # Get the disk name of VMC2S2 to use it a parent disk for VMC1
    disks = vmconfig.CheckDevice(VMC2S2Snapshot.GetConfig(),
                                 Vim.Vm.Device.VirtualDisk)
    if len(disks) != 1:
        raise Exception('Failed to find parent disk2')
    parentDisk3 = disks[0].GetBacking().GetFileName()

    # Create a delta disk off VMC2S2 on VMC1
    Log('Adding delta disk off VMC2S2 to VMC1')
    configSpec = Vim.Vm.ConfigSpec()
    configSpec = vmconfig.AddScsiDisk(configSpec,
                                      datastorename=datastore,
                                      cfgInfo=vmC1.GetConfig())
    SetDeltaDiskBacking(configSpec, 0, parentDisk3)
    vm.Reconfigure(vmC1, configSpec)

    # Final picture
    # vmP: S1 -> S1C1 -> S1C1C1 (disk1, disk2)
    #        `-> S1C2      |
    # vmC2:        |        `-> vmC2S1 -> vmC2S2 (disk1, disk2)
    # vmC1:         `- (disk1)               `- (disk2)

    Log('Verify parent VM domain policy')
    domainP = 'hostd' + str(vmP._GetMoId())
    vmPdir = GetVMHomeDir(vmP)
    vm.PowerOn(vmP)
    found = CheckInPolicy(domainP, [(vmPdir, 3)])
    if len(found) != 1:
        DumpFilePolicy(domainP)
        raise Exception('Did not find parent VM home directory in policy')
    vm.PowerOff(vmP)

    Log('Verify linked child 2 has permission to the parent VM')
    domainC2 = 'hostd' + str(vmC2._GetMoId())
    vmC2dir = GetVMHomeDir(vmC2)
    vm.PowerOn(vmC2)
    found = CheckInPolicy(domainC2, [(vmC2dir, 3), (vmPdir, 1)])
    if len(found) != 2:
        raise Exception('Did not find all expected permission in child 2. ' +
                        'Found: %s' % ', '.join(found))
    vm.PowerOff(vmC2)

    Log('Verify linked child 1 has permission to the parent VM and child 2')
    domainC1 = 'hostd' + str(vmC1._GetMoId())
    vmC1dir = GetVMHomeDir(vmC1)
    vm.PowerOn(vmC1)
    found = CheckInPolicy(domainC1, [(vmC1dir, 3), (vmPdir, 1), (vmC2dir, 1)])
    if len(found) != 3:
        raise Exception('Did not find all expected permission in child 1. ' +
                        'Found: %s' % ', '.join(found))
    vm.PowerOff(vmC1)

    Log('Delete S1C2.  Linked child 1 should not be affected.')
    vimutil.InvokeAndTrack(S1C2Snapshot.Remove, True)
    vm.PowerOn(vmC1)
    found = CheckInPolicy(domainC1, [(vmC1dir, 3), (vmPdir, 1), (vmC2dir, 1)])
    if len(found) != 3:
        raise Exception('Did not find all expected permission in child 1. ' +
                        'Found: %s' % ', '.join(found))
    vm.PowerOff(vmC1)

    Log('Remove disk1 from linked child 1. Verify policy does not change.')
    disks = vmconfig.CheckDevice(vmC1.GetConfig(), Vim.Vm.Device.VirtualDisk)
    disk1 = None
    for disk in disks:
        if disk.backing.parent.fileName == parentDisk1:
            disk1 = disk
    if disk1 is None:
        raise Exception('Did not find disk based on %s' % parentDisk1)
    configSpec = Vim.Vm.ConfigSpec()
    fileOp = Vim.Vm.Device.VirtualDeviceSpec.FileOperation.destroy
    vmconfig.RemoveDeviceFromSpec(configSpec, disk1, fileOp)
    vm.Reconfigure(vmC1, configSpec)
    vm.PowerOn(vmC1)
    found = CheckInPolicy(domainC1, [(vmC1dir, 3), (vmPdir, 1), (vmC2dir, 1)])
    if len(found) != 3:
        raise Exception('Did not find all expected permission in child 1. ' +
                        'Found: %s' % ', '.join(found))
    vm.PowerOff(vmC1)

    Log('Destroy linked child 2. Verify policy of linked child 1.')
    vm.Destroy(vmC2)
    vm.PowerOn(vmC1)
    found = CheckInPolicy(domainC1, [(vmC1dir, 3), (vmPdir, 1), (vmC2dir, 1)])
    if len(found) != 3:
        raise Exception('Did not find all expected permission in child 1. ' +
                        'Found: %s' % ', '.join(found))
    vm.PowerOff(vmC1)

    Log('Re-create linked child 2 by hot-adding disks based off S1C1C1.')
    configSpec = vmconfig.CreateDefaultSpec(name=child2Name,
                                            datastoreName=datastore)
    configSpec = vmconfig.AddScsiCtlr(configSpec)
    configSpec = vmconfig.AddScsiDisk(configSpec,
                                      datastorename=datastore,
                                      capacity=1024)
    vimutil.InvokeAndTrack(vmFolder.CreateVm, configSpec, resPool)
    vmC2 = folder.Find(child2Name)
    domainC2 = 'hostd' + str(vmC2._GetMoId())
    vmC2dir = GetVMHomeDir(vmC2)
    vm.PowerOn(vmC2)
    found = CheckInPolicy(domainC2, [(vmC2dir, 3)])
    if len(found) != 1:
        DumpFilePolicy(domainC2)
        raise Exception(
            'Did not find expected permission in recreated child 2.')
    configSpec = Vim.Vm.ConfigSpec()
    configSpec = vmconfig.AddScsiDisk(configSpec,
                                      datastorename=datastore,
                                      capacity=1024,
                                      cfgInfo=vmC2.GetConfig())
    SetDeltaDiskBacking(configSpec, 0, parentDisk2)
    vimutil.InvokeAndTrack(vmC2.Reconfigure, configSpec)
    found = CheckInPolicy(domainC2, [(vmC2dir, 3), (vmPdir, 1)])
    if len(found) != 2:
        raise Exception('Did not find all expected permission in recreated ' +
                        'child 2. Found: %s' % ', '.join(found))
    Log('Hot-remove newly added delta disk')
    disks = vmconfig.CheckDevice(vmC2.GetConfig(), Vim.Vm.Device.VirtualDisk)
    deltaDisk = None
    for disk in disks:
        if disk.backing.parent and disk.backing.parent.fileName == parentDisk2:
            deltaDisk = disk
            break
    assert (deltaDisk is not None)
    configSpec = Vim.Vm.ConfigSpec()
    fileOp = Vim.Vm.Device.VirtualDeviceSpec.FileOperation.destroy
    vmconfig.RemoveDeviceFromSpec(configSpec, deltaDisk, fileOp)
    vimutil.InvokeAndTrack(vmC2.Reconfigure, configSpec)
    found = CheckInPolicy(domainC2, [(vmPdir, 1)], True)
    if len(found) > 0:
        DumpFilePolicy(domainC2)
        raise Exception('Found unexpected parent disk dir permission')
    vm.PowerOff(vmC2)

    # Clean up VMs
    vm.Destroy(vmC1)
    vm.Destroy(vmC2)
    vm.Destroy(vmP)
    shutil.rmtree(vmC2dir, ignore_errors=True)
    shutil.rmtree(vmC1dir, ignore_errors=True)
    shutil.rmtree(vmPdir, ignore_errors=True)