OLD | NEW |
1 #!/bin/bash -e | 1 #!/bin/bash -e |
2 | 2 |
3 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 3 # Copyright (c) 2012 The Chromium Authors. All rights reserved. |
4 # Use of this source code is governed by a BSD-style license that can be | 4 # Use of this source code is governed by a BSD-style license that can be |
5 # found in the LICENSE file. | 5 # found in the LICENSE file. |
6 | 6 |
7 # This script installs Debian-derived distributions in a chroot environment. | 7 # This script installs Debian-derived distributions in a chroot environment. |
8 # It can for example be used to have an accurate 32bit build and test | 8 # It can for example be used to have an accurate 32bit build and test |
9 # environment when otherwise working on a 64bit machine. | 9 # environment when otherwise working on a 64bit machine. |
10 # N. B. it is unlikely that this script will ever work on anything other than a | 10 # N. B. it is unlikely that this script will ever work on anything other than a |
(...skipping 479 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
490 case "$1" in | 490 case "$1" in |
491 --) shift; break;; | 491 --) shift; break;; |
492 -h|--help) shift; help;; | 492 -h|--help) shift; help;; |
493 -l|--list) shift; list;; | 493 -l|--list) shift; list;; |
494 -c|--clean) shift; clean "${chroot}";; | 494 -c|--clean) shift; clean "${chroot}";; |
495 -C|--clean-all) shift; clean;; | 495 -C|--clean-all) shift; clean;; |
496 *) break;; | 496 *) break;; |
497 esac | 497 esac |
498 done | 498 done |
499 | 499 |
| 500 # Start a new chroot session and keep track of the session id. We inject this |
| 501 # id into all processes that run inside the chroot. Unless they go out of their |
| 502 # way to clear their environment, we can then later identify our child and |
| 503 # grand-child processes by scanning their environment. |
500 session="$(schroot -c "${chroot}" -b)" | 504 session="$(schroot -c "${chroot}" -b)" |
| 505 export CHROOT_SESSION_ID="${session}" |
501 | 506 |
502 if [ $# -eq 0 ]; then | 507 if [ $# -eq 0 ]; then |
| 508 # Run an interactive shell session |
503 schroot -c "${session}" -r -p | 509 schroot -c "${session}" -r -p |
504 else | 510 else |
| 511 # Run a command inside of the chroot environment |
505 p="$1"; shift | 512 p="$1"; shift |
506 schroot -c "${session}" -r -p "$p" -- "$@" | 513 schroot -c "${session}" -r -p "$p" -- "$@" |
507 fi | 514 fi |
508 rc=$? | 515 rc=$? |
509 | 516 |
| 517 # Compute the inode of the root directory inside of the chroot environment. |
510 i=$(schroot -c "${session}" -r -p ls -- -id /proc/self/root/. | | 518 i=$(schroot -c "${session}" -r -p ls -- -id /proc/self/root/. | |
511 awk '{ print $1 }') 2>/dev/null | 519 awk '{ print $1 }') 2>/dev/null |
| 520 other_pids= |
512 while [ -n "$i" ]; do | 521 while [ -n "$i" ]; do |
513 pids=$(ls -id1 /proc/*/root/. 2>/dev/null | | 522 # Identify processes by the inode number of their root directory. Then |
| 523 # remove all processes that we know belong to other sessions. We use |
| 524 # "sort | uniq -u" to do what amounts to a "set substraction operation". |
| 525 pids=$({ ls -id1 /proc/*/root/. 2>/dev/null | |
514 sed -e 's,^[^0-9]*'$i'.*/\([1-9][0-9]*\)/.*$,\1, | 526 sed -e 's,^[^0-9]*'$i'.*/\([1-9][0-9]*\)/.*$,\1, |
515 t | 527 t |
516 d') >/dev/null 2>&1 | 528 d'; |
517 [ -z "$pids" ] && break | 529 echo "${other_pids}"; |
518 kill -9 $pids | 530 echo "${other_pids}"; } | sort | uniq -u) >/dev/null 2>&1 |
| 531 # Kill all processes that are still left running in the session. This is |
| 532 # typically an assortment of daemon processes that were started |
| 533 # automatically. They result in us being unable to tear down the session |
| 534 # cleanly. |
| 535 [ -z "${pids}" ] && break |
| 536 for j in $pids; do |
| 537 # Unfortunately, the way that schroot sets up sessions has the |
| 538 # side-effect of being unable to tell one session apart from another. |
| 539 # This can result in us attempting to kill processes in other sessions. |
| 540 # We make a best-effort to avoid doing so. |
| 541 k="$( ( xargs -0 -n1 </proc/$j/environ ) 2>/dev/null | |
| 542 sed 's/^CHROOT_SESSION_ID=/x/;t1;d;:1;q')" |
| 543 if [ -n "${k}" -a "${k#x}" != "${session}" ]; then |
| 544 other_pids="${other_pids} |
| 545 ${j}" |
| 546 continue |
| 547 fi |
| 548 kill -9 $pids |
| 549 done |
519 done | 550 done |
| 551 # End the chroot session. This should clean up all temporary files. But if we |
| 552 # earlier failed to terminate all (daemon) processes inside of the session, |
| 553 # deleting the session could fail. When that happens, the user has to manually |
| 554 # clean up the stale files by invoking us with "--clean" after having killed |
| 555 # all running processes. |
520 schroot -c "${session}" -e | 556 schroot -c "${session}" -e |
521 exit $rc | 557 exit $rc |
522 EOF | 558 EOF |
523 sudo chown root:root /usr/local/bin/"${target%bit}" | 559 sudo chown root:root /usr/local/bin/"${target%bit}" |
524 sudo chmod 755 /usr/local/bin/"${target%bit}" | 560 sudo chmod 755 /usr/local/bin/"${target%bit}" |
525 | 561 |
526 # Add the standard Ubuntu update repositories if requested. | 562 # Add the standard Ubuntu update repositories if requested. |
527 [ "${alt_repos}" = "y" -a \ | 563 [ "${alt_repos}" = "y" -a \ |
528 -r "/var/lib/chroot/${target}/etc/apt/sources.list" ] && | 564 -r "/var/lib/chroot/${target}/etc/apt/sources.list" ] && |
529 sudo sed -i '/^deb .* [^ -]\+ main$/p | 565 sudo sed -i '/^deb .* [^ -]\+ main$/p |
(...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
807 | 843 |
808 For Chrome, this probably means you want to make your "out" directory a | 844 For Chrome, this probably means you want to make your "out" directory a |
809 symbolic link that points somewhere inside of "${HOME}/chroot". | 845 symbolic link that points somewhere inside of "${HOME}/chroot". |
810 | 846 |
811 You still need to run "gclient runhooks" whenever you switch from building | 847 You still need to run "gclient runhooks" whenever you switch from building |
812 outside of the chroot to inside of the chroot. But you will find that you | 848 outside of the chroot to inside of the chroot. But you will find that you |
813 don't have to repeatedly erase and then completely rebuild all your object | 849 don't have to repeatedly erase and then completely rebuild all your object |
814 and binary files. | 850 and binary files. |
815 | 851 |
816 EOF | 852 EOF |
OLD | NEW |