Jinsi ya kuanza kutumia Njia ya Mtumiaji katika Linux

Utangulizi kutoka kwa mfasiri: Kutokana na hali ya nyuma ya kuingia kwa wingi katika maisha yetu ya aina mbalimbali za kontena, inaweza kuwa ya kuvutia na muhimu sana kujua ni teknolojia gani ilianza mara moja. Baadhi yao wanaweza kutumika kwa manufaa hadi leo, lakini si kila mtu anakumbuka njia hizo (au anajua ikiwa hawakupata wakati wa maendeleo yao ya haraka). Teknolojia moja kama hiyo ni Njia ya Mtumiaji Linux. Mwandishi wa maandishi asilia alichimba sana, akibaini ni yapi kati ya maendeleo ya zamani ambayo bado hayafanyi kazi na ambayo hayafanyi kazi, na kuweka pamoja kitu kama maagizo ya hatua kwa hatua ya jinsi ya kujipatia UML ya pombe ya nyumbani mnamo 2k19. Na ndio, tulimwalika mwandishi wa chapisho asili kwa Habr Cadey, kwa hivyo ikiwa una maswali yoyote - uliza kwa Kiingereza kwenye maoni.

Jinsi ya kuanza kutumia Njia ya Mtumiaji katika Linux

Hali ya Mtumiaji katika Linux, kwa kweli, ni bandari ya kernel ya Linux yenyewe. Hali hii hukuruhusu kuendesha kinu kamili cha Linux kama mchakato wa mtumiaji na hutumiwa sana na wasanidi programu kujaribu viendeshaji. Lakini hali hii pia ni muhimu kama zana ya jumla ya kutengwa, kanuni ambayo ni sawa na uendeshaji wa mashine za kawaida. Hali hii hutoa kutengwa zaidi kuliko Docker, lakini chini ya mashine kamili ya mtandaoni kama KVM au Virtual Box.

Kwa ujumla, Njia ya Mtumiaji inaweza kuonekana kama zana ya kushangaza na ngumu kutumia, lakini bado ina matumizi yake. Baada ya yote, hii ni kernel kamili ya Linux inayoendesha kutoka kwa mtumiaji asiye na upendeleo. Kipengele hiki huruhusu msimbo ambao hauwezi kuaminiwa kufanya kazi bila tishio lolote kwa mashine mwenyeji. Na kwa kuwa hii ni kernel iliyojaa, michakato yake imetengwa na mashine ya mwenyeji, ambayo ni michakato inayoendeshwa ndani ya Hali ya Mtumiaji haitaonekana kwa mwenyeji. Hii sio kama chombo cha kawaida cha Docker, kwa hali ambayo mashine mwenyeji huona michakato ndani ya hazina kila wakati. Angalia kipande hiki cha pstree kutoka kwa seva yangu moja:

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

Na linganisha hii na pstree ya kernel ya Linux katika Njia ya Mtumiaji:

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

Wakati wa kufanya kazi na vyombo vya Docker, naweza kuona kutoka kwa mwenyeji majina ya michakato ambayo inaendeshwa kwa mgeni. Kwa Njia ya Mtumiaji ya Linux, hii haiwezekani. Ina maana gani? Hii inamaanisha kuwa zana za ufuatiliaji zinazopitia mfumo mdogo wa ukaguzi wa Linux sioni michakato inayoendesha katika mfumo wa wageni. Lakini katika hali zingine, kipengele hiki kinaweza kuwa upanga wenye makali kuwili.

Kwa ujumla, chapisho zima hapa chini ni mkusanyiko wa utafiti na majaribio mabaya ya kufikia matokeo yaliyohitajika. Ili kufanya hivyo, ilinibidi kutumia zana anuwai za zamani, kusoma vyanzo vya kernel, kufanya utatuzi mkubwa wa nambari iliyoandikwa katika siku ambazo nilikuwa bado katika shule ya msingi, na pia kufikiria na muundo wa Heroku kwa kutumia binary maalum kupata zana nilizohitaji. . Kazi hii yote ilisababisha watu kwenye IRC yangu kuniita uchawi. Natumai chapisho hili linatumika kama hati za kuaminika kwa mtu kujaribu kitu kimoja na kernels mpya zaidi na matoleo ya OS.

marekebisho

Kuweka Modi ya Mtumiaji wa Linux hufanywa kwa hatua kadhaa:

  • kufunga utegemezi kwa mwenyeji;
  • kupakua kernel ya Linux;
  • usanidi wa kujenga kernel;
  • mkusanyiko wa kernel;
  • ufungaji wa binary;
  • kusanidi mfumo wa faili wa mgeni;
  • uteuzi wa vigezo vya uzinduzi wa kernel;
  • kuanzisha mtandao wa wageni;
  • kuanzia punje ya wageni.

Nadhani ikiwa utaamua kuifanya mwenyewe, uwezekano mkubwa utafanya kila kitu kilichoelezewa katika mfumo fulani wa Ubuntu au Debian. Nilijaribu kutekeleza yote yaliyo hapo juu katika usambazaji ninaopenda - Alpine, lakini hakuna kilichotokea, inaonekana kwa sababu ya ukweli kwamba kernel ya Linux ina glibc-isms ya kufunga kwa madereva katika Njia ya Mtumiaji. Ninapanga kuripoti hii juu ya mkondo baada ya kuelewa shida.

Inasakinisha vitegemezi kwa seva pangishi

Ubuntu inahitaji angalau vifurushi vifuatavyo ili kuunda kernel ya Linux (ikizingatiwa usakinishaji safi):

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

Unaweza kuzisakinisha kwa amri ifuatayo (kama mzizi au sudo):

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

Kumbuka kuwa kuendesha programu ya usanidi wa menyu ya Linux kernel itahitaji usakinishaji wa libncurses-dev. Tafadhali hakikisha kuwa imewekwa na amri ifuatayo (kama mzizi au na sudo):

apt-get -y install libncurses-dev

Pakua Kernel

Amua mahali pa kupakua na kisha ujenge kernel. Kwa operesheni hii, utahitaji kutenga takriban 1,3 GB ya nafasi ya diski ngumu, kwa hivyo hakikisha unayo.

Baada ya kwenda kernel.org na upate URL ya kupakua kernel ya hivi punde thabiti. Wakati wa kuandika hii ni: https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.1.16.tar.xz

Pakua faili hii kwa kutumia 'wget':

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

Na kuiondoa na 'tar':

tar xJf linux-5.1.16.tar.xz

Sasa tunaingiza saraka iliyoundwa wakati wa kufungua tarball:

cd linux-5.1.16

Usanidi wa muundo wa Kernel

Mfumo wa kujenga kernel ni seti Faili za kutengeneza с nyingi zana maalum na hati za kubinafsisha mchakato. Kwanza, fungua programu ya usanidi inayoingiliana:

make ARCH=um menuconfig

Itakujengea na kukuonyesha kisanduku cha mazungumzo. Lini '[Select]', utaweza kusanidi kwa kutumia vitufe vya Nafasi au Ingiza. Nenda kwenye dirisha, kama kawaida, na mishale ya kibodi "juu" na "chini", na uchague vipengele - "kushoto" au "kulia".

Kiashiria cha kutazama —> inamaanisha kuwa uko kwenye menyu ndogo, iliyofikiwa na kitufe cha Ingiza. Njia ya kutoka ni wazi kupitia '[Exit]'.

Jumuisha chaguo zifuatazo katika '[Select]' na hakikisha wanayo '[*]' karibu nao:

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

Hiyo ndiyo yote, unaweza kutoka kwa dirisha hili kwa kuchagua mfululizo '[Exit]'. Hakikisha tu umeombwa kuhifadhi usanidi mwishoni na uchague '[Yes]'.

Ninapendekeza ucheze karibu na chaguzi za ujenzi wa kernel baada ya kusoma chapisho hili. Kupitia majaribio haya, unaweza kujifunza mengi katika suala la kuelewa kazi ya ufundi wa kiwango cha chini cha kernel na athari za bendera mbalimbali kwenye mkusanyiko wake.

Kujenga kernel

Linux kernel ni programu kubwa ambayo hufanya mambo mengi. Hata kwa usanidi mdogo kama huo kwenye vifaa vya zamani, inaweza kuchukua muda mrefu kuunda. Kwa hivyo jenga kernel na amri ifuatayo:

make ARCH=um -j$(nproc)

Kwa ajili ya nini? Amri hii itamwambia mjenzi wetu kutumia cores na nyuzi zote za CPU katika mchakato wa ujenzi. Timu $(nproc) mwisho wa Jenga hubadilisha matokeo ya amri nproc, ambayo ni sehemu ya coreutils katika muundo wa kawaida wa Ubuntu.

Baada ya muda, kernel yetu itakusanywa kuwa faili inayoweza kutekelezwa ./linux.

Inasakinisha binary

Kwa kuwa Njia ya Mtumiaji katika Linux huunda binary ya kawaida, unaweza kuisakinisha kama matumizi mengine yoyote. Hivi ndivyo nilivyofanya:

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

Inafaa pia kuhakikisha kuwa ~/bin iko ndani yako $PATH:

export PATH=$PATH:$HOME/bin

Kuanzisha mfumo wa faili wa mgeni

Unda saraka ya mfumo wa faili ya mgeni:

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

Fungua alpinelinux.org na uingie sehemu ya kupakua pata kiunga halisi cha kupakua MINI ROOT FILESYSTEM. Wakati wa kuandika hii ilikuwa:

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

Pakua tarball hii kwa kutumia 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

Sasa ingiza saraka ya mfumo wa faili ya mgeni na toa kumbukumbu:

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

Vitendo vilivyoelezwa vitaunda template ndogo ya mfumo wa faili. Kwa sababu ya asili ya mfumo, itakuwa ngumu sana kusakinisha vifurushi kupitia kidhibiti cha apk cha Alpine. Lakini FS hii itatosha kutathmini wazo la jumla.

Pia tunahitaji chombo tini ili kupunguza matumizi ya kumbukumbu michakato ya zombie mgeni wetu punje.

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

Kuunda safu ya amri ya kernel

Kiini cha Linux, kama programu zingine nyingi, ina hoja za mstari wa amri ambazo zinaweza kufikiwa kwa kubainisha ufunguo --help.

Yeye mwenyewe - msaada

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.

Paneli hii inaangazia vigezo kuu vya uzinduzi. Wacha tuendeshe kernel na seti ya chini inayohitajika ya chaguzi:

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

Mistari hapo juu inaambia kernel yetu yafuatayo:

  • Fikiria mfumo wa faili wa mizizi ni kifaa cha uwongo /dev/root.
  • Chagua majeshi kama kiendesha mfumo wa faili wa mizizi.
  • Weka mfumo wa faili wa mgeni tuliounda kwenye kifaa cha mizizi.
  • Na ndio, katika hali ya kusoma-kuandika.
  • Tumia tu MB 64 za RAM (unaweza kutumia kidogo zaidi kulingana na unachopanga kufanya, lakini 64 MB inaonekana kama kiwango bora zaidi).
  • Kokwa huanza kiatomati /bin/sh kama init- mchakato.

Tumia amri hii na unapaswa kupata kitu kama kifuatacho:

Karatasi moja zaidi

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

Udanganyifu hapo juu utatupa mfumo wa wageni kwa kiwango cha chini, bila vitu kama /proc au jina la mpangishaji lililokabidhiwa. Kwa mfano, jaribu amri zifuatazo:

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

Ili kuondoka kwa mgeni, chapa exit au bonyeza control-d. Hii itaua ganda ikifuatiwa na hofu ya kernel:

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

Tulipata hofu hii ya kernel kwa sababu kernel ya Linux inafikiria mchakato wa uanzishaji unaendelea kila wakati. Bila hivyo, mfumo hauwezi kufanya kazi tena na huanguka. Lakini kwa kuwa huu ni mchakato wa hali ya mtumiaji, matokeo yanayotokana hujituma SIGABRT, ambayo husababisha matokeo.

Mpangilio wa mtandao wa wageni

Na hapa ndipo mambo yanaanza kwenda kombo. Mitandao katika Modi ya Mtumiaji ya Linux ndipo dhana nzima ya "modi ya mtumiaji" inaanza kusambaratika. Baada ya yote, kwa kawaida katika ngazi ya mfumo, mtandao ni mdogo upendeleo njia za utekelezaji kwa sababu zetu sote zinazoeleweka.

Kumbuka. kwa .: unaweza kusoma zaidi juu ya chaguzi tofauti za kufanya kazi na mtandao katika UML hapa.

Safari ya Slirp

Walakini, kuna zana ya zamani na karibu isiyotumika inayoitwa Slirp, ambayo Modi ya Mtumiaji Linux inaweza kuingiliana na mtandao. Inafanya kazi kama mrundikano wa kiwango cha mtumiaji wa TCP/IP na hauhitaji ruhusa zozote za mfumo kufanya kazi. Chombo hiki kilikuwa iliyotolewa mwaka 1995, na sasisho la hivi punde ni la tarehe 2006. Slirp ni mzee sana. Wakati bila usaidizi na sasisho, wakusanyaji wamekwenda mbali sana kwamba sasa chombo hiki kinaweza kuelezewa tu kama kuoza kwa kanuni.

Kwa hivyo wacha tupakue Slirp kutoka kwa hazina za Ubuntu na tujaribu kuiendesha:

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)

Oh miungu. Wacha tusakinishe kitatuzi cha Slirp na tuone ikiwa tunaweza kujua kinachoendelea hapa:

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.

Hitilafu inashinda ndani yetu mstari huu. Wacha tuangalie stacktrace, labda kitu kitatusaidia hapo:

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

Hapa tunaona kwamba ajali hutokea wakati wa kuanza kwa kitanzi kikuu wakati slirp inapojaribu kuangalia kwa muda. Kwa wakati huu, ilibidi niache kujaribu kurekebisha. Lakini wacha tuone ikiwa Slirp iliyojengwa kutoka kwa aina inafanya kazi. Nilipakua tena kumbukumbu moja kwa moja kutoka kwa tovuti Chanzo, kwa sababu kuvuta kitu kutoka hapo kupitia safu ya amri ni chungu:

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

Hapa tunaona arifa kuhusu vitendaji ambavyo havijafafanuliwa ndani, yaani, kutoweza kuunganisha faili ya binary inayotokana. Inaonekana kuwa kati ya 2006 na hatua hii, gcc iliacha kutoa alama zinazotumiwa katika vitendaji vilivyojumuishwa vya faili za kati zilizokusanywa. Wacha tujaribu kubadilisha neno kuu inline kwenye maoni tupu na uangalie matokeo:

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

Hapana. Hii pia haifanyi kazi. Bado haiwezi kupata alama za vipengele hivi.

Kwa wakati huu, nilikata tamaa na kuanza kutazama Github Heroku kujenga vifurushi. Nadharia yangu ilikuwa kwamba kifurushi fulani cha ujenzi cha Heroku kingekuwa na jozi nilizohitaji. Mwishowe, utafutaji uliniongoza hapa. Nilipakua na kufungua uml.tar.gz na kupata yafuatayo:

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*

Hii ni binary ya utelezi! Je, anafanya kazi?

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

Haianguka - kwa hivyo inapaswa kufanya kazi! Wacha tupande hii binary ndani ~/bin/slirp:

cp slirp ~/bin/slirp

Ikiwa mtengenezaji wa kifurushi atakiondoa, I alifanya kioo.

Kuanzisha mtandao

Sasa wacha tuanzishe mtandao kwenye kernel yetu ya wageni. Sasisha chaguzi za uzinduzi:

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

Sasa wacha tuwashe mtandao:

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

Amri mbili za kwanza za usanidi /proc и /sys muhimu kwa kazi ifconfig, ambayo huweka kiolesura cha mtandao ili kuwasiliana na Slirp. Timu route huweka jedwali la kuelekeza kernel ili kulazimisha trafiki yote kutumwa kupitia handaki ya Slirp. Wacha tuangalie hii na swali la DNS:

nslookup google.com 8.8.8.8
Server:    8.8.8.8
Address 1: 8.8.8.8 dns.google

Name:      google.com
Address 1: 172.217.12.206 lga25s63-in-f14.1e100.net
Address 2: 2607:f8b0:4006:81b::200e lga25s63-in-x0e.1e100.net

Inafanya kazi!

Kumbuka kwa .: Inavyoonekana, chapisho asili liliandikwa kwenye eneo-kazi na kadi ya mtandao yenye waya, au usanidi mwingine ambao haukuhitaji viendeshi vya ziada. Kwenye kompyuta ndogo na WiFi 8265 kutoka Intel, hitilafu hutokea wakati wa kuongeza mtandao

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

Inavyoonekana, kernel haiwezi kuwasiliana na dereva wa kadi ya mtandao. Jaribio la kukusanya firmware kwenye kernel, kwa bahati mbaya, haikurekebisha hali hiyo. Wakati wa kuchapishwa, haikuwezekana kupata suluhisho katika usanidi huu. Kwenye usanidi rahisi (kwa mfano, kwenye Virtualbox), kiolesura huinuka kwa usahihi.

Wacha tubadilishe uelekezaji upya na hati ifuatayo ya ganda:

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

Na uweke alama kuwa inaweza kutekelezwa:

chmod +x init.sh

Na kisha tutafanya mabadiliko kwenye safu ya amri ya kernel:

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

Na turudie:

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

Mtandao upo imara!

faili ya docker

Ili iwe rahisi kwako kuangalia haya yote, nimekusanya Dockerfile, ambayo husasisha hatua nyingi zilizoelezwa na inapaswa kukupa usanidi wa kufanya kazi. Mimi pia nina punje iliyosanidiwa awali, ambayo ina kila kitu kilichoelezwa katika chapisho. Lakini ni muhimu kuelewa kwamba hapa nimeelezea tu mpangilio wa chini.

Natumai chapisho hili limekusaidia kuelewa jinsi ya kuongeza kernel ya wageni. Ilibadilika kuwa aina fulani ya monster, lakini uchapishaji ulichukuliwa kama mwongozo wa kina juu ya kujenga, kusakinisha na kusanidi Hali ya Mtumiaji katika Linux chini ya matoleo ya kisasa ya mifumo ya uendeshaji ya familia hii. Hatua zinazofuata zinapaswa kujumuisha kusakinisha huduma na programu nyingine tayari ndani ya mfumo wa wageni. Kwa kuwa picha za kontena za Docker zimetangazwa tu, unapaswa kuwa na uwezo wa kutoa picha kupitia docker export, na kisha kuamua njia yake ya usakinishaji kwenye mzizi wa mfumo wa faili wa kernel ya mgeni. Kweli, kisha utekeleze hati ya ganda.

Shukrani za pekee kwa Rkeene kutoka #lobsters kwenye Freenode. Bila msaada wake kutatua Slirp, nisingeweza kufika hapa. Sijui jinsi mfumo wake wa Slackware unavyofanya kazi kwa usahihi na utelezi, lakini mifumo yangu ya Ubuntu na Alpine haikukubali kuteleza na Rkeene ya binary ilinipendekeza. Lakini inatosha kwangu kwamba angalau kitu kinanifanyia kazi.

Chanzo: mapenzi.com

Kuongeza maoni