commit 342fdad21f737bde2399231d772477d1b2221fe1 from: Stefan Sperling via: Thomas Adam date: Tue Mar 19 13:37:06 2024 UTC avoid a rename/stat race when gotd installs a new pack and then uses it Reset the cached repository's pack directory mtime after installing a new pack and pack index file. I have observed the mtime of the pack directory as reported by stat(2) remaining unchanged, until some time has passed beyond the rename(2) calls used to install the pack file and its index. If gotd immediately tries to read objects installed in a new pack file then the mtime reported by stat(2) might appear as unchanged. gotd will then fail to update its cached list of pack index files and not find the newly installed objects. Clearing the cached timestamp forces a readdir(3) call which does expose the newly installed pack index file as expected. Not sure whether stat(2) is supposed to immediately expose mtime changes after a rename(2). If so then this might warrant digging into the kernel. Seen while running regression tests for upcoming gotd notification support. commit - e8c5d4f87401e77adfdec88437f3b973e7b47262 commit + 342fdad21f737bde2399231d772477d1b2221fe1 blob - bc9ef0d64141e9df96d93d992d4b70ec9ccf4f2f blob + 27ecb3cb1f2dfa87ae9b75649146a015b1e45941 --- gotd/repo_write.c +++ gotd/repo_write.c @@ -1713,6 +1713,12 @@ repo_write_dispatch_session(int fd, short event, void err->msg); break; } + /* + * Ensure we re-read the pack index list + * upon next access. + */ + repo_write.repo->pack_path_mtime.tv_sec = 0; + repo_write.repo->pack_path_mtime.tv_nsec = 0; } err = update_refs(iev); if (err) { blob - ebe568d9449b25eac52742c96be60d186d6244e8 blob + 9754b5ea953bf492a5912577904d94d66b1426a8 --- gotd/session.c +++ gotd/session.c @@ -367,6 +367,10 @@ install_pack(struct gotd_session_client *client, const packidx_path); goto done; } + + /* Ensure we re-read the pack index list upon next access. */ + gotd_session.repo->pack_path_mtime.tv_sec = 0; + gotd_session.repo->pack_path_mtime.tv_nsec = 0; free(client->packidx_path); client->packidx_path = NULL;