Linux'ta Kullanıcı Modu'nu kullanmaya nasıl başlanır?

Çevirmenin girişi: Çeşitli konteyner türlerinin hayatımıza kitlesel girişinin arka planında, her şeyin bir zamanlar hangi teknolojilerle başladığını öğrenmek oldukça ilginç ve faydalı olabilir. Bunlardan bazıları bugüne kadar faydalı bir şekilde kullanılabilir, ancak herkes bu yöntemleri hatırlamıyor (veya hızlı gelişimleri sırasında yakalanıp yakalanmadıklarını bilmiyor). Böyle bir teknoloji Kullanıcı Modu Linux'tur. Orijinalin yazarı, eski gelişmelerden hangilerinin hala işe yarayıp hangilerinin işe yaramadığını bulmak için çok fazla araştırma yaptı ve 2k19'da kendinize nasıl bir homebrew UML alacağınıza dair adım adım talimat gibi bir şey hazırladı. Ve evet, orijinal gönderinin yazarını Habr'a davet ettik Temizlemek, yani herhangi bir sorunuz varsa yorumlarda İngilizce olarak sorun.

Linux'ta Kullanıcı Modu'nu kullanmaya nasıl başlanır?

Linux'taki Kullanıcı Modu aslında Linux çekirdeğinin kendisine yönelik bir bağlantı noktasıdır. Bu mod, bir kullanıcı işlemi olarak tam bir Linux çekirdeğini çalıştırmanıza olanak tanır ve geliştiriciler tarafından sürücüleri test etmek için yaygın olarak kullanılır. Ancak bu mod, prensibi sanal makinelerin çalışmasına benzer olan genel bir izolasyon aracı olarak da kullanışlıdır. Bu mod, Docker'dan daha fazla izolasyon sağlar ancak KVM veya Virtual Box gibi tam teşekküllü bir sanal makineden daha az izolasyon sağlar.

Genel olarak Kullanıcı Modu tuhaf ve kullanımı zor bir araç gibi görünebilir ancak yine de kullanım alanları vardır. Sonuçta bu, ayrıcalıklı olmayan bir kullanıcı tarafından çalıştırılan tam teşekküllü bir Linux çekirdeğidir. Bu özellik, potansiyel olarak güvenilmeyen kodun ana makineye herhangi bir tehdit oluşturmadan çalışmasına olanak tanır. Ve bu tam teşekküllü bir çekirdek olduğundan, süreçleri ana makineden izole edilmiştir, yani Kullanıcı Modunda çalışan işlemler ana bilgisayar tarafından görülmeyecek. Bu normal Docker konteynerine benzemez; bu durumda ana makine her zaman depo içindeki işlemleri görür. Sunucularımdan birindeki şu pstree parçasına bakın:

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

Ve bunu Kullanıcı Modundaki Linux çekirdeğinin pstree'siyle karşılaştırın:

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

Docker kapsayıcılarıyla çalışırken, konukta çalışan işlemlerin adlarını ana bilgisayardan görebiliyorum. Linux Kullanıcı Modunda bu mümkün değildir. Bu ne anlama geliyor? Bu, Linux'un denetim alt sistemi üzerinden çalışan izleme araçlarının görmüyorum Konuk sisteminde çalışan işlemler. Ancak bazı durumlarda bu özellik iki ucu keskin bir kılıca dönüşebilir.

Genel olarak, aşağıdaki gönderinin tamamı, istenen sonuca ulaşmak için yapılan araştırmaların ve kaba çabaların bir derlemesidir. Bunu yapmak için çeşitli eski araçları kullanmam, çekirdek kaynaklarını okumam, henüz ilkokuldayken yazdığım kodlarda yoğun hata ayıklama yapmam ve ayrıca ihtiyacım olan araçları bulmak için özel bir ikili dosya kullanarak Heroku yapılarını düzeltmem gerekiyordu. . Bütün bu çalışmalar IRC'mdeki adamların bana sihir demesine yol açtı. Umarım bu yazı, birisinin aynı şeyi daha yeni çekirdekler ve işletim sistemi sürümleriyle denemesi için güvenilir bir belge görevi görür.

Ayar

Linux Kullanıcı Modunun kurulumu birkaç adımda gerçekleştirilir:

  • ana bilgisayara bağımlılıkların kurulması;
  • Linux çekirdeğinin indirilmesi;
  • çekirdek yapı yapılandırması;
  • çekirdek derlemesi;
  • ikili kurulum;
  • konuk dosya sisteminin yapılandırılması;
  • çekirdek başlatma parametrelerinin seçimi;
  • bir misafir ağı kurmak;
  • misafir çekirdeği başlatıyorum.

Bunu kendiniz yapmaya karar verirseniz, büyük olasılıkla Ubuntu veya Debian benzeri bir sistemde açıklanan her şeyi yapacağınızı varsayıyorum. Yukarıdakilerin tümünü en sevdiğim dağıtım olan Alpine'da uygulamaya çalıştım, ancak görünüşe göre Linux çekirdeğinin Kullanıcı Modundaki sürücüler için katı bağlayıcı bir glibc-izm'lere sahip olması nedeniyle bundan hiçbir şey çıkmadı. Sorunu nihayet anladıktan sonra bunu yukarı akışa bildirmeyi planlıyorum.

Ana makineye bağımlılıklar yükleme

Ubuntu, Linux çekirdeğini oluşturmak için en azından aşağıdaki paketlere ihtiyaç duyar (temiz kurulum varsayılarak):

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

Bunları aşağıdaki komutla (root olarak veya sudo ile) yükleyebilirsiniz:

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

Linux çekirdek menüsü kurulum programını çalıştırmanın aşağıdakilerin yüklenmesini gerektireceğini unutmayın: libncurses-dev. Lütfen aşağıdaki komutla (root olarak veya sudo ile) kurulduğundan emin olun:

apt-get -y install libncurses-dev

Çekirdek indirme

Çekirdeği nereye indireceğinize ve ardından oluşturacağınıza karar verin. Bu işlem için yaklaşık 1,3 GB sabit disk alanı ayırmanız gerekecektir, bu nedenle buna sahip olduğunuzdan emin olun.

Gittikten sonra kernel.org ve en son kararlı çekirdeği indirmek için URL'yi alın. Bu yazının yazıldığı sırada durum şöyle: https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.1.16.tar.xz

Bu dosyayı kullanarak indirin 'wget':

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

Ve şununla çıkartın 'tar':

tar xJf linux-5.1.16.tar.xz

Şimdi tarball paketini açarken oluşturulan dizine giriyoruz:

cd linux-5.1.16

Çekirdek oluşturma kurulumu

Çekirdek yapı sistemi bir settir Makefile dosyaları с birçok süreci otomatikleştirmek için özel araçlar ve komut dosyaları. Öncelikle etkileşimli kurulum programını açın:

make ARCH=um menuconfig

Kısmen sizin için bir iletişim kutusu oluşturacak ve görüntüleyecektir. Ne zaman '[Select]', Space veya Enter tuşlarını kullanarak yapılandırma yapabileceksiniz. Her zamanki gibi klavyenin "yukarı" ve "aşağı" ok tuşlarını kullanarak pencerede gezinin ve "sol" veya "sağ" öğelerini seçin.

Görünüm işaretçisi —>, Enter tuşuyla erişilen bir alt menüde olduğunuz anlamına gelir. Bundan çıkış yolu belli ki '[Exit]'.

' içine aşağıdaki seçenekleri ekleyin[Select]' ve yanlarında '[*]' işaretinin olduğundan emin olun:

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

İşte bu kadar, ' seçeneğini art arda seçerek bu pencereden çıkabilirsiniz.[Exit]'. Sonunda yapılandırmayı kaydetmenizin istendiğinden emin olun ve ' seçeneğini seçin.[Yes]'.

Bu yazıyı okuduktan sonra çekirdek oluşturma seçenekleriyle denemenizi öneririm. Bu deneyler aracılığıyla, düşük seviyeli çekirdek mekaniğinin çalışmasını ve çeşitli bayrakların onun montajı üzerindeki etkisini anlama açısından çok şey öğrenebilirsiniz.

Çekirdeği oluşturmak

Linux çekirdeği pek çok şey yapan büyük bir programdır. Eski donanımda bu kadar minimal bir konfigürasyonla bile oluşturulması oldukça zaman alabilir. Yani çekirdeği aşağıdaki komutla oluşturun:

make ARCH=um -j$(nproc)

Ne için? Bu komut, oluşturucumuza derleme sürecinde mevcut tüm CPU çekirdeklerini ve iş parçacıklarını kullanmasını söyleyecektir. Takım $(nproc) Build'in sonunda komutun çıktısının yerini alır nprocbir parçası olan coreutils standart bir Ubuntu yapısında.

Bir süre sonra çekirdeğimiz çalıştırılabilir bir dosya halinde derlenecek ./linux.

İkiliyi yükleme

Linux'taki Kullanıcı Modu normal bir ikili dosya oluşturduğundan, onu diğer herhangi bir yardımcı program gibi yükleyebilirsiniz. İşte bunu nasıl yaptım:

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

Ayrıca bundan emin olmaya değer ~/bin senin içinde $PATH:

export PATH=$PATH:$HOME/bin

Konuk dosya sisteminin kurulması

Konuk dosya sistemi için bir dizin oluşturun:

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

alpinelinux.org'u açın ve indirme bölümü gerçek indirme bağlantısını bulun MINI ROOT FILESYSTEM. Bu yazı yazıldığı sırada şuydu:

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

Bu tarball'ı wget kullanarak indirin:

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

Şimdi konuk dosya sisteminin dizinine girin ve arşivi çıkarın:

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

Açıklanan eylemler küçük bir dosya sistemi şablonu oluşturacaktır. Sistemin doğası gereği Alpine apk yöneticisi aracılığıyla paketleri kurmak son derece zor olacaktır. Fakat bu FS genel fikri değerlendirmek için yeterli olacaktır.

Ayrıca bir araca ihtiyacımız var tini bellek tüketimini azaltmak için zombi süreçleri misafir çekirdeğimiz.

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

Çekirdek komut satırı oluşturma

Linux çekirdeği, diğer programların çoğunda olduğu gibi, anahtar belirtilerek erişilebilen komut satırı argümanlarına sahiptir. --help.

Kendisi - yardım

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.

Bu panel, başlatmanın ana parametrelerini vurgular. Çekirdeği gerekli minimum seçenek kümesiyle çalıştıralım:

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

Yukarıdaki satırlar çekirdeğimize şunları söylüyor:

  • Kök dosya sisteminin sahte bir aygıt olduğunu varsayalım /dev/root.
  • Seç hostf'ler kök dosya sistemi sürücüsü olarak.
  • Oluşturduğumuz misafir dosya sistemini kök cihaza bağlayın.
  • Ve evet, okuma-yazma modunda.
  • Yalnızca 64 MB RAM kullanın (ne yapmayı planladığınıza bağlı olarak çok daha az RAM kullanabilirsiniz, ancak 64 MB en uygun miktar gibi görünüyor).
  • Çekirdek otomatik olarak başlar /bin/sh gibi init-işlem.

Bu komutu çalıştırdığınızda aşağıdakine benzer bir şey elde etmelisiniz:

Bir sayfa daha

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
/ # 

Yukarıdaki manipülasyonlar bize şunu verecektir: minimum misafir sistemi, gibi şeyler olmadan /proc veya atanmış ana bilgisayar adı. Örneğin aşağıdaki komutları deneyin:

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

Konuk oturumunu kapatmak için şunu yazın: exit veya control-d tuşlarına basın. Bu, kabuğu öldürecek ve ardından çekirdek paniği gelecektir:

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

Bu çekirdek paniğini yaşadık çünkü Linux çekirdeği başlatma sürecinin her zaman çalıştığını düşünüyor. Bu olmadan sistem artık çalışamaz ve çöker. Ancak bu bir kullanıcı modu işlemi olduğundan, ortaya çıkan çıktı kendisini SIGABRT, bu da bir çıktıyla sonuçlanır.

Konuk ağ kurulumu

İşte işler burada ters gitmeye başlıyor. Kullanıcı Modunda Ağ Oluşturma Linux, sınırlı "kullanıcı modu" kavramının tamamının parçalanmaya başladığı yerdir. Sonuçta, genellikle sistem düzeyinde ağ sınırlıdır ayrıcalıklı hepimiz için anlaşılabilir nedenlerden dolayı yürütme modları.

Not. başına .: UML'de bir ağla çalışmaya yönelik farklı seçenekler hakkında daha fazla bilgi edinebilirsiniz burada.

Slirp'e Yolculuk

Ancak, eski ve neredeyse desteklenmeyen bir araç var: kaymakKullanıcı Modu Linux'un ağ ile etkileşime girebileceği . Kullanıcı düzeyindeki bir TCP/IP yığınına benzer şekilde çalışır ve çalışması için herhangi bir sistem izni gerektirmez. Bu araç 1995 yılında yayınlandıve en son güncelleme tarihli 2006 yılı. Slirp çok eskidir. Desteğin ve güncellemelerin olmadığı süre boyunca derleyiciler o kadar ileri gitti ki artık bu araç yalnızca şu şekilde tanımlanabilir: kod çürüğü.

Öyleyse Slirp'i Ubuntu depolarından indirelim ve çalıştırmayı deneyelim:

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)

Ah tanrılar. Slirp'in hata ayıklayıcısını yükleyelim ve burada neler olduğunu çözebilecek miyiz görelim:

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.

Hata içimizde atıyor bu hat. Stacktrace'e bakalım, belki orada bize yardımcı olabilecek bir şeyler vardır:

(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.

Burada, ana döngü başlangıcında, slirp zaman aşımlarını kontrol etmeye çalıştığında kilitlenmenin meydana geldiğini görüyoruz. Bu noktada hata ayıklamaya çalışmaktan vazgeçmek zorunda kaldım. Ama bakalım Slirp bir çeşit işe yarayacak mı? Arşivi doğrudan siteden yeniden indirdim Sourceforge, çünkü bir şeyi oradan komut satırına sürüklemek bir acıdır:

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

Burada tanımlanmamış yerleşik işlevlerle, yani ortaya çıkan ikili dosyaya bağlanılamamasıyla ilgili uyarıları görüyoruz. Görünüşe göre 2006 ile bu nokta arasında gcc, ara derlenmiş dosyaların yerleşik işlevlerinde kullanılan sembolleri üretmeyi bıraktı. Anahtar kelimeyi değiştirmeyi deneyelim inline boş bir yorumda ve sonuca bakın:

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

Hayır. Bu da işe yaramıyor. Bu işlevlere ilişkin simgeleri hâlâ bulamıyorum.

Bu noktada pes ettim ve Github'a bakmaya başladım. Heroku derleme paketleri. Benim teorim, bazı Heroku derleme paketlerinin ihtiyacım olan ikili dosyaları içereceği yönündeydi. Sonunda arama beni yönlendirdi burada burada. İndirip paketini açtım uml.tar.gz ve şunları buldum:

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*

Bu slirp ikilisi! Çalışıyor mu?

./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 ...

Çökmüyor; bu yüzden çalışması gerekiyor! Bu ikiliyi yerleştirelim ~/bin/slirp:

cp slirp ~/bin/slirp

Paket oluşturucunun onu kaldırması durumunda, bir ayna yaptım.

Ağ yapılandırması

Şimdi misafir çekirdeğimizde ağı kuralım. Başlatma seçeneklerini güncelleyin:

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

Şimdi ağı açalım:

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

İlk iki konfigürasyon komutu /proc и /sys iş için gerekli ifconfigAğ arayüzünü Slirp ile iletişim kuracak şekilde ayarlar. Takım route çekirdek yönlendirme tablosunu tüm trafiğin Slirp tüneli üzerinden gönderilmesini zorlayacak şekilde ayarlar. Bunu bir DNS sorgusu ile kontrol edelim:

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

İşe yarıyor!

başına not: Görünüşe göre, orijinal gönderi kablolu bir ağ kartıyla veya ek sürücüler gerektirmeyen başka bir yapılandırmayla bir masaüstüne yazılmış. Intel'den WiFi 8265'e sahip bir dizüstü bilgisayarda ağ yükseltilirken bir hata oluşuyor

/ # 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
/ #

Görünüşe göre çekirdek ağ kartı sürücüsüyle iletişim kuramıyor. Firmware'i çekirdeğe derleme girişimi ne yazık ki durumu düzeltmedi. Yayınlandığı tarihte bu konfigürasyonda bir çözüm bulmak mümkün değildi. Daha basit yapılandırmalarda (örneğin, Virtualbox'ta) arayüz doğru şekilde yükselir.

Yönlendirmeyi aşağıdaki kabuk betiğiyle otomatikleştirelim:

#!/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

Ve yürütülebilir olarak işaretleyin:

chmod +x init.sh

Daha sonra çekirdek komut satırında değişiklikler yapacağız:

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

Ve tekrarlayalım:

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

Ağ stabil!

liman işçisi dosyası

Tüm bunları kontrol etmenizi kolaylaştırmak için topladım Dockerfileaçıklanan adımların çoğunu otomatikleştiren ve size çalışan bir yapılandırma sunması gereken. bende de var önceden yapılandırılmış çekirdek, yazıda açıklanan her şeye sahiptir. Ancak burada yalnızca minimum ayarı özetlediğimi anlamak önemlidir.

Umarım bu yazı konuk çekirdeği nasıl yükselteceğinizi anlamanıza yardımcı olmuştur. Bir tür canavar olduğu ortaya çıktı, ancak yayın, bu ailenin işletim sistemlerinin modern sürümleri altında Linux'ta Kullanıcı Modunun oluşturulması, kurulması ve yapılandırılması konusunda kapsamlı bir rehber olarak tasarlandı. Sonraki adımlar, halihazırda konuk sisteminde bulunan hizmetlerin ve diğer yazılımların yüklenmesini içermelidir. Docker kapsayıcı görüntüleri yalnızca halka açık tarball'lar olduğundan, görüntüyü şu şekilde çıkarabilmelisiniz: docker exportve ardından konuk çekirdeğin dosya sisteminin kökündeki kurulum yolunu belirleyin. O halde kabuk betiğini yürütün.

Freenode'daki #lobsters'tan Rkeene'ye özel teşekkürler. Slirp'te hata ayıklamanın yardımı olmasaydı bu kadar ileri gidemezdim. Slackware sisteminin slirp ile nasıl düzgün çalıştığı hakkında hiçbir fikrim yok, ancak Ubuntu ve Alpine sistemlerim slirp'i kabul etmedi ve Rkeene bana önerdi. Ama en azından bir şeyin işime yaraması benim için yeterli.

Kaynak: habr.com

Yorum ekle