1111import errno
1212import logging
1313import os
14+ import re
1415import stat
1516from textwrap import dedent
1617
2021from cloudinit .config .schema import MetaSchema , get_meta_doc
2122from cloudinit .distros import ALL_DISTROS
2223from cloudinit .settings import PER_ALWAYS
24+ from cloudinit import temp_utils
2325
2426NOBLOCK = "noblock"
2527
@@ -130,6 +132,15 @@ def _can_skip_resize_ufs(mount_point, devpth):
130132 return False
131133
132134
135+ def _can_skip_resize_zfs (zpool , devpth ):
136+ try :
137+ (out , _err ) = subp .subp (['zpool' , 'get' , '-Hp' , '-o' , 'value' ,
138+ 'expandsz' , zpool ])
139+ return out .strip () == '-'
140+ except subp .ProcessExecutionError as e :
141+ return False
142+
143+
133144# Do not use a dictionary as these commands should be able to be used
134145# for multiple filesystem types if possible, e.g. one command for
135146# ext2, ext3 and ext4.
@@ -143,7 +154,10 @@ def _can_skip_resize_ufs(mount_point, devpth):
143154 ("bcachefs" , _resize_bcachefs ),
144155]
145156
146- RESIZE_FS_PRECHECK_CMDS = {"ufs" : _can_skip_resize_ufs }
157+ RESIZE_FS_PRECHECK_CMDS = {
158+ "ufs" : _can_skip_resize_ufs ,
159+ "zfs" : _can_skip_resize_zfs ,
160+ }
147161
148162
149163def can_skip_resize (fs_type , resize_what , devpth ):
@@ -267,7 +281,12 @@ def handle(name: str, cfg: Config, cloud: Cloud, args: list) -> None:
267281 info = "dev=%s mnt_point=%s path=%s" % (devpth , mount_point , resize_what )
268282 LOG .debug ("resize_info: %s" , info )
269283
270- devpth = maybe_get_writable_device_path (devpth , info )
284+ if util .is_illumos () and fs_type == 'zfs' :
285+ # On illumos ZFS, the devices are just bare words like 'c0t0d0'
286+ # which can be used directly as arguments for the resize.
287+ pass
288+ else :
289+ devpth = maybe_get_writable_device_path (devpth , info )
271290 if not devpth :
272291 return # devpath was not a writable block device
273292
0 commit comments