[PATCH] Use shutil.move when os.rename fails


Devendra Tewari
 

---
meta/classes/sstate.bbclass | 26 ++++++++++++++++++++++----
1 file changed, 22 insertions(+), 4 deletions(-)

diff --git a/meta/classes/sstate.bbclass b/meta/classes/sstate.bbclass
index f579168162..f94aa96d70 100644
--- a/meta/classes/sstate.bbclass
+++ b/meta/classes/sstate.bbclass
@@ -384,6 +384,7 @@ def sstate_installpkg(ss, d):
def sstate_installpkgdir(ss, d):
import oe.path
import subprocess
+ import shutil

sstateinst = d.getVar("SSTATE_INSTDIR")
d.setVar('SSTATE_FIXMEDIR', ss['fixmedir'])
@@ -401,7 +402,11 @@ def sstate_installpkgdir(ss, d):

for state in ss['dirs']:
prepdir(state[1])
- os.rename(sstateinst + state[0], state[1])
+ try:
+ os.rename(sstateinst + state[0], state[1])
+ break
+ except OSError:
+ shutil.move(sstateinst + state[0], state[1])
sstate_install(ss, d)

for plain in ss['plaindirs']:
@@ -413,7 +418,11 @@ def sstate_installpkgdir(ss, d):
dest = plain
bb.utils.mkdirhier(src)
prepdir(dest)
- os.rename(src, dest)
+ try:
+ os.rename(src, dest)
+ break
+ except OSError:
+ shutil.move(src, dest)

return True

@@ -638,6 +647,7 @@ python sstate_hardcode_path () {

def sstate_package(ss, d):
import oe.path
+ import shutil

tmpdir = d.getVar('TMPDIR')

@@ -664,7 +674,11 @@ def sstate_package(ss, d):
continue
bb.error("sstate found an absolute path symlink %s pointing at %s. Please replace this with a relative link." % (srcpath, link))
bb.debug(2, "Preparing tree %s for packaging at %s" % (state[1], sstatebuild + state[0]))
- os.rename(state[1], sstatebuild + state[0])
+ try:
+ os.rename(state[1], sstatebuild + state[0])
+ break
+ except OSError:
+ shutil.move(state[1], sstatebuild + state[0])

workdir = d.getVar('WORKDIR')
sharedworkdir = os.path.join(d.getVar('TMPDIR'), "work-shared")
@@ -674,7 +688,11 @@ def sstate_package(ss, d):
pdir = plain.replace(sharedworkdir, sstatebuild)
bb.utils.mkdirhier(plain)
bb.utils.mkdirhier(pdir)
- os.rename(plain, pdir)
+ try:
+ os.rename(plain, pdir)
+ break
+ except OSError:
+ shutil.move(plain, pdir)

d.setVar('SSTATE_BUILDDIR', sstatebuild)
d.setVar('SSTATE_INSTDIR', sstatebuild)
--
2.29.2


Bruce Ashfield
 

Can you document the cases that os.rename() is failing ? And also why
would we expect the shutil.move() to work in those cases ?

If a change like this cases issues in the future, we need that extra
information in the commit head for proper triage.

Bruce

On Mon, Mar 29, 2021 at 11:16 AM Devendra Tewari
<devendra.tewari@...> wrote:

---
meta/classes/sstate.bbclass | 26 ++++++++++++++++++++++----
1 file changed, 22 insertions(+), 4 deletions(-)

diff --git a/meta/classes/sstate.bbclass b/meta/classes/sstate.bbclass
index f579168162..f94aa96d70 100644
--- a/meta/classes/sstate.bbclass
+++ b/meta/classes/sstate.bbclass
@@ -384,6 +384,7 @@ def sstate_installpkg(ss, d):
def sstate_installpkgdir(ss, d):
import oe.path
import subprocess
+ import shutil

sstateinst = d.getVar("SSTATE_INSTDIR")
d.setVar('SSTATE_FIXMEDIR', ss['fixmedir'])
@@ -401,7 +402,11 @@ def sstate_installpkgdir(ss, d):

for state in ss['dirs']:
prepdir(state[1])
- os.rename(sstateinst + state[0], state[1])
+ try:
+ os.rename(sstateinst + state[0], state[1])
+ break
+ except OSError:
+ shutil.move(sstateinst + state[0], state[1])
sstate_install(ss, d)

for plain in ss['plaindirs']:
@@ -413,7 +418,11 @@ def sstate_installpkgdir(ss, d):
dest = plain
bb.utils.mkdirhier(src)
prepdir(dest)
- os.rename(src, dest)
+ try:
+ os.rename(src, dest)
+ break
+ except OSError:
+ shutil.move(src, dest)

return True

@@ -638,6 +647,7 @@ python sstate_hardcode_path () {

def sstate_package(ss, d):
import oe.path
+ import shutil

tmpdir = d.getVar('TMPDIR')

@@ -664,7 +674,11 @@ def sstate_package(ss, d):
continue
bb.error("sstate found an absolute path symlink %s pointing at %s. Please replace this with a relative link." % (srcpath, link))
bb.debug(2, "Preparing tree %s for packaging at %s" % (state[1], sstatebuild + state[0]))
- os.rename(state[1], sstatebuild + state[0])
+ try:
+ os.rename(state[1], sstatebuild + state[0])
+ break
+ except OSError:
+ shutil.move(state[1], sstatebuild + state[0])

workdir = d.getVar('WORKDIR')
sharedworkdir = os.path.join(d.getVar('TMPDIR'), "work-shared")
@@ -674,7 +688,11 @@ def sstate_package(ss, d):
pdir = plain.replace(sharedworkdir, sstatebuild)
bb.utils.mkdirhier(plain)
bb.utils.mkdirhier(pdir)
- os.rename(plain, pdir)
+ try:
+ os.rename(plain, pdir)
+ break
+ except OSError:
+ shutil.move(plain, pdir)

d.setVar('SSTATE_BUILDDIR', sstatebuild)
d.setVar('SSTATE_INSTDIR', sstatebuild)
--
2.29.2




--
- Thou shalt not follow the NULL pointer, for chaos and madness await
thee at its end
- "Use the force Harry" - Gandalf, Star Trek II


Konrad Weihmann <kweihmann@...>
 

Yes please quote a bit from the python manpage [1] - I certainly see the difference (and the edge cases where os.rename might fail), but that should be documented as part of the commit message

[1] https://docs.python.org/3/library/shutil.html#shutil.move

On 29.03.21 17:21, Bruce Ashfield wrote:
Can you document the cases that os.rename() is failing ? And also why
would we expect the shutil.move() to work in those cases ?
If a change like this cases issues in the future, we need that extra
information in the commit head for proper triage.
Bruce
On Mon, Mar 29, 2021 at 11:16 AM Devendra Tewari
<devendra.tewari@...> wrote:

---
meta/classes/sstate.bbclass | 26 ++++++++++++++++++++++----
1 file changed, 22 insertions(+), 4 deletions(-)

diff --git a/meta/classes/sstate.bbclass b/meta/classes/sstate.bbclass
index f579168162..f94aa96d70 100644
--- a/meta/classes/sstate.bbclass
+++ b/meta/classes/sstate.bbclass
@@ -384,6 +384,7 @@ def sstate_installpkg(ss, d):
def sstate_installpkgdir(ss, d):
import oe.path
import subprocess
+ import shutil

sstateinst = d.getVar("SSTATE_INSTDIR")
d.setVar('SSTATE_FIXMEDIR', ss['fixmedir'])
@@ -401,7 +402,11 @@ def sstate_installpkgdir(ss, d):

for state in ss['dirs']:
prepdir(state[1])
- os.rename(sstateinst + state[0], state[1])
+ try:
+ os.rename(sstateinst + state[0], state[1])
+ break
+ except OSError:
+ shutil.move(sstateinst + state[0], state[1])
sstate_install(ss, d)

for plain in ss['plaindirs']:
@@ -413,7 +418,11 @@ def sstate_installpkgdir(ss, d):
dest = plain
bb.utils.mkdirhier(src)
prepdir(dest)
- os.rename(src, dest)
+ try:
+ os.rename(src, dest)
+ break
+ except OSError:
+ shutil.move(src, dest)

return True

@@ -638,6 +647,7 @@ python sstate_hardcode_path () {

def sstate_package(ss, d):
import oe.path
+ import shutil

tmpdir = d.getVar('TMPDIR')

@@ -664,7 +674,11 @@ def sstate_package(ss, d):
continue
bb.error("sstate found an absolute path symlink %s pointing at %s. Please replace this with a relative link." % (srcpath, link))
bb.debug(2, "Preparing tree %s for packaging at %s" % (state[1], sstatebuild + state[0]))
- os.rename(state[1], sstatebuild + state[0])
+ try:
+ os.rename(state[1], sstatebuild + state[0])
+ break
+ except OSError:
+ shutil.move(state[1], sstatebuild + state[0])

workdir = d.getVar('WORKDIR')
sharedworkdir = os.path.join(d.getVar('TMPDIR'), "work-shared")
@@ -674,7 +688,11 @@ def sstate_package(ss, d):
pdir = plain.replace(sharedworkdir, sstatebuild)
bb.utils.mkdirhier(plain)
bb.utils.mkdirhier(pdir)
- os.rename(plain, pdir)
+ try:
+ os.rename(plain, pdir)
+ break
+ except OSError:
+ shutil.move(plain, pdir)

d.setVar('SSTATE_BUILDDIR', sstatebuild)
d.setVar('SSTATE_INSTDIR', sstatebuild)
--
2.29.2




Devendra Tewari
 

Sure.

Would the following commit message be sufficient?

Use shutil.move when os.rename fails

Incremental build in Docker fails with

OSError: [Errno 18] Invalid cross-device link

When source and destination are on different overlay filesystems.

This change handles the error with os.rename and retries with shutil.move.

Thanks,
Devendra

On 29 Mar 2021, at 12:23, Konrad Weihmann <kweihmann@...> wrote:

Yes please quote a bit from the python manpage [1] - I certainly see the difference (and the edge cases where os.rename might fail), but that should be documented as part of the commit message

[1] https://docs.python.org/3/library/shutil.html#shutil.move

On 29.03.21 17:21, Bruce Ashfield wrote:
Can you document the cases that os.rename() is failing ? And also why
would we expect the shutil.move() to work in those cases ?
If a change like this cases issues in the future, we need that extra
information in the commit head for proper triage.
Bruce
On Mon, Mar 29, 2021 at 11:16 AM Devendra Tewari
<devendra.tewari@...> wrote:

---
meta/classes/sstate.bbclass | 26 ++++++++++++++++++++++----
1 file changed, 22 insertions(+), 4 deletions(-)

diff --git a/meta/classes/sstate.bbclass b/meta/classes/sstate.bbclass
index f579168162..f94aa96d70 100644
--- a/meta/classes/sstate.bbclass
+++ b/meta/classes/sstate.bbclass
@@ -384,6 +384,7 @@ def sstate_installpkg(ss, d):
def sstate_installpkgdir(ss, d):
import oe.path
import subprocess
+ import shutil

sstateinst = d.getVar("SSTATE_INSTDIR")
d.setVar('SSTATE_FIXMEDIR', ss['fixmedir'])
@@ -401,7 +402,11 @@ def sstate_installpkgdir(ss, d):

for state in ss['dirs']:
prepdir(state[1])
- os.rename(sstateinst + state[0], state[1])
+ try:
+ os.rename(sstateinst + state[0], state[1])
+ break
+ except OSError:
+ shutil.move(sstateinst + state[0], state[1])
sstate_install(ss, d)

for plain in ss['plaindirs']:
@@ -413,7 +418,11 @@ def sstate_installpkgdir(ss, d):
dest = plain
bb.utils.mkdirhier(src)
prepdir(dest)
- os.rename(src, dest)
+ try:
+ os.rename(src, dest)
+ break
+ except OSError:
+ shutil.move(src, dest)

return True

@@ -638,6 +647,7 @@ python sstate_hardcode_path () {

def sstate_package(ss, d):
import oe.path
+ import shutil

tmpdir = d.getVar('TMPDIR')

@@ -664,7 +674,11 @@ def sstate_package(ss, d):
continue
bb.error("sstate found an absolute path symlink %s pointing at %s. Please replace this with a relative link." % (srcpath, link))
bb.debug(2, "Preparing tree %s for packaging at %s" % (state[1], sstatebuild + state[0]))
- os.rename(state[1], sstatebuild + state[0])
+ try:
+ os.rename(state[1], sstatebuild + state[0])
+ break
+ except OSError:
+ shutil.move(state[1], sstatebuild + state[0])

workdir = d.getVar('WORKDIR')
sharedworkdir = os.path.join(d.getVar('TMPDIR'), "work-shared")
@@ -674,7 +688,11 @@ def sstate_package(ss, d):
pdir = plain.replace(sharedworkdir, sstatebuild)
bb.utils.mkdirhier(plain)
bb.utils.mkdirhier(pdir)
- os.rename(plain, pdir)
+ try:
+ os.rename(plain, pdir)
+ break
+ except OSError:
+ shutil.move(plain, pdir)

d.setVar('SSTATE_BUILDDIR', sstatebuild)
d.setVar('SSTATE_INSTDIR', sstatebuild)
--
2.29.2




Devendra Tewari
 

On 29 Mar 2021, at 12:35, Devendra Tewari <devendra.tewari@...> wrote:

Sure.

Would the following commit message be sufficient?

Use shutil.move when os.rename fails

Incremental build in Docker fails with

OSError: [Errno 18] Invalid cross-device link

When source and destination are on different overlay filesystems.

This change handles the error with os.rename and retries with shutil.move.

Thanks,
Devendra

On 29 Mar 2021, at 12:23, Konrad Weihmann <kweihmann@...> wrote:

Yes please quote a bit from the python manpage [1] - I certainly see the difference (and the edge cases where os.rename might fail), but that should be documented as part of the commit message

[1] https://docs.python.org/3/library/shutil.html#shutil.move

On 29.03.21 17:21, Bruce Ashfield wrote:
Can you document the cases that os.rename() is failing ? And also why
would we expect the shutil.move() to work in those cases ?
If a change like this cases issues in the future, we need that extra
information in the commit head for proper triage.
Bruce
On Mon, Mar 29, 2021 at 11:16 AM Devendra Tewari
<devendra.tewari@...> wrote:

---
meta/classes/sstate.bbclass | 26 ++++++++++++++++++++++----
1 file changed, 22 insertions(+), 4 deletions(-)

diff --git a/meta/classes/sstate.bbclass b/meta/classes/sstate.bbclass
index f579168162..f94aa96d70 100644
--- a/meta/classes/sstate.bbclass
+++ b/meta/classes/sstate.bbclass
@@ -384,6 +384,7 @@ def sstate_installpkg(ss, d):
def sstate_installpkgdir(ss, d):
import oe.path
import subprocess
+ import shutil

sstateinst = d.getVar("SSTATE_INSTDIR")
d.setVar('SSTATE_FIXMEDIR', ss['fixmedir'])
@@ -401,7 +402,11 @@ def sstate_installpkgdir(ss, d):

for state in ss['dirs']:
prepdir(state[1])
- os.rename(sstateinst + state[0], state[1])
+ try:
+ os.rename(sstateinst + state[0], state[1])
+ break
+ except OSError:
+ shutil.move(sstateinst + state[0], state[1])
sstate_install(ss, d)

for plain in ss['plaindirs']:
@@ -413,7 +418,11 @@ def sstate_installpkgdir(ss, d):
dest = plain
bb.utils.mkdirhier(src)
prepdir(dest)
- os.rename(src, dest)
+ try:
+ os.rename(src, dest)
+ break
+ except OSError:
+ shutil.move(src, dest)

return True

@@ -638,6 +647,7 @@ python sstate_hardcode_path () {

def sstate_package(ss, d):
import oe.path
+ import shutil

tmpdir = d.getVar('TMPDIR')

@@ -664,7 +674,11 @@ def sstate_package(ss, d):
continue
bb.error("sstate found an absolute path symlink %s pointing at %s. Please replace this with a relative link." % (srcpath, link))
bb.debug(2, "Preparing tree %s for packaging at %s" % (state[1], sstatebuild + state[0]))
- os.rename(state[1], sstatebuild + state[0])
+ try:
+ os.rename(state[1], sstatebuild + state[0])
+ break
+ except OSError:
+ shutil.move(state[1], sstatebuild + state[0])

workdir = d.getVar('WORKDIR')
sharedworkdir = os.path.join(d.getVar('TMPDIR'), "work-shared")
@@ -674,7 +688,11 @@ def sstate_package(ss, d):
pdir = plain.replace(sharedworkdir, sstatebuild)
bb.utils.mkdirhier(plain)
bb.utils.mkdirhier(pdir)
- os.rename(plain, pdir)
+ try:
+ os.rename(plain, pdir)
+ break
+ except OSError:
+ shutil.move(plain, pdir)

d.setVar('SSTATE_BUILDDIR', sstatebuild)
d.setVar('SSTATE_INSTDIR', sstatebuild)
--
2.29.2




Richard Purdie
 

On Mon, 2021-03-29 at 12:14 -0300, Devendra Tewari wrote:
---
 meta/classes/sstate.bbclass | 26 ++++++++++++++++++++++----
 1 file changed, 22 insertions(+), 4 deletions(-)

diff --git a/meta/classes/sstate.bbclass b/meta/classes/sstate.bbclass
index f579168162..f94aa96d70 100644
--- a/meta/classes/sstate.bbclass
+++ b/meta/classes/sstate.bbclass
@@ -384,6 +384,7 @@ def sstate_installpkg(ss, d):
 def sstate_installpkgdir(ss, d):
     import oe.path
     import subprocess
+ import shutil
 

     sstateinst = d.getVar("SSTATE_INSTDIR")
     d.setVar('SSTATE_FIXMEDIR', ss['fixmedir'])
@@ -401,7 +402,11 @@ def sstate_installpkgdir(ss, d):
 

     for state in ss['dirs']:
         prepdir(state[1])
- os.rename(sstateinst + state[0], state[1])
+ try:
+ os.rename(sstateinst + state[0], state[1])
+ break
That break should definitely not be there, that changes behaviour.

+ except OSError:
+ shutil.move(sstateinst + state[0], state[1])
     sstate_install(ss, d)
 

     for plain in ss['plaindirs']:
@@ -413,7 +418,11 @@ def sstate_installpkgdir(ss, d):
         dest = plain
         bb.utils.mkdirhier(src)
         prepdir(dest)
- os.rename(src, dest)
+ try:
+ os.rename(src, dest)
+ break
Same here...

+ except OSError:
+ shutil.move(src, dest)
 

     return True
 

@@ -638,6 +647,7 @@ python sstate_hardcode_path () {
 

 def sstate_package(ss, d):
     import oe.path
+ import shutil
 

     tmpdir = d.getVar('TMPDIR')
 

@@ -664,7 +674,11 @@ def sstate_package(ss, d):
                     continue
                 bb.error("sstate found an absolute path symlink %s pointing at %s. Please replace this with a relative link." % (srcpath, link))
         bb.debug(2, "Preparing tree %s for packaging at %s" % (state[1], sstatebuild + state[0]))
- os.rename(state[1], sstatebuild + state[0])
+ try:
+ os.rename(state[1], sstatebuild + state[0])
+ break
and again...

+ except OSError:
+ shutil.move(state[1], sstatebuild + state[0])
 

     workdir = d.getVar('WORKDIR')
     sharedworkdir = os.path.join(d.getVar('TMPDIR'), "work-shared")
@@ -674,7 +688,11 @@ def sstate_package(ss, d):
             pdir = plain.replace(sharedworkdir, sstatebuild)
         bb.utils.mkdirhier(plain)
         bb.utils.mkdirhier(pdir)
- os.rename(plain, pdir)
+ try:
+ os.rename(plain, pdir)
+ break

and again...

+ except OSError:
+ shutil.move(plain, pdir)
 

     d.setVar('SSTATE_BUILDDIR', sstatebuild)
     d.setVar('SSTATE_INSTDIR', sstatebuild)


Devendra Tewari
 

Thanks! My bad. The example I looked up in Python docs had a break and I just realized it was a looping example.

Here’s the updated patch (or should I submit it again via git send-email?)

From 9deb390dcdcaef66cec2fae39454c7fb3c81c4e4 Mon Sep 17 00:00:00 2001
From: Devendra Tewari <devendra.tewari@...>
Date: Mon, 29 Mar 2021 19:41:02 -0300
Subject: [PATCH] Use shutil.move when os.rename fails

Incremental build in Docker fails with

OSError: [Errno 18] Invalid cross-device link

When source and destination are on different overlay filesystems.

This change handles the error with os.rename and retries with shutil.move.
---
 meta/classes/sstate.bbclass               | 22 ++++++++++++++++++----
 vscode-bitbake-build/executeBitBakeCmd.sh |  3 +++
 2 files changed, 21 insertions(+), 4 deletions(-)
 create mode 100755 vscode-bitbake-build/executeBitBakeCmd.sh

diff --git a/meta/classes/sstate.bbclass b/meta/classes/sstate.bbclass
index f579168162..301dfc27db 100644
--- a/meta/classes/sstate.bbclass
+++ b/meta/classes/sstate.bbclass
@@ -384,6 +384,7 @@ def sstate_installpkg(ss, d):
 def sstate_installpkgdir(ss, d):
     import oe.path
     import subprocess
+    import shutil

 

     sstateinst = d.getVar("SSTATE_INSTDIR")
     d.setVar('SSTATE_FIXMEDIR', ss['fixmedir'])
@@ -401,7 +402,10 @@ def sstate_installpkgdir(ss, d):

 

     for state in ss['dirs']:
         prepdir(state[1])
-        os.rename(sstateinst + state[0], state[1])
+        try:
+            os.rename(sstateinst + state[0], state[1])
+        except OSError:
+            shutil.move(sstateinst + state[0], state[1])
     sstate_install(ss, d)

 

     for plain in ss['plaindirs']:
@@ -413,7 +417,10 @@ def sstate_installpkgdir(ss, d):
         dest = plain
         bb.utils.mkdirhier(src)
         prepdir(dest)
-        os.rename(src, dest)
+        try:
+            os.rename(src, dest)
+        except OSError:
+            shutil.move(src, dest)

 

     return True

 

@@ -638,6 +645,7 @@ python sstate_hardcode_path () {

 

 def sstate_package(ss, d):
     import oe.path
+    import shutil

 

     tmpdir = d.getVar('TMPDIR')

 

@@ -664,7 +672,10 @@ def sstate_package(ss, d):
                     continue
                 bb.error("sstate found an absolute path symlink %s pointing at %s. Please replace this with a relative link." % (srcpath, link))
         bb.debug(2, "Preparing tree %s for packaging at %s" % (state[1], sstatebuild + state[0]))
-        os.rename(state[1], sstatebuild + state[0])
+        try:
+            os.rename(state[1], sstatebuild + state[0])
+        except OSError:
+            shutil.move(state[1], sstatebuild + state[0])

 

     workdir = d.getVar('WORKDIR')
     sharedworkdir = os.path.join(d.getVar('TMPDIR'), "work-shared")
@@ -674,7 +685,10 @@ def sstate_package(ss, d):
             pdir = plain.replace(sharedworkdir, sstatebuild)
         bb.utils.mkdirhier(plain)
         bb.utils.mkdirhier(pdir)
-        os.rename(plain, pdir)
+        try:
+            os.rename(plain, pdir)
+        except OSError:
+            shutil.move(plain, pdir)

 

     d.setVar('SSTATE_BUILDDIR', sstatebuild)
     d.setVar('SSTATE_INSTDIR', sstatebuild)
diff --git a/vscode-bitbake-build/executeBitBakeCmd.sh b/vscode-bitbake-build/executeBitBakeCmd.sh
new file mode 100755
index 0000000000..d7a4c5a5aa
--- /dev/null
+++ b/vscode-bitbake-build/executeBitBakeCmd.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+. ./oe-init-build-env vscode-bitbake-build > /dev/null
+bitbake-layers show-layers
\ No newline at end of file
-- 
2.29.2


On 29 Mar 2021, at 17:38, Richard Purdie <richard.purdie@...> wrote:

On Mon, 2021-03-29 at 12:14 -0300, Devendra Tewari wrote:
---
 meta/classes/sstate.bbclass | 26 ++++++++++++++++++++++----
 1 file changed, 22 insertions(+), 4 deletions(-)

diff --git a/meta/classes/sstate.bbclass b/meta/classes/sstate.bbclass
index f579168162..f94aa96d70 100644
--- a/meta/classes/sstate.bbclass
+++ b/meta/classes/sstate.bbclass
@@ -384,6 +384,7 @@ def sstate_installpkg(ss, d):
 def sstate_installpkgdir(ss, d):
     import oe.path
     import subprocess
+    import shutil
 

     sstateinst = d.getVar("SSTATE_INSTDIR")
     d.setVar('SSTATE_FIXMEDIR', ss['fixmedir'])
@@ -401,7 +402,11 @@ def sstate_installpkgdir(ss, d):
 

     for state in ss['dirs']:
         prepdir(state[1])
-        os.rename(sstateinst + state[0], state[1])
+        try:
+            os.rename(sstateinst + state[0], state[1])
+            break

That break should definitely not be there, that changes behaviour.

+        except OSError:
+            shutil.move(sstateinst + state[0], state[1])
     sstate_install(ss, d)
 

     for plain in ss['plaindirs']:
@@ -413,7 +418,11 @@ def sstate_installpkgdir(ss, d):
         dest = plain
         bb.utils.mkdirhier(src)
         prepdir(dest)
-        os.rename(src, dest)
+        try:
+            os.rename(src, dest)
+            break

Same here...

+        except OSError:
+            shutil.move(src, dest)
 

     return True
 

@@ -638,6 +647,7 @@ python sstate_hardcode_path () {
 

 def sstate_package(ss, d):
     import oe.path
+    import shutil
 

     tmpdir = d.getVar('TMPDIR')
 

@@ -664,7 +674,11 @@ def sstate_package(ss, d):
                     continue
                 bb.error("sstate found an absolute path symlink %s pointing at %s. Please replace this with a relative link." % (srcpath, link))
         bb.debug(2, "Preparing tree %s for packaging at %s" % (state[1], sstatebuild + state[0]))
-        os.rename(state[1], sstatebuild + state[0])
+        try:
+            os.rename(state[1], sstatebuild + state[0])
+            break

and again...

+        except OSError:
+            shutil.move(state[1], sstatebuild + state[0])
 

     workdir = d.getVar('WORKDIR')
     sharedworkdir = os.path.join(d.getVar('TMPDIR'), "work-shared")
@@ -674,7 +688,11 @@ def sstate_package(ss, d):
             pdir = plain.replace(sharedworkdir, sstatebuild)
         bb.utils.mkdirhier(plain)
         bb.utils.mkdirhier(pdir)
-        os.rename(plain, pdir)
+        try:
+            os.rename(plain, pdir)
+            break


and again...

+        except OSError:
+            shutil.move(plain, pdir)
 

     d.setVar('SSTATE_BUILDDIR', sstatebuild)
     d.setVar('SSTATE_INSTDIR', sstatebuild)


Andre McCurdy
 

On Mon, Mar 29, 2021 at 3:45 PM Devendra Tewari
<devendra.tewari@...> wrote:

Thanks! My bad. The example I looked up in Python docs had a break and I just realized it was a looping example.

Here’s the updated patch (or should I submit it again via git send-email?)
It would be better to use shutil.move unconditionally in all cases,
rather than have a separate shutil.move code path which only gets
tested by people doing incremental builds in docker.


Devendra Tewari
 

I did try that but got an error that does not happen when we try os.rename first. I'll try to reproduce it again.

I suspect there may be subtle differences in os.rename vs shutil.move with respect to what happens when origin and/or destination do not exist or are invalid.

On 29 Mar 2021, at 20:00, Andre McCurdy <armccurdy@...> wrote:

On Mon, Mar 29, 2021 at 3:45 PM Devendra Tewari
<devendra.tewari@...> wrote:

Thanks! My bad. The example I looked up in Python docs had a break and I just realized it was a looping example.

Here’s the updated patch (or should I submit it again via git send-email?)
It would be better to use shutil.move unconditionally in all cases,
rather than have a separate shutil.move code path which only gets
tested by people doing incremental builds in docker.


Andre McCurdy
 

On Mon, Mar 29, 2021 at 4:07 PM Devendra Tewari
<devendra.tewari@...> wrote:

I did try that but got an error that does not happen when we try os.rename first. I'll try to reproduce it again.

I suspect there may be subtle differences in os.rename vs shutil.move with respect to what happens when origin and/or destination do not exist or are invalid.
If there are subtle issues which you don't yet understand then that's
all the more reason for not hiding the new shutil.move code behind a
test which will pass for 99.9% of users. Please figure that out before
sending another version of the patch.

On 29 Mar 2021, at 20:00, Andre McCurdy <armccurdy@...> wrote:

On Mon, Mar 29, 2021 at 3:45 PM Devendra Tewari
<devendra.tewari@...> wrote:

Thanks! My bad. The example I looked up in Python docs had a break and I just realized it was a looping example.

Here’s the updated patch (or should I submit it again via git send-email?)
It would be better to use shutil.move unconditionally in all cases,
rather than have a separate shutil.move code path which only gets
tested by people doing incremental builds in docker.


Devendra Tewari
 

Will do. Thanks.

On 29 Mar 2021, at 20:10, Andre McCurdy <armccurdy@...> wrote:

On Mon, Mar 29, 2021 at 4:07 PM Devendra Tewari
<devendra.tewari@...> wrote:

I did try that but got an error that does not happen when we try os.rename first. I'll try to reproduce it again.

I suspect there may be subtle differences in os.rename vs shutil.move with respect to what happens when origin and/or destination do not exist or are invalid.
If there are subtle issues which you don't yet understand then that's
all the more reason for not hiding the new shutil.move code behind a
test which will pass for 99.9% of users. Please figure that out before
sending another version of the patch.

On 29 Mar 2021, at 20:00, Andre McCurdy <armccurdy@...> wrote:

On Mon, Mar 29, 2021 at 3:45 PM Devendra Tewari
<devendra.tewari@...> wrote:

Thanks! My bad. The example I looked up in Python docs had a break and I just realized it was a looping example.

Here’s the updated patch (or should I submit it again via git send-email?)
It would be better to use shutil.move unconditionally in all cases,
rather than have a separate shutil.move code path which only gets
tested by people doing incremental builds in docker.


Devendra Tewari
 

With the following patch

From f29ec67239094a256fcfc119fb75be90923d3448 Mon Sep 17 00:00:00 2001
From: Devendra Tewari <devendra.tewari@...>
Date: Mon, 29 Mar 2021 21:11:56 -0300
Subject: [PATCH] Use shutil.move to rename sstate

Incremental build in Docker fails with

OSError: [Errno 18] Invalid cross-device link

When source and destination are on different overlay filesystems.

shutil.move uses os.rename when destination is on the current filesystem,
otherwise source is copied to destination and then removed.
---
 meta/classes/sstate.bbclass | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/meta/classes/sstate.bbclass b/meta/classes/sstate.bbclass
index f579168162..2e87697e3e 100644
--- a/meta/classes/sstate.bbclass
+++ b/meta/classes/sstate.bbclass
@@ -384,6 +384,7 @@ def sstate_installpkg(ss, d):
 def sstate_installpkgdir(ss, d):
     import oe.path
     import subprocess
+    import shutil
 
     sstateinst = d.getVar("SSTATE_INSTDIR")
     d.setVar('SSTATE_FIXMEDIR', ss['fixmedir'])
@@ -401,7 +402,7 @@ def sstate_installpkgdir(ss, d):
 
     for state in ss['dirs']:
         prepdir(state[1])
-        os.rename(sstateinst + state[0], state[1])
+        shutil.move(sstateinst + state[0], state[1])
     sstate_install(ss, d)
 
     for plain in ss['plaindirs']:
@@ -413,7 +414,7 @@ def sstate_installpkgdir(ss, d):
         dest = plain
         bb.utils.mkdirhier(src)
         prepdir(dest)
-        os.rename(src, dest)
+        shutil.move(src, dest)
 
     return True
 
@@ -638,6 +639,7 @@ python sstate_hardcode_path () {
 
 def sstate_package(ss, d):
     import oe.path
+    import shutil
 
     tmpdir = d.getVar('TMPDIR')
 
@@ -664,7 +666,7 @@ def sstate_package(ss, d):
                     continue
                 bb.error("sstate found an absolute path symlink %s pointing at %s. Please replace this with a relative link." % (srcpath, link))
         bb.debug(2, "Preparing tree %s for packaging at %s" % (state[1], sstatebuild + state[0]))
-        os.rename(state[1], sstatebuild + state[0])
+        shutil.move(state[1], sstatebuild + state[0])
 
     workdir = d.getVar('WORKDIR')
     sharedworkdir = os.path.join(d.getVar('TMPDIR'), "work-shared")
@@ -674,7 +676,7 @@ def sstate_package(ss, d):
             pdir = plain.replace(sharedworkdir, sstatebuild)
         bb.utils.mkdirhier(plain)
         bb.utils.mkdirhier(pdir)
-        os.rename(plain, pdir)
+        shutil.move(plain, pdir)
 
     d.setVar('SSTATE_BUILDDIR', sstatebuild)
     d.setVar('SSTATE_INSTDIR', sstatebuild)
-- 
2.29.2

The build fails with

#12 2734.2 2021-03-30 01:14:29 - INFO     - NOTE: recipe linux-libc-headers-5.10-r0: task do_package_write_rpm: Started
#12 2734.4 2021-03-30 01:14:29 - INFO     - NOTE: recipe lzo-native-2.10-r0: task do_prepare_recipe_sysroot: Started
#12 2734.8 2021-03-30 01:14:30 - INFO     - NOTE: recipe lzo-native-2.10-r0: task do_prepare_recipe_sysroot: Succeeded
#12 2734.9 2021-03-30 01:14:30 - INFO     - NOTE: Running task 2441 of 4982 (virtual:native:/home/pi/docker-meta-raspberrypi/layers/poky/meta/recipes-support/lzo/lzo_2.10.bb:do_configure)
#12 2735.0 2021-03-30 01:14:30 - ERROR    - ERROR: linux-libc-headers-5.10-r0 do_package_write_rpm: Error executing a python function in exec_python_func() autogenerated:
#12 2735.0 2021-03-30 01:14:30 - ERROR    - 
#12 2735.0 2021-03-30 01:14:30 - ERROR    - The stack trace of python calls that resulted in this exception/failure was:
#12 2735.0 2021-03-30 01:14:30 - ERROR    - File: 'exec_python_func() autogenerated', lineno: 2, function: <module>
#12 2735.0 2021-03-30 01:14:30 - ERROR    - 0001:
#12 2735.0 2021-03-30 01:14:30 - ERROR    - *** 0002:write_specfile(d)
#12 2735.0 2021-03-30 01:14:30 - ERROR    - 0003:
#12 2735.0 2021-03-30 01:14:30 - ERROR    - File: '/home/pi/docker-meta-raspberrypi/layers/poky/meta/classes/package_rpm.bbclass', lineno: 342, function: write_specfile
#12 2735.0 2021-03-30 01:14:30 - ERROR    - 0338:        localdata.setVar('PKG', pkgname)
#12 2735.0 2021-03-30 01:14:30 - ERROR    - 0339:
#12 2735.0 2021-03-30 01:14:30 - ERROR    - 0340:        localdata.setVar('OVERRIDES', d.getVar("OVERRIDES", False) + ":" + pkg)
#12 2735.0 2021-03-30 01:14:30 - ERROR    - 0341:
#12 2735.0 2021-03-30 01:14:30 - ERROR    - *** 0342:        conffiles = get_conffiles(pkg, d)
#12 2735.0 2021-03-30 01:14:30 - ERROR    - 0343:        dirfiles = localdata.getVar('DIRFILES')
#12 2735.0 2021-03-30 01:14:30 - ERROR    - 0344:        if dirfiles is not None:
#12 2735.0 2021-03-30 01:14:30 - ERROR    - 0345:            dirfiles = dirfiles.split()
#12 2735.0 2021-03-30 01:14:30 - ERROR    - 0346:
#12 2735.0 2021-03-30 01:14:30 - ERROR    - File: '/home/pi/docker-meta-raspberrypi/layers/poky/meta/classes/package.bbclass', lineno: 304, function: get_conffiles
#12 2735.0 2021-03-30 01:14:30 - ERROR    - 0300:def get_conffiles(pkg, d):
#12 2735.0 2021-03-30 01:14:30 - ERROR    - 0301:    pkgdest = d.getVar('PKGDEST')
#12 2735.0 2021-03-30 01:14:30 - ERROR    - 0302:    root = os.path.join(pkgdest, pkg)
#12 2735.0 2021-03-30 01:14:30 - ERROR    - 0303:    cwd = os.getcwd()
#12 2735.0 2021-03-30 01:14:30 - ERROR    - *** 0304:    os.chdir(root)
#12 2735.0 2021-03-30 01:14:30 - ERROR    - 0305:
#12 2735.0 2021-03-30 01:14:30 - ERROR    - 0306:    conffiles = d.getVar('CONFFILES_%s' % pkg);
#12 2735.0 2021-03-30 01:14:30 - ERROR    - 0307:    if conffiles == None:
#12 2735.0 2021-03-30 01:14:30 - ERROR    - 0308:        conffiles = d.getVar('CONFFILES')
#12 2735.0 2021-03-30 01:14:30 - ERROR    - Exception: FileNotFoundError: [Errno 2] No such file or directory: '/home/pi/docker-meta-raspberrypi/build/tmp/work/arm1176jzfshf-vfp-poky-linux-gnueabi/linux-libc-headers/5.10-r0/packages-split/linux-libc-headers-src'

A fully reproducible build can be found at https://github.com/tewarid/docker-meta-raspberrypi/tree/ee083820c565da646b745bc25e439c13f3205dbe. Please see build instructions in the readme.

I can’t seem to find a root cause and don’t have the time to look into this any further.

On 29 Mar 2021, at 20:13, Devendra Tewari <devendra.tewari@...> wrote:

Will do. Thanks.

On 29 Mar 2021, at 20:10, Andre McCurdy <armccurdy@...> wrote:

On Mon, Mar 29, 2021 at 4:07 PM Devendra Tewari
<devendra.tewari@...> wrote:

I did try that but got an error that does not happen when we try os.rename first. I'll try to reproduce it again.

I suspect there may be subtle differences in os.rename vs shutil.move with respect to what happens when origin and/or destination do not exist or are invalid.

If there are subtle issues which you don't yet understand then that's
all the more reason for not hiding the new shutil.move code behind a
test which will pass for 99.9% of users. Please figure that out before
sending another version of the patch.

On 29 Mar 2021, at 20:00, Andre McCurdy <armccurdy@...> wrote:

On Mon, Mar 29, 2021 at 3:45 PM Devendra Tewari
<devendra.tewari@...> wrote:

Thanks! My bad. The example I looked up in Python docs had a break and I just realized it was a looping example.

Here’s the updated patch (or should I submit it again via git send-email?)

It would be better to use shutil.move unconditionally in all cases,
rather than have a separate shutil.move code path which only gets
tested by people doing incremental builds in docker.




Richard Purdie
 

On Mon, 2021-03-29 at 16:00 -0700, Andre McCurdy wrote:
On Mon, Mar 29, 2021 at 3:45 PM Devendra Tewari
<devendra.tewari@...> wrote:

Thanks! My bad. The example I looked up in Python docs had a break and I just realized it was a looping example.

Here’s the updated patch (or should I submit it again via git send-email?)
It would be better to use shutil.move unconditionally in all cases,
rather than have a separate shutil.move code path which only gets
tested by people doing incremental builds in docker.
This is a speed sensitive section of code and shutil has traditionally proved 
to be slow so I disagree with that, rename is very much preferred here where
we can.

Cheers,

Richard


Devendra Tewari
 

I understand that parallel tasks can result in such issues, but would expect some kind of dependency graph that would prevent them from happening. I wish I had more time to understand the issue fully.

Here’s the last version of my patch that still uses os.rename, and on error uses shutil.move, with the reasoning explained in the commit message. There are tons of os.rename in code elsewhere, and I’ve encountered similar issues when doing incremental builds, but I’ll leave fixing them to those with more time at hand. Cheers.

From aeba1f9728f69cdf2ce4ba285be86761d8024f9d Mon Sep 17 00:00:00 2001
From: Devendra Tewari <devendra.tewari@...>
Date: Tue, 30 Mar 2021 08:27:40 -0300
Subject: [PATCH] Use shutil.move when os.rename fails

Incremental build in Docker fails with

OSError: [Errno 18] Invalid cross-device link

When source and destination are on different overlay filesystems.

This change handles error with os.rename and retries with shutil.move.
The reason os.rename is still used is because shutil.move is too slow
for speed sensitive sections of code.
---
meta/classes/sstate.bbclass | 22 ++++++++++++++++++----
1 file changed, 18 insertions(+), 4 deletions(-)

diff --git a/meta/classes/sstate.bbclass b/meta/classes/sstate.bbclass
index f579168162..301dfc27db 100644
--- a/meta/classes/sstate.bbclass
+++ b/meta/classes/sstate.bbclass
@@ -384,6 +384,7 @@ def sstate_installpkg(ss, d):
def sstate_installpkgdir(ss, d):
import oe.path
import subprocess
+ import shutil

sstateinst = d.getVar("SSTATE_INSTDIR")
d.setVar('SSTATE_FIXMEDIR', ss['fixmedir'])
@@ -401,7 +402,10 @@ def sstate_installpkgdir(ss, d):

for state in ss['dirs']:
prepdir(state[1])
- os.rename(sstateinst + state[0], state[1])
+ try:
+ os.rename(sstateinst + state[0], state[1])
+ except OSError:
+ shutil.move(sstateinst + state[0], state[1])
sstate_install(ss, d)

for plain in ss['plaindirs']:
@@ -413,7 +417,10 @@ def sstate_installpkgdir(ss, d):
dest = plain
bb.utils.mkdirhier(src)
prepdir(dest)
- os.rename(src, dest)
+ try:
+ os.rename(src, dest)
+ except OSError:
+ shutil.move(src, dest)

return True

@@ -638,6 +645,7 @@ python sstate_hardcode_path () {

def sstate_package(ss, d):
import oe.path
+ import shutil

tmpdir = d.getVar('TMPDIR')

@@ -664,7 +672,10 @@ def sstate_package(ss, d):
continue
bb.error("sstate found an absolute path symlink %s pointing at %s. Please replace this with a relative link." % (srcpath, link))
bb.debug(2, "Preparing tree %s for packaging at %s" % (state[1], sstatebuild + state[0]))
- os.rename(state[1], sstatebuild + state[0])
+ try:
+ os.rename(state[1], sstatebuild + state[0])
+ except OSError:
+ shutil.move(state[1], sstatebuild + state[0])

workdir = d.getVar('WORKDIR')
sharedworkdir = os.path.join(d.getVar('TMPDIR'), "work-shared")
@@ -674,7 +685,10 @@ def sstate_package(ss, d):
pdir = plain.replace(sharedworkdir, sstatebuild)
bb.utils.mkdirhier(plain)
bb.utils.mkdirhier(pdir)
- os.rename(plain, pdir)
+ try:
+ os.rename(plain, pdir)
+ except OSError:
+ shutil.move(plain, pdir)

d.setVar('SSTATE_BUILDDIR', sstatebuild)
d.setVar('SSTATE_INSTDIR', sstatebuild)
--
2.29.2

On 30 Mar 2021, at 08:10, Richard Purdie <richard.purdie@...> wrote:

On Mon, 2021-03-29 at 16:00 -0700, Andre McCurdy wrote:
On Mon, Mar 29, 2021 at 3:45 PM Devendra Tewari
<devendra.tewari@...> wrote:

Thanks! My bad. The example I looked up in Python docs had a break and I just realized it was a looping example.

Here’s the updated patch (or should I submit it again via git send-email?)
It would be better to use shutil.move unconditionally in all cases,
rather than have a separate shutil.move code path which only gets
tested by people doing incremental builds in docker.
This is a speed sensitive section of code and shutil has traditionally proved
to be slow so I disagree with that, rename is very much preferred here where
we can.

Cheers,

Richard


Denys Dmytriyenko
 

The link is for a 10-year old bug, probably not what you wanted.
Also, if a patch fixes existing bug in bugzilla, it needs to reference it in
commit message as well - [YOCTO#1234567]

On Mon, Mar 29, 2021 at 12:37:45PM -0300, Devendra Tewari wrote:
Also, this is due to https://bugzilla.yoctoproject.org/show_bug.cgi?id=1430.

On 29 Mar 2021, at 12:35, Devendra Tewari <devendra.tewari@...> wrote:

Sure.

Would the following commit message be sufficient?

Use shutil.move when os.rename fails

Incremental build in Docker fails with

OSError: [Errno 18] Invalid cross-device link

When source and destination are on different overlay filesystems.

This change handles the error with os.rename and retries with shutil.move.

Thanks,
Devendra

On 29 Mar 2021, at 12:23, Konrad Weihmann <kweihmann@...> wrote:

Yes please quote a bit from the python manpage [1] - I certainly see the difference (and the edge cases where os.rename might fail), but that should be documented as part of the commit message

[1] https://docs.python.org/3/library/shutil.html#shutil.move

On 29.03.21 17:21, Bruce Ashfield wrote:
Can you document the cases that os.rename() is failing ? And also why
would we expect the shutil.move() to work in those cases ?
If a change like this cases issues in the future, we need that extra
information in the commit head for proper triage.
Bruce
On Mon, Mar 29, 2021 at 11:16 AM Devendra Tewari
<devendra.tewari@...> wrote:

---
meta/classes/sstate.bbclass | 26 ++++++++++++++++++++++----
1 file changed, 22 insertions(+), 4 deletions(-)

diff --git a/meta/classes/sstate.bbclass b/meta/classes/sstate.bbclass
index f579168162..f94aa96d70 100644
--- a/meta/classes/sstate.bbclass
+++ b/meta/classes/sstate.bbclass
@@ -384,6 +384,7 @@ def sstate_installpkg(ss, d):
def sstate_installpkgdir(ss, d):
import oe.path
import subprocess
+ import shutil

sstateinst = d.getVar("SSTATE_INSTDIR")
d.setVar('SSTATE_FIXMEDIR', ss['fixmedir'])
@@ -401,7 +402,11 @@ def sstate_installpkgdir(ss, d):

for state in ss['dirs']:
prepdir(state[1])
- os.rename(sstateinst + state[0], state[1])
+ try:
+ os.rename(sstateinst + state[0], state[1])
+ break
+ except OSError:
+ shutil.move(sstateinst + state[0], state[1])
sstate_install(ss, d)

for plain in ss['plaindirs']:
@@ -413,7 +418,11 @@ def sstate_installpkgdir(ss, d):
dest = plain
bb.utils.mkdirhier(src)
prepdir(dest)
- os.rename(src, dest)
+ try:
+ os.rename(src, dest)
+ break
+ except OSError:
+ shutil.move(src, dest)

return True

@@ -638,6 +647,7 @@ python sstate_hardcode_path () {

def sstate_package(ss, d):
import oe.path
+ import shutil

tmpdir = d.getVar('TMPDIR')

@@ -664,7 +674,11 @@ def sstate_package(ss, d):
continue
bb.error("sstate found an absolute path symlink %s pointing at %s. Please replace this with a relative link." % (srcpath, link))
bb.debug(2, "Preparing tree %s for packaging at %s" % (state[1], sstatebuild + state[0]))
- os.rename(state[1], sstatebuild + state[0])
+ try:
+ os.rename(state[1], sstatebuild + state[0])
+ break
+ except OSError:
+ shutil.move(state[1], sstatebuild + state[0])

workdir = d.getVar('WORKDIR')
sharedworkdir = os.path.join(d.getVar('TMPDIR'), "work-shared")
@@ -674,7 +688,11 @@ def sstate_package(ss, d):
pdir = plain.replace(sharedworkdir, sstatebuild)
bb.utils.mkdirhier(plain)
bb.utils.mkdirhier(pdir)
- os.rename(plain, pdir)
+ try:
+ os.rename(plain, pdir)
+ break
+ except OSError:
+ shutil.move(plain, pdir)

d.setVar('SSTATE_BUILDDIR', sstatebuild)
d.setVar('SSTATE_INSTDIR', sstatebuild)
--
2.29.2




Devendra Tewari
 

Here's the correct link https://bugzilla.yoctoproject.org/show_bug.cgi?id=14301. I'll resubmit the patch referencing the bug in the commit message. Thanks.

Em 30 de mar. de 2021, à(s) 18:59, Denys Dmytriyenko <denis@...> escreveu:

The link is for a 10-year old bug, probably not what you wanted.
Also, if a patch fixes existing bug in bugzilla, it needs to reference it in
commit message as well - [YOCTO#1234567]


On Mon, Mar 29, 2021 at 12:37:45PM -0300, Devendra Tewari wrote:
Also, this is due to https://bugzilla.yoctoproject.org/show_bug.cgi?id=1430.

On 29 Mar 2021, at 12:35, Devendra Tewari <devendra.tewari@...> wrote:

Sure.

Would the following commit message be sufficient?

  Use shutil.move when os.rename fails

  Incremental build in Docker fails with

  OSError: [Errno 18] Invalid cross-device link

  When source and destination are on different overlay filesystems.

  This change handles the error with os.rename and retries with shutil.move.

Thanks,
Devendra

On 29 Mar 2021, at 12:23, Konrad Weihmann <kweihmann@...> wrote:

Yes please quote a bit from the python manpage [1] - I certainly see the difference (and the edge cases where os.rename might fail), but that should be documented as part of the commit message

[1] https://docs.python.org/3/library/shutil.html#shutil.move

On 29.03.21 17:21, Bruce Ashfield wrote:
Can you document the cases that os.rename() is failing ? And also why
would we expect the shutil.move() to work in those cases ?
If a change like this cases issues in the future, we need that extra
information in the commit head for proper triage.
Bruce
On Mon, Mar 29, 2021 at 11:16 AM Devendra Tewari
<devendra.tewari@...> wrote:

---
meta/classes/sstate.bbclass | 26 ++++++++++++++++++++++----
1 file changed, 22 insertions(+), 4 deletions(-)

diff --git a/meta/classes/sstate.bbclass b/meta/classes/sstate.bbclass
index f579168162..f94aa96d70 100644
--- a/meta/classes/sstate.bbclass
+++ b/meta/classes/sstate.bbclass
@@ -384,6 +384,7 @@ def sstate_installpkg(ss, d):
def sstate_installpkgdir(ss, d):
   import oe.path
   import subprocess
+    import shutil

   sstateinst = d.getVar("SSTATE_INSTDIR")
   d.setVar('SSTATE_FIXMEDIR', ss['fixmedir'])
@@ -401,7 +402,11 @@ def sstate_installpkgdir(ss, d):

   for state in ss['dirs']:
       prepdir(state[1])
-        os.rename(sstateinst + state[0], state[1])
+        try:
+            os.rename(sstateinst + state[0], state[1])
+            break
+        except OSError:
+            shutil.move(sstateinst + state[0], state[1])
   sstate_install(ss, d)

   for plain in ss['plaindirs']:
@@ -413,7 +418,11 @@ def sstate_installpkgdir(ss, d):
       dest = plain
       bb.utils.mkdirhier(src)
       prepdir(dest)
-        os.rename(src, dest)
+        try:
+            os.rename(src, dest)
+            break
+        except OSError:
+            shutil.move(src, dest)

   return True

@@ -638,6 +647,7 @@ python sstate_hardcode_path () {

def sstate_package(ss, d):
   import oe.path
+    import shutil

   tmpdir = d.getVar('TMPDIR')

@@ -664,7 +674,11 @@ def sstate_package(ss, d):
                   continue
               bb.error("sstate found an absolute path symlink %s pointing at %s. Please replace this with a relative link." % (srcpath, link))
       bb.debug(2, "Preparing tree %s for packaging at %s" % (state[1], sstatebuild + state[0]))
-        os.rename(state[1], sstatebuild + state[0])
+        try:
+            os.rename(state[1], sstatebuild + state[0])
+            break
+        except OSError:
+            shutil.move(state[1], sstatebuild + state[0])

   workdir = d.getVar('WORKDIR')
   sharedworkdir = os.path.join(d.getVar('TMPDIR'), "work-shared")
@@ -674,7 +688,11 @@ def sstate_package(ss, d):
           pdir = plain.replace(sharedworkdir, sstatebuild)
       bb.utils.mkdirhier(plain)
       bb.utils.mkdirhier(pdir)
-        os.rename(plain, pdir)
+        try:
+            os.rename(plain, pdir)
+            break
+        except OSError:
+            shutil.move(plain, pdir)

   d.setVar('SSTATE_BUILDDIR', sstatebuild)
   d.setVar('SSTATE_INSTDIR', sstatebuild)
--
2.29.2








Devendra Tewari
 

From 57b633a93bd91b7b1aa21cce5ac7997b958ca917 Mon Sep 17 00:00:00 2001
From: Devendra Tewari <devendra.tewari@...>
Date: Thu, 1 Apr 2021 16:07:25 -0300
Subject: [PATCH] Use shutil.move when os.rename fails

Incremental build in Docker fails with

OSError: [Errno 18] Invalid cross-device link

When source and destination are on different overlay filesystems.

This change handles error with os.rename and retries with shutil.move.
The reason os.rename is still used is because shutil.move is too slow
for speed sensitive sections of code.

[Yocto #14301]
---
 meta/classes/sstate.bbclass | 22 ++++++++++++++++++----
 1 file changed, 18 insertions(+), 4 deletions(-)

diff --git a/meta/classes/sstate.bbclass b/meta/classes/sstate.bbclass
index 8e8efd18d5..60f7a94285 100644
--- a/meta/classes/sstate.bbclass
+++ b/meta/classes/sstate.bbclass
@@ -384,6 +384,7 @@ def sstate_installpkg(ss, d):
 def sstate_installpkgdir(ss, d):
     import oe.path
     import subprocess
+    import shutil
 
     sstateinst = d.getVar("SSTATE_INSTDIR")
     d.setVar('SSTATE_FIXMEDIR', ss['fixmedir'])
@@ -401,7 +402,10 @@ def sstate_installpkgdir(ss, d):
 
     for state in ss['dirs']:
         prepdir(state[1])
-        os.rename(sstateinst + state[0], state[1])
+        try:
+            os.rename(sstateinst + state[0], state[1])
+        except OSError:
+            shutil.move(sstateinst + state[0], state[1])
     sstate_install(ss, d)
 
     for plain in ss['plaindirs']:
@@ -413,7 +417,10 @@ def sstate_installpkgdir(ss, d):
         dest = plain
         bb.utils.mkdirhier(src)
         prepdir(dest)
-        os.rename(src, dest)
+        try:
+            os.rename(src, dest)
+        except OSError:
+            shutil.move(src, dest)
 
     return True
 
@@ -638,6 +645,7 @@ python sstate_hardcode_path () {
 
 def sstate_package(ss, d):
     import oe.path
+    import shutil
 
     tmpdir = d.getVar('TMPDIR')
 
@@ -664,7 +672,10 @@ def sstate_package(ss, d):
                     continue
                 bb.error("sstate found an absolute path symlink %s pointing at %s. Please replace this with a relative link." % (srcpath, link))
         bb.debug(2, "Preparing tree %s for packaging at %s" % (state[1], sstatebuild + state[0]))
-        os.rename(state[1], sstatebuild + state[0])
+        try:
+            os.rename(state[1], sstatebuild + state[0])
+        except OSError:
+            shutil.move(state[1], sstatebuild + state[0])
 
     workdir = d.getVar('WORKDIR')
     sharedworkdir = os.path.join(d.getVar('TMPDIR'), "work-shared")
@@ -674,7 +685,10 @@ def sstate_package(ss, d):
             pdir = plain.replace(sharedworkdir, sstatebuild)
         bb.utils.mkdirhier(plain)
         bb.utils.mkdirhier(pdir)
-        os.rename(plain, pdir)
+        try:
+            os.rename(plain, pdir)
+        except OSError:
+            shutil.move(plain, pdir)
 
     d.setVar('SSTATE_BUILDDIR', sstatebuild)
     d.setVar('SSTATE_INSTDIR', sstatebuild)
-- 
2.29.2


On Tue, Mar 30, 2021 at 7:39 PM Devendra Tewari <devendra.tewari@...> wrote:
Here's the correct link https://bugzilla.yoctoproject.org/show_bug.cgi?id=14301. I'll resubmit the patch referencing the bug in the commit message. Thanks.

Em 30 de mar. de 2021, à(s) 18:59, Denys Dmytriyenko <denis@...> escreveu:

The link is for a 10-year old bug, probably not what you wanted.
Also, if a patch fixes existing bug in bugzilla, it needs to reference it in
commit message as well - [YOCTO#1234567]


On Mon, Mar 29, 2021 at 12:37:45PM -0300, Devendra Tewari wrote:
Also, this is due to https://bugzilla.yoctoproject.org/show_bug.cgi?id=1430.

On 29 Mar 2021, at 12:35, Devendra Tewari <devendra.tewari@...> wrote:

Sure.

Would the following commit message be sufficient?

  Use shutil.move when os.rename fails

  Incremental build in Docker fails with

  OSError: [Errno 18] Invalid cross-device link

  When source and destination are on different overlay filesystems.

  This change handles the error with os.rename and retries with shutil.move.

Thanks,
Devendra

On 29 Mar 2021, at 12:23, Konrad Weihmann <kweihmann@...> wrote:

Yes please quote a bit from the python manpage [1] - I certainly see the difference (and the edge cases where os.rename might fail), but that should be documented as part of the commit message

[1] https://docs.python.org/3/library/shutil.html#shutil.move

On 29.03.21 17:21, Bruce Ashfield wrote:
Can you document the cases that os.rename() is failing ? And also why
would we expect the shutil.move() to work in those cases ?
If a change like this cases issues in the future, we need that extra
information in the commit head for proper triage.
Bruce
On Mon, Mar 29, 2021 at 11:16 AM Devendra Tewari
<devendra.tewari@...> wrote:

---
meta/classes/sstate.bbclass | 26 ++++++++++++++++++++++----
1 file changed, 22 insertions(+), 4 deletions(-)

diff --git a/meta/classes/sstate.bbclass b/meta/classes/sstate.bbclass
index f579168162..f94aa96d70 100644
--- a/meta/classes/sstate.bbclass
+++ b/meta/classes/sstate.bbclass
@@ -384,6 +384,7 @@ def sstate_installpkg(ss, d):
def sstate_installpkgdir(ss, d):
   import oe.path
   import subprocess
+    import shutil

   sstateinst = d.getVar("SSTATE_INSTDIR")
   d.setVar('SSTATE_FIXMEDIR', ss['fixmedir'])
@@ -401,7 +402,11 @@ def sstate_installpkgdir(ss, d):

   for state in ss['dirs']:
       prepdir(state[1])
-        os.rename(sstateinst + state[0], state[1])
+        try:
+            os.rename(sstateinst + state[0], state[1])
+            break
+        except OSError:
+            shutil.move(sstateinst + state[0], state[1])
   sstate_install(ss, d)

   for plain in ss['plaindirs']:
@@ -413,7 +418,11 @@ def sstate_installpkgdir(ss, d):
       dest = plain
       bb.utils.mkdirhier(src)
       prepdir(dest)
-        os.rename(src, dest)
+        try:
+            os.rename(src, dest)
+            break
+        except OSError:
+            shutil.move(src, dest)

   return True

@@ -638,6 +647,7 @@ python sstate_hardcode_path () {

def sstate_package(ss, d):
   import oe.path
+    import shutil

   tmpdir = d.getVar('TMPDIR')

@@ -664,7 +674,11 @@ def sstate_package(ss, d):
                   continue
               bb.error("sstate found an absolute path symlink %s pointing at %s. Please replace this with a relative link." % (srcpath, link))
       bb.debug(2, "Preparing tree %s for packaging at %s" % (state[1], sstatebuild + state[0]))
-        os.rename(state[1], sstatebuild + state[0])
+        try:
+            os.rename(state[1], sstatebuild + state[0])
+            break
+        except OSError:
+            shutil.move(state[1], sstatebuild + state[0])

   workdir = d.getVar('WORKDIR')
   sharedworkdir = os.path.join(d.getVar('TMPDIR'), "work-shared")
@@ -674,7 +688,11 @@ def sstate_package(ss, d):
           pdir = plain.replace(sharedworkdir, sstatebuild)
       bb.utils.mkdirhier(plain)
       bb.utils.mkdirhier(pdir)
-        os.rename(plain, pdir)
+        try:
+            os.rename(plain, pdir)
+            break
+        except OSError:
+            shutil.move(plain, pdir)

   d.setVar('SSTATE_BUILDDIR', sstatebuild)
   d.setVar('SSTATE_INSTDIR', sstatebuild)
--
2.29.2








Devendra Tewari
 

On 30 Mar 2021, at 08:55, Devendra Tewari <devendra.tewari@...> wrote:

I understand that parallel tasks can result in such issues, but would expect some kind of dependency graph that would prevent them from happening. I wish I had more time to understand the issue fully.

Here’s the last version of my patch that still uses os.rename, and on error uses shutil.move, with the reasoning explained in the commit message. There are tons of os.rename in code elsewhere, and I’ve encountered similar issues when doing incremental builds, but I’ll leave fixing them to those with more time at hand. Cheers.
Here’s a patch that catches error with all os.rename in the code, and retries with shutil.move when that happens.



From aeba1f9728f69cdf2ce4ba285be86761d8024f9d Mon Sep 17 00:00:00 2001
From: Devendra Tewari <devendra.tewari@...>
Date: Tue, 30 Mar 2021 08:27:40 -0300
Subject: [PATCH] Use shutil.move when os.rename fails

Incremental build in Docker fails with

OSError: [Errno 18] Invalid cross-device link

When source and destination are on different overlay filesystems.

This change handles error with os.rename and retries with shutil.move.
The reason os.rename is still used is because shutil.move is too slow
for speed sensitive sections of code.
---
meta/classes/sstate.bbclass | 22 ++++++++++++++++++----
1 file changed, 18 insertions(+), 4 deletions(-)

diff --git a/meta/classes/sstate.bbclass b/meta/classes/sstate.bbclass
index f579168162..301dfc27db 100644
--- a/meta/classes/sstate.bbclass
+++ b/meta/classes/sstate.bbclass
@@ -384,6 +384,7 @@ def sstate_installpkg(ss, d):
def sstate_installpkgdir(ss, d):
import oe.path
import subprocess
+ import shutil

sstateinst = d.getVar("SSTATE_INSTDIR")
d.setVar('SSTATE_FIXMEDIR', ss['fixmedir'])
@@ -401,7 +402,10 @@ def sstate_installpkgdir(ss, d):

for state in ss['dirs']:
prepdir(state[1])
- os.rename(sstateinst + state[0], state[1])
+ try:
+ os.rename(sstateinst + state[0], state[1])
+ except OSError:
+ shutil.move(sstateinst + state[0], state[1])
sstate_install(ss, d)

for plain in ss['plaindirs']:
@@ -413,7 +417,10 @@ def sstate_installpkgdir(ss, d):
dest = plain
bb.utils.mkdirhier(src)
prepdir(dest)
- os.rename(src, dest)
+ try:
+ os.rename(src, dest)
+ except OSError:
+ shutil.move(src, dest)

return True

@@ -638,6 +645,7 @@ python sstate_hardcode_path () {

def sstate_package(ss, d):
import oe.path
+ import shutil

tmpdir = d.getVar('TMPDIR')

@@ -664,7 +672,10 @@ def sstate_package(ss, d):
continue
bb.error("sstate found an absolute path symlink %s pointing at %s. Please replace this with a relative link." % (srcpath, link))
bb.debug(2, "Preparing tree %s for packaging at %s" % (state[1], sstatebuild + state[0]))
- os.rename(state[1], sstatebuild + state[0])
+ try:
+ os.rename(state[1], sstatebuild + state[0])
+ except OSError:
+ shutil.move(state[1], sstatebuild + state[0])

workdir = d.getVar('WORKDIR')
sharedworkdir = os.path.join(d.getVar('TMPDIR'), "work-shared")
@@ -674,7 +685,10 @@ def sstate_package(ss, d):
pdir = plain.replace(sharedworkdir, sstatebuild)
bb.utils.mkdirhier(plain)
bb.utils.mkdirhier(pdir)
- os.rename(plain, pdir)
+ try:
+ os.rename(plain, pdir)
+ except OSError:
+ shutil.move(plain, pdir)

d.setVar('SSTATE_BUILDDIR', sstatebuild)
d.setVar('SSTATE_INSTDIR', sstatebuild)
--
2.29.2


On 30 Mar 2021, at 08:10, Richard Purdie <richard.purdie@...> wrote:

On Mon, 2021-03-29 at 16:00 -0700, Andre McCurdy wrote:
On Mon, Mar 29, 2021 at 3:45 PM Devendra Tewari
<devendra.tewari@...> wrote:

Thanks! My bad. The example I looked up in Python docs had a break and I just realized it was a looping example.

Here’s the updated patch (or should I submit it again via git send-email?)
It would be better to use shutil.move unconditionally in all cases,
rather than have a separate shutil.move code path which only gets
tested by people doing incremental builds in docker.
This is a speed sensitive section of code and shutil has traditionally proved
to be slow so I disagree with that, rename is very much preferred here where
we can.

Cheers,

Richard


Khem Raj
 

None of my images are bootable when this patch is applied, because
symlinks that busybox should provide arent created in the image. This
patch should be looked into a bit further, how was it tested ?

On Mon, Apr 19, 2021 at 11:43 AM Devendra Tewari
<devendra.tewari@...> wrote:



On 30 Mar 2021, at 08:55, Devendra Tewari <devendra.tewari@...> wrote:

I understand that parallel tasks can result in such issues, but would expect some kind of dependency graph that would prevent them from happening. I wish I had more time to understand the issue fully.

Here’s the last version of my patch that still uses os.rename, and on error uses shutil.move, with the reasoning explained in the commit message. There are tons of os.rename in code elsewhere, and I’ve encountered similar issues when doing incremental builds, but I’ll leave fixing them to those with more time at hand. Cheers.
Here’s a patch that catches error with all os.rename in the code, and retries with shutil.move when that happens.



From aeba1f9728f69cdf2ce4ba285be86761d8024f9d Mon Sep 17 00:00:00 2001
From: Devendra Tewari <devendra.tewari@...>
Date: Tue, 30 Mar 2021 08:27:40 -0300
Subject: [PATCH] Use shutil.move when os.rename fails

Incremental build in Docker fails with

OSError: [Errno 18] Invalid cross-device link

When source and destination are on different overlay filesystems.

This change handles error with os.rename and retries with shutil.move.
The reason os.rename is still used is because shutil.move is too slow
for speed sensitive sections of code.
---
meta/classes/sstate.bbclass | 22 ++++++++++++++++++----
1 file changed, 18 insertions(+), 4 deletions(-)

diff --git a/meta/classes/sstate.bbclass b/meta/classes/sstate.bbclass
index f579168162..301dfc27db 100644
--- a/meta/classes/sstate.bbclass
+++ b/meta/classes/sstate.bbclass
@@ -384,6 +384,7 @@ def sstate_installpkg(ss, d):
def sstate_installpkgdir(ss, d):
import oe.path
import subprocess
+ import shutil

sstateinst = d.getVar("SSTATE_INSTDIR")
d.setVar('SSTATE_FIXMEDIR', ss['fixmedir'])
@@ -401,7 +402,10 @@ def sstate_installpkgdir(ss, d):

for state in ss['dirs']:
prepdir(state[1])
- os.rename(sstateinst + state[0], state[1])
+ try:
+ os.rename(sstateinst + state[0], state[1])
+ except OSError:
+ shutil.move(sstateinst + state[0], state[1])
sstate_install(ss, d)

for plain in ss['plaindirs']:
@@ -413,7 +417,10 @@ def sstate_installpkgdir(ss, d):
dest = plain
bb.utils.mkdirhier(src)
prepdir(dest)
- os.rename(src, dest)
+ try:
+ os.rename(src, dest)
+ except OSError:
+ shutil.move(src, dest)

return True

@@ -638,6 +645,7 @@ python sstate_hardcode_path () {

def sstate_package(ss, d):
import oe.path
+ import shutil

tmpdir = d.getVar('TMPDIR')

@@ -664,7 +672,10 @@ def sstate_package(ss, d):
continue
bb.error("sstate found an absolute path symlink %s pointing at %s. Please replace this with a relative link." % (srcpath, link))
bb.debug(2, "Preparing tree %s for packaging at %s" % (state[1], sstatebuild + state[0]))
- os.rename(state[1], sstatebuild + state[0])
+ try:
+ os.rename(state[1], sstatebuild + state[0])
+ except OSError:
+ shutil.move(state[1], sstatebuild + state[0])

workdir = d.getVar('WORKDIR')
sharedworkdir = os.path.join(d.getVar('TMPDIR'), "work-shared")
@@ -674,7 +685,10 @@ def sstate_package(ss, d):
pdir = plain.replace(sharedworkdir, sstatebuild)
bb.utils.mkdirhier(plain)
bb.utils.mkdirhier(pdir)
- os.rename(plain, pdir)
+ try:
+ os.rename(plain, pdir)
+ except OSError:
+ shutil.move(plain, pdir)

d.setVar('SSTATE_BUILDDIR', sstatebuild)
d.setVar('SSTATE_INSTDIR', sstatebuild)
--
2.29.2


On 30 Mar 2021, at 08:10, Richard Purdie <richard.purdie@...> wrote:

On Mon, 2021-03-29 at 16:00 -0700, Andre McCurdy wrote:
On Mon, Mar 29, 2021 at 3:45 PM Devendra Tewari
<devendra.tewari@...> wrote:

Thanks! My bad. The example I looked up in Python docs had a break and I just realized it was a looping example.

Here’s the updated patch (or should I submit it again via git send-email?)
It would be better to use shutil.move unconditionally in all cases,
rather than have a separate shutil.move code path which only gets
tested by people doing incremental builds in docker.
This is a speed sensitive section of code and shutil has traditionally proved
to be slow so I disagree with that, rename is very much preferred here where
we can.

Cheers,

Richard




Devendra Tewari
 

I created an image for Raspberry Pi Zero W from code at https://github.com/tewarid/docker-meta-raspberrypi/tree/sstate, using Docker for macOS, and on Ubuntu 20.04-LTS, and wrote it out to an SDCard using bmaptool. Booted and checked that busybox symlinks in rootfs look all right.

Em 21 de abr. de 2021, à(s) 02:22, Khem Raj <raj.khem@...> escreveu:

None of my images are bootable when this patch is applied, because
symlinks that busybox should provide arent created in the image. This
patch should be looked into a bit further,  how was it tested ?

On Mon, Apr 19, 2021 at 11:43 AM Devendra Tewari
<devendra.tewari@...> wrote:



On 30 Mar 2021, at 08:55, Devendra Tewari <devendra.tewari@...> wrote:

I understand that parallel tasks can result in such issues, but would expect some kind of dependency graph that would prevent them from happening. I wish I had more time to understand the issue fully.

Here’s the last version of my patch that still uses os.rename, and on error uses shutil.move, with the reasoning explained in the commit message. There are tons of os.rename in code elsewhere, and I’ve encountered similar issues when doing incremental builds, but I’ll leave fixing them to those with more time at hand. Cheers.

Here’s a patch that catches error with all os.rename in the code, and retries with shutil.move when that happens.



From aeba1f9728f69cdf2ce4ba285be86761d8024f9d Mon Sep 17 00:00:00 2001
From: Devendra Tewari <devendra.tewari@...>
Date: Tue, 30 Mar 2021 08:27:40 -0300
Subject: [PATCH] Use shutil.move when os.rename fails

Incremental build in Docker fails with

OSError: [Errno 18] Invalid cross-device link

When source and destination are on different overlay filesystems.

This change handles error with os.rename and retries with shutil.move.
The reason os.rename is still used is because shutil.move is too slow
for speed sensitive sections of code.
---
meta/classes/sstate.bbclass | 22 ++++++++++++++++++----
1 file changed, 18 insertions(+), 4 deletions(-)

diff --git a/meta/classes/sstate.bbclass b/meta/classes/sstate.bbclass
index f579168162..301dfc27db 100644
--- a/meta/classes/sstate.bbclass
+++ b/meta/classes/sstate.bbclass
@@ -384,6 +384,7 @@ def sstate_installpkg(ss, d):
def sstate_installpkgdir(ss, d):
  import oe.path
  import subprocess
+    import shutil

  sstateinst = d.getVar("SSTATE_INSTDIR")
  d.setVar('SSTATE_FIXMEDIR', ss['fixmedir'])
@@ -401,7 +402,10 @@ def sstate_installpkgdir(ss, d):

  for state in ss['dirs']:
      prepdir(state[1])
-        os.rename(sstateinst + state[0], state[1])
+        try:
+            os.rename(sstateinst + state[0], state[1])
+        except OSError:
+            shutil.move(sstateinst + state[0], state[1])
  sstate_install(ss, d)

  for plain in ss['plaindirs']:
@@ -413,7 +417,10 @@ def sstate_installpkgdir(ss, d):
      dest = plain
      bb.utils.mkdirhier(src)
      prepdir(dest)
-        os.rename(src, dest)
+        try:
+            os.rename(src, dest)
+        except OSError:
+            shutil.move(src, dest)

  return True

@@ -638,6 +645,7 @@ python sstate_hardcode_path () {

def sstate_package(ss, d):
  import oe.path
+    import shutil

  tmpdir = d.getVar('TMPDIR')

@@ -664,7 +672,10 @@ def sstate_package(ss, d):
                  continue
              bb.error("sstate found an absolute path symlink %s pointing at %s. Please replace this with a relative link." % (srcpath, link))
      bb.debug(2, "Preparing tree %s for packaging at %s" % (state[1], sstatebuild + state[0]))
-        os.rename(state[1], sstatebuild + state[0])
+        try:
+            os.rename(state[1], sstatebuild + state[0])
+        except OSError:
+            shutil.move(state[1], sstatebuild + state[0])

  workdir = d.getVar('WORKDIR')
  sharedworkdir = os.path.join(d.getVar('TMPDIR'), "work-shared")
@@ -674,7 +685,10 @@ def sstate_package(ss, d):
          pdir = plain.replace(sharedworkdir, sstatebuild)
      bb.utils.mkdirhier(plain)
      bb.utils.mkdirhier(pdir)
-        os.rename(plain, pdir)
+        try:
+            os.rename(plain, pdir)
+        except OSError:
+            shutil.move(plain, pdir)

  d.setVar('SSTATE_BUILDDIR', sstatebuild)
  d.setVar('SSTATE_INSTDIR', sstatebuild)
--
2.29.2


On 30 Mar 2021, at 08:10, Richard Purdie <richard.purdie@...> wrote:

On Mon, 2021-03-29 at 16:00 -0700, Andre McCurdy wrote:
On Mon, Mar 29, 2021 at 3:45 PM Devendra Tewari
<devendra.tewari@...> wrote:

Thanks! My bad. The example I looked up in Python docs had a break and I just realized it was a looping example.

Here’s the updated patch (or should I submit it again via git send-email?)

It would be better to use shutil.move unconditionally in all cases,
rather than have a separate shutil.move code path which only gets
tested by people doing incremental builds in docker.

This is a speed sensitive section of code and shutil has traditionally proved
to be slow so I disagree with that, rename is very much preferred here where
we can.

Cheers,

Richard