2222import subprocess
2323import os
2424import stat
25+ import sys
26+ import time
2527import tempfile
2628from cloudinit .CloudConfig import per_always
2729
@@ -34,15 +36,14 @@ def handle(_name, cfg, _cloud, log, args):
3436 if str (args [0 ]).lower () in ['true' , '1' , 'on' , 'yes' ]:
3537 resize_root = True
3638 else :
37- resize_root = util .get_cfg_option_bool (cfg , "resize_rootfs" , True )
39+ resize_root = util .get_cfg_option_str (cfg , "resize_rootfs" , True )
3840
39- if not resize_root :
41+ if str ( resize_root ). lower () in [ 'false' , '0' ] :
4042 return
4143
42- # this really only uses the filename from mktemp, then we mknod into it
43- (fd , devpth ) = tempfile .mkstemp ()
44- os .unlink (devpth )
45- os .close (fd )
44+ # we use mktemp rather than mkstemp because early in boot nothing
45+ # else should be able to race us for this, and we need to mknod.
46+ devpth = tempfile .mktemp (prefix = "cloudinit.resizefs." , dir = "/run" )
4647
4748 try :
4849 st_dev = os .stat ("/" ).st_dev
@@ -65,9 +66,6 @@ def handle(_name, cfg, _cloud, log, args):
6566 os .unlink (devpth )
6667 raise
6768
68- log .debug ("resizing root filesystem (type=%s, maj=%i, min=%i)" %
69- (str (fstype ).rstrip ("\n " ), os .major (st_dev ), os .minor (st_dev )))
70-
7169 if str (fstype ).startswith ("ext" ):
7270 resize_cmd = ['resize2fs' , devpth ]
7371 elif fstype == "xfs" :
@@ -77,7 +75,28 @@ def handle(_name, cfg, _cloud, log, args):
7775 log .debug ("not resizing unknown filesystem %s" % fstype )
7876 return
7977
78+ if resize_root == "noblock" :
79+ fid = os .fork ()
80+ if fid == 0 :
81+ try :
82+ do_resize (resize_cmd , devpth , log )
83+ os ._exit (0 ) # pylint: disable=W0212
84+ except Exception as exc :
85+ sys .stderr .write ("Failed: %s" % exc )
86+ os ._exit (1 ) # pylint: disable=W0212
87+ else :
88+ do_resize (resize_cmd , devpth , log )
89+
90+ log .debug ("resizing root filesystem (type=%s, maj=%i, min=%i, val=%s)" %
91+ (str (fstype ).rstrip ("\n " ), os .major (st_dev ), os .minor (st_dev ),
92+ resize_root ))
93+
94+ return
95+
96+
97+ def do_resize (resize_cmd , devpth , log ):
8098 try :
99+ start = time .time ()
81100 util .subp (resize_cmd )
82101 except subprocess .CalledProcessError as e :
83102 log .warn ("Failed to resize filesystem (%s)" % resize_cmd )
@@ -86,4 +105,4 @@ def handle(_name, cfg, _cloud, log, args):
86105 raise
87106
88107 os .unlink (devpth )
89- return
108+ log . debug ( "resize took %s seconds" % ( time . time () - start ))
0 commit comments