Gentoo Archives: gentoo-amd64

From: Barry.SCHWARTZ@×××××××××××××.org
To: gentoo-amd64@l.g.o
Subject: Re: [gentoo-amd64] chroot howto?
Date: Wed, 13 Jul 2005 10:07:25
Message-Id: 20050713100551.GA8904@crud.crud.mn.org
In Reply to: [gentoo-amd64] chroot howto? by Peter Humphrey
1 Peter Humphrey <prh@××××××××××.uk> wrote:
2 > I unpacked an x86 stage 3, and set up hosts, networks and users as
3 > instructed, but when I tried "linux32 chroot /mnt/gentoo32 /bin/bash" I
4 > got a permission-refused error on /bin/bash. (I tried both with and
5 > without --login; it made no difference.)
6
7 Did you do this as root?
8
9 > So I unpacked a portage
10 > snapshot, rebooted from the installation CD and tried again. I could
11 > then chroot. I reasoned that /bin/bash could not be executed because
12 > there was no 32-bit kernel, so I emerged and compiled gentoo-sources in
13 > /mnt/gentoo32. After that I could chroot from the installed system.
14
15 You don't need a 32-bit kernel. For a few things it can be convenient
16 to have kernel sources present, but I don't remember what things those
17 are. Cross that bridge if you come to it.
18
19 > But how much more of a Gentoo system do I need to build in the chroot
20 > jail? Emerge --sync? Emerge system? I have /mnt/tmp bound to
21 > /mnt/gentoo32/mnt/tmp, and /mnt/home, /mnt/boot, /mnt/usr/share and
22 > /mnt/usr/portage/distfiles bound similarly. Do I need to env-update
23 > whenever I chroot? What difference is there between chroot with and
24 > without --login, apart from sourcing /etc/profile etc?
25
26 I set up my own init script that uses 'mount --bind' to mount and
27 unmount things that you need inside the chroot. So that happens at
28 initialization.
29
30 As far as getting into the chroot, if I am root I do it with a Perl script:
31
32 ===========================================
33 #!/usr/bin/perl -wT
34
35 $root_32bit = "/gentoo32"; # The root directory of the 32-bit environment.
36
37 $ENV{PATH} = '/bin:/usr/bin';
38 delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};
39
40 $#ARGV == -1 or die "$0: Does not accept arguments\n";
41
42 # su to oneself. Non-root users may be asked for their password.
43 # (We require that the user name begin with an alphabetic character
44 # and consist only of alphanumeric characters.)
45 $user = getpwuid($<);
46 $user =~ /^([[:alpha:]][[:alnum:]]*)$/
47 or die "$0: \"$user\" doesn't look like a user name to me\n";
48 $user = $1;
49 exec "linux32", "chroot", "$root_32bit", "su", "-", "$user";
50
51 die "$0: $!\n";
52 ===========================================
53
54 If I am non-root I do it with a simple suid root C program that is
55 adapted from linux32.
56
57 ===========================================
58 /* $Id: l32.c,v 1.3 2004/08/18 05:09:30 trashman Exp $ */
59
60 #include <linux/personality.h>
61 #undef personality
62 #include <stdlib.h>
63 #include <stdio.h>
64 #include <string.h>
65 #include <unistd.h>
66 #include <errno.h>
67 #include <limits.h>
68
69 long int personality(unsigned long int persona);
70
71
72 /* Restrict address space to 3 GB, for the sake of buggy Java. */
73 const unsigned long int default_personality = PER_LINUX32_3GB;
74 const char *const gentoo32 = "/gentoo32";
75
76
77 int main(int argc, char *argv[], char *envp[] __attribute__((unused)))
78 {
79 int result;
80 long int long_result;
81 unsigned long int pers;
82 char *cwd;
83
84 if (argc < 2) {
85 fprintf(stderr, "Usage: %s COMMAND [ARG]...\n", argv[0]);
86 exit(1);
87 }
88
89 pers = default_personality;
90
91 cwd = getcwd(NULL, 0); /* Linux-specific: allocate as many
92 * bytes as necessary. */
93 if (cwd == NULL) {
94 fprintf(stderr, "Can't allocate necessary space: %s\n", strerror(errno));
95 exit(1);
96 }
97
98 long_result = personality(pers);
99 if (long_result == -1) {
100 fprintf(stderr, "Can't set personality %lx: %s\n", pers, strerror(errno));
101 exit(1);
102 }
103
104 result = chroot(gentoo32);
105 if (result != 0) {
106 fprintf(stderr, "Can't chroot(%s): %s\n", gentoo32, strerror(errno));
107 exit(1);
108 }
109
110 /* Drop root privileges. */
111 result = setuid(getuid());
112 if (result != 0) {
113 fprintf(stderr, "Can't suid(%d): %s\n", getuid(), strerror(errno));
114 exit(1);
115 }
116
117 /* Make sure we are inside the chroot. */
118 result = chdir("/");
119 if (result != 0) {
120 fprintf(stderr, "Can't chdir(%s) within the chroot: %s\n",
121 gentoo32, strerror(errno));
122 exit(1);
123 }
124
125 /* Change into the chroot's equivalent of the current working
126 * directory. */
127 result = chdir(cwd);
128 if (result != 0) {
129 fprintf(stderr, "Can't chdir(%s) within the chroot: %s\n",
130 cwd, strerror(errno));
131 exit(1);
132 }
133
134 free(cwd);
135 execvp(argv[1], argv + 1);
136
137 abort(); /* We shouldn't get here. */
138 }
139 ===========================================
140
141 'l32 zsh --login' gets me a 32-bit shell.
142
143 I maintain my chroot as practically another whole system. That's
144 wasteful but makes some things a lot easier -- even maintenance is
145 easier with all that waste, because you are letting portage 'think'
146 for you about what it needs to install.
147
148 I used to also run stuff like sshd inside the chroot, but don't
149 anymore, and I think you can ignore that.
150
151 --
152 Barry.SCHWARTZ@×××××××××××××.org http://www.chemoelectric.org
153 Esperantistoj rajtas skribi al Barijo.SXVARCO@×××××××××××××.org

Replies

Subject Author
Re: [gentoo-amd64] chroot howto? Peter Humphrey <prh@××××××××××.uk>