Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot move source.tmp when installing package from git #2902

Closed
Cutano opened this issue Oct 6, 2022 · 50 comments
Closed

Cannot move source.tmp when installing package from git #2902

Cutano opened this issue Oct 6, 2022 · 50 comments
Labels
Milestone

Comments

@Cutano
Copy link

Cutano commented Oct 6, 2022

Xmake Version

v2.7.1

Operating System Version and Architecture

Windows 11 22H2

Describe Bug

image

error: cannot move source.tmp to source Permission denied

Expected Behavior

Deps installed successfully.

Project Configuration

No response

Additional Information and Error Logs

No response

@Cutano Cutano added the bug label Oct 6, 2022
@waruqi
Copy link
Member

waruqi commented Oct 6, 2022

you can add -vD and let me see full logs.

xmake f -c -vD

@Cutano
Copy link
Author

Cutano commented Oct 7, 2022

Thanks for the reply!
Here's the full logs:
image

@Cutano
Copy link
Author

Cutano commented Oct 7, 2022

Here's another log when I use particular version of ImGui:
image

image

@waruqi
Copy link
Member

waruqi commented Oct 7, 2022

I don't know, maybe some other process is accessing this directory, you can check it. %localappdata%/.xmake/cache/... /source.tmp

@Cutano
Copy link
Author

Cutano commented Oct 8, 2022

It seems that the problem is associated with Git. I cleared my Git config then reinstalled it, and it's fine.

@Cutano Cutano closed this as completed Oct 8, 2022
@xq114
Copy link
Contributor

xq114 commented Oct 8, 2022

Please reopen this issue. I just ran into the same issue; I'm wondering why xmake clone a repository to source.tmp instead of copying it directly into source?

packagedir = path.join(sourcedir .. ".tmp", package:name())
if package:branch() then
-- only shadow clone this branch
git.clone(url, {depth = 1, recursive = true, longpaths = longpaths, branch = package:branch(), outputdir = packagedir})
-- download package from revision or tag?
else
-- clone whole history and tags
git.clone(url, {longpaths = longpaths, outputdir = packagedir})
-- attempt to checkout the given version
local revision = package:revision(url_alias) or package:tag() or package:commit() or package:version_str()
git.checkout(revision, {repodir = packagedir})
-- update all submodules
if os.isfile(path.join(packagedir, ".gitmodules")) then
git.submodule.update({init = true, recursive = true, longpaths = longpaths, repodir = packagedir})
end
end
-- move to source directory
os.rm(sourcedir)
os.mv(sourcedir .. ".tmp", sourcedir)

I think it does nothing but making more errors, since git could occupy this folder, and the performance would suffer from the useless copying.

@Cutano Cutano reopened this Oct 8, 2022
@SirLynix
Copy link
Member

SirLynix commented Oct 8, 2022

and the performance would suffer from the useless copying

Moving a folder on the same disk is a very fast operation, it doesn't involve copying.

My theory on this error is that git is still using the folder after cloning it on some configs, maybe to index it, so it locks the .tmp folder preventing it to be moved.

@waruqi
Copy link
Member

waruqi commented Oct 8, 2022

os.mv is very fast, and normally, source.tmp should only be occupied by one git process, and it will stop occupying this directory as soon as git clone finishes. Unless the git process or its child processes have not fully exited after git clone has finished and continue to occupy it.

The use of source.tmp is to ensure the integrity of the source directory, so that even if git is killed during the clone process, there will not be an incomplete source directory.

@SirLynix
Copy link
Member

SirLynix commented Oct 8, 2022

maybe xmake could try to move it multiple times if it fails, waiting a bit between tries until it reaches a max_tries value.

@waruqi
Copy link
Member

waruqi commented Oct 8, 2022

But I need to know the root cause, why the git clone process exits and source.tmp continues to be occupied.

@Cutano
Copy link
Author

Cutano commented Oct 8, 2022

os.mv is very fast, and normally, source.tmp should only be occupied by one git process, and it will stop occupying this directory as soon as git clone finishes. Unless the git process or its child processes have not fully exited after git clone has finished and continue to occupy it.

I have tried rebooting and build directly after that, there should be no process occupied, but failed with the same issue.

@SirLynix
Copy link
Member

SirLynix commented Oct 8, 2022

I have tried rebooting and build directly after that, there should be no process occupied, but failed with the same issue.

if that operation failed xmake will clone it again with git, causing the same issue.

If someone successfully reproduces this issue, it would be nice to use a software like https://lockhunter.com to quickly check what processes lock the .tmp folder

@waruqi
Copy link
Member

waruqi commented Oct 8, 2022

os.mv is very fast, and normally, source.tmp should only be occupied by one git process, and it will stop occupying this directory as soon as git clone finishes. Unless the git process or its child processes have not fully exited after git clone has finished and continue to occupy it.

I have tried rebooting and build directly after that, there should be no process occupied, but failed with the same issue.

That's weird, it's like a MoveFileExW problem, but I don't know why it's failing if no any process occupied.

@waruqi
Copy link
Member

waruqi commented Oct 8, 2022

@Cutano You can check that no other process is occupying it, or run xmake l os.mv xxxx/source.tmp xxxx/source to quickly verify that os.mv is working

@Cutano
Copy link
Author

Cutano commented Oct 8, 2022

@Cutano You can check that no other process is occupying it, or run xmake l os.mv xxxx/source.tmp xxxx/source to quickly verify that os.mv is working

I can't reproduce after I reinstalled git. Btw, is there anything to do with the Detached HEAD state of the cloned git repo?
image

@waruqi
Copy link
Member

waruqi commented Oct 8, 2022

@Cutano You can check that no other process is occupying it, or run xmake l os.mv xxxx/source.tmp xxxx/source to quickly verify that os.mv is working

I can't reproduce after I reinstalled git. Btw, is there anything to do with the Detached HEAD state of the cloned git repo? image

It shouldn't have anything to do with this.

@xq114
Copy link
Contributor

xq114 commented Oct 8, 2022

image

@xq114
Copy link
Contributor

xq114 commented Oct 8, 2022

Git did not exit until xmake exits, even if making xmake sleep for 20s

只要xmake不退出,git也不退出,我在中间加了sleep 20s,git就一直占用了20s

@waruqi
Copy link
Member

waruqi commented Oct 8, 2022

Where did you add os.sleep? As soon as the git.clone()/os.exec("git clone") call returns, the git process should have exited

@SirLynix
Copy link
Member

SirLynix commented Oct 8, 2022

Process Monitor could help understand what's going on here, it's very powerful.

@xq114
Copy link
Contributor

xq114 commented Oct 8, 2022

image
here

@waruqi
Copy link
Member

waruqi commented Oct 8, 2022

image here

The git.clone/git.checkout calls have returned and the git process should have exited. I don't know why the git process still exists.

@xq114
Copy link
Contributor

xq114 commented Oct 8, 2022

And there is another strange thing. Spawning only one git process will not cause the issue.

This code will cause the issue;
image

While this won't.
image

@xq114
Copy link
Contributor

xq114 commented Oct 8, 2022

if the issue cannot be addressed, can xmake provide a way to get around? i.e. force xmake to treat source.tmp as complete

@waruqi
Copy link
Member

waruqi commented Oct 8, 2022

no way. And if another git process does keep occupying source.tmp, then even cloning directly to the source directory may cause other problems.

@waruqi
Copy link
Member

waruqi commented Oct 8, 2022

I tried it, it works for me.

import("devel.git")

function main()
    os.tryrm("testgit")
    git.clone("https://github.com/nothings/stb.git", {outputdir = "testgit"})
    git.checkout("4af130e86341928e3003ba5657f3e9faec50c1dc", {repodir = "testgit"})
    os.tryrm("teststb")
    os.mv("testgit", "teststb")
end

@waruqi
Copy link
Member

waruqi commented Oct 8, 2022

image

where is your git.exe? my git is mingw64\bin\git.exe, it will call some git processes in mingw64\libexec\git-core

but your git process is mingw64\libexec\git-core\git.exe

It is possible that the git process called by xmake has already exited, but an additional git.exe child process has been created inside git, which is associated with the parent process and has not been exited.

@xq114
Copy link
Contributor

xq114 commented Oct 8, 2022

git 2.32.0 did not work. Should xmake prompt a warning if their git is outdated?

@waruqi
Copy link
Member

waruqi commented Oct 8, 2022

git 2.32.0 did not work. Should xmake prompt a warning if their git is outdated?

But xmake doesn't know if it's outdated. Theoretically, xmake can use any version of git until it meet this problem

and my git is 2.20.0, it works.

@xq114
Copy link
Contributor

xq114 commented Oct 8, 2022

git 2.32.0 did not work. Should xmake prompt a warning if their git is outdated?

But xmake doesn't know if it's outdated. Theoretically, xmake can use any version of git until it meet this problem

and my git is 2.20.0, it works.

Did you test it on windows? Since now only windows users reported the issue

@waruqi
Copy link
Member

waruqi commented Oct 8, 2022

git 2.32.0 did not work. Should xmake prompt a warning if their git is outdated?

But xmake doesn't know if it's outdated. Theoretically, xmake can use any version of git until it meet this problem
and my git is 2.20.0, it works.

Did you test it on windows? Since now only windows users reported the issue

yeah, on my win7

@waruqi
Copy link
Member

waruqi commented Oct 8, 2022

@Cutano what is your previous git version?

@waruqi
Copy link
Member

waruqi commented Oct 9, 2022

git 2.32.0 did not work. Should xmake prompt a warning if their git is outdated?

I tried 2.32.2. it works for me. https://github.com/git-for-windows/git/releases/download/v2.32.0.windows.1/MinGit-2.32.0-64-bit.zip

import("devel.git")

function main()
    os.tryrm("testgit")
    git.clone("https://github.com/nothings/stb.git", {outputdir = "testgit"})
    git.checkout("4af130e86341928e3003ba5657f3e9faec50c1dc", {repodir = "testgit"})
    os.tryrm("teststb")
    os.mv("testgit", "teststb")
end
xmake l test.lua

@Cutano
Copy link
Author

Cutano commented Oct 9, 2022

@Cutano what is your previous git version?

Probably 2.30, I deleted the package but I remember git was installed around May.

@waruqi waruqi changed the title Package installation failed when using xmake-repo cannot move source.tmp when installing package from git Oct 16, 2022
@waruqi waruqi changed the title cannot move source.tmp when installing package from git Cannot move source.tmp when installing package from git Oct 16, 2022
@Longxr
Copy link

Longxr commented Oct 17, 2022

source tmp_20221017145323

Xmake Version
v2.5.6
Operating System Version and Architecture
Windows 11 21H2
Git Version
git version 2.34.0.windows.1 did not work
git version 2.38.0.windows.1 also did not work

edit C:\Program Files\xmake\modules\private\action\require\impl\actions\download.lua os.mv => os.cp can work
image

@kantraksel
Copy link

kantraksel commented Oct 30, 2022

I had similar problem (could not install sentry-native, because source.tmp was busy), but i remembered git had introduced fsmonitor. So I disabled fsmonitor (git config --global core.fsmonitor false) and killed all remaining git processes (which were instances of fsmonitor). After that xmake did all remaining work.

Win11 with latest updates, git version 2.38.1.windows.1

@waruqi
Copy link
Member

waruqi commented Oct 30, 2022

I had similar problem (could not install sentry-native, because source.tmp was busy), but i remembered git had introduced fsmonitor. So I disabled fsmonitor (git config --global core.fsmonitor false) and killed all remaining git processes (which were instances of fsmonitor). After that xmake did all remaining work.

Win11 with latest updates, git version 2.38.1.windows.1

@Longxr @xq114 @Cutano Maybe this is the cause of the problem, you can try.

@waruqi
Copy link
Member

waruqi commented Oct 30, 2022

I have improved it, can you try it?

xmake update -s github:xmake-io/xmake#fswatcher

@xq114
Copy link
Contributor

xq114 commented Oct 30, 2022

source tmp_20221017145323

Xmake Version v2.5.6 Operating System Version and Architecture Windows 11 21H2 Git Version git version 2.34.0.windows.1 did not work git version 2.38.0.windows.1 also did not work

edit C:\Program Files\xmake\modules\private\action\require\impl\actions\download.lua os.mv => os.cp can work image

Then how about this one? This issue happens with curl, not git

@waruqi
Copy link
Member

waruqi commented Oct 30, 2022

source tmp_20221017145323
Xmake Version v2.5.6 Operating System Version and Architecture Windows 11 21H2 Git Version git version 2.34.0.windows.1 did not work git version 2.38.0.windows.1 also did not work
edit C:\Program Files\xmake\modules\private\action\require\impl\actions\download.lua os.mv => os.cp can work image

Then how about this one? This issue happens with curl, not git

I don't know, but it should have nothing to do with curl, only unpacking tar.gz will access source.tmp. But 7z should not take up source.tmp when it finishes unpacking the file

@waruqi
Copy link
Member

waruqi commented Oct 31, 2022

I have improved it, can you try it?

xmake update -s github:xmake-io/xmake#fswatcher

Have you all tested this patch and if it works I plan to merge it.

waruqi added a commit that referenced this issue Nov 2, 2022
@waruqi
Copy link
Member

waruqi commented Nov 2, 2022

I've merged the patch for now, so you can watch it for a while

@Cutano
Copy link
Author

Cutano commented Nov 3, 2022

I have improved it, can you try it?

xmake update -s github:xmake-io/xmake#fswatcher

Have you all tested this patch and if it works I plan to merge it.

Works for me, seems to be the root cause, thanks!

@waruqi
Copy link
Member

waruqi commented Nov 5, 2022

I have merged into dev.

I closed it first and if you have this questions later, you can open it again.

@waruqi waruqi closed this as completed Nov 5, 2022
@waruqi waruqi added this to the v2.7.3 milestone Nov 5, 2022
@waruqi
Copy link
Member

waruqi commented Nov 24, 2022

I have tried rebooting and build directly after that, there should be no process occupied, but failed with the same issue.

if that operation failed xmake will clone it again with git, causing the same issue.

If someone successfully reproduces this issue, it would be nice to use a software like https://lockhunter.com to quickly check what processes lock the .tmp folder

another tool, handle.exe

https://learn.microsoft.com/zh-cn/sysinternals/downloads/handle

we can run os.exec("handle.exe") to dump all when os.rm is failed.

like this

cl.exe pid: 960 ruki-PC\ruki
    C: File          \Device\Mup\VBoxSvr\projects\personal\tbox
   64: File          \Device\Mup\VBoxSvr\projects\personal\tbox\log.txt
   80: File          \Device\Mup\VBoxSvr\projects\personal\tbox\src\tbox\math\random\random.c
   84: File          \Device\Mup\VBoxSvr\projects\personal\tbox\src\tbox\platform\platform.h
   88: File          \Device\Mup\VBoxSvr\projects\personal\tbox\src\tbox\platform\cpu.h
   8C: File          \Device\Mup\VBoxSvr\projects\personal\tbox\src\tbox\platform\windows\prefix.h
   90: File          C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\um\WinSock2.h
   94: File          C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\um\Windows.h
   98: File          C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\um\WinBase.h
   9C: File          C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\um\minwinbase.h
  194: File          C:\Users\ruki\AppData\Local\Temp\.xmake\221124\_77208C9047E4413089E0BFC612B8D490.i.err
  1AC: File          C:\Users\ruki\AppData\Local\Temp\.xmake\221124\_E9E9002D13D34D70854D314DA21B47C0.i.out
  1BC: File          C:\Users\ruki\AppData\Local\Temp\.xmake\221124\_D0AEF6C2663C4A1087E001ADAF0CC180.i.out
  1C0: File          C:\Users\ruki\AppData\Local\Temp\.xmake\221124\_21D071E92D5B4E208900A55EAFF82A30.i.err

@waruqi
Copy link
Member

waruqi commented Nov 24, 2022

Then how about this one? This issue happens with curl, not git

https://github.com/tboox/tbox/blob/5832d9d3eb26f4472de8f1f4de33a3367642c9eb/src/tbox/platform/windows/process.c#L452

bInheritHandle = TRUE;
if (!tb_kernel32()->CreateProcessW(tb_null, command, &sap, &sat, bInheritHandle, flags, (LPVOID)environment, attr && attr->curdir? curdir : tb_null, &process->si, &process->pi))

I probably figured out the root cause. xmake creates child processes with inheritance handles enabled by default.

If source.tmp has been already opened occupied (os.cd()) when multiple subprocesses are executed in parallel, they will all inherit its handle.

Even if the current git/unzip subprocess has exited and no longer accesses it, it will continue to be occupied by other subprocesses that may not have direct access to it.

I had a similar problem when I executed the cl.exe sub-process in parallel and I was unable to delete the files accessed by other cl.exe processes.

But if I disable the inheritance handle, it works.

os.tryrm(outfile)

@waruqi
Copy link
Member

waruqi commented Nov 25, 2022

Although I know the cause of the problem, I don't know how to fix it and I can't disable handle inheritance. I can't disable handle inheritance because it is needed for the process to redirect input and output.

Why can't CreateProcess be configured directly to inherit only the STARTUPINFO.hStdOutputhandle of the current incoming parameter?

Tell CreateProcess to inherit by SetHandleInformation(si.hStdOutput, HANDLE_FLAG_INHERIT, TRUE) and it will globally affect other child processes.


maybe I can try STARTUPINFOEX/lpAttributeList

@waruqi
Copy link
Member

waruqi commented Nov 25, 2022

I have improved to spawn process on windows. tboox/tbox@5b62232

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

6 participants