pivot_ root のソースコード
今回使っているswitch_
% less docs/BusyBox.1
...
pivot_root
pivot_root NEW_ROOT PUT_OLD
Move the current root file system to PUT_OLD and make
NEW_ROOT the new root file system
...
switch_root
switch_root [-c /dev/console] NEW_ROOT NEW_INIT [ARGUMENTS_TO_INIT]
Use from PID 1 under initramfs to free initramfs,
chroot to NEW_ROOT, and exec NEW_INIT
Options:
-c Redirect console to device on new root
...
BusyBox のマニュアルには上記のような使い方の簡単な記述しかなく,
仕方ないのでBusyBoxのソースコードを眺めてみました。
% cat -n busybox-1.13.2/util-linux/pivot_root.c
...
11 #include "libbb.h"
12
13 extern int pivot_root(const char * new_root,const char * put_old);
14
15 int pivot_root_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
16 int pivot_root_main(int argc, char **argv)
17 {
18 if (argc != 3)
19 bb_show_usage();
20
21 if (pivot_root(argv[1], argv[2]) < 0) {
22 /* prints "pivot_root: " */
23 bb_perror_nomsg_and_die();
24 }
25
26 return EXIT_SUCCESS;
27 }
BusyBoxのpivot_
紹介はしませんでしたが,
カーネルソースの調査
システムコールとなるとカーネルソースの中の話になるので簡単には手が出せそうにありませんが,
% find /usr/src/linux -follow | xargs grep -i pivot_root | cat -n
1 /usr/src/linux/arch/s390/include/asm/unistd.h:#define __NR_pivot_root 217
2 /usr/src/linux/arch/s390/kernel/syscalls.S:SYSCALL(sys_pivot_root,sys_pivot_root,sys32_pivot_root_wrapper)
...
88 /usr/src/linux/Documentation/early-userspace/README: filesystem via linuxrc and use the pivot_root syscall. The initrd is
89 /usr/src/linux/Documentation/arm/IXP4xx: a pivot_root to NFS.
90 /usr/src/linux/usr/include/asm/unistd_64.h:#define __NR_pivot_root 155
91 /usr/src/linux/usr/include/asm/unistd_64.h:__SYSCALL(__NR_pivot_root, sys_pivot_root)
92 /usr/src/linux/usr/include/asm/unistd_32.h:#define __NR_pivot_root 217
各種アークテクチャ
実際の処理はどこだろうな…,
% cat -n /usr/src/linux/fs/namespace.c
...
2157 /*
2158 * pivot_root Semantics:
2159 * Moves the root file system of the current process to the directory put_old,
2160 * makes new_root as the new root file system of the current process, and sets
2161 * root/cwd of all processes which had them on the current root to new_root.
2162 *
2163 * Restrictions:
2164 * The new_root and put_old must be directories, and must not be on the
2165 * same file system as the current process root. The put_old must be
2166 * underneath new_root, i.e. adding a non-zero number of /.. to the string
2167 * pointed to by put_old must yield the same directory as new_root. No other
2168 * file system may be mounted on put_old. After all, new_root is a mountpoint.
2169 *
2170 * Also, the current root cannot be on the 'rootfs' (initial ramfs) filesystem.
2171 * See Documentation/filesystems/ramfs-rootfs-initramfs.txt for alternatives
2172 * in this situation.
2173 *
2174 * Notes:
2175 * - we don't move root/cwd if they are not at the root (reason: if something
2176 * cared enough to change them, it's probably wrong to force them elsewhere)
2177 * - it's okay to pick a root that isn't the root of a file system, e.g.
2178 * /nfs/my_root where /nfs is the mount point. It must be a mountpoint,
2179 * though, so you may need to say mount --bind /nfs/my_root /nfs/my_root
2180 * first.
2181 */
2182 SYSCALL_DEFINE2(pivot_root, const char __user *, new_root,
2183 const char __user *, put_old)
2184 {
2185 struct vfsmount *tmp;
2186 struct path new, old, parent_path, root_parent, root;
2187 int error;
2188
2189 if (!capable(CAP_SYS_ADMIN))
2190 return -EPERM;
2191
どういう処理をしているのかを見る前に,
そもそもinitial ramfs(initramfs)をルートファイルシステムにしている状態ではpivot_