Skip to content

atomic_helper.write_file missing os.fsync() leaves 0-byte files on sudden reboot/power-loss, causing fatal JSONDecodeError in stages.py #7078

Description

@snehadhar-source

os.rename(tf.name, filename)

When a system crashes or is forcefully rebooted (e.g. SIGKILL, hard reset) right after cloud-init writes instance cache files, network-config.json can become a 0-byte file on reboot.
On the next boot, cloud-init crashes on an unhandled JSONDecodeError and fails to initialize networking.

Root Cause

  1. Missing fsync before rename: cloudinit/atomic_helper.py writes to a tempfile and calls os.rename() without tf.flush() or os.fsync(). On filesystems like ext4 (with delayed allocation), rename commits directory metadata to the journal while dirty data remains in volatile RAM. A sudden crash before background writeback leaves an empty file (Size: 0, Blocks: 0).
  2. Missing error handling: cloudinit/stages.py:448 calls util.load_json() without try...except, raising unhandled json.decoder.JSONDecodeError on empty/corrupted cache.

Suggested Fix

  1. cloudinit/atomic_helper.py: Flush and sync before rename:

    tf.write(content)
    tf.flush()
    try:
    os.fsync(tf.fileno())
    except OSError:
    pass
    os.chmod(tf.name, mode)
    os.rename(tf.name, filename)

  2. cloudinit/stages.py: Handle corrupted/empty JSON gracefully

if os.path.isfile(net_cfg_fname):
try:
content = util.load_text_file(net_cfg_fname)
if content:
return util.load_json(content)
except (json.decoder.JSONDecodeError, ValueError) as exc:
LOG.warning("Failed to parse cached network config at %s: %s", net_cfg_fname, exc)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions