in azurelinuxagent/daemon/resourcedisk/default.py [0:0]
def mkfile(self, filename, nbytes):
"""
Create a non-sparse file of that size. Deletes and replaces existing
file.
To allow efficient execution, fallocate will be tried first. This
includes
``os.posix_fallocate`` on Python 3.3+ (unix) and the ``fallocate``
command
in the popular ``util-linux{,-ng}`` package.
A dd fallback will be tried too. When size < 64M, perform
single-pass dd.
Otherwise do two-pass dd.
"""
if not isinstance(nbytes, int):
nbytes = int(nbytes)
if nbytes <= 0:
raise ResourceDiskError("Invalid swap size [{0}]".format(nbytes))
if os.path.isfile(filename):
os.remove(filename)
# If file system is xfs, use dd right away as we have been reported that
# swap enabling fails in xfs fs when disk space is allocated with
# fallocate
ret = 0
fn_sh = shellutil.quote((filename,))
if self.fs not in ['xfs', 'ext4']:
# os.posix_fallocate
if sys.version_info >= (3, 3):
# Probable errors:
# - OSError: Seen on Cygwin, libc notimpl?
# - AttributeError: What if someone runs this under...
fd = None
try:
fd = os.open(
filename,
os.O_CREAT | os.O_WRONLY | os.O_EXCL,
stat.S_IRUSR | stat.S_IWUSR)
os.posix_fallocate(fd, 0, nbytes) # pylint: disable=no-member
return 0
except BaseException:
# Not confident with this thing, just keep trying...
pass
finally:
if fd is not None:
os.close(fd)
# fallocate command
ret = shellutil.run(
u"umask 0077 && fallocate -l {0} {1}".format(nbytes, fn_sh))
if ret == 0:
return ret
logger.info("fallocate unsuccessful, falling back to dd")
# dd fallback
dd_maxbs = 64 * 1024 ** 2
dd_cmd = "umask 0077 && dd if=/dev/zero bs={0} count={1} " \
"conv=notrunc of={2}"
blocks = int(nbytes / dd_maxbs)
if blocks > 0:
ret = shellutil.run(dd_cmd.format(dd_maxbs, blocks, fn_sh)) << 8
remains = int(nbytes % dd_maxbs)
if remains > 0:
ret += shellutil.run(dd_cmd.format(remains, 1, fn_sh))
if ret == 0:
logger.info("dd successful")
else:
logger.error("dd unsuccessful")
return ret