Package com.vmware.aurora.vc

Source Code of com.vmware.aurora.vc.VcSnapshotImpl$SerializationProxy

/***************************************************************************
* Copyright (c) 2012-2013 VMware, Inc. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
***************************************************************************/

package com.vmware.aurora.vc;

import java.util.HashMap;
import java.util.Map;

import com.vmware.aurora.global.DiskSize;
import com.vmware.aurora.util.AuAssert;
import com.vmware.aurora.vc.VcTask.TaskType;
import com.vmware.aurora.vc.VcTaskMgr.IVcTaskBody;
import com.vmware.aurora.vc.VcVirtualMachineImpl.VmOp;
import com.vmware.aurora.vc.vcservice.VcContext;
import com.vmware.vim.binding.vim.vm.ConfigInfo;
import com.vmware.vim.binding.vim.vm.FileLayoutEx;
import com.vmware.vim.binding.vim.vm.FileLayoutEx.DiskLayout;
import com.vmware.vim.binding.vim.vm.FileLayoutEx.DiskUnit;
import com.vmware.vim.binding.vim.vm.FileLayoutEx.FileInfo;
import com.vmware.vim.binding.vim.vm.FileLayoutEx.SnapshotLayout;
import com.vmware.vim.binding.vim.vm.Snapshot;
import com.vmware.vim.binding.vim.vm.device.VirtualDevice;
import com.vmware.vim.binding.vim.vm.device.VirtualDisk;
import com.vmware.vim.binding.vim.vm.device.VirtualDiskOption.DiskMode;
import com.vmware.vim.binding.vmodl.ManagedObject;
import com.vmware.vim.binding.vmodl.ManagedObjectReference;
import com.vmware.vim.binding.vmodl.fault.ManagedObjectNotFound;

public interface VcSnapshot extends VcVmBase {

   /**
    * Remove a snapshot asynchronously.
    * @throws Exception
    * @return the task
    */
   public VcTask remove(final IVcTaskCallback callback) throws Exception;

   /**
    * Remove a snapshot.
    * @throws Exception
    */
   public void remove() throws Exception;

   /**
    * Return parent Vm
    */
   public VcVirtualMachine getVm();

   /**
    * @return the name of the snapshot
    */
   public String getName();

   /**
    * Gets the size of the snapshot on data storage.
    * @return The size.
    */
   public DiskSize getSizeOnData(DiskSchema disSchema);

   /**
    * Get the size details of each disks in the snapshot.
    * @return The size.
    */
   public Map<DeviceId, DiskSize> getSizeDetail();

   /**
    * Gets the size of the snapshot on all storages.
    * @return The size.
    */
   public DiskSize getSize();

   /**
    * Get the vmsn file size of the snapshot.
    */
   public DiskSize getVmsnFileSize();

   /**
    * Revert to a snapshot.
    * @param callback (optional) call-back function for the task
    * @return the task for revert to the snapshot
    * @throws Exception
    */
   VcTask revert(final IVcTaskCallback callback) throws Exception;

   void revert() throws Exception;

}

@SuppressWarnings("serial")
class VcSnapshotImpl extends VcVmBaseImpl implements VcSnapshot {
   private final VcVirtualMachineImpl vm;
   private final String name;
   private ConfigInfo config;
   private DiskSize size;
   private Map<DeviceId, DiskSize> sizeDetail;
   private DiskSize vmsnFileSize;

   @Override
   protected void update(ManagedObject mo) {
      final Snapshot snap = (Snapshot)mo;
      config = snap.getConfig();
      updateSize();
   }

   /*
    * There is no way to find out the VM from VC's Snapshot moref,
    * so we add it during initialization.
    */
   protected VcSnapshotImpl(Snapshot mo, VcVirtualMachineImpl vm, String name) {
      super(mo);
      AuAssert.check(vm != null);
      this.vm = vm;
      this.name = name;
      update(mo);
   }

   @Override
   protected ConfigInfo getConfig() {
      return config;
   }

   @Override
   public String getName() {
      return MoUtil.fromURLString(name);
   }

   public VcVirtualMachine getVm() {
      return vm;
   }

   @Override
   public VcDatacenter getDatacenter() {
      return vm.getDatacenter();
   }

   @Override
   public VcTask remove(final IVcTaskCallback callback) throws Exception {
      // remove child snaps=false, consolidate=true
      VcTask task = VcContext.getTaskMgr().execute(new IVcTaskBody() {
         @Override
         public VcTask body() throws Exception {
            Snapshot snap = getManagedObject();
            return new VcTask(TaskType.RemoveSnap, snap.remove(false, true), callback);
         }
      });
      return task;
   }

   void removeInt() throws Exception {
      try {
         VcTask task = remove(VcCache.getRefreshVcTaskCB(vm));
         task.waitForCompletion();
      } catch (ManagedObjectNotFound e) {
         // The object was gone. Nothing to do.
         logger.info("cannot destroy " + this + ", not found.");
      }
   }

   @Override
   public void remove() throws Exception {
      vm.safeExecVmOp(new VmOp<Void>() {
         public Void exec() throws Exception {
            removeInt();
            return null;
         }
      });
   }

   private VirtualDevice findDevice(VirtualDevice[] devices, int key) {
      for (VirtualDevice device : devices) {
         if (device.getKey() == key) {
            return device;
         }
      }
      return null;
   }

   /**
    * Calculate size of snapshot files.
    *
    * Note: This is done at configuration time,
    *       so it won't get updated if file size ever changes.
    */
   private void updateSize() {
      FileLayoutEx fileLayout = vm.getFileLayout();

      // create file map to avoid unnecessary loops
      Map<Integer, FileInfo> fileMap = new HashMap<Integer, FileInfo>();
      if (fileLayout.getFile() != null) {
         for (FileInfo fileInfo : fileLayout.getFile()) {
            fileMap.put(fileInfo.getKey(), fileInfo);
         }
      }

      sizeDetail = new HashMap<DeviceId, DiskSize>();
      size = new DiskSize(0);

      if (fileLayout.getSnapshot() == null) {
         logger.info("missing snapshot layout in " + vm);
         return;
      }
      // search for the snapshot's files
      for (SnapshotLayout snapshotLayout : fileLayout.getSnapshot()) {
         if (getMoRef().equals(snapshotLayout.getKey())) {
            // loop through each disk and count the last diskunit in the chain only
            // because the previous ones are shared with the other snapshots so don't double counting
            VirtualDevice[] devices = getConfig().getHardware().getDevice();
            for(DiskLayout disk : snapshotLayout.getDisk()) {
               VirtualDisk vdisk = (VirtualDisk)findDevice(devices, disk.getKey());
               String diskMode = ((VirtualDisk.FlatVer2BackingInfo)vdisk.getBacking()).getDiskMode();
               // independent disks are not included in snapshot
               if (!diskMode.equals(DiskMode.independent_nonpersistent.name()) &&
                   !diskMode.equals(DiskMode.independent_persistent.name())) {
                  DiskUnit[] diskUnits = disk.getChain();
                  int[] fileKeys = diskUnits[diskUnits.length - 1].getFileKey();

                  // count the total of each file's size
                  long total = 0;
                  for (int fileKey : fileKeys) {
                     FileInfo fileInfo = fileMap.get(fileKey);
                     if (fileInfo != null) {
                        total += fileInfo.getSize();
                     }
                  }

                  // add up
                  size.add(total);
                  DeviceId deviceId =
                        new DeviceId(findDevice(devices, vdisk.getControllerKey()), vdisk);
                  sizeDetail.put(deviceId, new DiskSize(total));
               }
            }

            // add vmsn file size which is always on data storage
            FileInfo fileInfo = fileMap.get(snapshotLayout.getDataKey());
            if (fileInfo != null) {
               size.add(fileInfo.getSize());
               vmsnFileSize = new DiskSize(fileInfo.getSize());
            }
            return;
         }
      }
      // no matching file layout for this snapshot?
   }

   @Override
   public DiskSize getSize() {
      return size;
   }

   @Override
   public DiskSize getSizeOnData(DiskSchema diskSchema) {
      DiskSize dataSize = new DiskSize(0);
      Map<DeviceId, DiskSize> sizeDetail = getSizeDetail();
      for (DiskSpec diskSpec : diskSchema.getDiskSpecs()) {
         // only the snapshot of the archive disk is on backup storage since V1.0
         if (!diskSpec.getDiskType().equals(DiskType.Archive)) {
            DiskSize size = sizeDetail.get(diskSpec.getDeviceId());
            if (size != null) {
               dataSize.add(size);
            }
         }
      }
      dataSize.add(getVmsnFileSize());
      return dataSize;
   }

   @Override
   public Map<DeviceId, DiskSize> getSizeDetail() {
      return sizeDetail;
   }

   @Override
   public DiskSize getVmsnFileSize() {
      return vmsnFileSize;
   }

   @Override
   public VcTask revert(final IVcTaskCallback callback) throws Exception {
      // revert to snapshot: host=null, suppressPowerOn=false
      VcTask task = VcContext.getTaskMgr().execute(new IVcTaskBody() {
         @Override
         public VcTask body() throws Exception {
            final Snapshot snap = getManagedObject();
            return new VcTask(TaskType.RevertSanp, snap.revert(null, false), callback);
         }
      });
      return task;
   }

   @Override
   public void revert() throws Exception {
      try {
         VcTask task = revert(VcCache.getRefreshVcTaskCB(vm));
         task.waitForCompletion();
      } catch (ManagedObjectNotFound e) {
         // The object was gone. Nothing to do.
         logger.info("cannot revert to " + this + ", not found.");
      }
   }

   /**
    * Extends VcObject serialization proxy with extra parameters.
    */
   protected static class SerializationProxy extends VcObjectImpl.SerializationProxy
   {
       private final ManagedObjectReference vmMoref;

       private SerializationProxy(VcSnapshotImpl snapshot) {
          super(snapshot);
          vmMoref = snapshot.vm.getMoRef();
       }

       @Override
       protected final VcObject getCachedObject() {
          VcVirtualMachineImpl vm = VcCache.get(vmMoref);
          return vm.getSnapshot(moRef);
       }
   }

   @Override
   protected Object writeReplace() {
       return new SerializationProxy(this);
   }

}
TOP

Related Classes of com.vmware.aurora.vc.VcSnapshotImpl$SerializationProxy

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.