100 Days of DevOps — Day 76-How Linux Kernel is organized

Prashant Lakhera
6 min readApr 27, 2019

--

To view the updated DevOps course(101DaysofDevOps)

Course Registration link: https://www.101daysofdevops.com/register/

Course Link: https://www.101daysofdevops.com/courses/101-days-of-devops/

YouTube link: https://www.youtube.com/user/laprashant/videos

Welcome to Day 76 of 100 Days of DevOps, Focus for today is How Linux Kernel is organized

In Linux we have

  • User Space: User(Processes/Application/Services) need to do something and for that, a typical interface is a shell
  • Kernel Space: Kernel is the only component that has direct access to hardware.
User Space ----> Kernel SpaceSignals
System Calls

If User needs to interact with Kernel there is a limited option, which is provided by the kernel and strictly defined by the kernel what user can do

  • Signal
  • System Calls

System Calls

  • An essential part of the Linux Operating System
  • Processes cannot access the kernel directly
  • System calls are used as an interface for processes to the kernel. glibc provides a library interface to use system calls from programs
  • A common task like opening, listing, reading, and writing to files all involves system calls
  • The fork() and exec() system calls determine how a process start
  • fork(): the kernel creates an almost identical copy of the current process and replaces that
  • exec(): the kernel starts a program, which replaces the current process

There is one more thing involved in this whole process called libraries which is just an additional code used by either shell or process to add more functionalities. For eg: the most important one is glibc which provides functions and system calls

# ldd $(which passwd)linux-vdso.so.1 => (0x00007ffe9fff4000)libuser.so.1 => /lib64/libuser.so.1 (0x00007f4074149000)libgobject-2.0.so.0 => /lib64/libgobject-2.0.so.0 (0x00007f4073ef9000)libglib-2.0.so.0 => /lib64/libglib-2.0.so.0 (0x00007f4073bc1000)libpopt.so.0 => /lib64/libpopt.so.0 (0x00007f40739b7000)libpam.so.0 => /lib64/libpam.so.0 (0x00007f40737a8000)libpam_misc.so.0 => /lib64/libpam_misc.so.0 (0x00007f40735a3000)libaudit.so.1 => /lib64/libaudit.so.1 (0x00007f407337b000)libselinux.so.1 => /lib64/libselinux.so.1 (0x00007f4073154000)libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f4072f37000)libc.so.6 => /lib64/libc.so.6 (0x00007f4072b76000)libgmodule-2.0.so.0 => /lib64/libgmodule-2.0.so.0 (0x00007f4072972000)libcrypt.so.1 => /lib64/libcrypt.so.1 (0x00007f407273a000)libffi.so.6 => /lib64/libffi.so.6 (0x00007f4072532000)libdl.so.2 => /lib64/libdl.so.2 (0x00007f407232e000)libcap-ng.so.0 => /lib64/libcap-ng.so.0 (0x00007f4072127000)libpcre.so.1 => /lib64/libpcre.so.1 (0x00007f4071ec6000)/lib64/ld-linux-x86–64.so.2 (0x00007f4074576000)libfreebl3.so => /lib64/libfreebl3.so (0x00007f4071cc3000)

Typically we have two types of libraries

  • Static: eg header files(stdio.h)
  • Dynamic: Stored on disk(eg: libc.so),generally find inside /lib64 or /usr/lib64

Generally, the application doesn’t have any idea where to find these libraries, these are helper program ld.so which does this task on behalf of an application. ld.soprograms reads some default directories

# ls -l /etc/ld.so.conf.d/total 8-r — r — r — . 1 root root 63 Oct 19 11:29 kernel-3.10.0–514.el7.x86_64.conf-rw-r — r — . 1 root root 17 Sep 21 08:18 mariadb-x86_64.conf

So if we have some libraries in some non-standard path we can put inside this directory and then run ldconfig to update the library cache

# ldconfig -v

The way Kernel interact with hardware is via drivers

Kernel → Drivers → Hardware

One important thing to note Linux Kernel is pluggable i.e drivers are not a part of Kernel and can be plugged when it’s required, another way to define is Linux Kernel is modular in nature.

Now let’s zoom in more into Kernel

The kernel has an interface called Memory Management which decides how information is stored/fetch from RAM

Scheduling interface determine which process get CPU attention and which process need to wait

Drivers Determine how Kernel interact with Disk

Kernel --> Memory Management --> RAMKernel --> Scheduling --> CPUKernel --> Drivers --> Disk

Now to check the currently loaded module, run lsmod which is just userspace interface for /proc/modules and it represents the data in a nice format.

# lsmodModule Size Used byiptable_filter 12810 0isofs 39844 0intel_powerclamp 14419 0intel_rapl 19321 0iosf_mbi 13523 1 intel_raplcrc32_pclmul 13113 0ghash_clmulni_intel 13259 0cirrus 24597 1ttm 93908 1 cirrusdrm_kms_helper 146456 1 cirrusppdev 17671 0syscopyarea 12529 1 drm_kms_helpersysfillrect 12701 1 drm_kms_helpersysimgblt 12640 1 drm_kms_helper

Now to get more information about particular module run modinfo

# modinfo isofsfilename: /lib/modules/3.10.0–514.el7.x86_64/kernel/fs/isofs/isofs.kolicense: GPLalias: iso9660alias: fs-iso9660rhelversion: 7.3srcversion: 3967035CBA55EF4A7821695depends:intree: Yvermagic: 3.10.0–514.el7.x86_64 SMP mod_unload modversionssigner: Red Hat Enterprise Linux kernel signing keysig_key: 75:FE:A1:DF:24:5A:CC:D9:7A:17:FE:3A:36:72:61:E6:5F:8A:1E:60sig_hashalgo: sha256

Strace

strace — trace system calls and signals

-c — count time, calls, and errors for each syscall and report summary

# strace -fc lsanaconda-ks.cfg original-ks.cfg% time seconds usecs/call calls errors syscall— — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — —34.48 0.000060 2 28 mmap22.99 0.000040 4 11 open19.54 0.000034 2 18 mprotect8.62 0.000015 2 10 read5.17 0.000009 1 14 close5.17 0.000009 1 12 fstat2.30 0.000004 2 2 1 access0.57 0.000001 0 3 brk0.57 0.000001 1 1 execve0.57 0.000001 1 1 arch_prctl0.00 0.000000 0 1 write0.00 0.000000 0 1 1 stat0.00 0.000000 0 3 munmap0.00 0.000000 0 2 rt_sigaction0.00 0.000000 0 1 rt_sigprocmask0.00 0.000000 0 2 ioctl0.00 0.000000 0 2 getdents0.00 0.000000 0 1 getrlimit0.00 0.000000 0 2 2 statfs0.00 0.000000 0 1 set_tid_address0.00 0.000000 0 1 openat0.00 0.000000 0 1 set_robust_list— — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — —100.00 0.000174 118 4 total

To check for a specific system call

-e expr — a qualifying expression: option=[!]all or option=[!]val1[,val2]…

# strace -e open lsopen(“/etc/ld.so.cache”, O_RDONLY|O_CLOEXEC) = 3open(“/lib64/libselinux.so.1”, O_RDONLY|O_CLOEXEC) = 3open(“/lib64/libcap.so.2”, O_RDONLY|O_CLOEXEC) = 3open(“/lib64/libacl.so.1”, O_RDONLY|O_CLOEXEC) = 3open(“/lib64/libc.so.6”, O_RDONLY|O_CLOEXEC) = 3open(“/lib64/libpcre.so.1”, O_RDONLY|O_CLOEXEC) = 3open(“/lib64/libdl.so.2”, O_RDONLY|O_CLOEXEC) = 3open(“/lib64/libattr.so.1”, O_RDONLY|O_CLOEXEC) = 3open(“/lib64/libpthread.so.0”, O_RDONLY|O_CLOEXEC) = 3open(“/proc/filesystems”, O_RDONLY) = 3open(“/usr/lib/locale/locale-archive”, O_RDONLY|O_CLOEXEC) = 3anaconda-ks.cfg original-ks.cfg+++ exited with 0 +++

To check for library call use ltrace

ltrace — A library call tracer

  • c count time and calls, and report a summary on exit.
  • -f trace children (fork() and clone()).
# ltrace -fc lsanaconda-ks.cfg original-ks.cfg% time seconds usecs/call calls function— — — — — — — — — — — — — — — — — — — — — — — — — — — — — —50.80 0.006370 6370 1 __libc_start_main6.91 0.000866 866 1 exit6.87 0.000861 50 17 readdir4.70 0.000589 49 12 __ctype_get_mb_cur_max4.43 0.000555 55 10 __errno_location3.55 0.000445 49 9 malloc3.28 0.000411 51 8 getenv1.94 0.000243 48 5 memcpy1.78 0.000223 55 4 free1.54 0.000193 48 4 __freading1.51 0.000189 63 3 __overflow1.24 0.000156 52 3 strlen1.14 0.000143 71 2 fclose0.99 0.000124 124 1 setlocale0.90 0.000113 56 2 fwrite_unlocked0.79 0.000099 49 2 __fpending0.78 0.000098 49 2 fileno0.76 0.000095 47 2 fflush0.60 0.000075 75 1 closedir0.57 0.000072 72 1 opendir0.57 0.000072 72 1 ioctl0.51 0.000064 64 1 exit_group0.47 0.000059 59 1 isatty0.45 0.000056 56 1 strrchr0.45 0.000056 56 1 bindtextdomain0.44 0.000055 55 1 __cxa_atexit0.42 0.000053 53 1 getopt_long0.42 0.000053 53 1 strcoll0.41 0.000052 52 1 textdomain0.40 0.000050 50 1 realloc0.39 0.000049 49 1 _setjmp— — — — — — — — — — — — — — — — — — — — — — — — — — — — — —100.00 0.012539 101 total

Signals

Signals provide software interrupt, it’s a method to tell a process that it has to do something

# kill -l1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR111) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+338) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+843) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+1348) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-1253) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-758) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-263) SIGRTMAX-1 64) SIGRTMAX

Looking forward from you guys to join this journey and spend a minimum an hour every day for the next 100 days on DevOps work and post your progress using any of the below medium.

Reference

--

--

Prashant Lakhera
Prashant Lakhera

Written by Prashant Lakhera

AWS Community Builder, Ex-Redhat, Author, Blogger, YouTuber, RHCA, RHCDS, RHCE, Docker Certified,4XAWS, CCNA, MCP, Certified Jenkins, Terraform Certified, 1XGCP

No responses yet