diff --git a/api/src/com/cloud/api/commands/CreateStorageNetworkIpRangeCmd.java b/api/src/com/cloud/api/commands/CreateStorageNetworkIpRangeCmd.java index b9ecee00cf9..5d26e1a17ea 100755 --- a/api/src/com/cloud/api/commands/CreateStorageNetworkIpRangeCmd.java +++ b/api/src/com/cloud/api/commands/CreateStorageNetworkIpRangeCmd.java @@ -19,7 +19,7 @@ import com.cloud.exception.ResourceAllocationException; import com.cloud.exception.ResourceUnavailableException; import com.cloud.user.Account; -@Implementation(description="Creates a VLAN IP range.", responseObject=StorageNetworkIpRangeResponse.class) +@Implementation(description="Creates a Storage network IP range.", responseObject=StorageNetworkIpRangeResponse.class) public class CreateStorageNetworkIpRangeCmd extends BaseAsyncCmd { public static final Logger s_logger = Logger.getLogger(CreateStorageNetworkIpRangeCmd.class); @@ -29,27 +29,23 @@ public class CreateStorageNetworkIpRangeCmd extends BaseAsyncCmd { //////////////// API parameters ///////////////////// ///////////////////////////////////////////////////// @IdentityMapper(entityTableName="host_pod_ref") - @Parameter(name=ApiConstants.POD_ID, type=CommandType.LONG, description="optional parameter. Have to be specified for Direct Untagged vlan only.") + @Parameter(name=ApiConstants.POD_ID, type=CommandType.LONG, description="UUID of pod where the ip range belongs to") private Long podId; - @Parameter(name=ApiConstants.START_IP, type=CommandType.STRING, required=true, description="the beginning IP address in the VLAN IP range") + @Parameter(name=ApiConstants.START_IP, type=CommandType.STRING, required=true, description="the beginning IP address") private String startIp; - @Parameter(name=ApiConstants.END_IP, type=CommandType.STRING, description="the ending IP address in the VLAN IP range") + @Parameter(name=ApiConstants.END_IP, type=CommandType.STRING, description="the ending IP address") private String endIp; - @Parameter(name=ApiConstants.VLAN, type=CommandType.INTEGER, description="the ID or VID of the VLAN. Optional, null means no vlan") + @Parameter(name=ApiConstants.VLAN, type=CommandType.INTEGER, description="Optional. the vlan the ip range sits on") private Integer vlan; @IdentityMapper(entityTableName="data_center") - @Parameter(name=ApiConstants.ZONE_ID, type=CommandType.LONG, description="the Zone ID of the VLAN IP range") + @Parameter(name=ApiConstants.ZONE_ID, type=CommandType.LONG, description="The uuid of zone") private Long zoneId; - - @IdentityMapper(entityTableName="networks") - @Parameter(name=ApiConstants.NETWORK_ID, type=CommandType.LONG, description="the network id") - private Long networkID; - - @Parameter(name=ApiConstants.NETMASK, type=CommandType.STRING, required=true, description="the netmask for the Pod") + + @Parameter(name=ApiConstants.NETMASK, type=CommandType.STRING, required=true, description="the netmask for storage network") private String netmask; ///////////////////////////////////////////////////// @@ -75,11 +71,7 @@ public class CreateStorageNetworkIpRangeCmd extends BaseAsyncCmd { public Long getZoneId() { return zoneId; } - - public Long getNetworkID() { - return networkID; - } - + public String getNetmask() { return netmask; } diff --git a/api/src/com/cloud/api/commands/DeleteStorageNetworkIpRangeCmd.java b/api/src/com/cloud/api/commands/DeleteStorageNetworkIpRangeCmd.java index 8aa1addd952..f73c3084be1 100755 --- a/api/src/com/cloud/api/commands/DeleteStorageNetworkIpRangeCmd.java +++ b/api/src/com/cloud/api/commands/DeleteStorageNetworkIpRangeCmd.java @@ -29,7 +29,7 @@ public class DeleteStorageNetworkIpRangeCmd extends BaseAsyncCmd { ///////////////////////////////////////////////////// @IdentityMapper(entityTableName="dc_storage_network_ip_range") - @Parameter(name=ApiConstants.ID, type=CommandType.LONG, required=true, description="the storage network IP range ID") + @Parameter(name=ApiConstants.ID, type=CommandType.LONG, required=true, description="the uuid of the storage network ip range") private Long id; ///////////////////////////////////////////////////// diff --git a/api/src/com/cloud/api/commands/listStorageNetworkIpRangeCmd.java b/api/src/com/cloud/api/commands/listStorageNetworkIpRangeCmd.java index 7dd832a534b..af0984433d6 100755 --- a/api/src/com/cloud/api/commands/listStorageNetworkIpRangeCmd.java +++ b/api/src/com/cloud/api/commands/listStorageNetworkIpRangeCmd.java @@ -34,15 +34,15 @@ public class listStorageNetworkIpRangeCmd extends BaseAsyncCmd { ///////////////////////////////////////////////////// @IdentityMapper(entityTableName="dc_storage_network_ip_range") - @Parameter(name=ApiConstants.ID, type=CommandType.LONG, description="optional parameter. Storaget network IP range id, if specicied, using it to search the range.") + @Parameter(name=ApiConstants.ID, type=CommandType.LONG, description="optional parameter. Storaget network IP range uuid, if specicied, using it to search the range.") private Long rangeId; @IdentityMapper(entityTableName="host_pod_ref") - @Parameter(name=ApiConstants.POD_ID, type=CommandType.LONG, description="optional parameter. Pod id, if specicied and range id is absent, using it to search the range.") + @Parameter(name=ApiConstants.POD_ID, type=CommandType.LONG, description="optional parameter. Pod uuid, if specicied and range uuid is absent, using it to search the range.") private Long podId; @IdentityMapper(entityTableName="data_center") - @Parameter(name=ApiConstants.ZONE_ID, type=CommandType.LONG, description="optional parameter. Zone id, if specicied and both pod id and range id are absent, using it to search the range.") + @Parameter(name=ApiConstants.ZONE_ID, type=CommandType.LONG, description="optional parameter. Zone uuid, if specicied and both pod uuid and range uuid are absent, using it to search the range.") private Long zoneId; ///////////////////////////////////////////////////// diff --git a/api/src/com/cloud/api/response/StorageNetworkIpRangeResponse.java b/api/src/com/cloud/api/response/StorageNetworkIpRangeResponse.java index 27988e2b80c..8491674a2f1 100755 --- a/api/src/com/cloud/api/response/StorageNetworkIpRangeResponse.java +++ b/api/src/com/cloud/api/response/StorageNetworkIpRangeResponse.java @@ -6,14 +6,14 @@ import com.cloud.serializer.Param; import com.google.gson.annotations.SerializedName; public class StorageNetworkIpRangeResponse extends BaseResponse { - @SerializedName(ApiConstants.VLAN) @Param(description="the ID of storage network IP range.") - private Long id; + @SerializedName(ApiConstants.VLAN) @Param(description="the uuid of storage network IP range.") + private String uuid; @SerializedName(ApiConstants.VLAN) @Param(description="the ID or VID of the VLAN.") private Integer vlan; - @SerializedName(ApiConstants.POD_ID) @Param(description="the Pod ID for the VLAN IP range") - private IdentityProxy podId = new IdentityProxy("host_pod_ref"); + @SerializedName(ApiConstants.POD_ID) @Param(description="the Pod uuid for the VLAN IP range") + private String podUuid; @SerializedName(ApiConstants.START_IP) @Param(description="the start ip of the VLAN IP range") private String startIp; @@ -21,26 +21,26 @@ public class StorageNetworkIpRangeResponse extends BaseResponse { @SerializedName(ApiConstants.END_IP) @Param(description="the end ip of the VLAN IP range") private String endIp; - @SerializedName(ApiConstants.NETWORK_ID) @Param(description="the network id of vlan range") - private IdentityProxy networkId = new IdentityProxy("networks"); + @SerializedName(ApiConstants.NETWORK_ID) @Param(description="the network uuid of vlan range") + private String networkUuid; - @SerializedName(ApiConstants.ZONE_ID) @Param(description="the Zone ID of the VLAN IP range") - private IdentityProxy zoneId = new IdentityProxy("data_center"); + @SerializedName(ApiConstants.ZONE_ID) @Param(description="the Zone uuid of the VLAN IP range") + private String zoneUuid; - public void setId(Long id) { - this.id = id; + public void setUuid(String uuId) { + this.uuid = uuid; } - public void setZoneId(Long zoneId) { - this.zoneId.setValue(zoneId); + public void setZoneUuid(String zoneUuid) { + this.zoneUuid = zoneUuid; } public void setVlan(Integer vlan) { this.vlan = vlan; } - public void setPodId(Long podId) { - this.podId.setValue(podId); + public void setPodUuid(String podUuid) { + this.podUuid = podUuid; } public void setStartIp(String startIp) { @@ -51,7 +51,7 @@ public class StorageNetworkIpRangeResponse extends BaseResponse { this.endIp = endIp; } - public void setNetworkId(Long networkId) { - this.networkId.setValue(networkId); + public void setNetworkUuid(String networkUuid) { + this.networkUuid = networkUuid; } } diff --git a/api/src/com/cloud/dc/StorageNetworkIpRange.java b/api/src/com/cloud/dc/StorageNetworkIpRange.java index 663eb3e4e8f..b5042dbd52d 100755 --- a/api/src/com/cloud/dc/StorageNetworkIpRange.java +++ b/api/src/com/cloud/dc/StorageNetworkIpRange.java @@ -1,17 +1,17 @@ package com.cloud.dc; public interface StorageNetworkIpRange { - long getId(); + String getUuid(); - int getVlan(); + Integer getVlan(); - long getPodId(); + String getPodUuid(); String getStartIp(); String getEndIp(); - long getNetworkId(); + String getNetworkUuid(); - long getDataCenterId(); + String getZoneUuid(); } diff --git a/api/src/com/cloud/network/Networks.java b/api/src/com/cloud/network/Networks.java old mode 100644 new mode 100755 index 3bffc6f9b7a..3ad532c4583 --- a/api/src/com/cloud/network/Networks.java +++ b/api/src/com/cloud/network/Networks.java @@ -61,6 +61,7 @@ public class Networks { Vswitch("vs", String.class), LinkLocal(null, null), Vnet("vnet", Long.class), + Storage("storage", Integer.class), UnDecided(null, null); private String scheme; diff --git a/client/tomcatconf/commands.properties.in b/client/tomcatconf/commands.properties.in index 5801bf6f851..1ce70f7bc31 100755 --- a/client/tomcatconf/commands.properties.in +++ b/client/tomcatconf/commands.properties.in @@ -317,3 +317,10 @@ addTrafficType=com.cloud.api.commands.AddTrafficTypeCmd;1 deleteTrafficType=com.cloud.api.commands.DeleteTrafficTypeCmd;1 listTrafficTypes=com.cloud.api.commands.ListTrafficTypesCmd;1 updateTrafficType=com.cloud.api.commands.UpdateTrafficTypeCmd;1 + +#### Storage Network commands +createStorageNetworkIpRange=com.cloud.api.commands.CreateStorageNetworkIpRangeCmd;1 +deleteStorageNetworkIpRange=com.cloud.api.commands.DeleteStorageNetworkIpRangeCmd;1 +listStorageNetworkIpRange=com.cloud.api.commands.listStorageNetworkIpRangeCmd;1 + + diff --git a/client/tomcatconf/components.xml.in b/client/tomcatconf/components.xml.in index fe00bf51d61..03cc7d45934 100755 --- a/client/tomcatconf/components.xml.in +++ b/client/tomcatconf/components.xml.in @@ -59,6 +59,7 @@ + diff --git a/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java b/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java index e65401ba37e..9c73da315a8 100755 --- a/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java +++ b/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java @@ -650,6 +650,14 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe long account = Long.parseLong(nic.getBroadcastUri().getHost()); return createTunnelNetwork(conn, account); } + } else if (nic.getBroadcastType() == BroadcastDomainType.Storage) { + URI broadcastUri = nic.getBroadcastUri(); + if (broadcastUri == null) { + return network.getNetwork(); + } else { + long vlan = Long.parseLong(broadcastUri.getHost()); + return enableVlanNetwork(conn, vlan, network); + } } throw new CloudRuntimeException("Unable to support this type of network broadcast domain: " + nic.getBroadcastUri()); diff --git a/patches/systemvm/debian/config/etc/init.d/cloud-early-config b/patches/systemvm/debian/config/etc/init.d/cloud-early-config index 580ab149c5e..abbfb8cd5ca 100755 --- a/patches/systemvm/debian/config/etc/init.d/cloud-early-config +++ b/patches/systemvm/debian/config/etc/init.d/cloud-early-config @@ -589,10 +589,26 @@ setup_dhcpsrvr() { fi } +setup_storage_network() { + if [ x"$STORAGE_IP" == "x" -o x"$STORAGE_NETMASK" == "x" ] + then + log_it "Incompleted parameters STORAGE_IP:$STORAGE_IP, STORAGE_NETMASK:$STORAGE_NETMASK, STORAGE_CIDR:$STORAGE_CIDR. Cannot setup storage network" + return + fi + + echo "" >> /etc/network/interfaces + echo "auto eth3" >> /etc/network/interfaces + + setup_interface "3" "$STORAGE_IP" "$STORAGE_NETMASK" + #ip route add "$STORAGE_CIDR" via "$STORAGE_IP" + log_it "Successfully setup storage network with STORAGE_IP:$STORAGE_IP, STORAGE_NETMASK:$STORAGE_NETMASK, STORAGE_CIDR:$STORAGE_CIDR" +} + setup_secstorage() { log_it "Setting up secondary storage system vm" local hyp=$1 setup_common eth0 eth1 eth2 + setup_storage_network [ -n "$MTU" ] && ifconfig eth1 mtu $MTU sed -i /gateway/d /etc/hosts public_ip=$ETH2_IP @@ -719,6 +735,9 @@ CMDLINE=$(cat /var/cache/cloud/cmdline) TYPE="unknown" BOOTPROTO="static" DISABLE_RP_FILTER="false" +STORAGE_IP="" +STORAGE_NETMASK="" +STORAGE_CIDR="" for i in $CMDLINE do @@ -787,8 +806,8 @@ for i in $CMDLINE SSHONGUEST=$VALUE ;; name) - NAME=$VALUE - ;; + NAME=$VALUE + ;; dhcprange) DHCP_RANGE=$(echo $VALUE | tr ':' ',') ;; @@ -797,7 +816,7 @@ for i in $CMDLINE ;; type) TYPE=$VALUE - ;; + ;; defaultroute) DEFAULTROUTE=$VALUE ;; @@ -825,6 +844,15 @@ for i in $CMDLINE mtu) MTU=$VALUE ;; + storageip) + STORAGE_IP=$VALUE + ;; + storagenetmask) + STORAGE_NETMASK=$VALUE + ;; + storagecidr) + STORAGE_CIDR=$VALUE + ;; esac done } diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java index 211792fe01d..807a8d8c146 100755 --- a/server/src/com/cloud/api/ApiResponseHelper.java +++ b/server/src/com/cloud/api/ApiResponseHelper.java @@ -3241,13 +3241,13 @@ public class ApiResponseHelper implements ResponseGenerator { @Override public StorageNetworkIpRangeResponse createStorageNetworkIpRangeResponse(StorageNetworkIpRange result) { StorageNetworkIpRangeResponse response = new StorageNetworkIpRangeResponse(); - response.setId(result.getId()); + response.setUuid(result.getUuid()); response.setVlan(result.getVlan()); response.setEndIp(result.getEndIp()); response.setStartIp(result.getStartIp()); - response.setPodId(result.getPodId()); - response.setZoneId(result.getDataCenterId()); - response.setNetworkId(result.getNetworkId()); + response.setPodUuid(result.getPodUuid()); + response.setZoneUuid(result.getZoneUuid()); + response.setNetworkUuid(result.getNetworkUuid()); return response; } } diff --git a/server/src/com/cloud/configuration/DefaultComponentLibrary.java b/server/src/com/cloud/configuration/DefaultComponentLibrary.java index d1b1e4b1c30..cb963993982 100755 --- a/server/src/com/cloud/configuration/DefaultComponentLibrary.java +++ b/server/src/com/cloud/configuration/DefaultComponentLibrary.java @@ -55,6 +55,8 @@ import com.cloud.dc.dao.DataCenterIpAddressDaoImpl; import com.cloud.dc.dao.DcDetailsDaoImpl; import com.cloud.dc.dao.HostPodDaoImpl; import com.cloud.dc.dao.PodVlanMapDaoImpl; +import com.cloud.dc.dao.StorageNetworkIpAddressDaoImpl; +import com.cloud.dc.dao.StorageNetworkIpRangeDaoImpl; import com.cloud.dc.dao.VlanDaoImpl; import com.cloud.domain.dao.DomainDaoImpl; import com.cloud.event.dao.EventDaoImpl; @@ -71,6 +73,7 @@ import com.cloud.keystore.KeystoreManagerImpl; import com.cloud.maint.UpgradeManagerImpl; import com.cloud.maint.dao.AgentUpgradeDaoImpl; import com.cloud.network.NetworkManagerImpl; +import com.cloud.network.StorageNetworkManagerImpl; import com.cloud.network.dao.ExternalFirewallDeviceDaoImpl; import com.cloud.network.dao.ExternalLoadBalancerDeviceDaoImpl; import com.cloud.network.dao.FirewallRulesCidrsDaoImpl; @@ -327,6 +330,8 @@ public class DefaultComponentLibrary extends ComponentLibraryBase implements Com addDao("NetworkExternalFirewallDao", NetworkExternalFirewallDaoImpl.class); addDao("PhysicalNetworkTrafficTypeDao", PhysicalNetworkTrafficTypeDaoImpl.class); addDao("NetworkServiceMapDao", NetworkServiceMapDaoImpl.class); + addDao("StorageNetworkIpAddressDao", StorageNetworkIpAddressDaoImpl.class); + addDao("StorageNetworkIpRangeDao", StorageNetworkIpRangeDaoImpl.class); } @Override @@ -382,6 +387,7 @@ public class DefaultComponentLibrary extends ComponentLibraryBase implements Com addManager("ProjectManager", ProjectManagerImpl.class); addManager("ElasticLoadBalancerManager", ElasticLoadBalancerManagerImpl.class); addManager("SwiftManager", SwiftManagerImpl.class); + addManager("StorageNetworkManager", StorageNetworkManagerImpl.class); } @Override diff --git a/server/src/com/cloud/dc/StorageNetworkIpAddressVO.java b/server/src/com/cloud/dc/StorageNetworkIpAddressVO.java index b2b43dbec41..ff00d1b80a4 100755 --- a/server/src/com/cloud/dc/StorageNetworkIpAddressVO.java +++ b/server/src/com/cloud/dc/StorageNetworkIpAddressVO.java @@ -7,6 +7,9 @@ import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; +import javax.persistence.PrimaryKeyJoinColumn; +import javax.persistence.SecondaryTable; +import javax.persistence.SecondaryTables; import javax.persistence.Table; import javax.persistence.Temporal; import javax.persistence.TemporalType; @@ -15,6 +18,7 @@ import com.cloud.network.IpAddress.State; @Entity @Table(name="op_dc_storage_network_ip_address") +@SecondaryTables({@SecondaryTable(name = "dc_storage_network_ip_range", pkJoinColumns = { @PrimaryKeyJoinColumn(name = "range_id", referencedColumnName = "id")})}) public class StorageNetworkIpAddressVO { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @@ -36,6 +40,9 @@ public class StorageNetworkIpAddressVO { @Column(name = "mac_address") long mac; + + @Column(name = "vlan", table = "dc_storage_network_ip_range", insertable = false, updatable = false) + Integer vlan; protected StorageNetworkIpAddressVO() { } @@ -83,4 +90,8 @@ public class StorageNetworkIpAddressVO { public void setCidrSize(int cidr) { this.cidrSize =cidr; } + + public Integer getVlan() { + return vlan; + } } diff --git a/server/src/com/cloud/dc/StorageNetworkIpRangeVO.java b/server/src/com/cloud/dc/StorageNetworkIpRangeVO.java index a89aff28560..1d53859f6c3 100755 --- a/server/src/com/cloud/dc/StorageNetworkIpRangeVO.java +++ b/server/src/com/cloud/dc/StorageNetworkIpRangeVO.java @@ -1,22 +1,34 @@ package com.cloud.dc; +import java.util.UUID; + import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; +import javax.persistence.PrimaryKeyJoinColumn; +import javax.persistence.SecondaryTable; +import javax.persistence.SecondaryTables; import javax.persistence.Table; @Entity @Table(name="dc_storage_network_ip_range") +@SecondaryTables({@SecondaryTable(name="networks", pkJoinColumns={@PrimaryKeyJoinColumn(name="network_id", referencedColumnName="id")}), + @SecondaryTable(name="host_pod_ref", pkJoinColumns={@PrimaryKeyJoinColumn(name="pod_id", referencedColumnName="id")}), + @SecondaryTable(name="data_center", pkJoinColumns={@PrimaryKeyJoinColumn(name="data_center_id", referencedColumnName="id")}), +}) public class StorageNetworkIpRangeVO implements StorageNetworkIpRange { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id") private long id; + @Column(name = "uuid") + String uuid; + @Column(name = "vlan") - private int vlan; + private Integer vlan; @Column(name = "data_center_id") private long dataCenterId; @@ -33,7 +45,17 @@ public class StorageNetworkIpRangeVO implements StorageNetworkIpRange { @Column(name = "network_id") private long networkId; - public StorageNetworkIpRangeVO(long dcId, long podId, long networkId, String startIp, String endIp, int vlan) { + @Column(name = "uuid", table = "networks", insertable = false, updatable = false) + String networkUuid; + + @Column(name = "uuid", table = "host_pod_ref", insertable = false, updatable = false) + String podUuid; + + @Column(name = "uuid", table = "data_center", insertable = false, updatable = false) + String zoneUuid; + + public StorageNetworkIpRangeVO(long dcId, long podId, long networkId, String startIp, String endIp, Integer vlan) { + this(); this.dataCenterId = dcId; this.podId = podId; this.networkId = networkId; @@ -43,7 +65,7 @@ public class StorageNetworkIpRangeVO implements StorageNetworkIpRange { } protected StorageNetworkIpRangeVO() { - + this.uuid = UUID.randomUUID().toString(); } public long getId() { @@ -74,7 +96,7 @@ public class StorageNetworkIpRangeVO implements StorageNetworkIpRange { this.networkId = nwId; } - public int getVlan() { + public Integer getVlan() { return vlan; } @@ -93,8 +115,28 @@ public class StorageNetworkIpRangeVO implements StorageNetworkIpRange { public void setEndIp(String end) { this.endIp = end; } - + public String getEndIp() { return endIp; } + + @Override + public String getUuid() { + return uuid; + } + + @Override + public String getPodUuid() { + return podUuid; + } + + @Override + public String getNetworkUuid() { + return networkUuid; + } + + @Override + public String getZoneUuid() { + return zoneUuid; + } } diff --git a/server/src/com/cloud/dc/dao/StorageNetworkIpAddressDaoImpl.java b/server/src/com/cloud/dc/dao/StorageNetworkIpAddressDaoImpl.java index 531713e37e7..50e17b517e2 100755 --- a/server/src/com/cloud/dc/dao/StorageNetworkIpAddressDaoImpl.java +++ b/server/src/com/cloud/dc/dao/StorageNetworkIpAddressDaoImpl.java @@ -33,13 +33,13 @@ public class StorageNetworkIpAddressDaoImpl extends GenericDaoBase listByPodId(long podId); List listByDataCenterId(long dcId); + + long countRanges(); } diff --git a/server/src/com/cloud/dc/dao/StorageNetworkIpRangeDaoImpl.java b/server/src/com/cloud/dc/dao/StorageNetworkIpRangeDaoImpl.java index 26bc0682988..aef63aac17f 100755 --- a/server/src/com/cloud/dc/dao/StorageNetworkIpRangeDaoImpl.java +++ b/server/src/com/cloud/dc/dao/StorageNetworkIpRangeDaoImpl.java @@ -3,9 +3,11 @@ package com.cloud.dc.dao; import java.util.List; import java.util.Map; +import javax.ejb.Local; import javax.naming.ConfigurationException; import com.cloud.dc.StorageNetworkIpRangeVO; +import com.cloud.utils.db.DB; import com.cloud.utils.db.Filter; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.GenericSearchBuilder; @@ -13,10 +15,20 @@ import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.SearchCriteria2; import com.cloud.utils.db.SearchCriteriaService; +import com.cloud.utils.db.SearchCriteria.Func; import com.cloud.utils.db.SearchCriteria.Op; +@Local(value={StorageNetworkIpRangeDao.class}) +@DB(txn=false) public class StorageNetworkIpRangeDaoImpl extends GenericDaoBase implements StorageNetworkIpRangeDao { - + protected final GenericSearchBuilder countRanges; + + protected StorageNetworkIpRangeDaoImpl() { + countRanges = createSearchBuilder(Long.class); + countRanges.select(null, Func.COUNT, null); + countRanges.done(); + } + @Override public List listByPodId(long podId) { SearchCriteriaService sc = SearchCriteria2.create(StorageNetworkIpRangeVO.class); @@ -37,5 +49,11 @@ public class StorageNetworkIpRangeDaoImpl extends GenericDaoBase sc = countRanges.create(); + return customSearch(sc, null).get(0); + } } diff --git a/server/src/com/cloud/network/StorageNetworkManager.java b/server/src/com/cloud/network/StorageNetworkManager.java index 03ad6c05f00..cfe851baaa0 100755 --- a/server/src/com/cloud/network/StorageNetworkManager.java +++ b/server/src/com/cloud/network/StorageNetworkManager.java @@ -8,5 +8,5 @@ public interface StorageNetworkManager extends Manager { void releaseIpAddress(String ip); - boolean isAStorageIpAddress(String ip); + boolean isStorageIpRangeAvailable(); } diff --git a/server/src/com/cloud/network/StorageNetworkManagerImpl.java b/server/src/com/cloud/network/StorageNetworkManagerImpl.java index 0d47e31ad31..172927d96e0 100755 --- a/server/src/com/cloud/network/StorageNetworkManagerImpl.java +++ b/server/src/com/cloud/network/StorageNetworkManagerImpl.java @@ -91,7 +91,7 @@ public class StorageNetworkManagerImpl implements StorageNetworkManager, Storage List curRanges = _sNwIpRangeDao.listByPodId(podId); for (StorageNetworkIpRangeVO range : curRanges) { if (NetUtils.ipRangesOverlap(startIp, endIp, range.getStartIp(), range.getEndIp())) { - throw new InvalidParameterValueException("The Storage network Start IP and endIP address range overlap with private IP :" + range.getStartIp() + ":" + range.getEndIp()); + throw new InvalidParameterValueException("The Storage network Start IP and endIP address range overlap with private IP :" + range.getStartIp() + " - " + range.getEndIp()); } } } @@ -180,7 +180,7 @@ public class StorageNetworkManagerImpl implements StorageNetworkManager, Storage StringBuilder res = new StringBuilder(); res.append("Below IP of range " + rangeId + " is still in use:"); for (String ip : ips) { - res.append(ip); + res.append(ip).append(","); } return res.toString(); } @@ -269,10 +269,8 @@ public class StorageNetworkManagerImpl implements StorageNetworkManager, Storage } @Override - public boolean isAStorageIpAddress(String ip) { - SearchCriteriaService sc = SearchCriteria2.create(StorageNetworkIpAddressVO.class); - sc.addAnd(sc.getEntity().getIpAddress(), Op.EQ, ip); - return sc.find() == null ? false : true; + public boolean isStorageIpRangeAvailable() { + return _sNwIpRangeDao.countRanges() > 0; } } diff --git a/server/src/com/cloud/network/guru/PodBasedNetworkGuru.java b/server/src/com/cloud/network/guru/PodBasedNetworkGuru.java old mode 100644 new mode 100755 index b2e2281c8ae..851507f98c9 --- a/server/src/com/cloud/network/guru/PodBasedNetworkGuru.java +++ b/server/src/com/cloud/network/guru/PodBasedNetworkGuru.java @@ -40,6 +40,7 @@ import com.cloud.network.Networks.AddressFormat; import com.cloud.network.Networks.BroadcastDomainType; import com.cloud.network.Networks.Mode; import com.cloud.network.Networks.TrafficType; +import com.cloud.network.StorageNetworkManager; import com.cloud.offering.NetworkOffering; import com.cloud.user.Account; import com.cloud.utils.Pair; @@ -58,6 +59,7 @@ import com.cloud.vm.VirtualMachineProfile; public class PodBasedNetworkGuru extends AdapterBase implements NetworkGuru { private static final Logger s_logger = Logger.getLogger(PodBasedNetworkGuru.class); @Inject DataCenterDao _dcDao; + @Inject StorageNetworkManager _sNwMgr; Random _rand = new Random(System.currentTimeMillis()); @Override @@ -68,6 +70,11 @@ public class PodBasedNetworkGuru extends AdapterBase implements NetworkGuru { return null; } + if (type == TrafficType.Storage && _sNwMgr.isStorageIpRangeAvailable()) { + s_logger.debug("There is some storage ip available, let StorageNetworkGuru to handle storage traffic type, not me"); + return null; + } + NetworkVO config = new NetworkVO(type, Mode.Static, BroadcastDomainType.Native, offering.getId(), Network.State.Setup, plan.getDataCenterId(), plan.getPhysicalNetworkId()); return config; } @@ -84,7 +91,7 @@ public class PodBasedNetworkGuru extends AdapterBase implements NetworkGuru { public NicProfile allocate(Network config, NicProfile nic, VirtualMachineProfile vm) throws InsufficientVirtualNetworkCapcityException, InsufficientAddressCapacityException { TrafficType trafficType = config.getTrafficType(); - assert (trafficType == TrafficType.Storage || trafficType == TrafficType.Management) : "Well, I can't take care of this config now can I? " + config; + assert trafficType == TrafficType.Management || trafficType == TrafficType.Storage: "Well, I can't take care of this config now can I? " + config; if (nic != null) { if (nic.getRequestedIp() != null) { diff --git a/server/src/com/cloud/network/guru/StorageNetworkGuru.java b/server/src/com/cloud/network/guru/StorageNetworkGuru.java index 6dd468c10ab..46ac9ae852e 100755 --- a/server/src/com/cloud/network/guru/StorageNetworkGuru.java +++ b/server/src/com/cloud/network/guru/StorageNetworkGuru.java @@ -37,7 +37,6 @@ import com.cloud.vm.Nic.ReservationStrategy; public class StorageNetworkGuru extends AdapterBase implements NetworkGuru { private static final Logger s_logger = Logger.getLogger(StorageNetworkGuru.class); @Inject StorageNetworkManager _sNwMgr; - @Inject DataCenterDao _dcDao; protected StorageNetworkGuru() { super(); @@ -45,7 +44,12 @@ public class StorageNetworkGuru extends AdapterBase implements NetworkGuru { protected boolean canHandle(NetworkOffering offering) { if (offering.getTrafficType() == TrafficType.Storage && offering.isSystemOnly()) { - return true; + if (_sNwMgr.isStorageIpRangeAvailable()) { + return true; + } else { + s_logger.debug("No storage network ip range availabe, let PodBasedNetworkGuru to handle storage traffic type, not me"); + return false; + } } else { s_logger.trace("It's not storage network offering, skip it."); return false; @@ -93,48 +97,32 @@ public class StorageNetworkGuru extends AdapterBase implements NetworkGuru { public void reserve(NicProfile nic, Network network, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context) throws InsufficientVirtualNetworkCapcityException, InsufficientAddressCapacityException, ConcurrentOperationException { Pod pod = dest.getPod(); - String ipAddress = null; - Long macLong = null; - Integer cidrSize = null; + Integer vlan = null; StorageNetworkIpAddressVO ip = _sNwMgr.acquireIpAddress(pod.getId()); - if (ip != null) { - ipAddress = ip.getIpAddress(); - macLong = ip.getMac(); - cidrSize = ip.getCidrSize(); - } else { - s_logger.debug("Can not get an ip from storage network ip range for pod " + pod.getId() + ", acquire one from managment ip range"); - /* Pick up an ip from management ip range if there is no available in storage ip range because of either user not added it or run out of */ - Pairip1 = _dcDao.allocatePrivateIpAddress(dest.getDataCenter().getId(), pod.getId(), nic.getId(), - context.getReservationId()); - if (ip1 == null) { - throw new InsufficientAddressCapacityException("Unable to get a storage network ip address", Pod.class, pod.getId()); - } - ipAddress = ip1.first(); - macLong = ip1.second(); - cidrSize = pod.getCidrSize(); + if (ip == null) { + throw new InsufficientAddressCapacityException("Unable to get a storage network ip address", Pod.class, pod.getId()); } - - nic.setIp4Address(ipAddress); - nic.setMacAddress(NetUtils.long2Mac(NetUtils.createSequenceBasedMacAddress(macLong))); + + vlan = ip.getVlan(); + nic.setIp4Address(ip.getIpAddress()); + nic.setMacAddress(NetUtils.long2Mac(NetUtils.createSequenceBasedMacAddress(ip.getMac()))); nic.setFormat(AddressFormat.Ip4); - nic.setNetmask(NetUtils.getCidrNetmask(cidrSize)); - nic.setBroadcastType(BroadcastDomainType.Native); - nic.setBroadcastUri(null); + nic.setNetmask(NetUtils.getCidrNetmask(ip.getCidrSize())); + nic.setBroadcastType(BroadcastDomainType.Storage); + if (vlan != null) { + nic.setBroadcastUri(BroadcastDomainType.Storage.toUri(vlan)); + } else { + nic.setBroadcastUri(null); + } nic.setIsolationUri(null); - s_logger.debug("Allocated a nic " + nic + " for " + vm); + s_logger.debug("Allocated a storage nic " + nic + " for " + vm); } @Override public boolean release(NicProfile nic, VirtualMachineProfile vm, String reservationId) { - if (_sNwMgr.isAStorageIpAddress(nic.getIp4Address())) { - _sNwMgr.releaseIpAddress(nic.getIp4Address()); - s_logger.debug("Release an storage ip " + nic.getIp4Address()); - } else { - _dcDao.releasePrivateIpAddress(nic.getId(), nic.getReservationId()); - s_logger.debug("Release an storage ip that is from managment ip range " + nic.getIp4Address()); - } - + _sNwMgr.releaseIpAddress(nic.getIp4Address()); + s_logger.debug("Release an storage ip " + nic.getIp4Address()); nic.deallocate(); return true; } diff --git a/server/src/com/cloud/server/ConfigurationServerImpl.java b/server/src/com/cloud/server/ConfigurationServerImpl.java index 9969d784679..3642a5026cd 100755 --- a/server/src/com/cloud/server/ConfigurationServerImpl.java +++ b/server/src/com/cloud/server/ConfigurationServerImpl.java @@ -79,6 +79,7 @@ import com.cloud.network.guru.ControlNetworkGuru; import com.cloud.network.guru.DirectPodBasedNetworkGuru; import com.cloud.network.guru.PodBasedNetworkGuru; import com.cloud.network.guru.PublicNetworkGuru; +import com.cloud.network.guru.StorageNetworkGuru; import com.cloud.offering.NetworkOffering; import com.cloud.offering.NetworkOffering.Availability; import com.cloud.offerings.NetworkOfferingServiceMapVO; @@ -953,7 +954,7 @@ public class ConfigurationServerImpl implements ConfigurationServer { guruNames.put(TrafficType.Public, PublicNetworkGuru.class.getSimpleName()); guruNames.put(TrafficType.Management, PodBasedNetworkGuru.class.getSimpleName()); guruNames.put(TrafficType.Control, ControlNetworkGuru.class.getSimpleName()); - guruNames.put(TrafficType.Storage, PodBasedNetworkGuru.class.getSimpleName()); + guruNames.put(TrafficType.Storage, StorageNetworkGuru.class.getSimpleName()); guruNames.put(TrafficType.Guest, DirectPodBasedNetworkGuru.class.getSimpleName()); for (DataCenterVO zone : zones) { @@ -978,7 +979,7 @@ public class ConfigurationServerImpl implements ConfigurationServer { TrafficType trafficType= offering.getTrafficType(); boolean isNetworkDefault = false; - if (trafficType == TrafficType.Management || trafficType == TrafficType.Storage) { + if (trafficType == TrafficType.Management) { broadcastDomainType = BroadcastDomainType.Native; } else if (trafficType == TrafficType.Control) { broadcastDomainType = BroadcastDomainType.LinkLocal; @@ -997,6 +998,8 @@ public class ConfigurationServerImpl implements ConfigurationServer { } networkDomain = "cs" + Long.toHexString(Account.ACCOUNT_ID_SYSTEM) + _domainSuffix; + } else if (offering.getTrafficType() == TrafficType.Storage) { + broadcastDomainType = BroadcastDomainType.Storage; } if (broadcastDomainType != null) { diff --git a/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java b/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java index f8d11f7133c..9c8b2a3d42c 100755 --- a/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java +++ b/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java @@ -525,7 +525,7 @@ public class SecondaryStorageManagerImpl implements SecondaryStorageVmManager, V NetworkVO defaultNetwork = defaultNetworks.get(0); - List offerings = _networkMgr.getSystemAccountNetworkOfferings(NetworkOfferingVO.SystemControlNetwork, NetworkOfferingVO.SystemManagementNetwork); + List offerings = _networkMgr.getSystemAccountNetworkOfferings(NetworkOfferingVO.SystemControlNetwork, NetworkOfferingVO.SystemManagementNetwork, NetworkOfferingVO.SystemStorageNetwork); List> networks = new ArrayList>(offerings.size() + 1); NicProfile defaultNic = new NicProfile(); defaultNic.setDefaultNic(true); @@ -1034,6 +1034,9 @@ public class SecondaryStorageManagerImpl implements SecondaryStorageVmManager, V buf.append(" private.network.device=").append("eth").append(deviceId); } else if (nic.getTrafficType() == TrafficType.Public) { buf.append(" public.network.device=").append("eth").append(deviceId); + } else if (nic.getTrafficType() == TrafficType.Storage) { + buf.append(" storageip=").append(nic.getIp4Address()); + buf.append(" storagenetmask=").append(nic.getNetmask()); } } diff --git a/setup/db/create-schema.sql b/setup/db/create-schema.sql index 98dd28ad86e..40c32e9df69 100755 --- a/setup/db/create-schema.sql +++ b/setup/db/create-schema.sql @@ -562,29 +562,29 @@ CREATE TABLE `cloud`.`op_dc_link_local_ip_address_alloc` ( CREATE TABLE `cloud`.`dc_storage_network_ip_range` ( `id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT, + `uuid` varchar(40), `start_ip` char(40) NOT NULL COMMENT 'start ip address', `end_ip` char(40) NOT NULL COMMENT 'end ip address', `vlan` int unsigned DEFAULT NULL COMMENT 'vlan the storage network on', `data_center_id` bigint unsigned NOT NULL, + `pod_id` bigint unsigned NOT NULL COMMENT 'pod it belongs to', `network_id` bigint unsigned NOT NULL COMMENT 'id of corresponding network offering', PRIMARY KEY (`id`), CONSTRAINT `fk_storage_ip_range__network_id` FOREIGN KEY (`network_id`) REFERENCES `networks`(`id`), CONSTRAINT `fk_storage_ip_range__data_center_id` FOREIGN KEY (`data_center_id`) REFERENCES `data_center`(`id`), - CONSTRAINT `fk_storage_ip_range___network_id` FOREIGN KEY (`physical_network_id`) REFERENCES `physical_network`(`id`) - CONSTRAINT `uc_vlan__uuid` UNIQUE (`uuid`), + CONSTRAINT `fk_storage_ip_range__pod_id` FOREIGN KEY (`pod_id`) REFERENCES `host_pod_ref`(`id`), + CONSTRAINT `uc_storage_ip_range__uuid` UNIQUE (`uuid`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; CREATE TABLE `cloud`.`op_dc_storage_network_ip_address` ( `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'primary key', `range_id` bigint unsigned NOT NULL COMMENT 'id of ip range in dc_storage_network_ip_range', - `pod_id` bigint unsigned NOT NULL COMMENT 'pod it belongs to', `ip_address` char(40) NOT NULL COMMENT 'ip address', `mac_address` bigint unsigned NOT NULL COMMENT 'mac address for storage ips', `cidr_size` int unsigned NOT NULL COMMENT 'CIDR size for storage network', `taken` datetime COMMENT 'Date taken', PRIMARY KEY (`id`), - CONSTRAINT `fk_storage_ip_address__range_id` FOREIGN KEY (`range_id`) REFERENCES `dc_storage_network_ip_range`(`id`) ON DELETE CASCADE, - CONSTRAINT `fk_storage_ip_address__pod_id` FOREIGN KEY (`pod_id`) REFERENCES `host_pod_ref`(`id`), + CONSTRAINT `fk_storage_ip_address__range_id` FOREIGN KEY (`range_id`) REFERENCES `dc_storage_network_ip_range`(`id`) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8; CREATE TABLE `cloud`.`host_pod_ref` (