Hoe om gebruikersmodus in Linux te begin gebruik

Inleiding van die vertaler: Teen die agtergrond van die massiewe toetrede tot ons lewens van verskeie soorte houers, kan dit nogal interessant en nuttig wees om uit te vind met watter tegnologieë dit alles een keer begin het. Sommige van hulle kan tot vandag toe nuttig gebruik word, maar nie almal onthou sulke metodes nie (of weet of hulle nie tydens hul vinnige ontwikkeling gevang is nie). Een so 'n tegnologie is User Mode Linux. Die skrywer van die oorspronklike het baie gegrawe, uitgepluis watter van die ou ontwikkelings nog werk en watter nie, en iets soos 'n stap-vir-stap instruksie saamgestel oor hoe om vir jou 'n tuisbrou UML in 2k19 te kry. En ja, ons het die skrywer van die oorspronklike pos na Habr genooi Cadey, so as jy enige vrae het - vra in Engels in die kommentaar.

Hoe om gebruikersmodus in Linux te begin gebruik

Gebruikersmodus in Linux is in werklikheid 'n poort van die Linux-kern na homself. Hierdie modus laat jou toe om 'n volledige Linux-kern as 'n gebruikersproses te laat loop en word algemeen deur ontwikkelaars gebruik om bestuurders te toets. Maar hierdie modus is ook nuttig as 'n algemene isolasie-instrument, waarvan die beginsel soortgelyk is aan die werking van virtuele masjiene. Hierdie modus bied meer isolasie as Docker, maar minder as 'n volwaardige virtuele masjien soos KVM of Virtual Box.

Oor die algemeen kan Gebruikersmodus na 'n vreemde en moeilike hulpmiddel lyk om te gebruik, maar dit het steeds sy gebruike. Dit is immers 'n volwaardige Linux-kern wat vanaf 'n onbevoorregte gebruiker loop. Hierdie kenmerk laat potensieel onbetroubare kode toe om te loop sonder enige bedreiging vir die gasheermasjien. En aangesien dit 'n volwaardige kern is, word die prosesse daarvan geïsoleer van die gasheermasjien, dit wil sê prosesse wat binne Gebruikersmodus loop, sal nie vir die gasheer sigbaar wees nie. Dit is nie soos die gewone Docker-houer nie, in welke geval die gasheermasjien altyd die prosesse binne die bewaarplek sien. Kyk na hierdie stukkie pstree van een van my bedieners:

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

En vergelyk dit met die pstree van die Linux-kern in Gebruikersmodus:

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

Wanneer ek met Docker-houers werk, kan ek van die gasheer die name van die prosesse wat in die gas loop, sien. Met Linux-gebruikersmodus is dit nie moontlik nie. Wat beteken dit? Dit beteken dat moniteringsinstrumente wat deur Linux se ouditsubstelsel loop sien nie prosesse wat in die gasstelsel loop. Maar in sommige situasies kan hierdie kenmerk 'n tweesnydende swaard word.

Oor die algemeen is die hele pos hieronder 'n versameling navorsing en rowwe pogings om die gewenste resultaat te bereik. Om dit te doen, moes ek verskeie ou gereedskap gebruik, die kernbronne lees, intensiewe ontfouting doen van kode wat geskryf is in die dae toe ek nog op laerskool was, en ook met Heroku-bouwerk peuter deur 'n spesiale binêre te gebruik om die gereedskap te vind wat ek nodig gehad het. . Al hierdie werk het daartoe gelei dat die ouens op my IRC my towerkrag genoem het. Ek hoop hierdie pos dien as betroubare dokumentasie vir iemand om dieselfde ding met nuwer pitte en OS-weergawes te probeer.

aanpassing

Die opstel van Linux-gebruikersmodus word in verskeie stappe gedoen:

  • die installering van afhanklikhede op die gasheer;
  • die aflaai van die Linux-kern;
  • kernbou-konfigurasie;
  • kernsamestelling;
  • binêre installasie;
  • die opstel van die gaslêerstelsel;
  • seleksie van kernbekendstellingparameters;
  • die opstel van 'n gasnetwerk;
  • die gaspit begin.

Ek neem aan dat as jy besluit om dit self te doen, jy heel waarskynlik alles sal doen wat beskryf word in een of ander Ubuntu- of Debian-agtige stelsel. Ek het al die bogenoemde in my gunsteling verspreiding probeer implementeer - Alpine, maar niks het daarvan gekom nie, blykbaar as gevolg van die feit dat die Linux-kern 'n hardbindende glibc-isms vir drywers in Gebruikersmodus het. Ek beplan om dit stroomop aan te meld nadat ek uiteindelik die probleem verstaan ​​het.

Installeer afhanklikhede op die gasheer

Ubuntu benodig ten minste die volgende pakkette om die Linux-kern te bou (met 'n skoon installasie):

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

U kan dit installeer met die volgende opdrag (as root of met sudo):

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

Let daarop dat die installering van die Linux-kernmenu-opstellingsprogram sal vereis libncurses-dev. Maak asseblief seker dat dit geïnstalleer is met die volgende opdrag (as root of met sudo):

apt-get -y install libncurses-dev

Kernel aflaai

Besluit waar om af te laai en bou dan die kern. Vir hierdie operasie sal jy ongeveer 1,3 GB hardeskyfspasie moet toewys, so maak seker jy het dit.

Na gaan na kernel.org en kry die URL om die nuutste stabiele kern af te laai. Met die skryf hiervan is dit: https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.1.16.tar.xz

Laai hierdie lêer af met behulp van 'wget':

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

En onttrek dit met 'tar':

tar xJf linux-5.1.16.tar.xz

Nou gaan ons die gids in wat geskep is wanneer die tarball uitgepak word:

cd linux-5.1.16

Kernbou-opstelling

Die kernboustelsel is 'n stel Maak lêers с baie pasgemaakte gereedskap en skrifte om die proses te outomatiseer. Maak eers die interaktiewe opstellingsprogram oop:

make ARCH=um menuconfig

Dit sal gedeeltelik 'n dialoogkassie vir jou bou en vertoon. Wanneer '[Select]', sal jy in staat wees om op te stel met behulp van die spasie- of Enter-sleutels. Navigeer deur die venster, soos gewoonlik, met die sleutelbordpyltjies "op" en "af", en kies elemente - "links" of "regs".

Die aansigwyser —> beteken dat jy in 'n subkieslys is, wat deur die Enter-sleutel verkry word. Die uitweg daaruit is natuurlik deur '[Exit]".

Sluit die volgende opsies in '[Select]' en maak seker dat hulle 'n '[*]' langs hulle het:

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

Dit is dit, jy kan hierdie venster verlaat deur agtereenvolgens '[Exit]'. Maak net seker dat jy gevra word om die konfigurasie aan die einde te stoor en kies '[Yes]".

Ek beveel aan dat jy met die kernbou-opsies speel nadat jy hierdie pos gelees het. Deur hierdie eksperimente kan jy baie leer in terme van die begrip van die werk van laevlak kernmeganika en die impak van verskeie vlae op die samestelling daarvan.

Die bou van die kern

Die Linux-kern is 'n groot program wat baie dinge doen. Selfs met so 'n minimale konfigurasie op ou hardeware, kan dit nogal 'n rukkie neem om te bou. Bou dus die kern met die volgende opdrag:

make ARCH=um -j$(nproc)

Vir wat? Hierdie opdrag sal ons bouer vertel om alle beskikbare SVE-kerns en -drade in die bouproses te gebruik. Span $(nproc) aan die einde van Bou vervang die uitvoer van die opdrag nproc, wat deel is van coreutils in 'n standaard Ubuntu-bou.

Na 'n rukkie sal ons kern saamgestel word in 'n uitvoerbare lêer ./linux.

Die installering van die binêre

Aangesien Gebruikersmodus in Linux 'n gewone binêre skep, kan jy dit installeer soos enige ander nutsprogram. Hier is hoe ek dit gedoen het:

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

Dit is ook die moeite werd om seker te maak dat ~/bin is in jou $PATH:

export PATH=$PATH:$HOME/bin

Die opstel van die gaslêerstelsel

Skep 'n gids vir die gaslêerstelsel:

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

Maak alpinelinux.org oop en in aflaai afdeling vind die werklike aflaaiskakel MINI ROOT FILESYSTEM. Met die skryf hiervan was dit:

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

Laai hierdie tarball af met 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

Voer nou die gids van die gaslêerstelsel in en onttrek die argief:

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

Die beskryfde aksies sal 'n klein lêerstelselsjabloon skep. As gevolg van die aard van die stelsel, sal dit uiters moeilik wees om pakkette deur die Alpine apk bestuurder te installeer. Maar hierdie FS sal genoeg wees om die algemene idee te evalueer.

Ons het ook 'n hulpmiddel nodig Tini geheueverbruik te beperk zombie prosesse ons gaspit.

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

Skep 'n kernopdragreël

Die Linux-kern, soos die meeste ander programme, het opdragreëlargumente wat verkry kan word deur die sleutel te spesifiseer --help.

Homself — 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.

Hierdie paneel beklemtoon die hoofparameters van die bekendstelling. Kom ons hardloop die kern met die minimum vereiste stel opsies:

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

Die lyne hierbo vertel ons kern die volgende:

  • Gestel die wortellêerstelsel is 'n pseudo-toestel /dev/root.
  • Kies gasheer as 'n wortellêerstelselbestuurder.
  • Monteer die gaslêerstelsel wat ons op die worteltoestel geskep het.
  • En ja, in lees-skryf-modus.
  • Gebruik slegs 64 MB RAM (jy kan baie minder gebruik afhangende van wat jy beplan om te doen, maar 64 MB lyk na die optimale hoeveelheid).
  • Die kern begin outomaties /bin/sh hoe init-proses.

Voer hierdie opdrag uit en jy behoort iets soos die volgende te kry:

Nog 'n vel

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

Die manipulasies hierbo sal ons gee gastestelsel ten minste, sonder dinge soos /proc of gasheernaam toegeken. Probeer byvoorbeeld die volgende opdragte:

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

Om by die gas af te meld, tik exit of druk beheer-d. Dit sal die dop doodmaak, gevolg deur 'n kernpaniek:

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

Ons het hierdie kernpaniek gekry omdat die Linux-kern dink die inisialiseringsproses is altyd aan die gang. Daarsonder kan die stelsel nie meer funksioneer nie en val dit ineen. Maar aangesien dit 'n gebruiker-modus proses is, stuur die gevolglike uitset homself na SIGABRT, wat 'n uitset tot gevolg het.

Gasnetwerk opstelling

En dit is waar dinge begin verkeerd loop. Netwerk in gebruikersmodus Linux is waar die hele konsep van beperkte "gebruikersmodus" uitmekaar begin val. Die netwerk is immers gewoonlik op stelselvlak beperk bevoorreg uitvoeringsmodusse vir almal van ons verstaanbare redes.

Let wel. per .: jy kan meer lees oor die verskillende opsies om met 'n netwerk in UML te werk hier.

Reis na Slirp

Daar is egter 'n ou en amper nie-ondersteunde instrument genoem Slurp, waarmee Gebruikersmodus Linux met die netwerk kan kommunikeer. Dit werk baie soos 'n TCP/IP-stapel op gebruikersvlak en vereis geen stelseltoestemmings om te loop nie. Hierdie instrument was in 1995 vrygestel, en die jongste opdatering is gedateer 2006. Slirp is baie oud. Gedurende die tyd sonder ondersteuning en opdaterings, het samestellers so ver gegaan dat hierdie instrument nou slegs beskryf kan word as kode vrot.

Laat ons dus Slirp van die Ubuntu-bewaarplekke aflaai en probeer om dit uit te voer:

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)

O gode. Kom ons installeer Slirp se ontfouter en kyk of ons kan uitvind wat hier aangaan:

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.

Die fout slaan in ons hierdie lyn. Kom ons kyk na die stapelspoor, miskien sal iets ons daar help:

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

Hier sien ons dat die ongeluk plaasvind tydens die begin van die hooflus wanneer slirp probeer kyk vir timeouts. Op hierdie stadium moes ek opgee om te probeer ontfout. Maar kom ons kyk of Slirp van soorte gebou is, werk. Ek het die argief direk vanaf die webwerf weer afgelaai source, want om iets daarvandaan deur die opdragreël te sleep is 'n pyn:

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

Hier sien ons waarskuwings oor ongedefinieerde ingeboude funksies, dit wil sê oor die onvermoë om die gevolglike binêre lêer te koppel. Dit blyk dat gcc tussen 2006 en hierdie punt opgehou het om simbole te produseer wat gebruik word in ingeboude funksies van intermediêre saamgestelde lêers. Kom ons probeer om die sleutelwoord te vervang inline op 'n leë opmerking en kyk na die resultaat:

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

Nope. Dit werk ook nie. Kan steeds nie simbole vir hierdie funksies vind nie.

Op hierdie stadium het ek opgegee en op Github begin kyk Heroku bou pakkette. My teorie was dat een of ander Heroku-boupakket die binaries sou bevat wat ek nodig het. Op die ou end het die soektog my gelei hier. Ek het afgelaai en uitgepak uml.tar.gz en die volgende gevind:

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*

Dit is die slirp binêre! Werk hy?

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

Crash nie - so dit behoort te werk! Kom ons plant hierdie binêre in ~/bin/slirp:

cp slirp ~/bin/slirp

In die geval dat die pakketskepper dit verwyder, ek 'n spieël gemaak.

Netwerkkonfigurasie

Kom ons stel nou die netwerk op ons gaskern op. Dateer bekendstellingopsies op:

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

Laat ons nou die netwerk aanskakel:

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

Die eerste twee konfigurasie opdragte /proc и /sys nodig vir werk ifconfig, wat die netwerkkoppelvlak stel om met Slirp te kommunikeer. Span route stel die kernroeteringtabel om alle verkeer te dwing om deur die Slirp-tonnel gestuur te word. Kom ons kyk dit met 'n DNS-navraag:

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

Работает!

Nota per .: Blykbaar is die oorspronklike pos op 'n lessenaar geskryf met 'n bedrade netwerkkaart, of 'n ander konfigurasie wat nie bykomende drywers vereis het nie. Op 'n skootrekenaar met WiFi 8265 van Intel vind 'n fout plaas wanneer die netwerk verhoog word

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

Blykbaar kan die kern nie met die netwerkkaartbestuurder kommunikeer nie. 'n Poging om die firmware in die kern saam te stel, het ongelukkig nie die situasie reggemaak nie. Ten tyde van publikasie was dit nie moontlik om 'n oplossing in hierdie opset te vind nie. Op eenvoudiger konfigurasies (byvoorbeeld in Virtualbox), styg die koppelvlak korrek.

Kom ons outomatiseer die herleiding met die volgende dopskrif:

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

En merk dit uitvoerbaar:

chmod +x init.sh

En dan sal ons veranderinge aan die kern-opdragreël aanbring:

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

En kom ons herhaal:

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

Die netwerk is stabiel!

docker-lêer

Om dit vir jou makliker te maak om dit alles na te gaan, het ek ingesamel dockerfile, wat die meeste van die stappe wat beskryf word outomatiseer en vir jou 'n werkende konfigurasie behoort te gee. ek het ook vooraf gekonfigureerde kern, wat alles bevat wat in die pos beskryf word. Maar dit is belangrik om te verstaan ​​dat ek hier slegs die minimum instelling uiteengesit het.

Ek hoop hierdie plasing het jou gehelp om te verstaan ​​hoe om 'n gaspit in te samel. Dit blyk 'n soort monster te wees, maar die publikasie is ontwerp as 'n omvattende gids oor die bou, installering en konfigurasie van gebruikersmodus in Linux onder moderne weergawes van bedryfstelsels van hierdie familie. Die volgende stappe moet die installering van dienste en ander sagteware wat reeds binne die gastestelsel is, insluit. Aangesien Docker-houerbeelde net gepubliseerde tarballs is, behoort u die beeld via te kan onttrek docker export, en bepaal dan sy installasiepad in die wortel van die gaskern se lêerstelsel. Wel, voer dan die dopskrif uit.

Spesiale dank aan Rkeene van #lobsters op Freenode. Sonder sy hulp om Slirp te ontfout, sou ek nie so ver gekom het nie. Ek het geen idee hoe sy Slackware-stelsel reg werk met slirp nie, maar my Ubuntu- en Alpine-stelsels het nie slirp aanvaar nie en die binêre Rkeene wat aan my voorgestel is. Maar dit is vir my genoeg dat iets darem vir my werk.

Bron: will.com

Voeg 'n opmerking