diff --git a/lib/cmdlib.py b/lib/cmdlib.py
index 82f9a297a42bff718d19b64a4746516ca7cefa94..1528c848b7878a9059413772130ef957d1ebcb88 100644
--- a/lib/cmdlib.py
+++ b/lib/cmdlib.py
@@ -7713,6 +7713,52 @@ class LUInstanceCreate(LogicalUnit):
     if self.op.identify_defaults:
       self._RevertToDefaults(cluster)
 
+    # disk checks/pre-build
+    self.disks = []
+    for disk in self.op.disks:
+      mode = disk.get("mode", constants.DISK_RDWR)
+      if mode not in constants.DISK_ACCESS_SET:
+        raise errors.OpPrereqError("Invalid disk access mode '%s'" %
+                                   mode, errors.ECODE_INVAL)
+      size = disk.get("size", None)
+      if size is None:
+        raise errors.OpPrereqError("Missing disk size", errors.ECODE_INVAL)
+      try:
+        size = int(size)
+      except (TypeError, ValueError):
+        raise errors.OpPrereqError("Invalid disk size '%s'" % size,
+                                   errors.ECODE_INVAL)
+      vg = disk.get("vg", self.cfg.GetVGName())
+      new_disk = {"size": size, "mode": mode, "vg": vg}
+      if "adopt" in disk:
+        new_disk["adopt"] = disk["adopt"]
+      self.disks.append(new_disk)
+
+    #### allocator run
+    # We run the iallocator here, so that we can use the primary node
+    # together with the network link for IP address reservation
+
+    if self.op.iallocator is not None:
+      self._RunAllocator()
+
+    #### node related checks
+
+    # check primary node
+    self.pnode = pnode = self.cfg.GetNodeInfo(self.op.pnode)
+    assert self.pnode is not None, \
+      "Cannot retrieve locked node %s" % self.op.pnode
+    if pnode.offline:
+      raise errors.OpPrereqError("Cannot use offline primary node '%s'" %
+                                 pnode.name, errors.ECODE_STATE)
+    if pnode.drained:
+      raise errors.OpPrereqError("Cannot use drained primary node '%s'" %
+                                 pnode.name, errors.ECODE_STATE)
+    if not pnode.vm_capable:
+      raise errors.OpPrereqError("Cannot use non-vm_capable primary node"
+                                 " '%s'" % pnode.name, errors.ECODE_STATE)
+
+    self.secondaries = []
+
     # NIC buildup
     self.nics = []
     for idx, nic in enumerate(self.op.nics):
@@ -7756,21 +7802,21 @@ class LUInstanceCreate(LogicalUnit):
                                      errors.ECODE_INVAL)
         nic_ip = self.hostname1.ip
         try:
-          self.cfg.ReserveIp(link, nic_ip, self.proc.GetECId())
+          self.cfg.ReserveIp(self.pnode.name, link, nic_ip, self.proc.GetECId())
         except errors.ReservationError:
           raise errors.OpPrereqError("IP address %s already in use"
                                      " in cluster" % nic_ip,
                                      errors.ECODE_NOTUNIQUE)
       elif ip.lower() == constants.NIC_IP_POOL:
-        nic_ip = self.cfg.GenerateIp(link, self.proc.GetECId())
-        logging.info("Chose ip %s from pool %s" % (nic_ip, link))
+        nic_ip = self.cfg.GenerateIp(self.pnode.name, link, self.proc.GetECId())
+        self.LogInfo("Chose IP %s from pool %s", nic_ip, link)
       else:
         if not netutils.IPAddress.IsValid(ip):
           raise errors.OpPrereqError("Invalid IP address '%s'" % ip,
                                      errors.ECODE_INVAL)
         nic_ip = ip
         try:
-          self.cfg.ReserveIp(link, nic_ip, self.proc.GetECId())
+          self.cfg.ReserveIp(self.pnode.name, link, nic_ip, self.proc.GetECId())
         except errors.ReservationError:
           raise errors.OpPrereqError("IP address %s already in use"
                                      " in cluster" % nic_ip,
@@ -7819,6 +7865,25 @@ class LUInstanceCreate(LogicalUnit):
         new_disk["adopt"] = disk["adopt"]
       self.disks.append(new_disk)
 
+    # ip ping checks (we use the same ip that was resolved in ExpandNames)
+    if self.op.ip_check:
+      if netutils.TcpPing(self.check_ip, constants.DEFAULT_NODED_PORT):
+        raise errors.OpPrereqError("IP %s of instance %s already in use" %
+                                   (self.check_ip, self.op.instance_name),
+                                   errors.ECODE_NOTUNIQUE)
+
+    #### mac address generation
+    # By generating here the mac address both the allocator and the hooks get
+    # the real final mac address rather than the 'auto' or 'generate' value.
+    # There is a race condition between the generation and the instance object
+    # creation, which means that we know the mac is valid now, but we're not
+    # sure it will be when we actually add the instance. If things go bad
+    # adding the instance will abort because of a duplicate mac, and the
+    # creation job will fail.
+    for nic in self.nics:
+      if nic.mac in (constants.VALUE_AUTO, constants.VALUE_GENERATE):
+        nic.mac = self.cfg.GenerateMAC(self.proc.GetECId())
+
     if self.op.mode == constants.INSTANCE_IMPORT:
 
       # Check that the new instance doesn't have less disks than the export
@@ -7858,48 +7923,6 @@ class LUInstanceCreate(LogicalUnit):
 
     # ENDIF: self.op.mode == constants.INSTANCE_IMPORT
 
-    # ip ping checks (we use the same ip that was resolved in ExpandNames)
-    if self.op.ip_check:
-      if netutils.TcpPing(self.check_ip, constants.DEFAULT_NODED_PORT):
-        raise errors.OpPrereqError("IP %s of instance %s already in use" %
-                                   (self.check_ip, self.op.instance_name),
-                                   errors.ECODE_NOTUNIQUE)
-
-    #### mac address generation
-    # By generating here the mac address both the allocator and the hooks get
-    # the real final mac address rather than the 'auto' or 'generate' value.
-    # There is a race condition between the generation and the instance object
-    # creation, which means that we know the mac is valid now, but we're not
-    # sure it will be when we actually add the instance. If things go bad
-    # adding the instance will abort because of a duplicate mac, and the
-    # creation job will fail.
-    for nic in self.nics:
-      if nic.mac in (constants.VALUE_AUTO, constants.VALUE_GENERATE):
-        nic.mac = self.cfg.GenerateMAC(self.proc.GetECId())
-
-    #### allocator run
-
-    if self.op.iallocator is not None:
-      self._RunAllocator()
-
-    #### node related checks
-
-    # check primary node
-    self.pnode = pnode = self.cfg.GetNodeInfo(self.op.pnode)
-    assert self.pnode is not None, \
-      "Cannot retrieve locked node %s" % self.op.pnode
-    if pnode.offline:
-      raise errors.OpPrereqError("Cannot use offline primary node '%s'" %
-                                 pnode.name, errors.ECODE_STATE)
-    if pnode.drained:
-      raise errors.OpPrereqError("Cannot use drained primary node '%s'" %
-                                 pnode.name, errors.ECODE_STATE)
-    if not pnode.vm_capable:
-      raise errors.OpPrereqError("Cannot use non-vm_capable primary node"
-                                 " '%s'" % pnode.name, errors.ECODE_STATE)
-
-    self.secondaries = []
-
     # mirror node verification
     if self.op.disk_template in constants.DTS_INT_MIRROR:
       if self.op.snode == pnode.name:
diff --git a/lib/config.py b/lib/config.py
index b58d4eec10623f085471f3adfbd55c2977d0b873..d5e981c42cba9e79814228fc993ac6c7d947b1fa 100644
--- a/lib/config.py
+++ b/lib/config.py
@@ -1234,9 +1234,12 @@ class ConfigWriter:
         raise errors.ConfigurationError("Cannot add instance %s:"
                                         " MAC address '%s' already in use." %
                                         (instance.name, nic.mac))
-      # Commit all IP addresses to the respective address pools
-      self._UnlockedCommitIp(nic.nicparams.get(constants.NIC_LINK, None),
-                             nic.ip)
+      link = nic.nicparams.get(constants.NIC_LINK, None)
+      net_uuid = self._UnlockedGetNetworkFromNodeLink(instance.primary_node,
+                                                      link)
+      if net_uuid:
+        # Commit all IP addresses to the respective address pools
+        self._UnlockedCommitIp(net_uuid, nic.ip)
 
     self._EnsureUUID(instance, ec_id)
 
@@ -1291,10 +1294,17 @@ class ConfigWriter:
     """
     if instance_name not in self._config_data.instances:
       raise errors.ConfigurationError("Unknown instance '%s'" % instance_name)
-    for nic in self._config_data.instances[instance_name].nics:
-      # Return all IP addresses to the respective address pools
-      self._UnlockedReleaseIp(nic.nicparams.get(constants.NIC_LINK, None),
-                              nic.ip)
+
+    instance = self._UnlockedGetInstanceInfo(instance_name)
+
+    for nic in instance.nics:
+      link = nic.nicparams.get(constants.NIC_LINK, None)
+      net_uuid = self._UnlockedGetNetworkFromNodeLink(instance.primary_node,
+                                                      link)
+      if net_uuid:
+        # Return all IP addresses to the respective address pools
+        self._UnlockedReleaseIp(net_uuid, nic.ip)
+
     del self._config_data.instances[instance_name]
     self._config_data.cluster.serial_no += 1
     self._WriteConfig()