Skip to contentSkip to conversation

Handle errors during license hard-links

PATCH New Manuel Huber 1 participant 2 messages Jun 11, 2016

lore
Share & tools
lore
#0 lore raw

cover Handle errors during license hard-links

This might be a real corner case I hit:

I'm using docker for building poky with separate volumes for source code (poky and all layers) and the actual build result. Poky tries to create hard links for licenses depending on st_dev. But unfortunately across docker volumes the number might be the same (0) but creating hard links still fails with EXDEV.

The following changes since commit 40e789d1fee7f0df2d23230fff38325119ad2935:

bitbake: lib/bb/main.py: Fix use of BBPOSTCONF and BBPRECONF (2016-06-09 18:00:58 +0100)

are available in the git repository at:

git://github.com/boon-code/poky bugfix/master/Fix-license-copy-in-docker
https://github.com/boon-code/poky/tree/bugfix/master/Fix-license-copy-in-docker

Manuel Huber (1):
Handle EXDEV if hard link to license fails

 meta/classes/license.bbclass | 20 +++++++++++++++-----
 1 file changed, 15 insertions(+), 5 deletions(-)
Signature · 1 line
2.5.0
#1 lore raw

PATCH 1/1 Handle EXDEV if hard link to license fails

From: Manuel Huber <[email protected]>

Hard links can still fail even if st_dev is the same for source and destination. In case of EXDEV error, fall back to copying...

---
 meta/classes/license.bbclass | 20 +++++++++++++++-----
 1 file changed, 15 insertions(+), 5 deletions(-)
meta/classes/license.bbclass +15 -5
index 10d6ed8..c543637 100644
@@ -342,6 +342,7 @@ def add_package_and_files(d):
 
 def copy_license_files(lic_files_paths, destdir):
     import shutil
+    import errno
 
     bb.utils.mkdirhier(destdir)
     for (basename, path) in lic_files_paths:
@@ -350,12 +351,21 @@ def copy_license_files(lic_files_paths, destdir):
             dst = os.path.join(destdir, basename)
             if os.path.exists(dst):
                 os.remove(dst)
-            if os.access(src, os.W_OK) and (os.stat(src).st_dev == os.stat(destdir).st_dev):
-                os.link(src, dst)
+            canlink = os.access(src, os.W_OK) and (os.stat(src).st_dev == os.stat(destdir).st_dev)
+            if canlink:
                 try:
-                    os.chown(dst,0,0)
+                    os.link(src, dst)
+                except OSError as err:
+                    if err.errno == errno.EXDEV:
+                        # Copy license files if hard-link is not possible even if st_dev is the
+                        # same on source and destination (docker container with device-mapper?)
+                        canlink = False
+                    else:
+                        raise
+                try:
+                    if canlink:
+                        os.chown(dst,0,0)
                 except OSError as err:
-                    import errno
                     if err.errno in (errno.EPERM, errno.EINVAL):
                         # Suppress "Operation not permitted" error, as
                         # sometimes this function is not executed under pseudo.
@@ -364,7 +374,7 @@ def copy_license_files(lic_files_paths, destdir):
                         pass
                     else:
                         raise
-            else:
+            if not canlink:
                 shutil.copyfile(src, dst)
         except Exception as e:
             bb.warn("Could not copy license file %s to %s: %s" % (src, dst, e))
Signature · 1 line
2.5.0