6363import com .cloud .api .storage .LinstorRevertBackupSnapshotCommand ;
6464import com .cloud .configuration .Config ;
6565import com .cloud .host .Host ;
66+ import com .cloud .host .HostVO ;
6667import com .cloud .host .dao .HostDao ;
6768import com .cloud .resource .ResourceState ;
6869import com .cloud .storage .DataStoreRole ;
@@ -921,9 +922,10 @@ private String revertSnapshotFromImageStore(
921922 _backupsnapshotwait ,
922923 VirtualMachineManager .ExecuteInSequence .value ());
923924
924- Optional <RemoteHostEndPoint > optEP = getDiskfullEP (linstorApi , rscName );
925+ final StoragePool pool = (StoragePool ) volumeInfo .getDataStore ();
926+ Optional <RemoteHostEndPoint > optEP = getDiskfullEP (linstorApi , pool , rscName );
925927 if (optEP .isEmpty ()) {
926- optEP = getLinstorEP (linstorApi , rscName );
928+ optEP = getLinstorEP (linstorApi , pool , rscName );
927929 }
928930
929931 if (optEP .isPresent ()) {
@@ -1068,6 +1070,22 @@ public void copyAsync(DataObject srcData, DataObject dstData, AsyncCompletionCal
10681070 callback .complete (res );
10691071 }
10701072
1073+ private Host getEnabledClusterHost (StoragePool storagePool , List <String > linstorNodeNames ) {
1074+ List <HostVO > csHosts ;
1075+ if (storagePool .getClusterId () != null ) {
1076+ csHosts = _hostDao .findByClusterId (storagePool .getClusterId ());
1077+ } else {
1078+ csHosts = _hostDao .findByDataCenterId (storagePool .getDataCenterId ());
1079+ }
1080+ Collections .shuffle (csHosts ); // so we do not always pick the same host for operations
1081+ for (HostVO host : csHosts ) {
1082+ if (host .getResourceState () == ResourceState .Enabled && linstorNodeNames .contains (host .getName ())) {
1083+ return host ;
1084+ }
1085+ }
1086+ return null ;
1087+ }
1088+
10711089 /**
10721090 * Tries to get a Linstor cloudstack end point, that is at least diskless.
10731091 *
@@ -1076,47 +1094,37 @@ public void copyAsync(DataObject srcData, DataObject dstData, AsyncCompletionCal
10761094 * @return Optional RemoteHostEndPoint if one could get found.
10771095 * @throws ApiException
10781096 */
1079- private Optional <RemoteHostEndPoint > getLinstorEP (DevelopersApi api , String rscName ) throws ApiException {
1097+ private Optional <RemoteHostEndPoint > getLinstorEP (DevelopersApi api , StoragePool storagePool , String rscName )
1098+ throws ApiException {
10801099 List <String > linstorNodeNames = LinstorUtil .getLinstorNodeNames (api );
1081- Collections .shuffle (linstorNodeNames ); // do not always pick the first linstor node
1082-
1083- Host host = null ;
1084- for (String nodeName : linstorNodeNames ) {
1085- host = _hostDao .findByName (nodeName );
1086- if (host != null && host .getResourceState () == ResourceState .Enabled ) {
1087- logger .info (String .format ("Linstor: Make resource %s available on node %s ..." , rscName , nodeName ));
1088- ApiCallRcList answers = api .resourceMakeAvailableOnNode (rscName , nodeName , new ResourceMakeAvailable ());
1089- if (!answers .hasError ()) {
1090- break ; // found working host
1091- } else {
1092- logger .error (
1093- String .format ("Linstor: Unable to make resource %s on node %s available: %s" ,
1094- rscName ,
1095- nodeName ,
1096- LinstorUtil .getBestErrorMessage (answers )));
1097- }
1100+ Host host = getEnabledClusterHost (storagePool , linstorNodeNames );
1101+ if (host != null ) {
1102+ logger .info ("Linstor: Make resource {} available on node {} ..." , rscName , host .getName ());
1103+ ApiCallRcList answers = api .resourceMakeAvailableOnNode (
1104+ rscName , host .getName (), new ResourceMakeAvailable ());
1105+ if (answers .hasError ()) {
1106+ logger .error ("Linstor: Unable to make resource {} on node {} available: {}" ,
1107+ rscName , host .getName (), LinstorUtil .getBestErrorMessage (answers ));
1108+ return Optional .empty ();
1109+ } else {
1110+ return Optional .of (RemoteHostEndPoint .getHypervisorHostEndPoint (host ));
10981111 }
10991112 }
11001113
1101- if (host == null )
1102- {
1103- logger .error ("Linstor: Couldn't create a resource on any cloudstack host." );
1104- return Optional .empty ();
1105- }
1106- else
1107- {
1108- return Optional .of (RemoteHostEndPoint .getHypervisorHostEndPoint (host ));
1109- }
1114+ logger .error ("Linstor: Couldn't create a resource on any cloudstack host." );
1115+ return Optional .empty ();
11101116 }
11111117
1112- private Optional <RemoteHostEndPoint > getDiskfullEP (DevelopersApi api , String rscName ) throws ApiException {
1118+ private Optional <RemoteHostEndPoint > getDiskfullEP (DevelopersApi api , StoragePool storagePool , String rscName )
1119+ throws ApiException {
11131120 List <com .linbit .linstor .api .model .StoragePool > linSPs = LinstorUtil .getDiskfulStoragePools (api , rscName );
11141121 if (linSPs != null ) {
1115- for (com .linbit .linstor .api .model .StoragePool sp : linSPs ) {
1116- Host host = _hostDao .findByName (sp .getNodeName ());
1117- if (host != null && host .getResourceState () == ResourceState .Enabled ) {
1118- return Optional .of (RemoteHostEndPoint .getHypervisorHostEndPoint (host ));
1119- }
1122+ List <String > linstorNodeNames = linSPs .stream ()
1123+ .map (com .linbit .linstor .api .model .StoragePool ::getNodeName )
1124+ .collect (Collectors .toList ());
1125+ Host host = getEnabledClusterHost (storagePool , linstorNodeNames );
1126+ if (host != null ) {
1127+ return Optional .of (RemoteHostEndPoint .getHypervisorHostEndPoint (host ));
11201128 }
11211129 }
11221130 logger .error ("Linstor: No diskfull host found." );
@@ -1197,7 +1205,7 @@ private Answer copyTemplate(DataObject srcData, DataObject dstData) {
11971205 VirtualMachineManager .ExecuteInSequence .value ());
11981206
11991207 try {
1200- Optional <RemoteHostEndPoint > optEP = getLinstorEP (api , rscName );
1208+ Optional <RemoteHostEndPoint > optEP = getLinstorEP (api , pool , rscName );
12011209 if (optEP .isPresent ()) {
12021210 answer = optEP .get ().sendMessage (cmd );
12031211 } else {
@@ -1239,7 +1247,7 @@ private Answer copyVolume(DataObject srcData, DataObject dstData) {
12391247 Answer answer ;
12401248
12411249 try {
1242- Optional <RemoteHostEndPoint > optEP = getLinstorEP (api , rscName );
1250+ Optional <RemoteHostEndPoint > optEP = getLinstorEP (api , pool , rscName );
12431251 if (optEP .isPresent ()) {
12441252 answer = optEP .get ().sendMessage (cmd );
12451253 }
@@ -1277,7 +1285,7 @@ private Answer copyFromTemporaryResource(
12771285 try {
12781286 String devName = restoreResourceFromSnapshot (api , pool , rscName , snapshotName , restoreName );
12791287
1280- Optional <RemoteHostEndPoint > optEPAny = getLinstorEP (api , restoreName );
1288+ Optional <RemoteHostEndPoint > optEPAny = getLinstorEP (api , pool , restoreName );
12811289 if (optEPAny .isPresent ()) {
12821290 // patch the src device path to the temporary linstor resource
12831291 snapshotObject .setPath (devName );
@@ -1346,7 +1354,7 @@ protected Answer copySnapshot(DataObject srcData, DataObject destData) {
13461354 VirtualMachineManager .ExecuteInSequence .value ());
13471355 cmd .setOptions (options );
13481356
1349- Optional <RemoteHostEndPoint > optEP = getDiskfullEP (api , rscName );
1357+ Optional <RemoteHostEndPoint > optEP = getDiskfullEP (api , pool , rscName );
13501358 Answer answer ;
13511359 if (optEP .isPresent ()) {
13521360 answer = optEP .get ().sendMessage (cmd );
0 commit comments