Comment 1 for bug 1962150

Revision history for this message
Adam Collard (adam-collard) wrote (last edit ):

Reading the code - https://github.com/canonical/cloud-init/blob/main/cloudinit/cmd/status.py#L141-L144 - , the status command tries to guard against the file not existing, but clearly this run slipped through - the file existed when we os.path.exists() it, but not when we open() it :|

Looking deeper, we can see that cmd.main.status_wrapper atomically writes JSON (yay!) to the 'data_d' (/var/lib/cloud/data) then symlinks that status file in the 'link_d' (/run/cloud-init). All seems reasonable, but let's look at how it does that symlinking:

https://github.com/canonical/cloud-init/blob/main/cloudinit/cmd/main.py#L755-L758

Note the `force=True`, and refer to the implementation of sym_link:

https://github.com/canonical/cloud-init/blob/2837b835f101d81704f018a4f872b1d660eb6f3e/cloudinit/util.py#L1887-L1891

.. which deletes the symlink, then re-creates it.

This is non-atomic and entirely possible for readers (such as `--wait`) to see the entry in the FS, before it gets deleted, the deletion to occur and then open it.