Skip to content

Commit

Permalink
zfs-vol: new mode of SR creation with a ZFS vdev specification
Browse files Browse the repository at this point in the history
This will allow management layers to present a suitable UI for the cases
they see fit without having to modify the interface.

Signed-off-by: Yann Dirson <[email protected]>
  • Loading branch information
ydirson committed Mar 27, 2024
1 parent a9a8458 commit 0017bea
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 10 deletions.
37 changes: 29 additions & 8 deletions plugins/volume/org.xen.xapi.storage.zfs-vol/sr.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,35 +25,56 @@ def create(self, dbg, sr_uuid, configuration, name, description):
log.debug('{}: SR.create: config={}, sr_uuid={}'.format(
dbg, configuration, sr_uuid))

# 2 ways to create a SR:
# 3 ways to create a SR:
# - from an existing zpool (manually created for complex configs)
# - from a "device" config string (comma-separated list of devices)
# - from a "vdev" config string (vdev specification suitable for `zfs create`)

if 'zpool' in configuration:
if 'device' in configuration:
log.error('"zpool" specified, "device" should not be used')
raise Exception('"zpool" specified, "device" should not be used')
if 'device' in configuration or 'vdev' in configuration:
log.error('"zpool" specified, "device" or "vdev" should not be used')
raise Exception('"zpool" specified, "device" or "vdev" should not be used')

# FIXME do we reject pools not under MOUNT_ROOT?

# FIXME validate existence of pool first?
pool_name = configuration['zpool']

elif 'device' in configuration:
devs = configuration['device'].split(',')
if 'vdev' in configuration:
log.error('"device" specified, "vdev" should not be used')
raise Exception('"device" specified, "vdev" should not be used')

vdev_defn = configuration['device'].split(',')

pool_name = "sr-{}".format(sr_uuid)
zfsutils.pool_create(dbg, pool_name, devs)
zfsutils.pool_create(dbg, pool_name, vdev_defn)

# "device" is only used once to create the zpool, which
# then becomes the sole way to designate the SR
configuration["orig-device"] = configuration['device']
del configuration['device']
configuration["zpool"] = pool_name

elif 'vdev' in configuration:
vdev_defn = configuration['vdev'].split(' ')
# check no word attempts to play tricks us passing arbitrary options
for word in vdev_defn:
if not (word[0].isalpha() or word[0] == "/"):
raise Exception('"vdev" contain invalid-looking string %r' % (word,))

pool_name = "sr-{}".format(sr_uuid)
zfsutils.pool_create(dbg, pool_name, vdev_defn)

# "vdev" is only used once to create the zpool, which
# then becomes the sole way to designate the SR
configuration["orig-vdev"] = configuration['vdev']
del configuration['vdev']
configuration["zpool"] = pool_name

else:
log.error('devices config must have "zpool" or "device"')
raise Exception('devices config must have "zpool" or "device"')
log.error('devices config must have "zpool", "vdev", or "device"')
raise Exception('devices config must have "zpool", "vdev", or "device"')

# FIXME this assumes zpool is mounted/attached
mountpoint = zfsutils.pool_mountpoint(dbg, pool_name)
Expand Down
4 changes: 2 additions & 2 deletions plugins/volume/org.xen.xapi.storage.zfs-vol/zfsutils.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,10 @@ def pool_mountpoint(dbg, pool_name):
cmd = "zfs get mountpoint -H -o value".split() + [ pool_name ]
return call(dbg, cmd).strip()

def pool_create(dbg, pool_name, devs):
def pool_create(dbg, pool_name, vdev_defn):
cmd = ("zpool create".split() + [pool_name] # FIXME '-f' ?
+ ['-R', MOUNT_ROOT]
+ devs)
+ vdev_defn)
call(dbg, cmd)

def pool_destroy(dbg, pool_name):
Expand Down

0 comments on commit 0017bea

Please sign in to comment.