// Copyright 2012 Citrix Systems, Inc. Licensed under the // Apache License, Version 2.0 (the "License"); you may not use this // file except in compliance with the License. Citrix Systems, Inc. // reserves all rights not expressly granted by 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. // // Automatically generated by addcopyright.py at 04/03/2012 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; } @Override public String toString() { StringBuffer sb = new StringBuffer(); sb.append("SnapshotInfo : { id: "); sb.append(_id); sb.append(", displayName: ").append(_displayName); sb.append(", numOfDisks: ").append(_numOfDisks); sb.append(", disks: ["); if(_disks != null) { int i = 0; for(DiskInfo diskInfo : _disks) { if(i > 0) sb.append(", "); sb.append(diskInfo.toString()); i++; } } sb.append("]}"); return sb.toString(); } } 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; } @Override public String toString() { return "DiskInfo: { device: " + _deviceName + ", file: " + _diskFileName + " }"; } } }