summaryrefslogtreecommitdiffstats
path: root/src/main/java/org/openslx/util/vm/DiskImage.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/org/openslx/util/vm/DiskImage.java')
-rw-r--r--src/main/java/org/openslx/util/vm/DiskImage.java205
1 files changed, 0 insertions, 205 deletions
diff --git a/src/main/java/org/openslx/util/vm/DiskImage.java b/src/main/java/org/openslx/util/vm/DiskImage.java
deleted file mode 100644
index 2b24a3f..0000000
--- a/src/main/java/org/openslx/util/vm/DiskImage.java
+++ /dev/null
@@ -1,205 +0,0 @@
-package org.openslx.util.vm;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.RandomAccessFile;
-import java.util.Arrays;
-
-import org.apache.log4j.Logger;
-import org.openslx.bwlp.thrift.iface.Virtualizer;
-import org.openslx.thrifthelper.TConst;
-import org.openslx.util.Util;
-
-public class DiskImage
-{
- private static final Logger LOGGER = Logger.getLogger( DiskImage.class );
- /**
- * Big endian representation of the 4 bytes 'KDMV'
- */
- private static final int VMDK_MAGIC = 0x4b444d56;
- private static final int VDI_MAGIC = 0x7f10dabe;
- /**
- * Big endian representation of the 4 bytes 'QFI\xFB'
- */
- private static final int QEMU_MAGIC = 0x514649fb;
-
- 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( TConst.VIRT_VMWARE ) )
- return VMDK;
- if ( virtId.equals( TConst.VIRT_VIRTUALBOX ) )
- return VDI;
- if ( virtId.equals( TConst.VIRT_QEMU ) )
- return QCOW2;
- 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 final String diskDescription;
-
- public ImageFormat getImageFormat()
- {
- return format;
- }
-
- public DiskImage( File disk ) throws FileNotFoundException, IOException, UnknownImageFormatException
- {
- LOGGER.debug( "Validating disk file: " + disk.getAbsolutePath() );
- try ( RandomAccessFile file = new RandomAccessFile( disk, "r" ) ) {
- // vmdk
- boolean isVmdkMagic = ( file.readInt() == VMDK_MAGIC );
- if ( isVmdkMagic || file.length() < 4096 ) {
- if ( isVmdkMagic ) {
- file.seek( 512 );
- } else {
- file.seek( 0 );
- }
- byte[] buffer = new byte[ (int)Math.min( 2048, file.length() ) ];
- file.readFully( buffer );
- VmwareConfig config;
- try {
- config = new VmwareConfig( buffer, findNull( buffer ) );
- } catch ( UnsupportedVirtualizerFormatException e ) {
- config = null;
- }
- if ( config != null ) {
- String sf = config.get( "createType" );
- String parent = config.get( "parentCID" );
- if ( sf != null || parent != null ) {
- subFormat = sf;
- 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 );
- }
- this.diskDescription = null;
- return;
- }
- }
- }
- // Format spec from: https://forums.virtualbox.org/viewtopic.php?t=8046
- // First 64 bytes are the opening tag: <<< .... >>>
- // which we don't care about, then comes the VDI signature
- file.seek( 64 );
- if ( file.readInt() == VDI_MAGIC ) {
- // skip the next 4 ints as they don't interest us:
- // - VDI version
- // - size of header, strangely irrelevant?
- // - image type, 1 for dynamic allocated storage, 2 for fixed size
- // - image flags, seem to be always 00 00 00 00
- file.skipBytes( 4 * 4 );
-
- // next 256 bytes are image description
- byte[] imageDesc = new byte[ 256 ];
- file.readFully( imageDesc );
- // next sections are irrelevant (int if not specified):
- // - offset blocks
- // - offset data
- // - cylinders
- // - heads
- // - sectors
- // - sector size
- // - <unused>
- // - disk size (long = 8 bytes)
- // - block size
- // - block extra data
- // - blocks in hdd
- // - blocks allocated
- file.skipBytes( 4 * 13 );
-
- // now it gets interesting, UUID of VDI
- byte[] diskUuid = new byte[ 16 ];
- file.readFully( diskUuid );
- // last snapshot uuid, mostly uninteresting since we don't support snapshots -> skip 16 bytes
- // TODO: meaning of "uuid link"? for now, skip 16
- file.skipBytes( 32 );
-
- // parent uuid, indicator if this VDI is a snapshot or not
- byte[] parentUuid = new byte[ 16 ];
- file.readFully( parentUuid );
- byte[] zeroUuid = new byte[ 16 ];
- Arrays.fill( zeroUuid, (byte)0 );
- this.isSnapshot = !Arrays.equals( parentUuid, zeroUuid );
- // VDI does not seem to support split VDI files so always standalone
- this.isStandalone = true;
- // compression is done by sparsifying the disk files, there is no flag for it
- this.isCompressed = false;
- this.format = ImageFormat.VDI;
- this.subFormat = null;
- this.diskDescription = new String( imageDesc );
- this.hwVersion = 0;
- return;
- }
-
- // TODO: qcow
- file.seek( 0 );
- if ( file.readInt() == QEMU_MAGIC ) {
- // dummy values
- this.isStandalone = true;
- this.isCompressed = false;
- this.isSnapshot = false;
- this.format = ImageFormat.QCOW2;
- this.subFormat = null;
- this.diskDescription = null;
- this.hwVersion = 0;
- return;
- }
- }
- throw new UnknownImageFormatException();
- }
-
- 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;
- }
-}