Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

use proper async messaging to update volume state

move commit on delete to the right place
actually apply volume attachment transactions
only send volume creation event on successfully submitting it to SC
fix to system/static mode network group lookup
tx functions for volume state additions to vm instance
  • Loading branch information...
commit 0440debcb767c86c275cf75d889054d1e49b8bb8 2 parents a758e7f + e4c4b26
@grze grze authored
View
36 clc/modules/cluster-manager/src/main/java/com/eucalyptus/blockstorage/StorageUtil.java
@@ -83,6 +83,7 @@
import com.eucalyptus.entities.EntityWrapper;
import com.eucalyptus.records.Logs;
import com.eucalyptus.util.EucalyptusCloudException;
+import com.eucalyptus.util.async.AsyncRequests;
import com.eucalyptus.vm.VmInstance;
import com.eucalyptus.vm.VmInstances;
import com.eucalyptus.vm.VmVolumeAttachment;
@@ -109,20 +110,12 @@
}
ArrayList<edu.ucsb.eucalyptus.msgs.Volume> reply = Lists.newArrayList( );
for ( String partition : partitionVolumeMap.keySet( ) ) {
- try {
- Map<String, StorageVolume> idStorageVolumeMap = updateVolumesInPartition( partitionVolumeMap, partition );
- for ( Volume v : partitionVolumeMap.get( partition ) ) {
- try {
- reply.add( volumeStateTransform( idStorageVolumeMap, v ) );
- } catch ( Exception ex ) {
- Logs.extreme( ).error( ex );
- reply.add( v.morph( new edu.ucsb.eucalyptus.msgs.Volume( ) ) );
- }
- }
- } catch ( EucalyptusCloudException ex ) {
- LOG.error( ex );
- Logs.extreme( ).error( ex, ex );
- for ( Volume v : partitionVolumeMap.get( partition ) ) {
+ Map<String, StorageVolume> idStorageVolumeMap = updateVolumesInPartition( partitionVolumeMap, partition );
+ for ( Volume v : partitionVolumeMap.get( partition ) ) {
+ try {
+ reply.add( volumeStateTransform( idStorageVolumeMap, v ) );
+ } catch ( Exception ex ) {
+ Logs.extreme( ).error( ex );
reply.add( v.morph( new edu.ucsb.eucalyptus.msgs.Volume( ) ) );
}
}
@@ -178,7 +171,7 @@
return aVolume;
}
- private static Map<String, StorageVolume> updateVolumesInPartition( Multimap<String, Volume> partitionVolumeMap, String partition ) throws EucalyptusCloudException {
+ private static Map<String, StorageVolume> updateVolumesInPartition( Multimap<String, Volume> partitionVolumeMap, String partition ) {
Map<String, StorageVolume> idStorageVolumeMap = Maps.newHashMap( );
ServiceConfiguration scConfig = Topology.lookup( Storage.class, Partitions.lookupByName( partition ) );
Iterator<String> volumeNames = Iterators.transform( partitionVolumeMap.get( partition ).iterator( ), new Function<Volume, String>( ) {
@@ -188,10 +181,15 @@ public String apply( Volume arg0 ) {
}
} );
DescribeStorageVolumesType descVols = new DescribeStorageVolumesType( Lists.newArrayList( volumeNames ) );
- Dispatcher sc = ServiceDispatcher.lookup( scConfig );
- DescribeStorageVolumesResponseType volState = sc.send( descVols );
- for ( StorageVolume vol : volState.getVolumeSet( ) ) {
- idStorageVolumeMap.put( vol.getVolumeId( ), vol );
+ try {
+ DescribeStorageVolumesResponseType volState = AsyncRequests.sendSync( scConfig, descVols );
+ for ( StorageVolume vol : volState.getVolumeSet( ) ) {
+ LOG.debug( "Volume states: " + vol.getVolumeId( ) + " " + vol.getStatus( ) + " " + vol.getActualDeviceName( ) );
+ idStorageVolumeMap.put( vol.getVolumeId( ), vol );
+ }
+ } catch ( Exception ex ) {
+ LOG.error( ex );
+ Logs.extreme( ).error( ex, ex );
}
return idStorageVolumeMap;
}
View
2  clc/modules/cluster-manager/src/main/java/com/eucalyptus/blockstorage/VolumeManager.java
@@ -385,12 +385,12 @@ public DetachVolumeResponseType detach( DetachVolumeType request ) throws Eucaly
EntityWrapper<Volume> db = EntityWrapper.get( Volume.class );
try {
vol = db.getUnique( Volume.named( ctx.getUserFullName( ).asAccountFullName( ), request.getVolumeId( ) ) );
+ db.commit( );
} catch ( EucalyptusCloudException e ) {
LOG.debug( e, e );
db.rollback( );
throw new EucalyptusCloudException( "Volume does not exist: " + request.getVolumeId( ) );
}
- db.commit( );
if ( !RestrictedTypes.filterPrivileged( ).apply( vol ) ) {
throw new EucalyptusCloudException( "Not authorized to detach volume " + request.getVolumeId( ) + " by " + ctx.getUser( ).getName( ) );
}
View
16 clc/modules/cluster-manager/src/main/java/com/eucalyptus/blockstorage/Volumes.java
@@ -63,14 +63,11 @@
package com.eucalyptus.blockstorage;
-import java.util.HashMap;
import java.util.List;
-import java.util.NoSuchElementException;
import java.util.concurrent.ExecutionException;
import javax.persistence.EntityTransaction;
import org.apache.log4j.Logger;
import org.hibernate.criterion.Example;
-import org.hibernate.exception.ConstraintViolationException;
import com.eucalyptus.auth.principal.UserFullName;
import com.eucalyptus.cloud.CloudMetadata.VolumeMetadata;
import com.eucalyptus.component.Partitions;
@@ -80,7 +77,6 @@
import com.eucalyptus.crypto.Crypto;
import com.eucalyptus.entities.Entities;
import com.eucalyptus.entities.EntityWrapper;
-import com.eucalyptus.entities.TransactionException;
import com.eucalyptus.entities.Transactions;
import com.eucalyptus.event.ListenerRegistry;
import com.eucalyptus.reporting.event.StorageEvent;
@@ -94,8 +90,8 @@
import com.eucalyptus.ws.client.ServiceDispatcher;
import com.google.common.base.Function;
import com.google.common.collect.Lists;
-import edu.ucsb.eucalyptus.msgs.AttachedVolume;
import edu.ucsb.eucalyptus.msgs.BaseMessage;
+import edu.ucsb.eucalyptus.msgs.CreateStorageVolumeResponseType;
import edu.ucsb.eucalyptus.msgs.CreateStorageVolumeType;
import edu.ucsb.eucalyptus.msgs.DescribeStorageVolumesResponseType;
import edu.ucsb.eucalyptus.msgs.DescribeStorageVolumesType;
@@ -196,12 +192,18 @@ public static Volume createStorageVolume( final ServiceConfiguration sc, final U
public void fire( final Volume t ) {
t.setState( State.GENERATING );
try {
+ final CreateStorageVolumeType req = new CreateStorageVolumeType( t.getDisplayName( ), t.getSize( ), snapId, null ).regardingUserRequest( request );
+ final CreateStorageVolumeResponseType ret = AsyncRequests.sendSync( sc, req );
+ LOG.debug( "Volume created: CreateStorageVolumeResponse: " +
+ ret.getVolumeId( ) + " " +
+ ret.getStatus( ) + " " +
+ ret.getSize( ) + " " +
+ ret.getSnapshotId( ) + " " +
+ ret.getCreateTime( ) );
ListenerRegistry.getInstance( ).fireEvent( new StorageEvent( StorageEvent.EventType.EbsVolume, true, t.getSize( ),
t.getOwnerUserId( ), t.getOwnerUserName( ),
t.getOwnerAccountNumber( ), t.getOwnerAccountName( ),
t.getScName( ), t.getPartition( ) ) );
- final CreateStorageVolumeType req = new CreateStorageVolumeType( t.getDisplayName( ), t.getSize( ), snapId, null ).regardingUserRequest( request );
- AsyncRequests.sendSync( sc, req );
} catch ( final Exception ex ) {
LOG.error( "Failed to create volume: " + t.toString( ), ex );
throw Exceptions.toUndeclared( ex );
View
68 clc/modules/cluster-manager/src/main/java/com/eucalyptus/vm/VmInstance.java
@@ -1353,48 +1353,44 @@ public VmVolumeAttachment lookupVolumeAttachment( final String volumeId ) {
/**
* @param attachVol
*/
- public void addTransientVolume( String deviceName, String remoteDevice, Volume vol ) {
- final EntityTransaction db = Entities.get( VmInstance.class );
- try {
- final VmInstance entity = Entities.merge( this );
- final Volume volEntity = Entities.merge( vol );
- VmVolumeAttachment attachVol = new VmVolumeAttachment( entity, vol.getDisplayName( ), deviceName, remoteDevice, AttachmentState.attaching.name( ), new Date( ), false );
- volEntity.setState( State.BUSY );
- entity.getTransientVolumeState( ).addVolumeAttachment( attachVol );
- db.commit( );
- } catch ( final RuntimeException ex ) {
- Logs.extreme( ).error( ex, ex );
- db.rollback( );
- throw ex;
- }
+ public void addTransientVolume( final String deviceName, final String remoteDevice, final Volume vol ) {
+ final Function<Volume, Volume> attachmentFunction = new Function<Volume, Volume>( ) {
+ public Volume apply( final Volume input ) {
+ final VmInstance entity = Entities.merge( VmInstance.this );
+ final Volume volEntity = Entities.merge( vol );
+ VmVolumeAttachment attachVol = new VmVolumeAttachment( entity, volEntity.getDisplayName( ), deviceName, remoteDevice, AttachmentState.attaching.name( ), new Date( ), false );
+ volEntity.setState( State.BUSY );
+ entity.getTransientVolumeState( ).addVolumeAttachment( attachVol );
+ return volEntity;
+ }
+ };
+ Entities.asTransaction( VmInstance.class, attachmentFunction, VmInstances.TX_RETRIES ).apply( vol );
}
public void addPersistentVolume( final String deviceName, final Volume vol ) {
- final EntityTransaction db = Entities.get( VmInstance.class );
- try {
- final VmInstance entity = Entities.merge( this );
- final VmVolumeAttachment volumeAttachment = new VmVolumeAttachment( entity, vol.getDisplayName( ), deviceName, vol.getRemoteDevice( ), AttachmentState.attached.name( ), new Date( ), true );
- entity.bootRecord.getPersistentVolumes( ).add( volumeAttachment );
- db.commit( );
- } catch ( final RuntimeException ex ) {
- Logs.extreme( ).error( ex, ex );
- db.rollback( );
- throw ex;
- }
+ final Function<Volume, Volume> attachmentFunction = new Function<Volume, Volume>( ) {
+ public Volume apply( final Volume input ) {
+ final VmInstance entity = Entities.merge( VmInstance.this );
+ final Volume volEntity = Entities.merge( vol );
+ final VmVolumeAttachment volumeAttachment = new VmVolumeAttachment( entity, vol.getDisplayName( ), deviceName, vol.getRemoteDevice( ), AttachmentState.attached.name( ), new Date( ), true );
+ entity.bootRecord.getPersistentVolumes( ).add( volumeAttachment );
+ return volEntity;
+ }
+ };
+ Entities.asTransaction( VmInstance.class, attachmentFunction, VmInstances.TX_RETRIES ).apply( vol );
}
public void addPermanentVolume( final String deviceName, final Volume vol ) {
- final EntityTransaction db = Entities.get( VmInstance.class );
- try {
- final VmInstance entity = Entities.merge( this );
- final VmVolumeAttachment volumeAttachment = new VmVolumeAttachment( entity, vol.getDisplayName( ), deviceName, vol.getRemoteDevice( ), AttachmentState.attached.name( ), new Date( ), false );
- entity.bootRecord.getPersistentVolumes( ).add( volumeAttachment );
- db.commit( );
- } catch ( final RuntimeException ex ) {
- Logs.extreme( ).error( ex, ex );
- db.rollback( );
- throw ex;
- }
+ final Function<Volume, Volume> attachmentFunction = new Function<Volume, Volume>( ) {
+ public Volume apply( final Volume input ) {
+ final VmInstance entity = Entities.merge( VmInstance.this );
+ final Volume volEntity = Entities.merge( vol );
+ final VmVolumeAttachment volumeAttachment = new VmVolumeAttachment( entity, vol.getDisplayName( ), deviceName, vol.getRemoteDevice( ), AttachmentState.attached.name( ), new Date( ), false );
+ entity.bootRecord.getPersistentVolumes( ).add( volumeAttachment );
+ return volEntity;
+ }
+ };
+ Entities.asTransaction( VmInstance.class, attachmentFunction, VmInstances.TX_RETRIES ).apply( vol );
}
/**
View
2  clc/modules/cluster-manager/src/main/java/com/eucalyptus/vm/VmInstances.java
@@ -318,7 +318,7 @@ public static VmVolumeAttachment lookupVolumeAttachment( final String volumeId )
db.commit( );
return ret;
} catch ( Exception ex ) {
- Logs.exhaust( ).error( ex, ex );
+ Logs.extreme( ).error( ex, ex );
db.rollback( );
throw new NoSuchElementException( ex.getMessage( ) );
}
Please sign in to comment.
Something went wrong with that request. Please try again.