Линукс дээр хэрэглэгчийн горимыг хэрхэн ашиглаж эхлэх вэ

Орчуулагчийн танилцуулга: Төрөл бүрийн савнууд бидний амьдралд асар их нэвтэрч байгаа энэ үед энэ бүхэн хэзээ нэгэн цагт ямар технологиор эхэлснийг олж мэдэх нь нэлээд сонирхолтой бөгөөд ашигтай байж болох юм. Тэдгээрийн заримыг өнөөдрийг хүртэл ашиг тустай ашиглаж болох боловч хүн бүр ийм аргыг санахгүй байна (эсвэл тэд хурдацтай хөгжиж байхдаа баригдаагүй бол мэддэггүй). Ийм технологийн нэг бол User Mode Linux юм. Жинхэнэ эхийг зохиогч нэлээд ухаж, хуучин бүтээн байгуулалтуудын аль нь ажиллаж байгаа, аль нь ажиллахгүй байгааг олж мэдээд, гэртээ ургуулсан UML-ийг хэрхэн яаж хийх талаар алхам алхмаар зааварчилгааг нэгтгэсэн. 2к19. Тийм ээ, бид анхны нийтлэлийн зохиогчийг Хабр руу урьсан Кади, хэрэв танд асуулт байвал тайлбар дээр англи хэлээр асуугаарай.

Линукс дээр хэрэглэгчийн горимыг хэрхэн ашиглаж эхлэх вэ

Линукс дахь хэрэглэгчийн горим нь үнэндээ Линуксийн цөмийн порт юм. Энэ горим нь хэрэглэгчийн процесс болгон Линуксийн цөмийг бүрэн ажиллуулах боломжийг олгодог бөгөөд хөгжүүлэгчид драйверуудыг шалгахад ихэвчлэн ашигладаг. Гэхдээ энэ горим нь ерөнхий тусгаарлах хэрэгсэл болгон бас ашигтай бөгөөд зарчим нь виртуал машинуудын ажиллагаатай төстэй юм. Энэ горим нь Docker-ээс илүү тусгаарлалтыг хангадаг боловч KVM эсвэл Virtual Box гэх мэт бүрэн хэмжээний виртуал машинаас бага.

Ерөнхийдөө Хэрэглэгчийн горим нь ашиглахад хэцүү, хачирхалтай хэрэгсэл мэт санагдаж болох ч энэ нь өөрийн хэрэглээтэй байдаг. Эцсийн эцэст энэ бол эрх мэдэлгүй хэрэглэгчээр ажилладаг бүрэн хэмжээний Линукс цөм юм. Энэ функц нь найдваргүй байж болзошгүй кодыг хост машинд аюул учруулахгүйгээр ажиллуулах боломжийг олгодог. Мөн энэ нь бүрэн хэмжээний цөм тул түүний процессууд нь хост машинаас тусгаарлагдсан байдаг Хэрэглэгчийн горимд ажиллаж байгаа процессууд хостод харагдахгүй. Энэ нь уламжлалт Docker контейнер шиг биш бөгөөд хост машин нь хадгалах доторх процессуудыг үргэлж хардаг. Миний серверүүдийн нэгээс авсан энэ бичлэгийг харна уу:

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}]

Үүнийг хэрэглэгчийн горим дахь Линуксийн цөмийн pstree-тэй харьцуулна уу:

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

Docker контейнеруудтай ажиллахдаа би зочинд ажиллаж байгаа процессуудын нэрийг хостоос харж болно. Линукс хэрэглэгчийн горимд үүнийг хийх боломжгүй. Энэ нь юу гэсэн үг вэ? Энэ нь Линуксийн аудитын дэд системээр ажилладаг хяналтын хэрэгслүүд гэсэн үг Бүү хар зочин системд ажиллаж байгаа процессууд. Гэхдээ зарим тохиолдолд энэ шинж чанар нь хоёр талдаа иртэй сэлэм байж болно.

Ерөнхийдөө доорх нийтлэл бол хүссэн үр дүндээ хүрэх судалгаа, бүдүүлэг оролдлогуудын цуглуулга юм. Үүнийг хийхийн тулд би янз бүрийн эртний хэрэгслүүдийг ашиглах, цөмийн эх сурвалжуудыг уншиж, бага сургуульд байхдаа бичсэн кодыг эрчимтэй дибаг хийх, мөн өөрт хэрэгтэй хэрэглүүрийг хайж олохын тулд тусгай хоёртын файл ашиглан Хероку бүтээцтэй ажиллах шаардлагатай болсон. Энэ бүх ажил миний IRC дээрх залуусыг намайг илбэчин гэж дуудахад хүргэсэн. Энэ нийтлэл нь шинэ цөм болон үйлдлийн системтэй ижил зүйлийг хийх найдвартай баримт бичиг болно гэж найдаж байна.

тохируулга

Линукс хэрэглэгчийн горимыг тохируулах нь хэд хэдэн алхмуудыг агуулна.

  • хост дээр хамаарлыг суулгах;
  • Linux цөмийг татаж авах;
  • цөм бүтээх тохиргоо;
  • цөмийн угсралт;
  • хоёртын файлыг суулгах;
  • зочин файлын системийг тохируулах;
  • цөмийн эхлүүлэх параметрүүдийг сонгох;
  • зочны сүлжээг бий болгох;
  • зочин цөмийг ажиллуулж байна.

Хэрэв та энэ бүгдийг өөрөө хийхээр шийдсэн бол Ubuntu эсвэл Debian-тай төстэй системд дурдсан бүх зүйлийг хийх болно гэж би бодож байна. Би дээрх бүх зүйлийг өөрийн дуртай Alpine түгээлтдээ хэрэгжүүлэхийг оролдсон боловч Линуксийн цөм нь Хэрэглэгчийн горимд байгаа драйверуудад зориулсан glibc-isms-тэй нягт холбоотой учраас юу ч бүтсэнгүй. Асуудлыг эцэслэн олж мэдсэнийхээ дараа би үүнийг дээд хэсэгт мэдээлэхээр төлөвлөж байна.

Хостоос хамаарлыг суулгаж байна

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)

Линукс цөмд зориулсан цэсийг өөрчлөх програмыг ажиллуулахын тулд суулгах шаардлагатай гэдгийг анхаарна уу libncurses-dev. Дараах тушаалыг (root эсвэл sudo ашиглан) ашиглан суулгасан эсэхийг шалгана уу.

apt-get -y install libncurses-dev

Цөмийг татаж байна

Хаана татаж авахаа тодорхойлж, дараа нь цөмийг бүтээнэ үү. Энэ үйлдэлд та хатуу дискэнд ойролцоогоор 1,3 ГБ зай хуваарилах шаардлагатай тул үүнийг байгаа эсэхийг шалгаарай.

Дараа нь оч 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]", та Spacebar эсвэл 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]'.

Энэ нийтлэлийг уншсаны дараа цөм бүтээх сонголтуудтай тоглохыг танд зөвлөж байна. Эдгээр туршилтуудаас та доод түвшний цөмийн механик хэрхэн ажилладаг, өөр өөр тугнууд цөмийг хэрхэн бүтээхэд хэрхэн нөлөөлдөг талаар ихийг мэдэж болно.

Цөмийг бүтээх

Линукс цөм нь маш олон зүйлийг хийдэг том програм юм. Хуучин тоног төхөөрөмж дээрх хамгийн бага тохиргоотой байсан ч угсралтад нэлээд хугацаа шаардагдана. Тиймээс дараах тушаалыг ашиглан цөмийг бүтээнэ үү.

make ARCH=um -j$(nproc)

Юуны төлөө? Энэ тушаал нь манай бүтээгчийг бүтээх явцад бүх CPU-ийн цөм болон урсгалуудыг ашиглахыг хэлэх болно. Баг $(nproc) Build-ийн төгсгөлд командын гаралтыг оруулна nprocхэсэг болох coreutils стандарт Ubuntu бүтээхэд.

Хэсэг хугацааны дараа манай цөмийг гүйцэтгэх боломжтой файл болгон хөрвүүлэх болно ./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

Энэхүү tarball-г wget ашиглан татаж авна уу:

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 нь ерөнхий санааг үнэлэхэд хангалттай байх болно.

Бидэнд бас хэрэгсэл хэрэгтэй цагаан тугалга санах ойн хэрэглээг зогсоох зомби үйл явц манай зочин цөм.

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

Цөмийн командын мөр үүсгэх

Линуксийн цөм нь бусад ихэнх програмуудын нэгэн адил тушаалын мөрийн аргументуудтай бөгөөд түлхүүрийг зааж өгснөөр хандаж болно. --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.
  • Сонгох hostfs root файлын системийн драйвер болгон.
  • Бидний үүсгэсэн зочин файлын системийг root төхөөрөмж дээр суулгана уу.
  • Тийм ээ, унших-бичих горимд.
  • Зөвхөн 64 мегабайт RAM ашигла (та юу хийхээр төлөвлөж байгаагаас хамааран хамаагүй бага ашиглах боломжтой, гэхдээ 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 эсвэл control-d товчийг дарна уу. Энэ нь бүрхүүлийг асааж, цөмийн үймээн самуун үүснэ:

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

Линукс цөм нь эхлүүлэх процесс үргэлж ажиллаж байгаа гэж боддог тул бид цөмийн үймээн самуунд автсан. Үүнгүйгээр систем ажиллахаа больж, унтардаг. Гэхдээ энэ нь хэрэглэгчийн горимын процесс тул үр дүн нь өөрөө илгээгддэг SIGABRT, энэ нь гарц руу хүргэдэг.

Зочны сүлжээг тохируулж байна

Гэвч эндээс л бидний хувьд бүх зүйл буруугаар эргэж эхэлдэг. Линукс хэрэглэгчийн горим дахь сүлжээ нь хязгаарлагдмал "хэрэглэгчийн горим" гэсэн ойлголт бүхэлдээ задарч эхэлдэг. Эцсийн эцэст сүлжээ нь ихэвчлэн системийн түвшинд хязгаарлагддаг давуу эрхтэй Бид бүгдэд тодорхой шалтгааны улмаас гүйцэтгэх горимууд.

Анхаарна уу per.: Та UML дээр сүлжээтэй ажиллах өөр өөр сонголтуудын талаар илүү ихийг уншиж болно энд.

Слип хийх аялал

Гэсэн хэдий ч эртний бөгөөд бараг дэмжигдээгүй хэрэгсэл байдаг Слип, Хэрэглэгчийн горимын Линукс сүлжээтэй харьцах боломжтой. Энэ нь бараг хэрэглэгчийн түвшний TCP/IP стек шиг ажилладаг бөгөөд ажиллуулахын тулд системийн ямар ч зөвшөөрөл шаарддаггүй. Энэ хэрэгсэл байсан 1995 онд гарсан, мөн сүүлийн шинэчлэлт нь огноотой 2006 он. Слирп маш хуучирсан. Дэмжлэг, шинэчлэлтгүй байсан хугацаанд хөрвүүлэгчид маш их хөгжсөн тул одоо энэ хэрэгслийг зөвхөн гэж нэрлэж болно "код ялзрах".

Тиймээс, Slirp-ийг Ubuntu репозитороос татаж аваад ажиллуулахыг оролдъё:

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 ажиллаж байгаа эсэхийг харцгаая. Би сайтаас шууд архивыг дахин татаж авсан Эх сурвалж, учир нь тэндээс командын мөрөөр ямар нэг зүйлийг чирэх нь өвдөлт юм:

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 багцуудыг бүтээх. Миний онол бол Хероку бүтээх багц нь надад хэрэгтэй хоёртын файлуудыг агуулсан байх болно. Эцэст нь миний эрэл хайгуул намайг хөтөлсөн яг энд. Би татаж аваад задалсан 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

Багцыг бүтээгч үүнийг устгасан тохиолдолд I толь хийсэн.

Сүлжээний тохиргоо

Одоо зочин цөм дээрээ сүлжээгээ тохируулцгаая. Эхлүүлэх параметрүүдийг шинэчилье:

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

Эхний хоёр тохиргооны команд /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

Сүлжээ тогтвортой байна!

docker файл

Энэ бүхнийг шалгахад хялбар болгохын тулд би цуглуулсан Докер файл, энэ нь тайлбарласан ихэнх алхмуудыг автоматжуулж, танд ажлын тохиргоог өгөх ёстой. Надад ч бас байгаа бэлэн цөмийн тохиргоо, энэ нь нийтлэлд тайлбарласан бүх зүйлийг агуулсан. Гэхдээ энд би зөвхөн хамгийн бага тохиргоог хийсэн гэдгийг ойлгох нь чухал юм.

Энэ нийтлэл нь зочин цөмийг хэрхэн авчрах талаар ойлгоход тань тусалсан гэж найдаж байна. Энэ нь ямар нэгэн мангас болж хувирсан боловч уг нийтлэл нь энэ гэр бүлийн үйлдлийн системийн орчин үеийн хувилбаруудын дагуу Линукс дээр хэрэглэгчийн горимыг угсрах, суулгах, тохируулах сэдвийн талаархи дэлгэрэнгүй гарын авлага байх зорилготой байв. Дараагийн алхмууд нь зочны системд байгаа үйлчилгээ болон бусад програм хангамжийг суулгахыг багтаасан байх ёстой. Docker контейнерийн зургууд нь зүгээр л сурталчилсан tarballs тул та дүрсийг дамжуулан задлах боломжтой байх ёстой docker export, дараа нь зочны цөмийн файлын системийн үндэст суулгах замыг тодорхойлно. За тэгээд бүрхүүлийн скриптийг ажиллуул.

Freenode дээрх # хавчаас Rkeene-д онцгой талархал илэрхийлье. Слирпийг дибаг хийхэд түүний тусламжгүйгээр би ийм хол явахгүй байсан. Түүний Slackware систем нь slirp-тай хэрхэн зөв ажилладаг талаар би мэдэхгүй ч миний Ubuntu болон Alpine системүүд slirp-ийг хүлээж аваагүй бөгөөд Rkeene хоёртын систем надад санал болгосон. Гэхдээ ядаж л ямар нэг зүйл надад тохирох нь надад хангалттай.

Эх сурвалж: www.habr.com

сэтгэгдэл нэмэх