Skip to content

Commit

Permalink
zfs-ng: implement sr-create 1/4: SR.create
Browse files Browse the repository at this point in the history
SR can then be disposed of using "xe sr-forget" and "zpool destroy".

Underlying zpool can be either separately created and given to
SR.create, or a set of devices can be specified to create a new zpool
on.

Notes:
- `SR.attach` will be necessary to complete `sr-create`: while from a
  calling user PoV things appear to have gone fine, SMlog reveals a
  call to `SR.attach`, which naturally failed as not yet implemented.
  Any attempt to `xe pbd-plug` naturally also fails.  See
  xapi-project/xen-api#5532.
- there is no plugin feature to shield from SR.* calls

Originally-by: Matias Ezequiel Vara Larsen <matias.vara@vates.fr>
Signed-off-by: Yann Dirson <yann.dirson@vates.tech>
  • Loading branch information
ydirson committed Mar 26, 2024
1 parent 2d9c8a7 commit 15f6cd8
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 1 deletion.
56 changes: 55 additions & 1 deletion plugins/volume/org.xen.xapi.storage.zfs-ng/sr.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,67 @@
from xapi.storage.libs.libcow.volume import COWVolume
import xapi.storage.api.v5.volume

import zfsutils


@util.decorate_all_routines(util.log_exceptions_in_function)
class Implementation(xapi.storage.api.v5.volume.SR_skeleton):
"SR driver to provide volumes from zvol's"

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:
# - from an existing zpool (manually created for complex configs)
# - from a "devices" config string (comma-separated list of devices)

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

# FIXME do we reject pools not under MOUNT_ROOT?

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

elif 'devices' in configuration:
devs = configuration['devices'].split(',')

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

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

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

# FIXME this assumes zpool is mounted/attached
mountpoint = zfsutils.pool_mountpoint(dbg, pool_name)
importlib.import_module('zfs-ng').Callbacks().create_database(mountpoint)

meta = {
'name': name,
'description': description,
'uuid': sr_uuid,
}
util.update_sr_metadata(dbg, 'file://' + mountpoint, meta)

log.debug('{}: SR.create: sr={}'.format(dbg, mountpoint))
return configuration


if __name__ == '__main__':
log.log_call_argv()
cmd = xapi.storage.api.v5.volume.SR_commandline(Implementation())
base = os.path.basename(sys.argv[0])
raise xapi.storage.api.v5.volume.Unimplemented(base)
if base == 'SR.create':
cmd.create()
else:
raise xapi.storage.api.v5.volume.Unimplemented(base)
15 changes: 15 additions & 0 deletions plugins/volume/org.xen.xapi.storage.zfs-ng/zfsutils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import os

from xapi.storage.common import call

MOUNT_ROOT = '/var/run/sr-mount'

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):
cmd = ("zpool create".split() + [pool_name] # FIXME '-f' ?
+ ['-R', MOUNT_ROOT]
+ devs)
call(dbg, cmd)

0 comments on commit 15f6cd8

Please sign in to comment.