1010
1111import errno
1212import os
13+ import re
1314import stat
1415from logging import Logger
1516from textwrap import dedent
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
@@ -123,6 +125,15 @@ def _can_skip_resize_ufs(mount_point, devpth):
123125 return False
124126
125127
128+ def _can_skip_resize_zfs (zpool , devpth ):
129+ try :
130+ (out , _err ) = subp .subp (['zpool' , 'get' , '-Hp' , '-o' , 'value' ,
131+ 'expandsz' , zpool ])
132+ return out .strip () == '-'
133+ except subp .ProcessExecutionError as e :
134+ return False
135+
136+
126137# Do not use a dictionary as these commands should be able to be used
127138# for multiple filesystem types if possible, e.g. one command for
128139# ext2, ext3 and ext4.
@@ -135,7 +146,10 @@ def _can_skip_resize_ufs(mount_point, devpth):
135146 ("hammer2" , _resize_hammer2 ),
136147]
137148
138- RESIZE_FS_PRECHECK_CMDS = {"ufs" : _can_skip_resize_ufs }
149+ RESIZE_FS_PRECHECK_CMDS = {
150+ "ufs" : _can_skip_resize_ufs ,
151+ "zfs" : _can_skip_resize_zfs ,
152+ }
139153
140154
141155def can_skip_resize (fs_type , resize_what , devpth ):
@@ -258,7 +272,12 @@ def handle(
258272 info = "dev=%s mnt_point=%s path=%s" % (devpth , mount_point , resize_what )
259273 log .debug ("resize_info: %s" % info )
260274
261- devpth = maybe_get_writable_device_path (devpth , info , log )
275+ if util .is_illumos () and fs_type == 'zfs' :
276+ # On illumos ZFS, the devices are just bare words like 'c0t0d0'
277+ # which can be used directly as arguments for the resize.
278+ pass
279+ else :
280+ devpth = maybe_get_writable_device_path (devpth , info , log )
262281 if not devpth :
263282 return # devpath was not a writable block device
264283
0 commit comments