Gentoo Archives: gentoo-dev

From: "Michał Górny" <mgorny@g.o>
To: gentoo-dev@l.g.o
Cc: ulm@g.o, zmedico@g.o, "Michał Górny" <mgorny@g.o>
Subject: [gentoo-dev] [PATCH] Introduce multibuild_merge_root() to merge interim installs.
Date: Mon, 25 Mar 2013 22:42:37
Message-Id: 1364251370-1579-1-git-send-email-mgorny@gentoo.org
In Reply to: Re: [gentoo-dev] [PATCH 1/2] Introduce multibuild_merge_root() to merge interim installs. by Ulrich Mueller
1 This is mostly a copy from distutils-r1. The function does copy all the
2 files from one location onto another, preserving whatever possible. It
3 can be run in parallel too without the risk of race conditions.
4
5 As suggested by Ulrich and Zac, I've modified the code to use checks
6 based on userland rather than tool checking. The code supports BSD and
7 GNU userlands as defined in the profiles. With any other userland, it
8 explicitly dies.
9 ---
10 gx86/eclass/distutils-r1.eclass | 41 +-------------------------------
11 gx86/eclass/multibuild.eclass | 52 +++++++++++++++++++++++++++++++++++++++++
12 2 files changed, 53 insertions(+), 40 deletions(-)
13
14 diff --git a/gx86/eclass/distutils-r1.eclass b/gx86/eclass/distutils-r1.eclass
15 index 0982e6c..3c21741 100644
16 --- a/gx86/eclass/distutils-r1.eclass
17 +++ b/gx86/eclass/distutils-r1.eclass
18 @@ -449,49 +449,10 @@ distutils-r1_python_install() {
19
20 if [[ ! ${DISTUTILS_SINGLE_IMPL} ]]; then
21 _distutils-r1_rename_scripts "${root}"
22 - _distutils-r1_merge_root "${root}" "${D}"
23 + multibuild_merge_root "${root}" "${D}"
24 fi
25 }
26
27 -# @FUNCTION: distutils-r1_merge_root
28 -# @USAGE: <src-root> <dest-root>
29 -# @INTERNAL
30 -# @DESCRIPTION:
31 -# Merge the directory tree from <src-root> to <dest-root>, removing
32 -# the <src-root> in the process.
33 -_distutils-r1_merge_root() {
34 - local src=${1}
35 - local dest=${2}
36 -
37 - local lockfile=${T}/distutils-r1-merge-lock
38 -
39 - if type -P lockf &>/dev/null; then
40 - # On BSD, we have 'lockf' wrapper.
41 - tar -C "${src}" -f - -c . \
42 - | lockf "${lockfile}" tar -x -f - -C "${dest}"
43 - else
44 - local lock_fd
45 - if type -P flock &>/dev/null; then
46 - # On Linux, we have 'flock' which can lock fd.
47 - redirect_alloc_fd lock_fd "${lockfile}" '>>'
48 - flock ${lock_fd}
49 - else
50 - ewarn "distutils-r1: no locking service found, please report."
51 - fi
52 -
53 - cp -a -l -n "${src}"/. "${dest}"/
54 -
55 - if [[ ${lock_fd} ]]; then
56 - # Close the lock file when we are done with it.
57 - # Prevents deadlock if we aren't in a subshell.
58 - eval "exec ${lock_fd}>&-"
59 - fi
60 - fi
61 - [[ ${?} == 0 ]] || die "Merging ${EPYTHON} image failed."
62 -
63 - rm -rf "${src}"
64 -}
65 -
66 # @FUNCTION: distutils-r1_python_install_all
67 # @DESCRIPTION:
68 # The default python_install_all(). It installs the documentation.
69 diff --git a/gx86/eclass/multibuild.eclass b/gx86/eclass/multibuild.eclass
70 index a3f1402..1152245 100644
71 --- a/gx86/eclass/multibuild.eclass
72 +++ b/gx86/eclass/multibuild.eclass
73 @@ -238,5 +238,57 @@ run_in_build_dir() {
74 return ${ret}
75 }
76
77 +# @FUNCTION: multibuild_merge_root
78 +# @USAGE: <src-root> <dest-root>
79 +# @DESCRIPTION:
80 +# Merge the directory tree (fake root) from <src-root> to <dest-root>
81 +# (the real root). Both directories have to be real, absolute paths
82 +# (i.e. including ${D}). Source root will be removed.
83 +#
84 +# This functions uses locking to support merging during parallel
85 +# installs.
86 +multibuild_merge_root() {
87 + local src=${1}
88 + local dest=${2}
89 +
90 + local lockfile=${T}/multibuild_merge_lock
91 + local ret
92 +
93 + if use userland_BSD; then
94 + # Locking is done by 'lockf' which can wrap a command.
95 + # 'cp -a -n' is broken:
96 + # http://www.freebsd.org/cgi/query-pr.cgi?pr=174489
97 + # using tar instead which is universal but terribly slow.
98 +
99 + tar -C "${src}" -f - -c . \
100 + | lockf "${lockfile}" tar -x -f - -C "${dest}"
101 + [[ ${PIPESTATUS[*]} == '0 0' ]]
102 + ret=${?}
103 + elif use userland_GNU; then
104 + # GNU has 'flock' which can't wrap commands but can lock
105 + # a fd which is good enough for us.
106 + # and cp works with '-a -n'.
107 +
108 + local lock_fd
109 + redirect_alloc_fd lock_fd "${lockfile}" '>>'
110 + flock ${lock_fd}
111 +
112 + cp -a -l -n "${src}"/. "${dest}"/
113 + ret=${?}
114 +
115 + # Close the lock file when we are done with it.
116 + # Prevents deadlock if we aren't in a subshell.
117 + eval "exec ${lock_fd}>&-"
118 + else
119 + die "Unsupported userland (${USERLAND}), please report."
120 + fi
121 +
122 + if [[ ${ret} -ne 0 ]]; then
123 + die "${MULTIBUILD_VARIANT:-(unknown)}: merging image failed."
124 + fi
125 +
126 + rm -rf "${src}"
127 +}
128 +
129 _MULTIBUILD=1
130 fi
131 --
132 1.8.1.5