)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"2a90189f10540caad47eb8813434f4af323e380f","unresolved":true,"context_lines":[{"line_number":14,"context_line":"causing swap.exists() to incorrectly return True and skip swap"},{"line_number":15,"context_line":"disk creation."},{"line_number":16,"context_line":""},{"line_number":17,"context_line":"Use os.open() with O_CREAT|O_EXCL to force a server-side lookup"},{"line_number":18,"context_line":"that bypasses the NFS client attribute cache before checking swap"},{"line_number":19,"context_line":"file existence. If the file does not actually exist, the probe"},{"line_number":20,"context_line":"file is immediately removed so that the NFS client cache is"},{"line_number":21,"context_line":"updated for subsequent os.path.exists() calls."},{"line_number":22,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":2,"id":"2fcc3395_952bd19a","line":19,"range":{"start_line":17,"start_character":0,"end_line":19,"end_character":16},"updated":"2026-05-19 17:44:49.000000000","message":"per https://man7.org/linux/man-pages/man2/open.2.html\n\nO_EXCL will raise an error if the file exists and is present on \nNFSv3 or later on kernel 2.6 or later. which in 2026 is ok for us eot assume\n\nthere is a callout fo rthe fact there will be a race if this is not supproted\n```\nIn NFS environments where O_EXCL\n              support is not provided, programs that rely on it for\n              performing locking tasks will contain a race condition.\n```\n\nbut we recommend nfs v4+ anyway as a basae lien ideally 4.2+\nso i feel like this is ok.,","commit_id":"390e48655a6f85f6add3dd24c72ce360b2bc8361"}],"/PATCHSET_LEVEL":[{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"0511abf1dac19671858ffce7635bf1d5e46d256e","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":3,"id":"ddb1fc12_66fced0d","updated":"2026-06-01 20:27:02.000000000","message":"+W with caveats :)","commit_id":"8936778c7e52e9aee476db92111e51171f3a5268"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"3b668bfa43aef86b3462510705c828b146224f72","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":3,"id":"6890365d_7a8ea76c","updated":"2026-06-01 23:09:19.000000000","message":"recheck ERROR tempest.lib.common.ssh paramiko.ssh_exception.NoValidConnectionsError: [Errno None] Unable to connect to port 22 on 172.24.5.111\n\nSeems guest booting too slowly based on how far it got in its console log","commit_id":"8936778c7e52e9aee476db92111e51171f3a5268"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"95b6fc8b8c9ff6b207f13d25d3415de5aaec73ff","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":3,"id":"58504996_149e01c4","updated":"2026-06-04 02:30:26.000000000","message":"recheck [instance: 87c4bcd5-c24d-4ce5-9e2d-2a5548811100] Live Migration failure: unable to connect to server at \u0027np635f12ee4def4:49152\u0027: Connection refused: libvirt.libvirtError: unable to connect to server at \u0027np635f12ee4def4:49152\u0027: Connection refused","commit_id":"8936778c7e52e9aee476db92111e51171f3a5268"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"6161fe8239766c68758a7c86f38461766cb938ba","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":3,"id":"a31bc578_1ac71e68","updated":"2026-06-02 16:19:00.000000000","message":"recheck guest SSH timeouts ... again?","commit_id":"8936778c7e52e9aee476db92111e51171f3a5268"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"f1d9f61dba27f3545973b4352928c40e98c9527a","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":3,"id":"a82d441f_a902ae73","updated":"2026-06-03 01:45:22.000000000","message":"recheck guest kernel panic","commit_id":"8936778c7e52e9aee476db92111e51171f3a5268"}],"nova/tests/unit/virt/libvirt/test_driver.py":[{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"9023cc3a121909ccb4c8e6eeac0a4a6217e8f020","unresolved":false,"context_lines":[{"line_number":17810,"context_line":"            size\u003dexpected * units.Mi, context\u003dself.context, swap_mb\u003dexpected,"},{"line_number":17811,"context_line":"            safe\u003dTrue)"},{"line_number":17812,"context_line":""},{"line_number":17813,"context_line":"    @mock.patch(\u0027os.open\u0027,"},{"line_number":17814,"context_line":"                side_effect\u003dOSError(errno.EEXIST, \u0027File exists\u0027))"},{"line_number":17815,"context_line":"    def test_refresh_nfs_swap_cache_file_exists(self, mock_open):"},{"line_number":17816,"context_line":"        \"\"\"O_CREAT|O_EXCL returns EEXIST: swap file truly exists.\"\"\""},{"line_number":17817,"context_line":"        libvirt_driver.LibvirtDriver._refresh_nfs_swap_cache(\u0027/swap\u0027)"}],"source_content_type":"text/x-python","patch_set":2,"id":"30dad604_f070bc7c","line":17814,"range":{"start_line":17813,"start_character":3,"end_line":17814,"end_character":65},"updated":"2026-05-19 17:52:59.000000000","message":"we may want to consdier usign mock.mock_open instead but i think this will likely work in this case.  we are not actully mockgn the open builtin function we are mockign the open function in the os module so i think this is correct.","commit_id":"390e48655a6f85f6add3dd24c72ce360b2bc8361"}],"nova/virt/libvirt/driver.py":[{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"2a90189f10540caad47eb8813434f4af323e380f","unresolved":true,"context_lines":[{"line_number":5066,"context_line":"        nova.privsep.fs.unprivileged_mkfs(\u0027swap\u0027, target)"},{"line_number":5067,"context_line":""},{"line_number":5068,"context_line":"    @staticmethod"},{"line_number":5069,"context_line":"    def _refresh_nfs_swap_cache(swap_path):"},{"line_number":5070,"context_line":"        \"\"\"Force NFS attribute cache refresh for a swap file path."},{"line_number":5071,"context_line":""},{"line_number":5072,"context_line":"        Uses O_CREAT|O_EXCL to force a server-side lookup bypassing"}],"source_content_type":"text/x-python","patch_set":2,"id":"8eabc2e1_96629f5b","line":5069,"range":{"start_line":5069,"start_character":8,"end_line":5069,"end_character":31},"updated":"2026-05-19 17:44:49.000000000","message":"so this is a littel misleading\n\ni woudl not expect calling this fuction to end up deletign the swap file\n\nif we are nfs back adn we call this whyle the gues is runign wont we just yank the swap file out form under the vm?","commit_id":"390e48655a6f85f6add3dd24c72ce360b2bc8361"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"9023cc3a121909ccb4c8e6eeac0a4a6217e8f020","unresolved":false,"context_lines":[{"line_number":5066,"context_line":"        nova.privsep.fs.unprivileged_mkfs(\u0027swap\u0027, target)"},{"line_number":5067,"context_line":""},{"line_number":5068,"context_line":"    @staticmethod"},{"line_number":5069,"context_line":"    def _refresh_nfs_swap_cache(swap_path):"},{"line_number":5070,"context_line":"        \"\"\"Force NFS attribute cache refresh for a swap file path."},{"line_number":5071,"context_line":""},{"line_number":5072,"context_line":"        Uses O_CREAT|O_EXCL to force a server-side lookup bypassing"}],"source_content_type":"text/x-python","patch_set":2,"id":"bde7c915_01fa60a1","line":5069,"range":{"start_line":5069,"start_character":8,"end_line":5069,"end_character":31},"in_reply_to":"8eabc2e1_96629f5b","updated":"2026-05-19 17:52:59.000000000","message":"actully we wont\n\nif the file exists we raisae an expction and never do the unlink\nwe only do that if we created the file so its safe.","commit_id":"390e48655a6f85f6add3dd24c72ce360b2bc8361"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"2a90189f10540caad47eb8813434f4af323e380f","unresolved":true,"context_lines":[{"line_number":5066,"context_line":"        nova.privsep.fs.unprivileged_mkfs(\u0027swap\u0027, target)"},{"line_number":5067,"context_line":""},{"line_number":5068,"context_line":"    @staticmethod"},{"line_number":5069,"context_line":"    def _refresh_nfs_swap_cache(swap_path):"},{"line_number":5070,"context_line":"        \"\"\"Force NFS attribute cache refresh for a swap file path."},{"line_number":5071,"context_line":""},{"line_number":5072,"context_line":"        Uses O_CREAT|O_EXCL to force a server-side lookup bypassing"},{"line_number":5073,"context_line":"        the NFS client attribute cache. If the file does not exist on"},{"line_number":5074,"context_line":"        the server, the probe file is removed so the client cache is"},{"line_number":5075,"context_line":"        updated for subsequent os.path.exists() calls."},{"line_number":5076,"context_line":"        \"\"\""},{"line_number":5077,"context_line":"        try:"},{"line_number":5078,"context_line":"            fd \u003d os.open(swap_path, os.O_CREAT | os.O_EXCL | os.O_WRONLY)"},{"line_number":5079,"context_line":"        except OSError as e:"},{"line_number":5080,"context_line":"            if e.errno !\u003d errno.EEXIST:"},{"line_number":5081,"context_line":"                raise"},{"line_number":5082,"context_line":"        else:"},{"line_number":5083,"context_line":"            os.close(fd)"},{"line_number":5084,"context_line":"            os.unlink(swap_path)"},{"line_number":5085,"context_line":""},{"line_number":5086,"context_line":"    @staticmethod"},{"line_number":5087,"context_line":"    def _get_console_log_path(instance):"}],"source_content_type":"text/x-python","patch_set":2,"id":"84571ba5_998a83b5","line":5084,"range":{"start_line":5069,"start_character":0,"end_line":5084,"end_character":32},"updated":"2026-05-19 17:44:49.000000000","message":"```suggestion\n    def _refresh_nfs_swap_cache(swap_path):\n        \"\"\"Force NFS attribute cache refresh for a swap file path.\n\n        Uses O_CREAT|O_EXCL to force a server-side lookup bypassing\n        the NFS client attribute cache. If the file does not exist on\n        the server, the probe file is removed so the client cache is\n        updated for subsequent os.path.exists() calls.\n        \"\"\"\n        try:\n            fd \u003d os.open(swap_path, os.O_CREAT | os.O_EXCL | os.O_WRONLY)\n            os.close(fd)\n            os.unlink(swap_path)\n        except FileExistsError:\n            pass\n```\n\nFileExistsError was added in python 3.3 so we can catch that explcity and we can avoid the try excpt else by puting the close and unlink in the try since they only ran before if the open worked and any excption form those would have propagated anyway.","commit_id":"390e48655a6f85f6add3dd24c72ce360b2bc8361"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"fffe04a3afe6af2544fab142629b280baaf3865f","unresolved":true,"context_lines":[{"line_number":5066,"context_line":"        nova.privsep.fs.unprivileged_mkfs(\u0027swap\u0027, target)"},{"line_number":5067,"context_line":""},{"line_number":5068,"context_line":"    @staticmethod"},{"line_number":5069,"context_line":"    def _refresh_nfs_swap_cache(swap_path):"},{"line_number":5070,"context_line":"        \"\"\"Force NFS attribute cache refresh for a swap file path."},{"line_number":5071,"context_line":""},{"line_number":5072,"context_line":"        Uses O_CREAT|O_EXCL to force a server-side lookup bypassing"},{"line_number":5073,"context_line":"        the NFS client attribute cache. If the file does not exist on"},{"line_number":5074,"context_line":"        the server, the probe file is removed so the client cache is"},{"line_number":5075,"context_line":"        updated for subsequent os.path.exists() calls."},{"line_number":5076,"context_line":"        \"\"\""},{"line_number":5077,"context_line":"        try:"},{"line_number":5078,"context_line":"            fd \u003d os.open(swap_path, os.O_CREAT | os.O_EXCL | os.O_WRONLY)"},{"line_number":5079,"context_line":"        except OSError as e:"},{"line_number":5080,"context_line":"            if e.errno !\u003d errno.EEXIST:"},{"line_number":5081,"context_line":"                raise"},{"line_number":5082,"context_line":"        else:"},{"line_number":5083,"context_line":"            os.close(fd)"},{"line_number":5084,"context_line":"            os.unlink(swap_path)"},{"line_number":5085,"context_line":""},{"line_number":5086,"context_line":"    @staticmethod"},{"line_number":5087,"context_line":"    def _get_console_log_path(instance):"}],"source_content_type":"text/x-python","patch_set":2,"id":"d078d40e_784bcdad","line":5084,"range":{"start_line":5069,"start_character":0,"end_line":5084,"end_character":32},"in_reply_to":"84571ba5_998a83b5","updated":"2026-05-29 21:19:56.000000000","message":"OK sure, that looks cleaner. Let me apply it.","commit_id":"390e48655a6f85f6add3dd24c72ce360b2bc8361"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"fd369c5f3e31bf065f49f125bef8d5c7eb009964","unresolved":false,"context_lines":[{"line_number":5066,"context_line":"        nova.privsep.fs.unprivileged_mkfs(\u0027swap\u0027, target)"},{"line_number":5067,"context_line":""},{"line_number":5068,"context_line":"    @staticmethod"},{"line_number":5069,"context_line":"    def _refresh_nfs_swap_cache(swap_path):"},{"line_number":5070,"context_line":"        \"\"\"Force NFS attribute cache refresh for a swap file path."},{"line_number":5071,"context_line":""},{"line_number":5072,"context_line":"        Uses O_CREAT|O_EXCL to force a server-side lookup bypassing"},{"line_number":5073,"context_line":"        the NFS client attribute cache. If the file does not exist on"},{"line_number":5074,"context_line":"        the server, the probe file is removed so the client cache is"},{"line_number":5075,"context_line":"        updated for subsequent os.path.exists() calls."},{"line_number":5076,"context_line":"        \"\"\""},{"line_number":5077,"context_line":"        try:"},{"line_number":5078,"context_line":"            fd \u003d os.open(swap_path, os.O_CREAT | os.O_EXCL | os.O_WRONLY)"},{"line_number":5079,"context_line":"        except OSError as e:"},{"line_number":5080,"context_line":"            if e.errno !\u003d errno.EEXIST:"},{"line_number":5081,"context_line":"                raise"},{"line_number":5082,"context_line":"        else:"},{"line_number":5083,"context_line":"            os.close(fd)"},{"line_number":5084,"context_line":"            os.unlink(swap_path)"},{"line_number":5085,"context_line":""},{"line_number":5086,"context_line":"    @staticmethod"},{"line_number":5087,"context_line":"    def _get_console_log_path(instance):"}],"source_content_type":"text/x-python","patch_set":2,"id":"7d006ebc_3bfcc966","line":5084,"range":{"start_line":5069,"start_character":0,"end_line":5084,"end_character":32},"in_reply_to":"d078d40e_784bcdad","updated":"2026-05-29 21:20:55.000000000","message":"Fix applied.","commit_id":"390e48655a6f85f6add3dd24c72ce360b2bc8361"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"0511abf1dac19671858ffce7635bf1d5e46d256e","unresolved":true,"context_lines":[{"line_number":5079,"context_line":"            os.close(fd)"},{"line_number":5080,"context_line":"            os.unlink(swap_path)"},{"line_number":5081,"context_line":"        except FileExistsError:"},{"line_number":5082,"context_line":"            pass"},{"line_number":5083,"context_line":""},{"line_number":5084,"context_line":"    @staticmethod"},{"line_number":5085,"context_line":"    def _get_console_log_path(instance):"}],"source_content_type":"text/x-python","patch_set":3,"id":"22d8a3e9_99b971e3","line":5082,"updated":"2026-06-01 20:27:02.000000000","message":"I really don\u0027t like this for a couple of reasons:\n\n1. We touch and remove\n2. We could be interrupted before close or before unlink and leave residue (which isn\u0027t fully avoidable, granted, but..)\n3. This sort of \"pre-tickle the attribute so a later call sees fresh data\" approach feels really obscure, easy to break, hard to test for, and obviously very NFS (and maybe NFS version) specific.\n\nI think what I\u0027d rather is we replace the code in `cache()` to just:\n\n1. Open with `O_CREAT|O_EXCL`. If fail, then return as it already exists\n2. Use the fd we get back to call `os.posix_fallocate()` ourselves instead of spawning the `fallocate` shell command (and doing all the testing involved to know ahead of time if we can even do that thing.\n\nBut, that is more involved and obviously will affect more than swap (which might be good anyway). So I\u0027ll approve this but maybe it would be good to explore the above as a follow-up better fix.","commit_id":"8936778c7e52e9aee476db92111e51171f3a5268"}]}
