summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPatrick Ohly <patrick.ohly@intel.com>2016-05-13 18:56:57 +0200
committerRichard Purdie <richard.purdie@linuxfoundation.org>2016-05-14 23:05:13 +0100
commit4dadbbdd46195fc60cd91f589102bca31cea3c2e (patch)
tree5862ae336831880eeaba31aa2f1bcdb4d4158b21
parent659ed8718bbc23a1b3945a09833ebf7f9e67c52c (diff)
downloadpoky-4dadbbdd46195fc60cd91f589102bca31cea3c2e.tar.gz
combo-layer: avoid too long command lines in update with history
As suspected, invoking "git archive" with all intended files as parameters can run into command line length limitations. Splitting up the parameters into multiple invocations (xargs-style) works and was tested after encountering the situation in practice. (From OE-Core rev: 1cb484ab99eabb5c24792757ab09d7f170f2e614) Signed-off-by: Patrick Ohly <patrick.ohly@intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-rwxr-xr-xscripts/combo-layer31
1 files changed, 29 insertions, 2 deletions
diff --git a/scripts/combo-layer b/scripts/combo-layer
index a0a737d6ee..1ca2ce6c02 100755
--- a/scripts/combo-layer
+++ b/scripts/combo-layer
@@ -1266,8 +1266,35 @@ def apply_commit(parent, rev, largs, wargs, dest_dir, file_filter=None):
1266 target = os.path.join(wargs["destdir"], dest_dir) 1266 target = os.path.join(wargs["destdir"], dest_dir)
1267 if not os.path.isdir(target): 1267 if not os.path.isdir(target):
1268 os.makedirs(target) 1268 os.makedirs(target)
1269 runcmd("git archive %s %s | tar -C %s -xf -" % (rev, ' '.join([pipes.quote(x) for x in update]), pipes.quote(target)), **largs) 1269 quoted_target = pipes.quote(target)
1270 runcmd("git add -f".split() + [os.path.join(dest_dir, x) for x in update], **wargs) 1270 # os.sysconf('SC_ARG_MAX') is lying: running a command with
1271 # string length 629343 already failed with "Argument list too
1272 # long" although SC_ARG_MAX = 2097152. "man execve" explains
1273 # the limitations, but those are pretty complicated. So here
1274 # we just hard-code a fixed value which is more likely to work.
1275 max_cmdsize = 64 * 1024
1276 while update:
1277 quoted_args = []
1278 unquoted_args = []
1279 cmdsize = 100 + len(quoted_target)
1280 while update:
1281 quoted_next = pipes.quote(update[0])
1282 size_next = len(quoted_next) + len(dest_dir) + 1
1283 logger.debug('cmdline length %d + %d < %d?' % (cmdsize, size_next, os.sysconf('SC_ARG_MAX')))
1284 if cmdsize + size_next < max_cmdsize:
1285 quoted_args.append(quoted_next)
1286 unquoted_args.append(update.pop(0))
1287 cmdsize += size_next
1288 else:
1289 logger.debug('Breaking the cmdline at length %d' % cmdsize)
1290 break
1291 logger.debug('Final cmdline length %d / %d' % (cmdsize, os.sysconf('SC_ARG_MAX')))
1292 cmd = "git archive %s %s | tar -C %s -xf -" % (rev, ' '.join(quoted_args), quoted_target)
1293 logger.debug('First cmdline length %d' % len(cmd))
1294 runcmd(cmd, **largs)
1295 cmd = "git add -f".split() + [os.path.join(dest_dir, x) for x in unquoted_args]
1296 logger.debug('Second cmdline length %d' % reduce(lambda x, y: x + len(y), cmd, 0))
1297 runcmd(cmd, **wargs)
1271 if delete: 1298 if delete:
1272 for path in delete: 1299 for path in delete:
1273 if dest_dir: 1300 if dest_dir: