Linux-da İstifadəçi rejimindən necə istifadə etməyə başlamaq olar

Tərcüməçidən giriş: Müxtəlif növ qabların həyatımıza kütləvi şəkildə daxil olması fonunda, bunların hamısının bir dəfə hansı texnologiyalarla başladığını öyrənmək olduqca maraqlı və faydalı ola bilər. Onlardan bəziləri bu günə qədər faydalı şəkildə istifadə edilə bilər, lakin hər kəs belə üsulları xatırlamır (yaxud onların sürətli inkişafı zamanı tutulmadığını bilir). Belə texnologiyalardan biri User Mode Linux-dur. Orijinalın müəllifi çoxlu qazıntılar apardı, köhnə inkişaflardan hansının hələ də işlədiyini və hansının işləmədiyini müəyyənləşdirdi və 2k19-da özünüzə homebrew UML əldə etmək üçün addım-addım təlimat kimi bir şey topladı. Bəli, orijinal yazının müəllifini Habr-a dəvət etdik Cadey, buna görə də hər hansı bir sualınız varsa - şərhlərdə ingilis dilində soruşun.

Linux-da İstifadəçi rejimindən necə istifadə etməyə başlamaq olar

Linux-da İstifadəçi Modu əslində Linux nüvəsinin öz portudur. Bu rejim bir istifadəçi prosesi kimi tam Linux nüvəsini işə salmağa imkan verir və adətən tərtibatçılar tərəfindən sürücüləri sınamaq üçün istifadə olunur. Amma bu rejim ümumi izolyasiya vasitəsi kimi də faydalıdır, prinsipi virtual maşınların işinə bənzəyir. Bu rejim Docker-dən daha çox izolyasiya təmin edir, lakin KVM və ya Virtual Box kimi tam hüquqlu virtual maşından daha azdır.

Ümumiyyətlə, İstifadəçi rejimi qəribə və istifadəsi çətin bir vasitə kimi görünə bilər, lakin hələ də istifadələri var. Axı, bu, imtiyazsız istifadəçidən işləyən tam hüquqlu Linux nüvəsidir. Bu xüsusiyyət potensial etibarsız kodun host maşın üçün heç bir təhlükə olmadan işləməsinə imkan verir. Və bu, tam hüquqlu bir nüvə olduğundan, onun prosesləri ana maşından təcrid olunur, yəni İstifadəçi rejimi daxilində işləyən proseslər hosta görünməyəcək. Bu, adi Docker konteynerinə bənzəmir, bu halda ana maşın həmişə depo daxilindəki prosesləri görür. Serverlərimdən birindən bu pstree parçasına baxı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}]

Bunu İstifadəçi rejimində Linux nüvəsinin pstree ilə müqayisə edin:

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

Docker konteynerləri ilə işləyərkən mən qonaqda işləyən proseslərin adlarını hostdan görə bilirəm. Linux İstifadəçi rejimi ilə bu mümkün deyil. Bunun mənası nədi? Bu o deməkdir ki, monitorinq alətləri Linux-un audit alt sistemi vasitəsilə işləyir görmürəm qonaq sistemində işləyən proseslər. Ancaq bəzi hallarda bu xüsusiyyət iki tərəfli qılınc ola bilər.

Ümumiyyətlə, aşağıda göstərilən bütün yazı istənilən nəticəyə nail olmaq üçün araşdırmalar və kobud cəhdlər toplusudur. Bunun üçün mən müxtəlif qədim alətlərdən istifadə etməli, ləpə mənbələrini oxumalı, hələ ibtidai məktəbdə oxuduğum günlərdə yazılmış kodun intensiv şəkildə sazlanması, həmçinin mənə lazım olan alətləri tapmaq üçün xüsusi binar proqramdan istifadə edərək Heroku konstruksiyaları ilə məşğul olmalı idim. . Bütün bu işlər mənim IRC-dəki oğlanları məni sehrli adlandırmağa vadar etdi. Ümid edirəm ki, bu yazı kiminsə yeni nüvələr və OS versiyaları ilə eyni şeyi sınaması üçün etibarlı sənəd kimi xidmət edir.

nizamlama

Linux İstifadəçi Rejiminin qurulması bir neçə addımda həyata keçirilir:

  • hostdan asılılıqların quraşdırılması;
  • Linux nüvəsini yükləmək;
  • kernel qurma konfiqurasiyası;
  • nüvə montajı;
  • ikili quraşdırma;
  • qonaq fayl sisteminin konfiqurasiyası;
  • nüvənin işə salınması parametrlərinin seçilməsi;
  • qonaq şəbəkəsinin qurulması;
  • qonaq nüvəsini işə salır.

Güman edirəm ki, bunu özünüz etmək qərarına gəlsəniz, çox güman ki, bəzi Ubuntu və ya Debian sistemlərində təsvir olunan hər şeyi edəcəksiniz. Yuxarıda göstərilənlərin hamısını ən çox sevdiyim paylamada - Alp-də həyata keçirməyə çalışdım, amma Linux nüvəsinin İstifadəçi rejimində sürücülər üçün sərt bağlayıcı glibc-ismlərə malik olması səbəbindən heç nə alınmadı. Problemi nəhayət başa düşdükdən sonra bunu yuxarıya bildirməyi planlaşdırıram.

Hostdan asılılıqların quraşdırılması

Ubuntu Linux nüvəsini qurmaq üçün ən azı aşağıdakı paketləri tələb edir (təmiz quraşdırmanı fərz etsək):

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

Onları aşağıdakı komanda ilə quraşdıra bilərsiniz (root və ya sudo ilə):

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

Qeyd edək ki, Linux nüvəsi menyusunun qurulması proqramının işlədilməsi üçün quraşdırma tələb olunacaq libncurses-dev. Zəhmət olmasa onun aşağıdakı əmrlə (root və ya sudo ilə) quraşdırıldığından əmin olun:

apt-get -y install libncurses-dev

Kernel yükləmə

Harada yükləyəcəyinizə qərar verin və sonra nüvəni qurun. Bu əməliyyat üçün siz təxminən 1,3 GB sabit disk sahəsi ayırmalı olacaqsınız, ona görə də bunun sizdə olduğundan əmin olun.

getdikdən sonra kernel.org və ən son stabil nüvəni yükləmək üçün URL əldə edin. Yazı zamanı bu: https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.1.16.tar.xz

istifadə edərək bu faylı yükləyin 'wget':

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

Və ilə çıxarın 'tar':

tar xJf linux-5.1.16.tar.xz

İndi tarballu açarkən yaradılan qovluğa daxil oluruq:

cd linux-5.1.16

Kernel qurmaq quraşdırma

Kernel qurma sistemi bir dəstdir Makefiles с çoxlu prosesi avtomatlaşdırmaq üçün xüsusi alətlər və skriptlər. Əvvəlcə interaktiv quraşdırma proqramını açın:

make ARCH=um menuconfig

O, qismən sizin üçün bir dialoq qutusu quracaq və göstərəcək. Nə vaxt '[Select]', siz Boşluq və ya Enter düymələrindən istifadə edərək konfiqurasiya edə biləcəksiniz. Pəncərəni həmişə olduğu kimi, klaviatura oxları ilə "yuxarı" və "aşağı" ilə gedin və elementləri seçin - "sol" və ya "sağ".

Baxış göstəricisi —> o deməkdir ki, siz Enter düyməsi ilə daxil olan alt menyudasınız. Bundan çıxış yolu açıq-aydın '[Exit]".

'-ə aşağıdakı seçimləri daxil edin[Select]' və onların yanında '[*]' işarəsi olduğundan əmin 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

Budur, ardıcıl olaraq ' seçərək bu pəncərədən çıxa bilərsiniz.[Exit]'. Yalnız sonunda konfiqurasiyanı yadda saxlamağın istəndiyinə əmin olun və '[Yes]".

Bu yazını oxuduqdan sonra kernel qurma seçimləri ilə məşğul olmağı məsləhət görürəm. Bu təcrübələr vasitəsilə siz aşağı səviyyəli nüvə mexanikasının işini və onun yığılmasına müxtəlif bayraqların təsirini başa düşmək baxımından çox şey öyrənə bilərsiniz.

Nüvənin qurulması

Linux nüvəsi çox şeyi yerinə yetirən böyük bir proqramdır. Köhnə avadanlıqda belə minimal konfiqurasiya olsa belə, onun qurulması kifayət qədər vaxt apara bilər. Beləliklə, nüvəni aşağıdakı əmrlə qurun:

make ARCH=um -j$(nproc)

Nə üçün? Bu əmr bizim inşaatçımıza quraşdırma prosesində bütün mövcud CPU nüvələrini və mövzularını istifadə etməyi söyləyəcək. Komanda $(nproc) Build sonunda əmrin çıxışını əvəz edir nprochissəsi olan coreutils standart Ubuntu quruluşunda.

Bir müddət sonra nüvəmiz icra edilə bilən bir fayla yığılacaq ./linux.

Binarın quraşdırılması

Linux-da İstifadəçi Modu adi ikili fayl yaratdığından, onu hər hansı digər yardım proqramı kimi quraşdıra bilərsiniz. Mən bunu necə etdim:

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

Buna da əmin olmağa dəyər ~/bin sənin içindədir $PATH:

export PATH=$PATH:$HOME/bin

Qonaq fayl sisteminin qurulması

Qonaq fayl sistemi üçün qovluq yaradın:

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

alpinelinux.org və daxil olun yükləmə bölməsi faktiki yükləmə linkini tapın MINI ROOT FILESYSTEM. Bu yazı yazarkən belə idi:

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

wget istifadə edərək bu tarballu yükləyin:

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

İndi qonaq fayl sisteminin kataloquna daxil olun və arxivi çıxarın:

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

Təsvir edilən hərəkətlər kiçik bir fayl sistemi şablonu yaradacaq. Sistemin təbiətinə görə, Alp apk meneceri vasitəsilə paketləri quraşdırmaq son dərəcə çətin olacaq. Amma bu FS ümumi fikri qiymətləndirmək üçün kifayət edəcək.

Bizə də alət lazımdır tini yaddaş istehlakını məhdudlaşdırmaq üçün zombi prosesləri qonağımız kernel.

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

Kernel əmr xəttinin yaradılması

Linux nüvəsi, əksər digər proqramlar kimi, açarı təyin etməklə əldə edilə bilən əmr satırı arqumentlərinə malikdir. --help.

Özü - kömək

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 işə salınmanın əsas parametrlərini vurğulayır. Minimum tələb olunan seçimlər dəsti ilə nüvəni işə salaq:

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

Yuxarıdakı sətirlər nüvəmizə aşağıdakıları deyir:

  • Fərz edək ki, kök fayl sistemi psevdo cihazdır /dev/root.
  • Seçin hostfs kök fayl sistemi sürücüsü kimi.
  • Kök cihazda yaratdığımız qonaq fayl sistemini quraşdırın.
  • Bəli, oxumaq-yazmaq rejimində.
  • Yalnız 64 MB RAM istifadə edin (etməyi planlaşdırdığınızdan asılı olaraq daha az istifadə edə bilərsiniz, lakin 64 MB optimal məbləğ kimi görünür).
  • Kernel avtomatik olaraq başlayır /bin/sh kimi init-proses.

Bu əmri işə salın və aşağıdakı kimi bir şey almalısınız:

Daha bir vərəq

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

Yuxarıdakı manipulyasiyalar bizə verəcəkdir minimum qonaq sistemikimi şeylər olmadan /proc və ya təyin edilmiş host adı. Məsələn, aşağıdakı əmrləri sınayın:

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

Qonaqdan çıxmaq üçün yazın exit və ya control-d düyməsini basın. Bu, qabığı öldürəcək və ardınca nüvə panikasına səbəb olacaq:

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

Linux nüvəsi başlatma prosesinin həmişə işlədiyini düşündüyü üçün bu ləpə panikasını aldıq. Bu olmadan, sistem artıq işləyə bilməz və çökür. Lakin bu, istifadəçi rejimində bir proses olduğundan, nəticə özünü göndərir SIGABRT, bu da çıxışla nəticələnir.

Qonaq şəbəkəsinin qurulması

Və burada işlər səhv getməyə başlayır. İstifadəçi rejimində şəbəkə qurmaq Linux məhdud "istifadəçi rejimi"nin bütün konsepsiyasının dağılmağa başladığı yerdir. Axı, adətən sistem səviyyəsində şəbəkə məhduddur imtiyazlı hamımız üçün başa düşülən səbəblərə görə icra rejimləri.

Qeyd. per .: UML-də şəbəkə ilə işləmək üçün müxtəlif variantlar haqqında daha çox oxuya bilərsiniz burada.

Slirpə səyahət

Bununla belə, adlı qədim və demək olar ki, dəstəklənməyən bir vasitə var Slirp, İstifadəçi Rejimi ilə Linux şəbəkə ilə əlaqə saxlaya bilər. O, istifadəçi səviyyəli TCP/IP yığını kimi işləyir və işləmək üçün heç bir sistem icazəsi tələb etmir. Bu alət idi 1995-cü ildə buraxılmışdır, və ən son yeniləmə tarixlidir 2006 il. Slirp çox köhnədir. Dəstək və yeniləmələrin olmadığı müddət ərzində tərtibçilər o qədər irəli getdilər ki, indi bu aləti yalnız olaraq təsvir etmək olar kod çürüməsi.

Beləliklə, Slirp-i Ubuntu repozitoriyalarından yükləyək və onu işə salmağa çalışaq:

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)

ey tanrılar. Gəlin Slirp-in sazlayıcısını quraşdıraq və burada nə baş verdiyini anlaya biləcəyimizə baxaq:

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.

Səhv bizim içimizdə döyünür bu xətt. Gəlin stacktrace-ə baxaq, bəlkə orada bizə nəsə kömək edəcək:

(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 görürük ki, qəza slirp fasilələri yoxlamağa çalışarkən əsas döngənin başlanğıcı zamanı baş verir. Bu nöqtədə debug cəhdindən əl çəkməli oldum. Ancaq gəlin görək növlərdən qurulmuş Slirp işləyirmi? Arxivi birbaşa saytdan yenidən yüklədim Sourceforge, çünki oradan bir şeyi komanda xətti ilə sürükləmək ağrı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 biz müəyyən edilməmiş daxili funksiyalar, yəni yaranan ikili faylı əlaqələndirə bilməmək barədə xəbərdarlıqları görürük. Göründüyü kimi, 2006-cı ildən bu nöqtəyə qədər gcc aralıq tərtib edilmiş faylların daxili funksiyalarında istifadə olunan simvolların istehsalını dayandırdı. Açar sözü əvəz etməyə çalışaq inline boş bir şərhdə və nəticəyə baxın:

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

Xeyr. Bu da işləmir. Hələ də bu funksiyalar üçün simvollar tapa bilmir.

Bu zaman imtina etdim və Github-a baxmağa başladım Heroku paketləri qurur. Mənim nəzəriyyəm ondan ibarət idi ki, bəzi Heroku qurma paketi mənə lazım olan ikili faylları ehtiva edir. Sonda axtarış məni apardı burada. Yüklədim və çıxardım uml.tar.gz və aşağıdakıları tapdı:

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 binar edir! O işləyir?

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

Qəzaya düşmür - buna görə də işləməlidir! Gəlin bu ikili faylı daxil edək ~/bin/slirp:

cp slirp ~/bin/slirp

Paketin yaradıcısı onu sildiyi halda, I güzgü düzəltdi.

Şəbəkə konfiqurasiyası

İndi qonaq nüvəmizdə şəbəkəni quraq. Başlatma seçimlərini yeniləyin:

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

İndi şəbəkəni işə salaq:

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 konfiqurasiya əmri /proc и /sys iş üçün lazımdır ifconfig, Slirp ilə əlaqə qurmaq üçün şəbəkə interfeysini təyin edir. Komanda route bütün trafiki Slirp tuneli vasitəsilə göndərilməyə məcbur etmək üçün nüvənin marşrutlaşdırma cədvəlini təyin edir. Bunu DNS sorğusu ilə yoxlayaq:

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

İşləyir!

Hər bir qeyd: Göründüyü kimi, orijinal yazı simli şəbəkə kartı və ya əlavə sürücü tələb etməyən başqa bir konfiqurasiya ilə iş masasında yazılmışdır. Intel-dən WiFi 8265 olan bir noutbukda şəbəkəni qaldırarkən xəta baş verir

/ # 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ündüyü kimi, nüvə şəbəkə kartı sürücüsü ilə əlaqə qura bilmir. Təəssüf ki, proqram təminatını nüvəyə yığmaq cəhdi vəziyyəti düzəltmədi. Nəşr zamanı bu konfiqurasiyada bir həll tapmaq mümkün deyildi. Daha sadə konfiqurasiyalarda (məsələn, Virtualbox-da) interfeys düzgün şəkildə yüksəlir.

Gəlin yönləndirməni aşağıdakı qabıq skripti ilə avtomatlaşdıraq:

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

Və onu icra edilə bilən olaraq qeyd edin:

chmod +x init.sh

Və sonra kernel əmr satırında dəyişikliklər edəcəyik:

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

Və təkrar edək:

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

Şəbəkə sabitdir!

docker faylı

Bütün bunları yoxlamağı asanlaşdırmaq üçün mən topladım Docker faylı, təsvir edilən addımların əksəriyyətini avtomatlaşdıran və sizə işlək konfiqurasiya verməli. Məndə də var əvvəlcədən konfiqurasiya edilmiş kernel, yazıda təsvir olunan hər şeyə malikdir. Ancaq başa düşmək lazımdır ki, burada yalnız minimum parametrləri qeyd etmişəm.

Ümid edirəm ki, bu yazı qonaq nüvəsini necə qaldıracağınızı anlamağa kömək etdi. Bir növ canavar olduğu ortaya çıxdı, lakin nəşr bu ailənin əməliyyat sistemlərinin müasir versiyaları altında Linux-da İstifadəçi rejiminin qurulması, quraşdırılması və konfiqurasiyası üzrə hərtərəfli bələdçi kimi hazırlanmışdır. Növbəti addımlara artıq qonaq sistemində olan xidmətlərin və digər proqram təminatının quraşdırılması daxildir. Docker konteyner şəkilləri sadəcə ictimailəşdirilmiş tarballs olduğundan, şəkli vasitəsilə çıxara bilməlisiniz docker export, sonra qonaq nüvəsinin fayl sisteminin kökündə onun quraşdırma yolunu müəyyənləşdirin. Yaxşı, sonra shell skriptini yerinə yetirin.

Freenode-da #lobsters-dən Rkeene-yə xüsusi təşəkkürlər. Slirp-də onun yardımı olmasaydı, mən bu qədər irəli gedə bilməzdim. Onun Slackware sisteminin slirp ilə necə düzgün işlədiyini bilmirəm, lakin mənim Ubuntu və Alp sistemlərim slirp qəbul etmədi və ikili Rkeene mənə təklif etdi. Ancaq mənim üçün ən azı bir şeyin mənim üçün işləməsi kifayətdir.

Mənbə: www.habr.com

Добавить комментарий