diff --git a/lib/backend.py b/lib/backend.py index 4b97e9bba69c30cee27411382e824c6b3a6e7490..c6e624d5253bba193afaaf71e89d3294ad743013 100644 --- a/lib/backend.py +++ b/lib/backend.py @@ -1549,7 +1549,7 @@ def GetMigrationStatus(instance): _Fail("Failed to get migration status: %s", err, exc=True) -def BlockdevCreate(disk, size, owner, on_primary, info): +def BlockdevCreate(disk, size, owner, on_primary, info, excl_stor): """Creates a block device for an instance. @type disk: L{objects.Disk} @@ -1564,6 +1564,8 @@ def BlockdevCreate(disk, size, owner, on_primary, info): @type info: string @param info: string that will be sent to the physical device creation, used for example to set (LVM) tags on LVs + @type excl_stor: boolean + @param excl_stor: Whether exclusive_storage is active @return: the new unique_id of the device (this can sometime be computed only after creation), or None. On secondary nodes, @@ -1590,7 +1592,7 @@ def BlockdevCreate(disk, size, owner, on_primary, info): clist.append(crdev) try: - device = bdev.Create(disk, clist) + device = bdev.Create(disk, clist, excl_stor) except errors.BlockDeviceError, err: _Fail("Can't create block device: %s", err) diff --git a/lib/bdev.py b/lib/bdev.py index 8201c267d6501267b36f6d96f0df335e0fa31fcf..0c8ab39a26c9329f523af54c71aca8d84d90be5e 100644 --- a/lib/bdev.py +++ b/lib/bdev.py @@ -290,7 +290,7 @@ class BlockDev(object): raise NotImplementedError @classmethod - def Create(cls, unique_id, children, size, params): + def Create(cls, unique_id, children, size, params, excl_stor): """Create the device. If the device cannot be created, it will return None @@ -524,7 +524,7 @@ class LogicalVolume(BlockDev): self.Attach() @classmethod - def Create(cls, unique_id, children, size, params): + def Create(cls, unique_id, children, size, params, excl_stor): """Create a new logical volume. """ @@ -2181,7 +2181,7 @@ class DRBD8(BaseDRBD): self.Shutdown() @classmethod - def Create(cls, unique_id, children, size, params): + def Create(cls, unique_id, children, size, params, excl_stor): """Create a new DRBD8 device. Since DRBD devices are not created per se, just assembled, this @@ -2190,6 +2190,9 @@ class DRBD8(BaseDRBD): """ if len(children) != 2: raise errors.ProgrammerError("Invalid setup for the drbd device") + if excl_stor: + raise errors.ProgrammerError("DRBD device requested with" + " exclusive_storage") # check that the minor is unused aminor = unique_id[4] proc_info = cls._MassageProcData(cls._GetProcData()) @@ -2355,7 +2358,7 @@ class FileStorage(BlockDev): _ThrowError("Can't stat %s: %s", self.dev_path, err) @classmethod - def Create(cls, unique_id, children, size, params): + def Create(cls, unique_id, children, size, params, excl_stor): """Create a new file. @param size: the size of file in MiB @@ -2364,6 +2367,9 @@ class FileStorage(BlockDev): @return: an instance of FileStorage """ + if excl_stor: + raise errors.ProgrammerError("FileStorage device requested with" + " exclusive_storage") if not isinstance(unique_id, (tuple, list)) or len(unique_id) != 2: raise ValueError("Invalid configuration data %s" % str(unique_id)) @@ -2420,12 +2426,15 @@ class PersistentBlockDevice(BlockDev): self.Attach() @classmethod - def Create(cls, unique_id, children, size, params): + def Create(cls, unique_id, children, size, params, excl_stor): """Create a new device This is a noop, we only return a PersistentBlockDevice instance """ + if excl_stor: + raise errors.ProgrammerError("Persistent block device requested with" + " exclusive_storage") return PersistentBlockDevice(unique_id, children, 0, params) def Remove(self): @@ -2517,7 +2526,7 @@ class RADOSBlockDevice(BlockDev): self.Attach() @classmethod - def Create(cls, unique_id, children, size, params): + def Create(cls, unique_id, children, size, params, excl_stor): """Create a new rbd device. Provision a new rbd volume inside a RADOS pool. @@ -2526,6 +2535,9 @@ class RADOSBlockDevice(BlockDev): if not isinstance(unique_id, (tuple, list)) or len(unique_id) != 2: raise errors.ProgrammerError("Invalid configuration data %s" % str(unique_id)) + if excl_stor: + raise errors.ProgrammerError("RBD device requested with" + " exclusive_storage") rbd_pool = params[constants.LDP_POOL] rbd_name = unique_id[1] @@ -2810,7 +2822,7 @@ class ExtStorageDevice(BlockDev): self.Attach() @classmethod - def Create(cls, unique_id, children, size, params): + def Create(cls, unique_id, children, size, params, excl_stor): """Create a new extstorage device. Provision a new volume using an extstorage provider, which will @@ -2820,6 +2832,9 @@ class ExtStorageDevice(BlockDev): if not isinstance(unique_id, (tuple, list)) or len(unique_id) != 2: raise errors.ProgrammerError("Invalid configuration data %s" % str(unique_id)) + if excl_stor: + raise errors.ProgrammerError("extstorage device requested with" + " exclusive_storage") # Call the External Storage's create script, # to provision a new Volume inside the External Storage @@ -3235,7 +3250,7 @@ def Assemble(disk, children): return device -def Create(disk, children): +def Create(disk, children, excl_stor): """Create a device. @type disk: L{objects.Disk} @@ -3243,10 +3258,12 @@ def Create(disk, children): @type children: list of L{bdev.BlockDev} @param children: the list of block devices that are children of the device represented by the disk parameter + @type excl_stor: boolean + @param excl_stor: Whether exclusive_storage is active """ _VerifyDiskType(disk.dev_type) _VerifyDiskParams(disk) device = DEV_MAP[disk.dev_type].Create(disk.physical_id, children, disk.size, - disk.params) + disk.params, excl_stor) return device diff --git a/lib/cmdlib.py b/lib/cmdlib.py index d023686908bfa801a809997335b5ecdce591cb9e..117a3a2024b784690d02bbb666374ea117130b18 100644 --- a/lib/cmdlib.py +++ b/lib/cmdlib.py @@ -9055,7 +9055,8 @@ def _CreateSingleBlockDev(lu, node, instance, device, info, force_open): """ lu.cfg.SetDiskID(device, node) result = lu.rpc.call_blockdev_create(node, device, device.size, - instance.name, force_open, info) + instance.name, force_open, info, + False) result.Raise("Can't create block device %s on" " node %s for instance %s" % (device, node, instance.name)) if device.physical_id is None: diff --git a/lib/rpc_defs.py b/lib/rpc_defs.py index 20c349a7cb388f28c26f3843156a6c500cabc27e..fc7b3facf5eeea62b8141564da61d579f91c7433 100644 --- a/lib/rpc_defs.py +++ b/lib/rpc_defs.py @@ -332,6 +332,7 @@ _BLOCKDEV_CALLS = [ ("owner", None, None), ("on_primary", None, None), ("info", None, None), + ("exclusive_storage", None, None), ], None, None, "Request creation of a given block device"), ("blockdev_wipe", SINGLE, None, constants.RPC_TMO_SLOW, [ ("bdev", ED_SINGLE_DISK_DICT_DP, None), diff --git a/lib/server/noded.py b/lib/server/noded.py index c6d653c3b0c8f7ef625587edf208940747dc9227..71e8edc323dbebf8825c939cafe58e861bf1bd50 100644 --- a/lib/server/noded.py +++ b/lib/server/noded.py @@ -179,11 +179,12 @@ class NodeRequestHandler(http.server.HttpServerHandler): """Create a block device. """ - bdev_s, size, owner, on_primary, info = params + (bdev_s, size, owner, on_primary, info, excl_stor) = params bdev = objects.Disk.FromDict(bdev_s) if bdev is None: raise ValueError("can't unserialize data!") - return backend.BlockdevCreate(bdev, size, owner, on_primary, info) + return backend.BlockdevCreate(bdev, size, owner, on_primary, info, + excl_stor) @staticmethod def perspective_blockdev_pause_resume_sync(params):