Skip to content

Commit

Permalink
zfs-ng: implement volume-create 2/2: Volume.create
Browse files Browse the repository at this point in the history
Note that if Volume.set were not implemented yet (or indeed cannot
complete and returns an error), we face xapi-project/xen-api#5530: if
the Volume.set call fails (to add the vdi-type=user custom-key
record), then the VDI object is not created (though, as this happens
after Volume.create, the zvol and DB entries were indeed created and
there suppression was not requested by SMAPI after the error).  But
since all the VDI information that count are here, "xe sr-scan" will
bring those VDI to life (after implementation of SR.ls).

Originally-by: Matias Ezequiel Vara Larsen <[email protected]>
Signed-off-by: Yann Dirson <[email protected]>
  • Loading branch information
ydirson committed Mar 26, 2024
1 parent 43bce71 commit 0768c33
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 1 deletion.
1 change: 1 addition & 0 deletions plugins/volume/org.xen.xapi.storage.zfs-ng/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ def query(self, dbg):
"version": "3.0",
"required_api_version": "5.0",
"features": [
"VDI_CREATE",
],
"configuration": {},
"required_cluster_stack": []}
Expand Down
39 changes: 38 additions & 1 deletion plugins/volume/org.xen.xapi.storage.zfs-ng/volume.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,55 @@
from xapi.storage.libs.libcow.volume_implementation import Implementation as \
DefaultImplementation

import zfsutils

@util.decorate_all_routines(util.log_exceptions_in_function)
class Implementation(DefaultImplementation):
"Volume driver to provide volumes from zvol's"

def create(self, dbg, sr, name, description, size, sharable):
meta = util.get_sr_metadata(dbg, 'file://' + sr)
pool_name = meta["zpool"]

with VolumeContext(self.callbacks, sr, 'w') as opq:
# FIXME how should we choose image format?
image_type = ImageFormat.IMAGE_RAW
image_format = ImageFormat.get_format(image_type)
vdi_uuid = str(uuid.uuid4())

with PollLock(opq, 'gl', self.callbacks, 0.5):
with self.callbacks.db_context(opq) as db:
volume = db.insert_new_volume(size, image_type)
db.insert_vdi(
name, description, vdi_uuid, volume.id, sharable)
path = zfsutils.zvol_path(pool_name, volume.id)
zfsutils.vol_create(dbg, path, size)

vdi_uri = self.callbacks.getVolumeUriPrefix(opq) + vdi_uuid

return {
'key': vdi_uuid, # FIXME check this
'uuid': vdi_uuid,
'name': name,
'description': description,
'read_write': True,
'virtual_size': size,
'physical_utilisation': size, # FIXME - incidently psize gets null in the db
'uri': [image_format.uri_prefix + vdi_uri],
'sharable': False,
'keys': {}
}

def call_volume_command():
"""Parse the arguments and call the required command"""
log.log_call_argv()
fsp = importlib.import_module("zfs-ng")
cmd = xapi.storage.api.v5.volume.Volume_commandline(
Implementation(fsp.Callbacks()))
base = os.path.basename(sys.argv[0])
if base == "Volume.set":
if base == "Volume.create":
cmd.create()
elif base == "Volume.set":
cmd.set()
elif base == "Volume.unset":
cmd.unset()
Expand Down
3 changes: 3 additions & 0 deletions plugins/volume/org.xen.xapi.storage.zfs-ng/zfs-ng.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,6 @@

class Callbacks(xapi.storage.libs.libcow.callbacks.Callbacks):
"ZFS-ng callbacks"

def getVolumeUriPrefix(self, opq):
return "zfs-ng/" + opq + "|"
11 changes: 11 additions & 0 deletions plugins/volume/org.xen.xapi.storage.zfs-ng/zfsutils.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@

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

def zvol_path(pool_name, vol_id):
return "{}/{}".format(pool_name, vol_id)

###

def pool_mountpoint(dbg, pool_name):
cmd = "zfs get mountpoint -H -o value".split() + [ pool_name ]
return call(dbg, cmd).strip()
Expand All @@ -27,3 +32,9 @@ def pool_get_free_space(dbg, sr_path):
# size is returned in bytes
cmd = "zpool get -Hp -o value free".split() + [ sr_path ]
return int(call(dbg, cmd))

def vol_create(dbg, zvol_path, size_mib):
cmd = ("zfs create".split() + [zvol_path]
+ ['-V', str(size_mib)]
)
call(dbg, cmd)

0 comments on commit 0768c33

Please sign in to comment.