Si të filloni të përdorni modalitetin e përdoruesit në Linux
Hyrje nga përkthyesi: Në sfondin e hyrjes masive në jetën tonë të llojeve të ndryshme të kontejnerëve, mund të jetë mjaft interesante dhe e dobishme të zbuloni se me çfarë teknologjish filloi gjithçka. Disa prej tyre mund të përdoren në mënyrë të dobishme edhe sot e kësaj dite, por jo të gjithë i mbajnë mend metoda të tilla (ose e dinë nëse nuk u kapën gjatë zhvillimit të tyre të shpejtë). Një teknologji e tillë është User Mode Linux. Autori i origjinalit bëri shumë gërmime, duke kuptuar se cilat prej zhvillimeve të vjetra funksionojnë ende dhe cilat jo, dhe bashkoi diçka si një udhëzim hap pas hapi se si të merrni një UML homebrew në 2k19. Dhe po, ne e ftuam autorin e postimit origjinal në Habr Kejdi, kështu që nëse keni ndonjë pyetje - pyesni në anglisht në komente.
Modaliteti i përdoruesit në Linux është, në fakt, një port i kernelit Linux për veten e tij. Kjo mënyrë ju lejon të ekzekutoni një kernel të plotë Linux si një proces përdoruesi dhe përdoret zakonisht nga zhvilluesit për të testuar drejtuesit. Por kjo mënyrë është gjithashtu e dobishme si një mjet për izolimin e përgjithshëm, parimi i të cilit është i ngjashëm me funksionimin e makinave virtuale. Ky modalitet ofron më shumë izolim se Docker, por më pak se një makinë virtuale e plotë si KVM ose Virtual Box.
Në përgjithësi, "Modaliteti i përdoruesit" mund të duket si një mjet i çuditshëm dhe i vështirë për t'u përdorur, por ka përdorimet e veta. Në fund të fundit, ky është një kernel Linux i plotë që funksionon si një përdorues i paprivilegjuar. Kjo veçori lejon që kodi potencialisht i pabesueshëm të ekzekutohet pa ndonjë kërcënim për makinën pritëse. Dhe meqenëse ky është një kernel i plotë, proceset e tij janë të izoluara nga makina pritës, d.m.th. proceset që ekzekutohen brenda modalitetit të përdoruesit nuk do të jenë të dukshme për hostin. Kjo nuk është si një kontejner tradicional Docker, në të cilin makina pritës i sheh gjithmonë proceset brenda ruajtjes. Shikoni këtë pjesë të pstree nga një prej serverëve të mi:
Dhe krahasojeni këtë me pstree të kernelit Linux në modalitetin e përdoruesit:
linux─┬─5*[linux]
└─slirp
Kur punoj me kontejnerët Docker, mund të shoh nga hosti emrat e proceseve që janë duke u ekzekutuar në mysafir. Me modalitetin e përdoruesit Linux, kjo nuk është e mundur. Çfarë do të thotë? Kjo do të thotë se mjetet e monitorimit që kalojnë përmes nënsistemit të auditimit të Linux nuk shoh proceset që funksionojnë në sistemin e mysafirëve. Por në disa situata kjo veçori mund të jetë një thikë me dy tehe.
Në përgjithësi, i gjithë postimi më poshtë është një koleksion kërkimesh dhe përpjekjesh të përafërta për të arritur rezultatin e dëshiruar. Për ta bërë këtë, më duhej të përdorja mjete të ndryshme të lashta, të lexoja burimet e kernelit, të bëja korrigjimin intensiv të kodit të shkruar në ditët kur isha ende në shkollën fillore dhe gjithashtu të ndërtoj ndërtimet e Heroku duke përdorur një binar të veçantë për të gjetur mjetet që më duheshin. . E gjithë kjo punë bëri që djemtë në IRC-në time të më quajnë magji. Shpresoj që ky postim të shërbejë si dokumentacion i besueshëm për dikë që të provojë të njëjtën gjë me kernelet më të reja dhe versionet e OS.
rregullim
Vendosja e modalitetit të përdoruesit Linux kryhet në disa hapa:
instalimi i varësive nga hosti;
shkarkimi i kernelit Linux;
konfigurimi i ndërtimit të kernelit;
montimi i kernelit;
instalim binar;
konfigurimi i sistemit të skedarëve të ftuar;
përzgjedhja e parametrave të nisjes së kernelit;
krijimi i një rrjeti të ftuar;
duke filluar kernelin e mysafirëve.
Unë supozoj se nëse vendosni ta bëni vetë, me shumë mundësi do të bëni gjithçka që përshkruhet në ndonjë sistem të ngjashëm me Ubuntu ose Debian. Unë u përpoqa të zbatoja të gjitha sa më sipër në shpërndarjen time të preferuar - Alpine, por asgjë nuk doli prej saj, me sa duket për shkak të faktit se kerneli Linux ka një glibc-izma të detyrueshme për drejtuesit në modalitetin e përdoruesit. Kam në plan ta raportoj këtë në rrjedhën e sipërme pasi ta kuptoj më në fund problemin.
Instalimi i varësive nga hosti
Ubuntu kërkon të paktën paketat e mëposhtme për të ndërtuar kernelin Linux (duke supozuar një instalim të pastër):
Vini re se ekzekutimi i programit të konfigurimit të menusë së kernelit Linux do të kërkojë instalimin e libncurses-dev. Ju lutemi sigurohuni që të jetë instaluar duke përdorur komandën e mëposhtme (si root ose duke përdorur sudo):
apt-get -y install libncurses-dev
Shkarkimi i kernelit
Përcaktoni se ku të shkarkoni dhe më pas ndërtoni kernelin. Do t'ju duhet të ndani afërsisht 1,3 GB hapësirë në hard disk për këtë operacion, prandaj sigurohuni që ta keni atë.
Tani futemi në drejtorinë e krijuar kur shpaketojmë tarballin:
cd linux-5.1.16
Konfigurimi i ndërtimit të kernelit
Sistemi i ndërtimit të kernelit është një grup Skedarët e krijuar с shumë mjetet dhe skriptet e personalizuara për të automatizuar procesin. Së pari, hapni programin e konfigurimit interaktiv:
make ARCH=um menuconfig
Ai do të ndërtojë dhe shfaq pjesërisht një kuti dialogu për ju. Kur '[Select]', do të mund të konfiguroni duke përdorur tastet Space ose Enter. Lundroni në dritare, si zakonisht, me shigjetat e tastierës "lart" dhe "poshtë", dhe zgjidhni elementët - "majtas" ose "djathtas".
Treguesi i pamjes —> do të thotë që jeni në një nënmenu, ku aksesohet duke shtypur tastin Enter. Rruga për të dalë prej saj është padyshim përmes '[Exit]'.
Përfshi opsionet e mëposhtme në '[Select]' dhe sigurohuni që të ketë një simbol '[*]' pranë tyre:
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
Kjo është e gjitha, ju mund të dilni nga kjo dritare duke zgjedhur në mënyrë sekuenciale '[Exit]'. Vetëm sigurohuni që ju kërkohet të ruani konfigurimin në fund dhe zgjidhni '[Yes]'.
Unë ju rekomandoj të luani me opsionet e ndërtimit të kernelit pasi të keni lexuar këtë postim. Nga këto eksperimente mund të mësoni shumë për mënyrën se si funksionon mekanika e kernelit të nivelit të ulët dhe se si flamuj të ndryshëm ndikojnë në ndërtimin e kernelit.
Ndërtimi i kernelit
Kerneli Linux është një program i madh që bën shumë gjëra. Edhe me një konfigurim kaq minimal në harduerin e vjetër, mund të duhet mjaft kohë për t'u ndërtuar. Pra, ndërtoni kernelin me komandën e mëposhtme:
make ARCH=um -j$(nproc)
Per cfare? Kjo komandë do t'i tregojë ndërtuesit tonë që të përdorë të gjitha bërthamat dhe fijet e disponueshme të CPU-së në procesin e ndërtimit. Ekipi $(nproc) në fund të Build zëvendëson daljen e komandës nproc, e cila është pjesë coreutils në një ndërtim standard të Ubuntu.
Pas ca kohësh, kerneli ynë do të përpilohet në një skedar të ekzekutueshëm ./linux.
Instalimi i binarit
Meqenëse Modaliteti i Përdoruesit në Linux krijon një binar të rregullt, mund ta instaloni atë si çdo mjet tjetër. Ja si e bëra:
mkdir -p ~/bin
cp linux ~/bin/linux
Gjithashtu ia vlen të siguroheni për këtë ~/bin është në tuajën $PATH:
export PATH=$PATH:$HOME/bin
Konfigurimi i sistemit të skedarëve të ftuar
Krijo një direktori për sistemin e skedarëve të ftuar:
mkdir -p $HOME/prefix/uml-demo
cd $HOME/prefix
Hapni alpinelinux.org dhe brenda seksioni i shkarkimit gjeni lidhjen aktuale të shkarkimit MINI ROOT FILESYSTEM. Në kohën e shkrimit kjo ishte:
Tani futni drejtorinë e sistemit të skedarëve të ftuar dhe nxirrni arkivin:
cd uml-demo
tar xf ../alpine-rootfs.tgz
Hapat e përshkruar do të krijojnë një shabllon të vogël të sistemit të skedarëve. Për shkak të mënyrës se si funksionon sistemi, instalimi i paketave përmes menaxherit apk Alpine do të jetë jashtëzakonisht i vështirë. Por kjo FS do të jetë e mjaftueshme për të vlerësuar idenë e përgjithshme.
Ne gjithashtu kemi nevojë për një mjet kazanët për të ndaluar konsumin e kujtesës proceset e zombies kerneli ynë i ftuar.
wget -O tini https://github.com/krallin/tini/releases/download/v0.18.0/tini-static
chmod +x tini
Krijimi i një linje komande të kernelit
Kerneli Linux, si shumica e programeve të tjera, ka argumente të linjës së komandës që mund të arrihen duke specifikuar çelësin --help.
Vetë - ndihmë
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.
Ky panel thekson parametrat kryesorë të nisjes. Le të ekzekutojmë kernelin me grupin minimal të kërkuar të opsioneve:
linux
root=/dev/root
rootfstype=hostfs
rootflags=$HOME/prefix/uml-demo
rw
mem=64M
init=/bin/sh
Rreshtat e mësipërme tregojnë kernelin tonë si vijon:
Le të supozojmë se sistemi i skedarëve rrënjë është një pseudo pajisje /dev/root.
Zgjidhni hostfs si një drejtues i sistemit të skedarëve rrënjë.
Montoni sistemin e skedarëve të ftuar që krijuam në pajisjen rrënjë.
Dhe po, në modalitetin lexim-shkrim.
Përdorni vetëm 64 MB RAM (mund të përdorni shumë më pak në varësi të asaj që planifikoni të bëni, por 64 MB duket si sasia optimale).
Kerneli fillon automatikisht /bin/sh si init-procesi.
Ekzekutoni këtë komandë dhe duhet të merrni diçka si më poshtë:
Një fletë më shumë
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
/ #
Manipulimet e mësipërme do të na japin sistemi i mysafirëve të paktën, pa gjëra të tilla si /proc ose emri i hostit të caktuar. Për shembull, provoni komandat e mëposhtme:
- uname -av
- cat /proc/self/pid
- hostname
Për të dalë nga sistemi i të ftuarve, futni exit ose shtypni kontroll-d. Kjo do të vrasë guaskën e ndjekur nga një panik kernel:
/ # exit
Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000000
fish: “./linux root=/dev/root rootflag…” terminated by signal SIGABRT (Abort)
Ne e morëm këtë panik të kernelit sepse kerneli Linux mendon se procesi i inicializimit është gjithmonë duke u ekzekutuar. Pa të, sistemi nuk mund të funksionojë më dhe rrëzohet. Por meqenëse ky është një proces i modalitetit të përdoruesit, dalja që rezulton dërgohet vetë te SIGABRT, e cila rezulton në një dalje.
Konfigurimi i rrjetit të vizitorëve
Dhe këtu gjërat fillojnë të shkojnë keq. Rrjetëzimi në modalitetin e përdoruesit Linux është vendi ku i gjithë koncepti i "modalitetit të përdoruesit" të kufizuar fillon të shpërbëhet. Në fund të fundit, zakonisht në nivelin e sistemit, rrjeti është i kufizuar të privilegjuar mënyrat e ekzekutimit për të gjithë ne arsye të kuptueshme.
shënim per.: Mund të lexoni më shumë rreth opsioneve të ndryshme për të punuar me një rrjet në UML këtu.
Udhëtim për në Slirp
Megjithatë, ekziston një mjet i lashtë dhe praktikisht i pambështetur i quajtur rrëshqitje, me të cilin Modaliteti i Përdoruesit Linux mund të ndërveprojë me rrjetin. Ai funksionon shumë si një pirg TCP/IP i nivelit të përdoruesit dhe nuk kërkon asnjë leje sistemi për të ekzekutuar. Ky mjet ishte lëshuar 1995, dhe përditësimi i fundit është i datës 2006. Slirp është shumë i vjetër. Gjatë kohës pa mbështetje dhe përditësime, përpiluesit kanë shkuar aq larg sa që tani ky mjet mund të përshkruhet vetëm si kalbja e kodit.
Pra, le të shkarkojmë Slirp nga depot e Ubuntu dhe të përpiqemi ta ekzekutojmë:
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 zot. Le të instalojmë korrigjuesin e Slirp dhe të shohim nëse mund të kuptojmë se çfarë po ndodh këtu:
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.
Gabimi rreh tek ne këtë linjë. Le të shohim stacktrace, mbase diçka do të na ndihmojë atje:
(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.
Këtu shohim se përplasja ndodh gjatë fillimit të ciklit kryesor kur slirp përpiqet të kontrollojë për afate kohore. Në këtë pikë, më duhej të hiqja dorë nga përpjekjet për korrigjimin e gabimeve. Por le të shohim nëse Slirp i ndërtuar sipas llojit funksionon. Unë e rishkarkova arkivin direkt nga faqja burimforge, sepse tërhiqni diçka nga atje përmes vijës së komandës është një dhimbje:
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
Këtu shohim alarme për funksionet e integruara të papërcaktuara, domethënë për pamundësinë për të lidhur skedarin binar që rezulton. Duket se midis 2006 dhe kësaj pike, gcc ndaloi së prodhuari simbole të përdorura në funksionet e integruara të skedarëve të përpiluar ndërmjetës. Le të përpiqemi të zëvendësojmë fjalën kyçe inline në një koment bosh dhe shikoni rezultatin:
vi slirp.h
:6
a
<enter>
#define inline /**/
<escape>
:wq
make
Jo. As kjo nuk funksionon. Ende nuk mund të gjesh simbole për këto funksione.
Në këtë pikë, hoqa dorë dhe fillova të shikoja në Github Heroku ndërton paketa. Teoria ime ishte se një paketë ndërtimi Heroku do të përmbante binarët që më duheshin. Në fund, kërkimi më çoi ketu. Kam shkarkuar dhe shpaketuar uml.tar.gz dhe gjeti sa vijon:
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*
Ky është binar slirp! A punon ai?
./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 ...
Nuk përplaset - kështu që duhet të funksionojë! Le ta vendosim këtë binar ~/bin/slirp:
Dy komandat e para të konfigurimit /proc и /sys të nevojshme për punë ifconfig, e cila vendos ndërfaqen e rrjetit për të komunikuar me Slirp. Ekipi route vendos tabelën e rrugëzimit të kernelit për të detyruar që i gjithë trafiku të dërgohet përmes tunelit Slirp. Le ta kontrollojmë këtë me një pyetje DNS:
Shënim për.: Me sa duket, postimi origjinal është shkruar në një desktop me një kartë rrjeti me kabllo, ose ndonjë konfigurim tjetër që nuk kërkon drejtues shtesë. Në një laptop me WiFi 8265 nga Intel, ndodh një gabim kur ngrihet rrjeti
/ # 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
/ #
Me sa duket, kerneli nuk mund të komunikojë me drejtuesin e diskut të rrjetit. Një përpjekje për të përpiluar firmware në kernel, për fat të keq, nuk e korrigjoi situatën. Në kohën e publikimit, asnjë zgjidhje nuk mund të gjendej ende në këtë konfigurim të veçantë. Në konfigurimet më të thjeshta (për shembull, në Virtualbox), ndërfaqja ngrihet saktë.
Le të automatizojmë ridrejtimin me skriptin e mëposhtëm të guaskës:
Dhe pastaj do të bëjmë ndryshime në vijën e komandës së kernelit:
linux
root=/dev/root
rootfstype=hostfs
rootflags=$HOME/prefix/uml-demo
rw
mem=64M
eth0=slirp,,$HOME/bin/slirp
init=/init.sh
Dhe le të përsërisim:
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
Rrjeti është i qëndrueshëm!
skedar docker
Për ta bërë më të lehtë për ju të kontrolloni të gjitha këto, kam mbledhur dockerfile, i cili automatizon shumicën e hapave të përshkruar dhe duhet t'ju ofrojë një konfigurim pune. Unë gjithashtu kam kernel i parakonfiguruar, e cila ka gjithçka që përshkruhet në postim. Por është e rëndësishme të kuptohet se këtu kam përshkruar vetëm cilësimin minimal.
Shpresoj se ky postim ju ka ndihmuar të kuptoni se si të krijoni një kernel të ftuar. Doli të ishte një lloj përbindëshi, por botimi kishte për qëllim si një udhëzues gjithëpërfshirës mbi temën e montimit, instalimit dhe konfigurimit të modalitetit të përdoruesit në Linux nën versionet moderne të sistemeve operative të kësaj familjeje. Hapat pasues duhet të përfshijnë instalimin e shërbimeve dhe softuerëve të tjerë tashmë brenda sistemit të mysafirëve. Meqenëse imazhet e kontejnerëve të Docker janë thjesht tarball të promovuar, duhet të jeni në gjendje të nxirrni imazhin nëpërmjet docker export, dhe më pas përcaktoni shtegun për ta instaluar atë në rrënjën e sistemit të skedarëve të kernelit të ftuar. Epo, atëherë ekzekutoni skriptin e guaskës.
Falënderime të veçanta për Rkeene nga #lobsters në Freenode. Pa ndihmën e tij në korrigjimin e Slirp, nuk do të kisha arritur deri këtu. Nuk e kam idenë sesi sistemi i tij Slackware funksionon siç duhet me slirp, por sistemet e mia Ubuntu dhe Alpine nuk e pranuan slirp-in dhe Rkeene binar më sugjeroi. Por mua më mjafton që të paktën diçka të funksionojë për mua.