Linux でナヌザヌ モヌドの䜿甚を開始する方法

翻蚳者からの玹介: さたざたな皮類のコンテナが私たちの生掻に倧量に参入しおいるこずを背景に、それがか぀おどのようなテクノロゞヌで始たったのかを知るこずは非垞に興味深く、有益です。 それらの䞭には、今日でも䟿利に䜿甚できるものもありたすが、誰もがそのような方法を芚えおいるわけではありたせんたたは、急速な開発䞭に捕らえられなかったかどうかを知っおいるわけではありたせん。 そのようなテクノロゞヌの 2 ぀がナヌザヌ モヌド Linux です。 オリゞナルの䜜者は、叀い開発のうちどれがただ機胜し、どれが機胜しおいないのかを培底的に調査し、19kXNUMX で自䜜の UML を入手する方法に぀いおの段階的な説明のようなものをたずめたした。 そしお、はい、元の投皿の著者を Habr に招埅したした クリア, 質問がある堎合は、コメント欄に英語で質問しおください。

Linux でナヌザヌ モヌドの䜿甚を開始する方法

実際、Linux のナヌザヌ モヌドは、Linux カヌネルをそれ自䜓に移怍したものです。 このモヌドでは、完党な Linux カヌネルをナヌザヌ プロセスずしお実行でき、開発者がドラむバヌをテストするために䞀般的に䜿甚されたす。 ただし、このモヌドは䞀般的な分離ツヌルずしおも圹立ち、その原理は仮想マシンの操䜜に䌌おいたす。 このモヌドでは、Docker よりも分離性が高くなりたすが、KVM や Virtual Box などの本栌的な仮想マシンよりも分離性は䜎くなりたす。

䞀般に、ナヌザヌ モヌドは奇劙で䜿いにくいツヌルのように思えるかもしれたせんが、それでも甚途はありたす。 結局のずころ、これは特暩のないナヌザヌから実行される本栌的な Linux カヌネルです。 この機胜により、信頌できない可胜性のあるコヌドをホスト マシンに脅嚁を䞎えるこずなく実行できたす。 これは本栌的なカヌネルであるため、そのプロセスはホスト マシンから分離されおいたす。 ナヌザヌモヌド内で実行されおいるプロセスはホストには衚瀺されたせん。 これは通垞の Docker コンテナずは異なりたす。この堎合、ホスト マシンは垞にリポゞトリ内のプロセスを参照したす。 私のサヌバヌの XNUMX ぀からの pstree のこの郚分を芋おください。

containerd─┬─containerd-shim─┬─tini─┬─dnsd───19*[{dnsd}]
           │                 │      └─s6-svscan───s6-supervise
           │                 └─10*[{containerd-shim}]
           ├─containerd-shim─┬─tini─┬─aerial───21*[{aerial}]
           │                 │      └─s6-svscan───s6-supervise
           │                 └─10*[{containerd-shim}]
           ├─containerd-shim─┬─tini─┬─s6-svscan───s6-supervise
           │                 │      └─surl
           │                 └─9*[{containerd-shim}]
           ├─containerd-shim─┬─tini─┬─h───13*[{h}]
           │                 │      └─s6-svscan───s6-supervise
           │                 └─10*[{containerd-shim}]
           ├─containerd-shim─┬─goproxy───14*[{goproxy}]
           │                 └─9*[{containerd-shim}]
           └─32*[{containerd}]

これをナヌザヌ モヌドの Linux カヌネルの pstree ず比范しおください。

linux─┬─5*[linux]
      └─slirp

Docker コンテナを操䜜する堎合、ゲストで実行されおいるプロセスの名前をホストから確認できたす。 Linux ナヌザヌ モヌドでは、これは䞍可胜です。 それはどういう意味ですか これは、Linux の監査サブシステムを介しお実行される監芖ツヌルを意味したす。 芋ない ゲスト システムで実行されおいるプロセス。 ただし、状況によっおは、この機胜が諞刃の剣になる可胜性がありたす。

䞀般に、以䞋の投皿党䜓は、望たしい結果を達成するための調査ず倧たかな詊みをたずめたものです。 これを行うには、さたざたな叀いツヌルを䜿甚し、カヌネル ゜ヌスを読み、小孊生の頃に曞いたコヌドを集䞭的にデバッグし、必芁なツヌルを芋぀けるために特別なバむナリを䜿甚しお Heroku ビルドをいじくり回さなければなりたせんでした。 。 こうした䜜業のすべおにより、IRC のメンバヌは私を魔法ず呌ぶようになりたした。 この投皿が、誰かが新しいカヌネルず OS バヌゞョンで同じこずを詊すための信頌できるドキュメントずしお圹立぀こずを願っおいたす。

調敎

Linux ナヌザヌ モヌドのセットアップは、いく぀かの手順で行われたす。

  • 䟝存関係をホストにむンストヌルしたす。
  • Linux カヌネルをダりンロヌドする。
  • カヌネルのビルド構成。
  • カヌネルアセンブリ。
  • バむナリのむンストヌル。
  • ゲストファむルシステムの構成。
  • カヌネル起動パラメヌタの遞択。
  • ゲストネットワヌクのセットアップ。
  • ゲストカヌネルを起動しおいたす。

自分でやるず決めた堎合は、Ubuntu たたは Debian に䌌たシステムで説明されおいるすべおのこずを行う可胜性が高いず思いたす。 䞊蚘のすべおを私のお気に入りのディストリビュヌションである Alpine に実装しようずしたしたが、䜕も起こりたせんでした。これは、Linux カヌネルがナヌザヌ モヌドのドラむバヌに察しおハヌド バむンドする glibc-ism を持っおいるためず思われたす。 最終的に問題を理解した埌、これを䞊流に報告する予定です。

ホストぞの䟝存関係のむンストヌル

Ubuntu では、Linux カヌネルを構築するには少なくずも次のパッケヌゞが必芁です (クリヌン むンストヌルを想定)。

- 'build-essential'
- 'flex'
- 'bison'
- 'xz-utils'
- 'wget'
- 'ca-certificates'
- 'bc'
- 'linux-headers'

これらは、次のコマンド (root たたは sudo で) を䜿甚しおむンストヌルできたす。

apt-get -y install build-essential flex bison xz-utils wget ca-certificates bc 
                   linux-headers-$(uname -r)

Linux カヌネル メニュヌ セットアップ プログラムを実行するには、 libncurses-dev。 次のコマンド (root たたは sudo で) を䜿甚しおむンストヌルされおいるこずを確認しおください。

apt-get -y install libncurses-dev

カヌネルのダりンロヌド

ダりンロヌドする堎所を決定し、カヌネルをビルドしたす。 この操䜜には、玄 1,3 GB のハヌドディスク容量を割り圓おる必芁があるため、必ず確保しおください。

に行った埌 kernel.org 最新の安定したカヌネルをダりンロヌドするための URL を取埗したす。 執筆時点では次のずおりです。 https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.1.16.tar.xz

このファむルをダりンロヌドするには、 'wget':

wget https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.1.16.tar.xz

そしおそれを抜出したす 'tar':

tar xJf linux-5.1.16.tar.xz

ここで、tarball を解凍したずきに䜜成されたディレクトリに入りたす。

cd linux-5.1.16

カヌネルビルドのセットアップ

カヌネルビルドシステムはセットです メむクファむル с 倚くの プロセスを自動化するためのカスタム ツヌルずスクリプト。 たず、察話型セットアップ プログラムを開きたす。

make ARCH=um menuconfig

郚分的にダむアログ ボックスが構築され、衚瀺されたす。 い぀ '[Select]' ず入力するず、Space キヌたたは Enter キヌを䜿甚しお蚭定できるようになりたす。 通垞どおり、キヌボヌドの矢印「䞊」ず「䞋」を䜿甚しおりィンドり内を移動し、芁玠を「巊」たたは「右」から遞択したす。

ビュヌ ポむンタ —> は、Enter キヌを抌すずアクセスできるサブメニュヌに入っおいるこずを意味したす。 そこから抜け出す方法は明らかに '[Exit]'。

' に次のオプションを含めたす[Select]' の暪に '[*]' があるこずを確認しおください。

UML-specific Options:
  - Host filesystem
Networking support (enable this to get the submenu to show up):
  - Networking options:
    - TCP/IP Networking
UML Network devices:
  - Virtual network device
  - SLiRP transport

以䞊です。続けお「」を遞択するず、このりィンドりを終了できたす。[Exit]'。 最埌に蚭定を保存するように求められるので、「」を遞択しおください。[Yes]'。

この投皿を読んだ埌、カヌネル ビルド オプションを詊しおみるこずをお勧めしたす。 これらの実隓を通じお、䜎レベルのカヌネル機構の動䜜ずそのアセンブリに察するさたざたなフラグの圱響を理解するずいう点で倚くのこずを孊ぶこずができたす。

カヌネルの構築

Linux カヌネルは、倚くのこずを実行する倧きなプログラムです。 叀いハヌドりェアでこのような最小限の構成を䜿甚した堎合でも、ビルドにはかなりの時間がかかる堎合がありたす。 したがっお、次のコマンドを䜿甚しおカヌネルを構築したす。

make ARCH=um -j$(nproc)

䜕のために このコマンドは、ビルド プロセスで利甚可胜なすべおの CPU コアずスレッドを䜿甚するようにビルダヌに指瀺したす。 チヌム $(nproc) ビルドの最埌にコマンドの出力を眮き換えたす nprocの䞀郚です coreutils 暙準の Ubuntu ビルドでは。

しばらくするず、カヌネルが実行可胜ファむルにコンパむルされたす。 ./linux.

バむナリのむンストヌル

Linux のナヌザヌ モヌドでは通垞のバむナリが䜜成されるため、他のナヌティリティず同様にむンストヌルできたす。 私がやった方法は次のずおりです。

mkdir -p ~/bin
cp linux ~/bin/linux

次のこずを確認するこずも䟡倀がありたす。 ~/bin あなたの䞭にありたす $PATH:

export PATH=$PATH:$HOME/bin

ゲストファむルシステムのセットアップ

ゲスト ファむル システム甚のディレクトリを䜜成したす。

mkdir -p $HOME/prefix/uml-demo
cd $HOME/prefix

alpinelinux.org を開き、 ダりンロヌドセクション 実際のダりンロヌドリンクを芋぀ける MINI ROOT FILESYSTEM。 執筆時点では次のずおりでした。

http://dl-cdn.alpinelinux.org/alpine/v3.10/releases/x86_64/alpine-minirootfs-3.10.0-x86_64.tar.gz

wget を䜿甚しおこの tarball をダりンロヌドしたす。

wget -O alpine-rootfs.tgz http://dl-cdn.alpinelinux.org/alpine/v3.10/releases/x86_64/alpine-minirootfs-3.10.0-x86_64.tar.gz

次に、ゲスト ファむル システムのディレクトリに入り、アヌカむブを抜出したす。

cd uml-demo
tar xf ../alpine-rootfs.tgz

説明されおいるアクションにより、小さなファむル システム テンプレヌトが䜜成されたす。 システムの性質䞊、Alpine apk マネヌゞャヌを通じおパッケヌゞをむンストヌルするこずは非垞に困難です。 しかし、この FS は䞀般的なアむデアを評䟡するのに十分です。

ツヌルも必芁です TINI メモリの消費を抑えるために ゟンビプロセス ゲストカヌネル。

wget -O tini https://github.com/krallin/tini/releases/download/v0.18.0/tini-static
chmod +x tini

カヌネルコマンドラむンの䜜成

Linux カヌネルには、他のほずんどのプログラムず同様に、キヌを指定するこずでアクセスできるコマンドラむン匕数がありたす。 --help.

圌自身—助けおください

linux --help
User Mode Linux v5.1.16
        available at http://user-mode-linux.sourceforge.net/

--showconfig
    Prints the config file that this UML binary was generated from.

iomem=<name>,<file>
    Configure <file> as an IO memory region named <name>.

mem=<Amount of desired ram>
    This controls how much "physical" memory the kernel allocates
    for the system. The size is specified as a number followed by
    one of 'k', 'K', 'm', 'M', which have the obvious meanings.
    This is not related to the amount of memory in the host.  It can
    be more, and the excess, if it's ever used, will just be swapped out.
        Example: mem=64M

--help
    Prints this message.

debug
    this flag is not needed to run gdb on UML in skas mode

root=<file containing the root fs>
    This is actually used by the generic kernel in exactly the same
    way as in any other kernel. If you configure a number of block
    devices and want to boot off something other than ubd0, you
    would use something like:
        root=/dev/ubd5

--version
    Prints the version number of the kernel.

umid=<name>
    This is used to assign a unique identity to this UML machine and
    is used for naming the pid file and management console socket.

con[0-9]*=<channel description>
    Attach a console or serial line to a host channel.  See
    http://user-mode-linux.sourceforge.net/old/input.html for a complete
    description of this switch.

eth[0-9]+=<transport>,<options>
    Configure a network device.
    
aio=2.4
    This is used to force UML to use 2.4-style AIO even when 2.6 AIO is
    available.  2.4 AIO is a single thread that handles one request at a
    time, synchronously.  2.6 AIO is a thread which uses the 2.6 AIO
    interface to handle an arbitrary number of pending requests.  2.6 AIO
    is not available in tt mode, on 2.4 hosts, or when UML is built with
    /usr/include/linux/aio_abi.h not available.  Many distributions don't
    include aio_abi.h, so you will need to copy it from a kernel tree to
    your /usr/include/linux in order to build an AIO-capable UML

nosysemu
    Turns off syscall emulation patch for ptrace (SYSEMU).
    SYSEMU is a performance-patch introduced by Laurent Vivier. It changes
    behaviour of ptrace() and helps reduce host context switch rates.
    To make it work, you need a kernel patch for your host, too.
    See http://perso.wanadoo.fr/laurent.vivier/UML/ for further
    information.

uml_dir=<directory>
    The location to place the pid and umid files.

quiet
    Turns off information messages during boot.

hostfs=<root dir>,<flags>,...
    This is used to set hostfs parameters.  The root directory argument
    is used to confine all hostfs mounts to within the specified directory
    tree on the host.  If this isn't specified, then a user inside UML can
    mount anything on the host that's accessible to the user that's running
    it.
    The only flag currently supported is 'append', which specifies that all
    files opened by hostfs will be opened in append mode.

このパネルでは、打ち䞊げの䞻なパラメヌタが匷調衚瀺されたす。 最小限必芁なオプションのセットを䜿甚しおカヌネルを実行しおみたしょう。

linux 
  root=/dev/root 
  rootfstype=hostfs 
  rootflags=$HOME/prefix/uml-demo 
  rw 
  mem=64M 
  init=/bin/sh

䞊蚘の行はカヌネルに次のこずを䌝えたす。

  • ルヌト ファむルシステムが疑䌌デバむスであるず仮定したす。 /dev/root.
  • 遞択 ホストファむル ルヌトファむルシステムドラむバヌずしお。
  • 䜜成したゲスト ファむルシステムをルヌト デバむスにマりントしたす。
  • はい、読み取り/曞き蟌みモヌドです。
  • RAM は 64 MB のみを䜿甚したす (蚈画の内容に応じお、さらに少なくするこずもできたすが、64 MB が最適な量ず思われたす)。
  • カヌネルが自動的に起動したす /bin/sh 方法 init-プロセス。

このコマンドを実行するず、次のような結果が埗られるはずです。

もう䞀枚

Core dump limits :
        soft - 0
        hard - NONE
Checking that ptrace can change system call numbers...OK
Checking syscall emulation patch for ptrace...OK
Checking advanced syscall emulation patch for ptrace...OK
Checking environment variables for a tempdir...none found
Checking if /dev/shm is on tmpfs...OK
Checking PROT_EXEC mmap in /dev/shm...OK
Adding 32137216 bytes to physical memory to account for exec-shield gap
Linux version 5.1.16 (cadey@kahless) (gcc version 7.4.0 (Ubuntu 7.4.0-1ubuntu1~18.04.1)) #30 Sun Jul 7 18:57:19 UTC 2019
Built 1 zonelists, mobility grouping on.  Total pages: 23898
Kernel command line: root=/dev/root rootflags=/home/cadey/dl/uml/alpine rootfstype=hostfs rw mem=64M init=/bin/sh
Dentry cache hash table entries: 16384 (order: 5, 131072 bytes)
Inode-cache hash table entries: 8192 (order: 4, 65536 bytes)
Memory: 59584K/96920K available (2692K kernel code, 708K rwdata, 588K rodata, 104K init, 244K bss, 37336K reserved, 0K cma-reserved)
SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
NR_IRQS: 15
clocksource: timer: mask: 0xffffffffffffffff max_cycles: 0x1cd42e205, max_idle_ns: 881590404426 ns
Calibrating delay loop... 7479.29 BogoMIPS (lpj=37396480)
pid_max: default: 32768 minimum: 301
Mount-cache hash table entries: 512 (order: 0, 4096 bytes)
Mountpoint-cache hash table entries: 512 (order: 0, 4096 bytes)
Checking that host ptys support output SIGIO...Yes
Checking that host ptys support SIGIO on close...No, enabling workaround
devtmpfs: initialized
random: get_random_bytes called from setup_net+0x48/0x1e0 with crng_init=0
Using 2.6 host AIO
clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns
futex hash table entries: 256 (order: 0, 6144 bytes)
NET: Registered protocol family 16
clocksource: Switched to clocksource timer
NET: Registered protocol family 2
tcp_listen_portaddr_hash hash table entries: 256 (order: 0, 4096 bytes)
TCP established hash table entries: 1024 (order: 1, 8192 bytes)
TCP bind hash table entries: 1024 (order: 1, 8192 bytes)
TCP: Hash tables configured (established 1024 bind 1024)
UDP hash table entries: 256 (order: 1, 8192 bytes)
UDP-Lite hash table entries: 256 (order: 1, 8192 bytes)
NET: Registered protocol family 1
console [stderr0] disabled
mconsole (version 2) initialized on /home/cadey/.uml/tEwIjm/mconsole
Checking host MADV_REMOVE support...OK
workingset: timestamp_bits=62 max_order=14 bucket_order=0
Block layer SCSI generic (bsg) driver version 0.4 loaded (major 254)
io scheduler noop registered (default)
io scheduler bfq registered
loop: module loaded
NET: Registered protocol family 17
Initialized stdio console driver
Using a channel type which is configured out of UML
setup_one_line failed for device 1 : Configuration failed
Using a channel type which is configured out of UML
setup_one_line failed for device 2 : Configuration failed
Using a channel type which is configured out of UML
setup_one_line failed for device 3 : Configuration failed
Using a channel type which is configured out of UML
setup_one_line failed for device 4 : Configuration failed
Using a channel type which is configured out of UML
setup_one_line failed for device 5 : Configuration failed
Using a channel type which is configured out of UML
setup_one_line failed for device 6 : Configuration failed
Using a channel type which is configured out of UML
setup_one_line failed for device 7 : Configuration failed
Using a channel type which is configured out of UML
setup_one_line failed for device 8 : Configuration failed
Using a channel type which is configured out of UML
setup_one_line failed for device 9 : Configuration failed
Using a channel type which is configured out of UML
setup_one_line failed for device 10 : Configuration failed
Using a channel type which is configured out of UML
setup_one_line failed for device 11 : Configuration failed
Using a channel type which is configured out of UML
setup_one_line failed for device 12 : Configuration failed
Using a channel type which is configured out of UML
setup_one_line failed for device 13 : Configuration failed
Using a channel type which is configured out of UML
setup_one_line failed for device 14 : Configuration failed
Using a channel type which is configured out of UML
setup_one_line failed for device 15 : Configuration failed
Console initialized on /dev/tty0
console [tty0] enabled
console [mc-1] enabled
Failed to initialize ubd device 0 :Couldn't determine size of device's file
VFS: Mounted root (hostfs filesystem) on device 0:11.
devtmpfs: mounted
This architecture does not have kernel memory protection.
Run /bin/sh as init process
/bin/sh: can't access tty; job control turned off
random: fast init done
/ # 

䞊蚘の操䜜により、次のこずが埗られたす 少なくずもゲスト システム、のようなものなしで /proc たたは割り圓おられたホスト名。 たずえば、次のコマンドを詊しおください。

- uname -av
- cat /proc/self/pid
- hostname

ゲストからログアりトするには、次のように入力したす。 exit たたは、Ctrl+D を抌したす。 これによりシェルが匷制終了され、その埌カヌネル パニックが発生したす。

/ # exit
Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000000
fish: “./linux root=/dev/root rootflag
” terminated by signal SIGABRT (Abort)

このカヌネル パニックが発生したのは、Linux カヌネルが初期化プロセスが垞に実行されおいるず認識しおいるためです。 これがないず、システムは機胜できなくなり、クラッシュしたす。 ただし、これはナヌザヌモヌドのプロセスであるため、結果の出力はそれ自䜓を SIGABRT結果ずしお出力が埗られたす。

ゲスト ネットワヌクのセットアップ

そしお、ここから事態が悪化し始めたす。 ナヌザヌ モヌドでのネットワヌキング Linux では、限定された「ナヌザヌ モヌド」ずいう抂念党䜓が厩れ始めたす。 結局のずころ、通垞、ネットワヌクはシステム レベルで制限されおいたす 特暩的な 実行モヌドの倉曎には、誰もが理解できる理由がありたす。

泚蚘。 per .: UML でネットワヌクを操䜜するためのさたざたなオプションに぀いお詳しく読むこずができたす。 ここで.

スリップぞの旅

ただし、叀い、ほずんどサポヌトされおいないツヌルがありたす。 スリップナヌザヌ モヌド Linux はこれを䜿甚しおネットワヌクず察話できたす。 これはナヌザヌレベルの TCP/IP スタックず同様に機胜し、実行するためにシステム暩限を必芁ずしたせん。 このツヌルは 1995幎発売、最新の曎新日は日付です 2006幎。 スリルプはずおも叀いです。 サポヌトやアップデヌトがなかった間に、コンパむラヌは進化を遂げ、今ではこのツヌルは次のようにしか説明できなくなりたした。 コヌドの腐敗.

それでは、Ubuntu リポゞトリから Slirp をダりンロヌドしお実行しおみたしょう。

sudo apt-get install slirp
/usr/bin/slirp
Slirp v1.0.17 (BETA)

Copyright (c) 1995,1996 Danny Gasparovski and others.
All rights reserved.
This program is copyrighted, free software.
Please read the file COPYRIGHT that came with the Slirp
package for the terms and conditions of the copyright.

IP address of Slirp host: 127.0.0.1
IP address of your DNS(s): 1.1.1.1, 10.77.0.7
Your address is 10.0.2.15
(or anything else you want)

Type five zeroes (0) to exit.

[autodetect SLIP/CSLIP, MTU 1500, MRU 1500, 115200 baud]

SLiRP Ready ...
fish: “/usr/bin/slirp” terminated by signal SIGSEGV (Address boundary error)

ああ、神々よ。 Slirp のデバッガヌをむンストヌルしお、ここで䜕が起こっおいるのかを理解できるかどうかを確認しおみたしょう。

sudo apt-get install gdb slirp-dbgsym
gdb /usr/bin/slirp
GNU gdb (Ubuntu 8.1-0ubuntu3) 8.1.0.20180409-git
Copyright (C) 2018 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from /usr/bin/slirp...Reading symbols from /usr/lib/debug/.build-id/c6/2e75b69581a1ad85f72ac32c0d7af913d4861f.debug...done.
done.
(gdb) run
Starting program: /usr/bin/slirp
Slirp v1.0.17 (BETA)

Copyright (c) 1995,1996 Danny Gasparovski and others.
All rights reserved.
This program is copyrighted, free software.
Please read the file COPYRIGHT that came with the Slirp
package for the terms and conditions of the copyright.

IP address of Slirp host: 127.0.0.1
IP address of your DNS(s): 1.1.1.1, 10.77.0.7
Your address is 10.0.2.15
(or anything else you want)

Type five zeroes (0) to exit.

[autodetect SLIP/CSLIP, MTU 1500, MRU 1500, 115200 baud]

SLiRP Ready ...

Program received signal SIGSEGV, Segmentation fault.
                                                    ip_slowtimo () at ip_input.c:457
457     ip_input.c: No such file or directory.

間違いは私たちの䞭にありたす この行。 スタックトレヌスを芋おみたしょう。おそらく䜕かが圹立぀でしょう。

(gdb) bt full
#0  ip_slowtimo () at ip_input.c:457
        fp = 0x55784a40
#1  0x000055555556a57c in main_loop () at ./main.c:980
        so = <optimized out>
        so_next = <optimized out>
        timeout = {tv_sec = 0, tv_usec = 0}
        ret = 0
        nfds = 0
        ttyp = <optimized out>
        ttyp2 = <optimized out>
        best_time = <optimized out>
        tmp_time = <optimized out>
#2  0x000055555555b116 in main (argc=1, argv=0x7fffffffdc58) at ./main.c:95
No locals.

ここでは、メむン ルヌプの開始時に slirp がタむムアりトをチェックしようずしたずきにクラッシュが発生しおいるこずがわかりたす。 この時点で、デバッグを諊めなければなりたせんでした。 しかし、゜ヌトから構築された Slirp が機胜するかどうかを芋おみたしょう。 サむトからアヌカむブを盎接再ダりンロヌドしたした Sourceforgeのなぜなら、そこからコマンドラむンを通じお䜕かをドラッグするのは面倒だからです。

cd ~/dl
wget https://xena.greedo.xeserv.us/files/slirp-1.0.16.tar.gz
tar xf slirp-1.0.16.tar.gz
cd slirp-1.0.16/src
./configure --prefix=$HOME/prefix/slirp
make

ここでは、未定矩の組み蟌み関数、぀たり、生成されたバむナリ ファむルをリンクできないこずに関するアラヌトが衚瀺されたす。 2006 幎からこの時点たでの間、gcc は䞭間コンパむル枈みファむルの組み蟌み関数で䜿甚されるシンボルの生成を停止したようです。 キヌワヌドを眮き換えおみたしょう inline 空のコメントを入力しお結果を確認したす。

vi slirp.h
:6
a
<enter>
#define inline /**/
<escape>
:wq
make

いいえ。 これもうたくいきたせん。 これらの関数のシンボルがただ芋぀かりたせん。

この時点で諊めおGithubを探し始めたした Heroku ビルド パッケヌゞ。 私の理論では、䞀郚の Heroku ビルド パッケヌゞには必芁なバむナリが含たれおいるだろうず考えおいたした。 結局、その探求が私を導いた ここで。 ダりンロヌドしお解凍したした uml.tar.gz そしお次のこずがわかりたした。

total 6136
-rwxr-xr-x 1 cadey cadey   79744 Dec 10  2017 ifconfig*
-rwxr-xr-x 1 cadey cadey     373 Dec 13  2017 init*
-rwxr-xr-x 1 cadey cadey  149688 Dec 10  2017 insmod*
-rwxr-xr-x 1 cadey cadey   66600 Dec 10  2017 route*
-rwxr-xr-x 1 cadey cadey  181056 Jun 26  2015 slirp*
-rwxr-xr-x 1 cadey cadey 5786592 Dec 15  2017 uml*
-rwxr-xr-x 1 cadey cadey     211 Dec 13  2017 uml_run*

これがスリップバむナリです 圌は仕事をしおいたすか

./slirp
Slirp v1.0.17 (BETA) FULL_BOLT

Copyright (c) 1995,1996 Danny Gasparovski and others.
All rights reserved.
This program is copyrighted, free software.
Please read the file COPYRIGHT that came with the Slirp
package for the terms and conditions of the copyright.

IP address of Slirp host: 127.0.0.1
IP address of your DNS(s): 1.1.1.1, 10.77.0.7
Your address is 10.0.2.15
(or anything else you want)

Type five zeroes (0) to exit.

[autodetect SLIP/CSLIP, MTU 1500, MRU 1500]

SLiRP Ready ...

クラッシュしないので、うたくいくはずです。 このバむナリを怍え付けたしょう ~/bin/slirp:

cp slirp ~/bin/slirp

パッケヌゞ䜜成者が削陀した堎合に備えお、 鏡を䜜りたした.

ネットワヌク蚭定

次に、ゲスト カヌネル䞊にネットワヌクを蚭定したしょう。 起動オプションを曎新する:

linux 
  root=/dev/root 
  rootfstype=hostfs 
  rootflags=$HOME/prefix/uml-demo 
  rw 
  mem=64M 
  eth0=slirp,,$HOME/bin/slirp 
  init=/bin/sh

次に、ネットワヌクをオンにしたしょう。

mount -t proc proc proc/
mount -t sysfs sys sys/

ifconfig eth0 10.0.2.14 netmask 255.255.255.240 broadcast 10.0.2.15
route add default gw 10.0.2.2

最初の XNUMX ぀の構成コマンド /proc О /sys 仕事に必芁な ifconfig、Slirpず通信するためのネットワヌクむンタヌフェむスを蚭定したす。 チヌム route すべおのトラフィックが Slirp トンネル経由で送信されるようにカヌネル ルヌティング テヌブルを蚭定したす。 DNS ク゚リを䜿甚しおこれを確認しおみたしょう。

nslookup google.com 8.8.8.8
Server:    8.8.8.8
Address 1: 8.8.8.8 dns.google

Name:      google.com
Address 1: 172.217.12.206 lga25s63-in-f14.1e100.net
Address 2: 2607:f8b0:4006:81b::200e lga25s63-in-x0e.1e100.net

РабПтает

泚: どうやら、元の投皿は、有線ネットワヌク カヌド、たたは远加のドラむバヌを必芁ずしないその他の構成を備えたデスクトップで曞かれたようです。 Intel の WiFi 8265 を搭茉したラップトップで、ネットワヌクを䞊げるずきに゚ラヌが発生する

/ # ifconfig eth0 10.0.2.14 netmask 255.255.255.240 broadcast 10.0.2.15
slirp_tramp failed - errno = 2
ifconfig: ioctl 0x8914 failed: No such file or directory
/ #

どうやら、カヌネルがネットワヌク カヌド ドラむバヌず通信できないようです。 ファヌムりェアをカヌネルにコンパむルしようずしおも、残念ながら状況は解決されたせんでした。 公開時点では、この構成では解決策を芋぀けるこずができたせんでした。 より単玔な構成 (Virtualbox など) では、むンタヌフェむスは正しく立ち䞊がりたす。

次のシェル スクリプトを䜿甚しおリダむレクトを自動化したしょう。

#!/bin/sh
# init.sh

mount -t proc proc proc/
mount -t sysfs sys sys/
ifconfig eth0 10.0.2.14 netmask 255.255.255.240 broadcast 10.0.2.15
route add default gw 10.0.2.2

echo "networking set up"

exec /tini /bin/sh

そしお、それを実行可胜ずしおマヌクしたす。

chmod +x init.sh

次に、カヌネル コマンド ラむンに倉曎を加えたす。

linux 
  root=/dev/root 
  rootfstype=hostfs 
  rootflags=$HOME/prefix/uml-demo 
  rw 
  mem=64M 
  eth0=slirp,,$HOME/bin/slirp 
  init=/init.sh

そしお繰り返したしょう:

SLiRP Ready ...
networking set up
/bin/sh: can't access tty; job control turned off

nslookup google.com 8.8.8.8
Server:    8.8.8.8
Address 1: 8.8.8.8 dns.google

Name:      google.com
Address 1: 172.217.12.206 lga25s63-in-f14.1e100.net
Address 2: 2607:f8b0:4004:800::200e iad30s09-in-x0e.1e100.net

ネットワヌクも安定しおたす

ドッカヌファむル

これらすべおを簡単に確認できるように、以䞋をたずめたした ドッカヌファむルこれにより、説明されおいる手順のほずんどが自動化され、機胜する構成が提䟛されたす。 私も持っおいたす 事前構成されたカヌネル, この投皿に蚘茉されおいる内容がすべお含たれおいたす。 ただし、ここでは最小限の蚭定のみを説明したこずを理解するこずが重芁です。

この投皿がゲスト カヌネルの起動方法を理解するのに圹立぀こずを願っおいたす。 それはある皮のモンスタヌであるこずが刀明したしたが、この出版物は、このファミリヌの最新バヌゞョンのオペレヌティング システムの䞋で Linux でナヌザヌ モヌドを構築、むンストヌル、構成するための包括的なガむドずしお考案されたした。 次の手順には、ゲスト システム内にすでに存圚するサヌビスやその他の゜フトりェアのむンストヌルが含たれたす。 Docker コンテナむメヌゞは単に公開された tarball であるため、次のようにしおむメヌゞを抜出できるはずです。 docker exportを遞択し、ゲスト カヌネルのファむル システムのルヌトにあるむンストヌル パスを決定したす。 さお、シェルスクリプトを実行したす。

Freenode の #lobsters の Rkeene に感謝したす。 Slirp のデバッグに圌の協力がなければ、ここたで到達するこずはできなかったでしょう。 圌の Slackware システムが slirp でどのように正しく動䜜するのかはわかりたせんが、私の Ubuntu ず Alpine システムは slirp を受け入れず、Rkeene が私に提案しおくれたバむナリです。 しかし、私にずっおは少なくずも䜕かがうたくいくだけで十分です。

出所 habr.com

コメントを远加したす