Package com.cybozu.vmbkp.soap

Source Code of com.cybozu.vmbkp.soap.SnapshotManager

/**
* @file
* @brief SnapshotManager
*
* Copyright (C) 2009,2010 Cybozu Inc., all rights reserved.
*
* @author Takashi HOSHINO <hoshino@labs.cybozu.co.jp>
*/
package com.cybozu.vmbkp.soap;

import java.util.LinkedList;
import java.util.logging.Logger;

import com.vmware.vim25.mo.VirtualMachine;
import com.vmware.vim25.mo.VirtualMachineSnapshot;
import com.vmware.vim25.VirtualMachineSnapshotTree;
import com.vmware.vim25.DiskChangeInfo;

import com.cybozu.vmbkp.util.VmInfo;
import com.cybozu.vmbkp.util.SnapInfo;
import com.cybozu.vmbkp.util.VmdkInfo;
import com.cybozu.vmbkp.util.VmdkBitmap;
import com.cybozu.vmbkp.util.Utility;

/**
* @brief Manage a snapshot of a virtual machine.
*/
public class SnapshotManager
{
    /**
     * Logger.
     */
    private static final Logger logger_ =
        Logger.getLogger(SnapshotManager.class.getName());
   
    private Connection conn_;
    private VirtualMachineSnapshot snapshot_;
    private VirtualMachineSnapshotTree snapshotTree_;
    private VirtualMachineManager vmm_;
    private VirtualMachineConfigManager configMgr_;

    /**
     * Constructor.
     *
     * You must not create this class by yourself.
     * Instead,
     * VirtualMachineManager.getCurrentSnapshot() or
     * VirtualMachineManager.searchSnapshotWithName().
     */
    public SnapshotManager
        (Connection conn, VirtualMachine vm, VirtualMachineSnapshot snapshot)
    {
        assert snapshot != null;
        conn_ = conn;
        vmm_ = new VirtualMachineManager(conn_, vm);
        snapshot_ = snapshot;
        snapshotTree_ = vmm_.searchSnapshotTreeWithMoref(this.getMoref());
        configMgr_ = new VirtualMachineConfigManager(conn_, snapshot_.getConfig());
    }

    /**
     * Get name of the snapshot.
     */
    public String getName()
    {
        /* This is virtual machine name. */
        /* return snapshot_.getConfig().getName(); */
       
        return snapshotTree_.getName();
    }

    /**
     * Get moref of the snapshot.
     */
    public String getMoref()
    {
        return snapshot_.getMOR().getVal();
    }

    /**
     * Generate SnapInfo object.
     */
    public SnapInfo getSnapInfo()
    {
        return new SnapInfo(getName(), getMoref());
    }

    /**
     * Generate VmInfo object.
     */
    public VmInfo getVmInfo()
    {
        return vmm_.getVmInfo();
    }

    /**
     * Get config manager of the snapshot.
     */
    public VirtualMachineConfigManager getConfig()
    {
        return configMgr_;
    }

    /**
     * Get virtual machine manager of the snapshot.
     */
    public VirtualMachineManager getVirtualMachine()
    {
        return vmm_;
    }

    /**
     * Get changed blocks information of specified vmdk file.
     * You should call isChangedDisk() before.
     *
     * @param vmdkInfo vmdk information obtained from getAllVmdkInfo() or so.
     * @param changeId changeId of the previous backup time. "*" is used if null.
     * @return changed block information as a bitmap data.
     */
    public VmdkBitmap getChangedBlocksOfDisk
        (VmdkInfo vmdkInfo, String baseChangeId)
    {
        final VirtualMachine vm = vmm_.getVirtualMachine();
        final VirtualMachineSnapshot vmSnap = snapshot_;

        if (baseChangeId == null) {
            baseChangeId = "*";
        }

        logger_.info(vmdkInfo.toString());
        logger_.info(baseChangeId); /* debug */

        final long capacityInBytes = vmdkInfo.capacityInKB_ * 1024L;
       
        /* block size is fixed to 1MB currently */
        VmdkBitmap bmp = new VmdkBitmap(capacityInBytes, 1024 * 1024);
       
        boolean isNotChangedAtAll = false;
        try {
            long offset = 0;
            DiskChangeInfo dci = null;
            do {
                dci = vm.queryChangedDiskAreas
                    (vmSnap, vmdkInfo.key_, offset, baseChangeId);

                if (offset == 0 && (dci.changedArea == null)) {
                    /*
                      ChangeId is not null and DiskChangeInfo.changedArea is null,
                       then the disk is not changed at all.
                     */
                    isNotChangedAtAll = true;
                    logger_.info("This vmdk is not changed at all " +
                                 "from previous backup.");
                    break;
                }
               
                for (int j = 0; j < dci.changedArea.length; j ++) {
                    long start = dci.getChangedArea()[j].getStart();
                    long len = dci.getChangedArea()[j].getLength();
                    logger_.info
                        (String.format
                         ("(%d,%d) %s \n", start, len,
                          (len % 1048576 == 0 ? "" : "not x MB")));

                    bmp.setRangeInBytes(start, len);
                }
                logger_.info
                    (String.format
                     ("offset %d, length %d\n",
                      dci.getStartOffset(), dci.getLength()));
                offset = dci.getStartOffset() + dci.getLength();
            } while (offset < capacityInBytes);
                   
        } catch (Exception e) {
            logger_.warning(Utility.toString(e));
            return null;
        }

        /* If isNotChangedAtAll is true, then all-zero bmp will be returned */
        return bmp;
    }

    /**
     * Check the specified vmdk is changed or not.
     * Call this before calling getChangedBlocksOfDisk().
     *
     * @param vmdkInfo vmdk information obtained from getAllVmdkInfo() or so.
     * @param changeId changeId of the previous backup time.
     * @return true if it is changed, or false.
     *         If baseChangeId is not valid, this method does not mean.
     */
    public boolean isChangedDisk(VmdkInfo vmdkInfo, String baseChangeId)
    {
        logger_.info("isChangedDisk start.");
       
        final VirtualMachine vm = vmm_.getVirtualMachine();
        final VirtualMachineSnapshot vmSnap = snapshot_;

        if (baseChangeId == null) {
            return false;
        }

        /* debug */
        vmdkInfo.print();
        logger_.info(baseChangeId);

        long offset = 0;
        DiskChangeInfo dci;
        try {
            dci = vm.queryChangedDiskAreas
                (vmSnap, vmdkInfo.key_, offset, baseChangeId);
        } catch (Exception e) {
            /*
              Candidates:
              com.vmware.vim25.FileFault,
              com.vmware.vim25.NotFound,
              com.vmware.vim25.RuntimeFault,
              java.rmi.RemoteException
             */
            logger_.warning(Utility.toString(e));
            return false;
        }

        logger_.info("isChangedDisk end");
       
        if (dci != null) {
            return true;
        } else {
            return false;
        }
    }

}
TOP

Related Classes of com.cybozu.vmbkp.soap.SnapshotManager

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.