blob: 80eec2af07b7f72a8e493882fd593da21dd39037 (
plain) (
tree)
|
|
package org.openslx.util.vm;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import org.openslx.bwlp.thrift.iface.Virtualizer;
import org.openslx.util.Util;
public class DiskImage
{
/**
* Big endian representation of the 4 bytes 'KDMV'
*/
private static final int VMDK_MAGIC = 0x4b444d56;
public enum ImageFormat
{
VMDK( "vmdk" ), QCOW2( "qcow2" ), VDI( "vdi" );
public final String extension;
private ImageFormat( String extension )
{
this.extension = extension;
}
public static ImageFormat defaultForVirtualizer( Virtualizer virt )
{
if ( virt == null )
return null;
return defaultForVirtualizer( virt.virtId );
}
public static ImageFormat defaultForVirtualizer( String virtId )
{
if ( virtId == null )
return null;
if ( virtId.equals( "vmware" ) )
return VMDK;
if ( virtId.equals( "virtualbox" ) )
return VDI;
return null;
}
}
public final boolean isStandalone;
public final boolean isCompressed;
public final boolean isSnapshot;
public final ImageFormat format;
public final String subFormat;
public final int hwVersion;
public DiskImage( File disk ) throws FileNotFoundException, IOException,
UnknownImageFormatException
{
// For now we only support VMDK...
try ( RandomAccessFile file = new RandomAccessFile( disk, "r" ) ) {
if ( file.readInt() != VMDK_MAGIC )
throw new UnknownImageFormatException();
file.seek( 512 );
byte[] buffer = new byte[ 2048 ];
file.readFully( buffer );
VmwareConfig config = new VmwareConfig( buffer, findNull( buffer ) );
subFormat = config.get( "createType" );
String parent = config.get( "parentCID" );
this.isStandalone = isStandaloneCreateType( subFormat, parent );
this.isCompressed = subFormat != null
&& subFormat.equalsIgnoreCase( "streamOptimized" );
this.isSnapshot = parent != null
&& !parent.equalsIgnoreCase( "ffffffff" );
this.format = ImageFormat.VMDK;
String hwv = config.get( "ddb.virtualHWVersion" );
if (hwv == null ) {
this.hwVersion = 10;
} else {
this.hwVersion = Util.parseInt( hwv, 10 );
}
}
}
private int findNull( byte[] buffer )
{
for ( int i = 0; i < buffer.length; ++i ) {
if ( buffer[i] == 0 )
return i;
}
return buffer.length;
}
private boolean isStandaloneCreateType( String type, String parent )
{
if ( type == null )
return false;
if ( parent != null && !parent.equalsIgnoreCase( "ffffffff" ) )
return false;
return type.equalsIgnoreCase( "streamOptimized" )
|| type.equalsIgnoreCase( "monolithicSparse" );
}
public static class UnknownImageFormatException extends Exception
{
private static final long serialVersionUID = -6647935235475007171L;
}
}
|