| /** |
| * Copyright (C) 2011 Cloud.com, Inc. All rights reserved. |
| */ |
| |
| package com.cloud.hypervisor.vmware.mo;
|
|
|
| import java.io.BufferedReader;
|
| import java.io.BufferedWriter;
|
| import java.io.ByteArrayInputStream;
|
| import java.io.ByteArrayOutputStream;
|
| import java.io.IOException;
|
| import java.io.InputStreamReader;
|
| import java.io.OutputStreamWriter;
|
| import java.util.ArrayList;
|
| import java.util.Properties;
|
|
|
| import org.apache.log4j.Logger;
|
|
|
| public class SnapshotDescriptor {
|
| private static final Logger s_logger = Logger.getLogger(SnapshotDescriptor.class);
|
|
|
| private Properties _properties = new Properties();
|
|
|
| public SnapshotDescriptor() {
|
| }
|
|
|
| public void parse(byte[] vmsdFileContent) throws IOException {
|
| BufferedReader in = null;
|
| try {
|
| in = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(vmsdFileContent)));
|
| String line;
|
| while((line = in.readLine()) != null) {
|
| // TODO, remember to remove this log, temporarily added for debugging purpose
|
| s_logger.info("Parse snapshot file content: " + line);
|
|
|
| String[] tokens = line.split("=");
|
| if(tokens.length == 2) {
|
| String name = tokens[0].trim();
|
| String value = tokens[1].trim();
|
| if(value.charAt(0) == '\"')
|
| value = value.substring(1, value.length() -1);
|
|
|
| _properties.put(name, value);
|
| }
|
| }
|
| } finally {
|
| if(in != null)
|
| in.close();
|
| }
|
| }
|
|
|
| public void removeDiskReferenceFromSnapshot(String diskFileName) {
|
| String numSnapshotsStr = _properties.getProperty("snapshot.numSnapshots");
|
| if(numSnapshotsStr != null) {
|
| int numSnaphosts = Integer.parseInt(numSnapshotsStr);
|
| for(int i = 0; i < numSnaphosts; i++) {
|
| String numDisksStr = _properties.getProperty(String.format("snapshot%d.numDisks", i));
|
| int numDisks = Integer.parseInt(numDisksStr);
|
|
|
| boolean diskFound = false;
|
| for(int j = 0; j < numDisks; j++) {
|
| String keyName = String.format("snapshot%d.disk%d.fileName", i, j);
|
| String fileName = _properties.getProperty(keyName);
|
| if(!diskFound) {
|
| if(fileName.equalsIgnoreCase(diskFileName)) {
|
| diskFound = true;
|
| _properties.remove(keyName);
|
| }
|
| } else {
|
| _properties.setProperty(String.format("snapshot%d.disk%d.fileName", i, j - 1), fileName);
|
| }
|
| }
|
|
|
| if(diskFound)
|
| _properties.setProperty(String.format("snapshot%d.numDisks", i), String.valueOf(numDisks-1));
|
| }
|
| }
|
| }
|
|
|
| public byte[] getVmsdContent() {
|
| BufferedWriter out = null;
|
| ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
|
|
| try {
|
| out = new BufferedWriter(new OutputStreamWriter(bos, "UTF-8"));
|
|
|
| out.write(".encoding = \"UTF-8\""); out.newLine();
|
| out.write(String.format("snapshot.lastUID = \"%s\"", _properties.getProperty("snapshot.lastUID"))); out.newLine();
|
| String numSnapshotsStr = _properties.getProperty("snapshot.numSnapshots");
|
| if(numSnapshotsStr == null || numSnapshotsStr.isEmpty())
|
| numSnapshotsStr = "0";
|
| out.write(String.format("snapshot.numSnapshots = \"%s\"", numSnapshotsStr)); out.newLine();
|
|
|
| String value = _properties.getProperty("snapshot.current");
|
| if(value != null) {
|
| out.write(String.format("snapshot.current = \"%s\"", value));
|
| out.newLine();
|
| }
|
|
|
| String key;
|
| for(int i = 0; i < Integer.parseInt(numSnapshotsStr); i++) {
|
| key = String.format("snapshot%d.uid", i);
|
| value = _properties.getProperty(key);
|
| out.write(String.format("%s = \"%s\"", key, value)); out.newLine();
|
|
|
| key = String.format("snapshot%d.filename", i);
|
| value = _properties.getProperty(key);
|
| out.write(String.format("%s = \"%s\"", key, value)); out.newLine();
|
|
|
| key = String.format("snapshot%d.displayName", i);
|
| value = _properties.getProperty(key);
|
| out.write(String.format("%s = \"%s\"", key, value)); out.newLine();
|
|
|
| key = String.format("snapshot%d.description", i);
|
| value = _properties.getProperty(key);
|
| out.write(String.format("%s = \"%s\"", key, value)); out.newLine();
|
|
|
| key = String.format("snapshot%d.createTimeHigh", i);
|
| value = _properties.getProperty(key);
|
| out.write(String.format("%s = \"%s\"", key, value)); out.newLine();
|
|
|
| key = String.format("snapshot%d.createTimeLow", i);
|
| value = _properties.getProperty(key);
|
| out.write(String.format("%s = \"%s\"", key, value)); out.newLine();
|
|
|
| key = String.format("snapshot%d.numDisks", i);
|
| value = _properties.getProperty(key);
|
| out.write(String.format("%s = \"%s\"", key, value)); out.newLine();
|
|
|
| int numDisks = Integer.parseInt(value);
|
| for(int j = 0; j < numDisks; j++) {
|
| key = String.format("snapshot%d.disk%d.fileName", i, j);
|
| value = _properties.getProperty(key);
|
| out.write(String.format("%s = \"%s\"", key, value)); out.newLine();
|
|
|
| key = String.format("snapshot%d.disk%d.node", i, j);
|
| value = _properties.getProperty(key);
|
| out.write(String.format("%s = \"%s\"", key, value)); out.newLine();
|
| }
|
| }
|
| } catch(IOException e) {
|
| assert(false);
|
| s_logger.error("Unexpected exception ", e);
|
| } finally {
|
| if(out != null) {
|
| try {
|
| out.close();
|
| } catch (IOException e) {
|
| }
|
| }
|
| }
|
|
|
| return bos.toByteArray();
|
| }
|
|
|
| private int getSnapshotId(String seqStr) {
|
| if(seqStr != null) {
|
| int seq = Integer.parseInt(seqStr);
|
| String numSnapshotStr = _properties.getProperty("snapshot.numSnapshots");
|
| assert(numSnapshotStr != null);
|
| for(int i = 0; i < Integer.parseInt(numSnapshotStr); i++) {
|
| String value = _properties.getProperty(String.format("snapshot%d.uid", i));
|
| if(value != null && Integer.parseInt(value) == seq)
|
| return i;
|
| }
|
| }
|
|
|
| return 0;
|
| }
|
|
|
| public SnapshotInfo[] getCurrentDiskChain() {
|
| ArrayList<SnapshotInfo> l = new ArrayList<SnapshotInfo>();
|
| String current = _properties.getProperty("snapshot.current");
|
| int id;
|
| while(current != null) {
|
| id = getSnapshotId(current);
|
| String numDisksStr = _properties.getProperty(String.format("snapshot%d.numDisks", id));
|
| int numDisks = 0; |
| if(numDisksStr != null && !numDisksStr.isEmpty()) { |
| numDisks = Integer.parseInt(numDisksStr);
|
| DiskInfo[] disks = new DiskInfo[numDisks];
|
| for(int i = 0; i < numDisks; i++) {
|
| disks[i] = new DiskInfo(
|
| _properties.getProperty(String.format("snapshot%d.disk%d.fileName", id, i)),
|
| _properties.getProperty(String.format("snapshot%d.disk%d.node", id, i))
|
| );
|
| }
|
|
|
| SnapshotInfo info = new SnapshotInfo();
|
| info.setId(id);
|
| info.setNumOfDisks(numDisks);
|
| info.setDisks(disks);
|
| info.setDisplayName(_properties.getProperty(String.format("snapshot%d.displayName", id)));
|
| l.add(info); |
| }
|
|
|
| current = _properties.getProperty(String.format("snapshot%d.parent", id));
|
| }
|
|
|
| return l.toArray(new SnapshotInfo[0]);
|
| }
|
|
|
| public static class SnapshotInfo {
|
| private int _id;
|
| private String _displayName;
|
| private int _numOfDisks;
|
| private DiskInfo[] _disks;
|
|
|
| public SnapshotInfo() {
|
| }
|
|
|
| public void setId(int id) {
|
| _id = id;
|
| }
|
|
|
| public int getId() {
|
| return _id;
|
| }
|
|
|
| public void setDisplayName(String name) {
|
| _displayName = name;
|
| }
|
|
|
| public String getDisplayName() {
|
| return _displayName;
|
| }
|
|
|
| public void setNumOfDisks(int numOfDisks) {
|
| _numOfDisks = numOfDisks;
|
| }
|
|
|
| public int getNumOfDisks() {
|
| return _numOfDisks;
|
| }
|
|
|
| public void setDisks(DiskInfo[] disks) {
|
| _disks = disks;
|
| }
|
|
|
| public DiskInfo[] getDisks() {
|
| return _disks;
|
| }
|
| }
|
|
|
| public static class DiskInfo {
|
| private String _diskFileName;
|
| private String _deviceName;
|
|
|
| public DiskInfo(String diskFileName, String deviceName) {
|
| _diskFileName = diskFileName;
|
| _deviceName = deviceName;
|
| }
|
|
|
| public String getDiskFileName() {
|
| return _diskFileName;
|
| }
|
|
|
| public String getDeviceName() {
|
| return _deviceName;
|
| }
|
| }
|
| }
|