Tuesday 26 May 2015

Linux CPU Info Intel(R) Xeon(R) CPU D-1540

Very interesting CPU:
processor    : 15
vendor_id    : GenuineIntel
cpu family    : 6
model        : 86
model name    : Intel(R) Xeon(R) CPU D-1540 @ 2.00GHz
stepping    : 2
microcode    : 0x7
cpu MHz        : 800.390
cache size    : 12288 KB
physical id    : 0
siblings    : 16
core id        : 7
cpu cores    : 8
apicid        : 15
initial apicid    : 15
fpu        : yes
fpu_exception    : yes
cpuid level    : 20
wp        : yes
flags        : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf eagerfpu pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 fma cx16 xtpr pdcm pcid dca sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch ida arat epb xsaveopt pln pts dtherm tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 hle avx2 smep bmi2 erms invpcid rtm rdseed adx smap
bogomips    : 4000.14
clflush size    : 64
cache_alignment    : 64
address sizes    : 46 bits physical, 48 bits virtual
power management:

Thursday 21 May 2015

kernel BUG at /var/lib/dkms/iscsitarget/!

Выбили вот такой мерзопакостный баг на Debian 7 попытавшись с машины,
где примонтирован LUN сделать smartctl -all:  
[184269.064497] device eth3 left promiscuous mode
[186412.825825] iscsi_trgt: BUG at /var/lib/dkms/iscsitarget/ assert(req->tio)
[186412.825876] Pid: 2488, comm: istiod2 Tainted: G O 3.2.0-4-amd64 #1 Debian 3.2.54-2
[186412.825879] Call Trace:
[186412.825888] [<ffffffffa01cd3f1>] ? send_data_rsp+0x45/0x1f4 [iscsi_trgt]
[186412.825893] [<ffffffffa01d60df>] ? ua_pending+0x19/0xa5 [iscsi_trgt]
[186412.825898] [<ffffffffa01d4db4>] ? disk_execute_cmnd+0x1cf/0x22d [iscsi_trgt]
[186412.825903] [<ffffffffa01d0a3d>] ? worker_thread+0xfd/0x255 [iscsi_trgt]
[186412.825908] [<ffffffff8103f6ba>] ? try_to_wake_up+0x197/0x197
[186412.825912] [<ffffffffa01d0940>] ? nthread_stop+0x35/0x35 [iscsi_trgt]
[186412.825947] [<ffffffff8105f681>] ? kthread+0x76/0x7e
[186412.825956] [<ffffffff81356ef4>] ? kernel_thread_helper+0x4/0x10
[186412.825963] [<ffffffff8105f60b>] ? kthread_worker_fn+0x139/0x139
[186412.825971] [<ffffffff81356ef0>] ? gs_change+0x13/0x13
[186412.825995] ------------[ cut here ]------------
[186412.826011] kernel BUG at /var/lib/dkms/iscsitarget/!
[186412.826072] invalid opcode: 0000 [#1] SMP
[186412.826130] CPU 1
[186412.826138] Modules linked in: iscsi_trgt(O) crc32c loop snd_pcm coretemp snd_page_alloc crc32c_intel ghash_clmulni_intel aesni_intel snd_timer aes_x86_64 acpi_cpufreq mperf aes_generic sb_edac snd processor i2c_i801 iTCO_wdt ioatdma soundcore iTCO_vendor_support cryptd edac_core joydev i2c_core thermal_sys pcspkr evdev wmi container button ext3 mbcache jbd usbhid hid sg sd_mod crc_t10dif ehci_hcd ahci libahci libata usbcore igb dca usb_common megaraid_sas scsi_mod [last unloaded: scsi_wait_scan]
[186412.826749] Pid: 2488, comm: istiod2 Tainted: G O 3.2.0-4-amd64 #1 Debian 3.2.54-2 Intel Corporation S2600CP/S2600CP
[186412.826857] RIP: 0010:[<ffffffffa01cd3f1>] [<ffffffffa01cd3f1>] send_data_rsp+0x45/0x1f4 [iscsi_trgt]
[186412.826948] RSP: 0018:ffff88022a547e10 EFLAGS: 00010286
[186412.826997] RAX: 0000000000000000 RBX: ffff8802216b1ae0 RCX: 0000000000001d05
[186412.827079] RDX: 0000000000001d05 RSI: ffff88022a547f58 RDI: ffff88022a547f58
[186412.827160] RBP: 0000000000000000 R08: 0000000000000002 R09: 00000000fffffffe
[186412.827242] R10: 0000000000000000 R11: 0000000000000002 R12: ffff880230281160
[186412.827323] R13: ffff880071534000 R14: ffff88022d5dde58 R15: ffff88022d5dde68
[186412.827405] FS: 0000000000000000(0000) GS:ffff880235820000(0000) knlGS:0000000000000000
[186412.827490] CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b
[186412.827541] CR2: 00007fff65423ba8 CR3: 0000000001605000 CR4: 00000000000406e0
[186412.827623] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[186412.827705] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
[186412.827787] Process istiod2 (pid: 2488, threadinfo ffff88022a546000, task ffff880230281160)
[186412.827871] Stack:
[186412.827908] ffff880200000000 ffff88023421c0c0 0000000000013780 ffffffffa01d60df
[186412.828005] ffff88022a547fd8 ffff8802216b1ae0 ffff880230281160 ffff880230281160
[186412.828102] ffff880071534000 ffff88022d5dde58 ffff88022d5dde68 ffffffffa01d4db4
[186412.828198] Call Trace:
[186412.828241] [<ffffffffa01d60df>] ? ua_pending+0x19/0xa5 [iscsi_trgt]
[186412.828298] [<ffffffffa01d4db4>] ? disk_execute_cmnd+0x1cf/0x22d [iscsi_trgt]
[186412.828382] [<ffffffffa01d0a3d>] ? worker_thread+0xfd/0x255 [iscsi_trgt]
[186412.828437] [<ffffffff8103f6ba>] ? try_to_wake_up+0x197/0x197
[186412.828491] [<ffffffffa01d0940>] ? nthread_stop+0x35/0x35 [iscsi_trgt]
[186412.828546] [<ffffffff8105f681>] ? kthread+0x76/0x7e
[186412.828596] [<ffffffff81356ef4>] ? kernel_thread_helper+0x4/0x10
[186412.828650] [<ffffffff8105f60b>] ? kthread_worker_fn+0x139/0x139
[186412.828703] [<ffffffff81356ef0>] ? gs_change+0x13/0x13
[186412.828752] Code: 48 85 ed 75 28 48 c7 c1 38 7d 1d a0 ba 88 01 00 00 48 c7 c6 a7 79 1d a0 48 c7 c7 df 79 1d a0 31 c0 e8 5c c1 17 e1 e8 8b a6 17 e1 <0f> 0b 48 89 df e8 d0 fa ff ff 8b 55 14 39 d0 0f 46 d0 85 d2 0f
[186412.829173] RIP [<ffffffffa01cd3f1>] send_data_rsp+0x45/0x1f4 [iscsi_trgt]
[186412.829232] RSP <ffff88022a547e10>
[186412.829825] ---[ end trace e43aba698581fccf ]---
[186413.508062] general protection fault: 0000 [#2] SMP
[186413.508324] CPU 0
[186413.508403] Modules linked in: iscsi_trgt(O) crc32c loop snd_pcm coretemp snd_page_alloc crc32c_intel ghash_clmulni_intel aesni_intel snd_timer aes_x86_64 acpi_cpufreq mperf aes_generic sb_edac snd processor i2c_i801 iTCO_wdt ioatdma soundcore iTCO_vendor_support cryptd edac_core joydev i2c_core thermal_sys pcspkr evdev wmi container button ext3 mbcache jbd usbhid hid sg sd_mod crc_t10dif ehci_hcd ahci libahci libata usbcore igb dca usb_common megaraid_sas scsi_mod [last unloaded: scsi_wait_scan]
[186413.512730] Pid: 2486, comm: istd2 Tainted: G D O 3.2.0-4-amd64 #1 Debian 3.2.54-2 Intel Corporation S2600CP/S2600CP
[186413.513108] RIP: 0010:[<ffffffff81036280>] [<ffffffff81036280>] __wake_up_common+0x3d/0x77
[186413.513336] RSP: 0018:ffff88022ab73ce0 EFLAGS: 00010083
[186413.513451] RAX: ffff88022a547e90 RBX: 0000000000000001 RCX: 0000000000000000
[186413.513599] RDX: 0000000000000000 RSI: 0000000000000003 RDI: ffff88022a547e90
[186413.513746] RBP: 0000000000000003 R08: 0000000000000000 R09: ffffffff81406060
[186413.513894] R10: 0000000000013780 R11: 0000000000003428 R12: ffffffffffffffe8
[186413.514042] R13: 0000000005010500 R14: 0000000000000000 R15: ffff88022d5dde70
[186413.514191] FS: 0000000000000000(0000) GS:ffff880235800000(0000) knlGS:0000000000000000
[186413.514342] CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b
[186413.514459] CR2: 00007f7bd8ca9594 CR3: 0000000001605000 CR4: 00000000000406f0
[186413.514607] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[186413.514755] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
[186413.514903] Process istd2 (pid: 2486, threadinfo ffff88022ab72000, task ffff88022b5b6ea0)
[186413.515053] Stack:
[186413.515157] 00000000000008d0 0000000000000000 0000000000000246 ffff88022d5dde68
[186413.515593] 0000000000000286 000000000000dba9 000000000000dbaa ffff880135ee0098
[186413.516028] 0000000000000001 ffffffff81037f81 0000000000000009 0000000000000000
[186413.516464] Call Trace:
[186413.516573] [<ffffffff81037f81>] ? __wake_up+0x35/0x46
[186413.516693] [<ffffffffa01ce20c>] ? iscsi_session_push_cmnd+0x1ba/0x24f [iscsi_trgt]
[186413.516845] [<ffffffffa01cfcca>] ? istd+0x500/0x101e [iscsi_trgt]
[186413.516966] [<ffffffff812ddf60>] ? inet_dgram_connect+0x72/0x72
[186413.517087] [<ffffffff8134ea11>] ? __schedule+0x5f9/0x610
[186413.517205] [<ffffffffa01cf7ca>] ? nthread_wakeup+0x2c/0x2c [iscsi_trgt]
[186413.517328] [<ffffffff8105f681>] ? kthread+0x76/0x7e
[186413.517446] [<ffffffff81356ef4>] ? kernel_thread_helper+0x4/0x10
[186413.517566] [<ffffffff8105f60b>] ? kthread_worker_fn+0x139/0x139
[186413.517685] [<ffffffff81356ef0>] ? gs_change+0x13/0x13
[186413.517800] Code: 53 89 d3 48 83 ec 18 48 8b 57 08 4c 8b 22 48 8d 42 e8 49 83 ec 18 eb 35 44 8b 28 4c 89 c1 4c 89 44 24 08 44 89 f2 89 ee 48 89 c7 <ff> 50 10 85 c0 4c 8b 44 24 08 74 0a 41 80 e5 01 74 04 ff cb 74
[186413.522659] RIP [<ffffffff81036280>] __wake_up_common+0x3d/0x77
[186413.522849] RSP <ffff88022ab73ce0>
[186413.522959] ---[ end trace e43aba698581fcd0 ]---

Как починить: коротко - обновляйтесь версию айскази модуля на ту, что поставляется в сорцах либо переходите на Jessie :)

Wednesday 20 May 2015

Technical comparison of OpenVZ and commercial Virtualization Platforms from Parallels/Odin

There are bunch promotion articles about PCS (Parallels/Odin Cloud Server) and Virtuozzo. But I can't find any technical comparison between OpenVZ (open source and free) and commercial platforms.

I have 7 years experience with OpenVZ and 2 year experience with PCS in heavy production, thus I could create this comparison table manually :)

Feature Commercial OpenVZ
API Yes No
Central management Yes, PVA (awfully buggy) No, multiple open source solutions
Toolkit for compaction of fat ploop images Yes, pcompact No, but could be done in few lines of code with vzctl compact
Toolkit for migration physical servers to containers Yes, p2c migrate No
Rebootless kernel update (without physical server rebootm kernel reboot only) Yes, vzreboot No
Pure kernel live updates (without physical server reboot, no kernel reboot) No, only with external tool KernelCare No, only with external tool KernelCare
Repair mode for VPS Yes No
Live migration between servers (no zero downtime) Yes Yes
Live migration between servers (zero downtime) Yes No
Flexible container OS templates Yes, vztemplates No, only precreated templates
Memory deduplication for binary files Yes, pfcache techology No
Support for cloud storages for containers Yes, Parallels Cloud Storage No, only NFS
Completely isolated disk subsystem for containers Yes, ploop Yes, ploop
Support for fully virtualized virtual machines Yes, bundled support for Parallels VM No but works perfectly with KVM on same server
Fast and reliable kernel on top of RHEL 2.6.32 Yes (same version as OpenVZ) Yes
Full backup capability Yes No but open source solutions exists
Incremental backup Yes No and no open source solutions
NUMA optimization (balancing) Yes No, but some open source solutions exists
Finally, you could decide what are you want and select proper product for your company.

Tuesday 19 May 2015

Технология дедупликации бинарных файлов в OpenVZ - pfcache и оценка ее эффективности

Что это такое?

Это довольно грамотный и умный механизм, суть которой сводится к хешированию (SHA-1) определенных файлов в папках (стандартно /bin, /lib, /lib64, /opt, /sbin, /usr источник, стр 15) внутри контейнера и сохранению их хэшей в расширенных атрибутах ext4 (xattr).

То есть схема такая:
1) Ставится ОС в контейнер
2) User space демон pfcached забегает в контейнер и прописывает SHA-1 хэши в расширенные атрибуты ext4 для всех файлов в папках /bin, /lib, /lib64, /opt, /sbin, /usr.

В случае, когда установка идет из ранее подготовленных ploop тушек, генерации можно избежать. Также ее можно избежать, если особым образом перепаковать обычные щаблоны с

Но если кратко далее алгоритм ведет себя так — если происходит попытка открытия файла, для которого у нас есть ключевая сумма в inode, мы обращаемся к таблице, где у нас содержатся все ключевые суммы уже загруженных каким-либо иным контейнером библиотек и если мы находим файл с таким же хеэшем, то просто подменяем попытку открытия на этот самый файл.

Также подобные «общие» файлы выносятся (тупо копируются) в отдельную файловую иерархию /vz/pfcache силами специального демона (имеется лишь в проприетарной версии OpemVZ - PCS/Virtuozzo). За счет этого множественные загрузки данных бинарных файлов в память из разных контейнеров приводят к тому, что они занимают меньше места в оперативной памяти и кэшируются (в страничном кэше Linux) ровно один раз. Что дает очень весомый профит в экономии памяти и работе системы в целом. Причем, наибольшей экономии удается добиться именно в случае, когда все контейнеры максимально унифицированы по версиям ПО/дистрибутивам.

Ради интереса содержимое этого спец дескриптора можно прочесть вот так:
getfattr -ntrusted.pfcache --only-values /vz/root/51822/usr/lib/apache2/mpm-prefork/apache2 2>/dev/null
На выходе получим обычный SHA1:
Насколько это эффективная штука можно провести исследование самолично:

В конкретно нашем случае (довольно большой разброд в ОС - 3 версии Debian, 2 версии CentOS + немного кастомных дистрибутивов и все это в различном состоянии обновленности)экономия составила около 2.5-4%, что очень высокая цена за фактическую потерю одного ядра (используется процессом pfcached, который хэширует файлы).

Но в случае, когда у Вас везде одна и та же ОС - это может дать весьма положительный эффект.

Monday 18 May 2015

Оценка эффективности сжатия OpenVZ ploop образов


В процессе эксплуатации наших ферм (а именно при их резервированными посредством нашего кастомного бэкап решения) мы обнаружили, что в среднем бинарные файлы ploop сжимаются в 2-4 раза (в зависимости от данных хранимых внутри). При этом используемое нами оборудование позволяет выполнять сжатие посредством многопоточного архиватора pigz на столь высоких скоростях, что время просто архивации без сжатия совпадает со временем архивации со сжатием, также при этом используется довольно малое число процессорных ресурсов.

Преимущество сжатие образов

Во-первых, при сжатии мы экономим довольно серьезно объем данных требуемый для хранения контейнеров, то есть снижаем стоимость владения за счет экономии места на дорогой СХД. Во-вторых, мы выигрываем в скорости за счет того, что с/на системы хранения читается/записывается как минимум вдвое меньше данных.


Чтобы максимально четко описать преимущества и реальную эффективность подхода мы выбрали наиболее "реальные" серверы с реальными клиентами и произвели замеры эффективности их сжатия. В процессе тестов мы попытались выполнить бинарное сжатие посредством архиватора gzip/pigz с целью показать, что внедрение функции сжатия в ploop контейнеры может дать огромный эффект по ускорению доступа к данным, а также по экономии дискового пространства. Далее приводятся результаты сжатия ploop образов от OpenVZ и Parallels Cloud Server. Сжатие осуществлялось тулкитом pigz: tar --use-compress-program=pigz -cpf

testovz1 / OpenVZ

Объем, занимаемый ploop образами до сжатия:  161G
После сжатия: 83 Gb
Итог: 1.93 раза сжатие

testpcs1 / Parallels Cloud Server

Объем, занимаемый ploop образами до сжатия:  427G
После сжатия: 258G
Итог: 1.6 раза сжатие


Таким образом, можно обратить внимание, что при хранении данных хостинг-ресурсов обеспечивается как минмиум двойная экономия дискового пространства.

Sunday 17 May 2015

Python: TypeError: execve() arg 3 contains a non-string value

This code will definitely produce this error:
new_env = os.environ.copy()
new_env['MY_ENV'] = 1234
subprocess.Popen( ['/bin/echo'], env=new_env)
How to fix? Add explicit conversion to str():
new_env = os.environ.copy()
new_env['MY_ENV'] = str(1234(
subprocess.Popen( ['/bin/echo'], env=new_env)

Как избавится от "No irq handler for vector (irq -1)" внутри KVM машины?

Среда - Debian 7 на железе и внутри виртуальной машины. Просто надо вырубить irqbalanced и на ноде и внутри виртуальной машины!

Если машины на systemd, то делать это так:
systemctl stop irqbalance
systemctl disable irqbalance

Saturday 16 May 2015

Mac OS и упорщение ssh логина к машинам через jump хост

Всем привет!

Очень часто встает задача, когда на какую-то из машин нужно логинится через промежуточный хост. Такой хост зовется jump хостом.

То есть, схема следующая, мы логинимся на хост: ssh, а после этого логинимся на хост ssh

Разумеется, когда это приходится делать часто - это крайне надоедает. Как найти выход? Во-первых, сделать авторизацию по ключу на jump хост, чтобы избавить себя от необходимости вводить пароль дважды.

Но можем ли мы прописать тот же публичный ключ и войти по нему на машину target? Нет, не можем, потому что в этом случае нам придется положить свои приватные ключи на потенциально небезопасную машину jump.

Но как же тут быть? Тут нам поможет мега фича ssh под названием ssh-agent!

Суть ее в том, что ssh выдает доступ к приватному ключу посредством безопасного канала прямо от машины target до на нашей клиентской машины!

Для начала, на машину target нужно положить свой публичный ssh ключ.

Но эта фича в Mac OS отключена по умолчанию, включаем:
sudo vim /etc/ssh/ssh_config

И правим там вот так:
 Host *
   SendEnv LANG LC_*
   ForwardAgent yes
После этого пробуем залогинится на машину jump:
ssh jump

И смотрим содержимое переменных среды:
env|grep SSH_AUTH_SOCK
Это означает, что все заработало как нужно - безопасный сокет для обращения к ssh agent с клиентской машины был корректно передан на машину jump.

А после этого как ни в чем ни бывало заходим на машину target, без запроса пароля - используя ранее одобренный сертификат:
ssh target
А можно сделать еще круче, объединить логин на jump хост с логином на машину target:
ssh -t -jump "ssh target"
 Вот так можно сильно упростить себе жизнь! :)

Thursday 14 May 2015

Birq - really awesome tool for IRQ interrupts balancing over all available cores

Site: Nice documentation:


Standard install:
cd /usr/src
git clone
cd birq
apt-get install -y autoconf
./configure --prefix=/opt/birq
make install
Run it with debug:
/opt/birq/sbin/birq   --verbose --debug
Awesome logic and care about NUMA/PCI-E locality here:
CPU0 package 0, core 0, irqs 2, old 1.84%, load 1.92%
    IRQ  14, [00000001], weight 0, intr 9, ata_piix
    IRQ  46, [00000001], weight 0, intr 32359, eth1-TxRx-6
CPU1 package 1, core 0, irqs 3, old 1.44%, load 1.67%
    IRQ   1, [00000002], weight 0, intr 0, i8042
    IRQ  15, [00000002], weight 0, intr 0, ata_piix
    IRQ  47, [00000002], weight 0, intr 32385, eth1-TxRx-7
CPU2 package 2, core 0, irqs 3, old 1.23%, load 1.67%
    IRQ   6, [00000004], weight 0, intr 0, floppy
    IRQ  40, [00000004], weight 0, intr 32374, eth1-TxRx-0
    IRQ  48, [00000004], weight 0, intr 0, eth1
CPU3 package 3, core 0, irqs 2, old 1.23%, load 2.33%
    IRQ   8, [00000008], weight 0, intr 0, rtc0
    IRQ  41, [00000008], weight 0, intr 32376, eth1-TxRx-1
CPU4 package 4, core 0, irqs 2, old 2.06%, load 2.32%
    IRQ   9, [00000010], weight 0, intr 0, acpi
    IRQ  42, [00000010], weight 0, intr 32331, eth1-TxRx-2
CPU5 package 5, core 0, irqs 2, old 1.85%, load 1.45%
    IRQ  10, [00000020], weight 0, intr 0, uhci_hcd:usb3, uhci_hcd:usb4, virtio0
    IRQ  43, [00000020], weight 0, intr 32322, eth1-TxRx-3
CPU6 package 6, core 0, irqs 2, old 2.70%, load 2.50%
    IRQ  11, [00000040], weight 0, intr 2, ehci_hcd:usb1, uhci_hcd:usb2, eth0
    IRQ  44, [00000040], weight 0, intr 32366, eth1-TxRx-4
CPU7 package 7, core 0, irqs 2, old 1.85%, load 1.67%
    IRQ  12, [00000080], weight 0, intr 0, i8042
    IRQ  45, [00000080], weight 0, intr 32353, eth1-TxRx-5

Tuesday 12 May 2015

Build libcuckoo on Mac OS X 10.10 Yosemite

Install ports:
sudo port install automake autoconf m4 libtool
Pull code:
cd /usr/src
git clone
Build it:
autoreconf -fis
./configure --prefix=/op/libcuckoo
make install

Friday 8 May 2015

pepsal 2.0.1 compilation on CentOS 6

Get code and build:
cd /usr/src/
wget '' -Opepsal-2.0.1.tar.gz
tar -xf pepsal-2.0.1.tar.gz
cd pepsal-2.0.1/
yum install -y libnetfilter_queue-devel
./configure --prefix=/opt/pepsal
But unfortunately something bad with code:
LANG=C make install
Making install in src
make[1]: Entering directory `/usr/src/pepsal-2.0.1/src'
gcc -DHAVE_CONFIG_H -I. -I../include    -I../include -g -O2 -MT pep.o -MD -MP -MF .deps/pep.Tpo -c -o pep.o pep.c
In file included from ../include/pepdefs.h:4,
                 from ../include/pepsal.h:16,
                 from pep.c:13:
/usr/include/sys/user.h:32: error: expected specifier-qualifier-list before '__uint16_t'
pep.c: In function 'nfqueue_get_syn':
pep.c:511: warning: passing argument 2 of 'nfq_get_payload' from incompatible pointer type
/usr/include/libnetfilter_queue/libnetfilter_queue.h:116: note: expected 'unsigned char **' but argument is of type 'char **'
make[1]: *** [pep.o] Error 1
make[1]: Leaving directory `/usr/src/pepsal-2.0.1/src'
make: *** [install-recursive] Error 1

And we need fix code. Please open include/pepdefs.h with editor and add this line before line #include <sys/user.h>:
#include <bits/types.h>

And compile again!

Well, everything works fins:
/opt/pepsal/bin/pepsal -V
PEPSal ver. 2.0.0
This bug related with broken code in sys/user.h:

Tuesday 5 May 2015

Linux TCP timestamp и его генерация

Столкнулся с интересной задачей по сетям и полез разбираться, как же генерируется TCP Timestamp в Linux. Испытания было решено провести на Linux 3.16 и моем любимом Debian Jessie.

Итак, для начала поднимем любой  http сервер на локалхосте и дернем его curl'ом с той же машины, глядя в этот момент на показания tcpdump.

 18:25:40.137056 IP > Flags [S], seq 4291943858, win 43690, options [mss 65495,sackOK,TS val 170139796 ecr 0,nop,wscale 7], length 0
18:25:40.137079 IP > Flags [S.], seq 3577086755, ack 4291943859, win 43690, options [mss 65495,sackOK,TS val 170139796 ecr 170139796,nop,wscale 7], length 0
Ок, что мы тут видим? Мы видим число 170139796,  которое и является TCP timestamp.

Как же оно сгенерировано?

После часа поисков по коду Линукс Ядра я наткнулся на вот такой код в файле include/net/tcp.h:
/* TCP timestamps are only 32-bits, this causes a slight
 * complication on 64-bit systems since we store a snapshot
 * of jiffies in the buffer control blocks below.  We decided
 * to use only the low 32-bits of jiffies and hide the ugly
 * casts with the following macro.
#define tcp_time_stamp          ((__u32)(jiffies))
Стало быть, некий jiffie (который сам по себе 64 битный) преобразуется в 32 битное значение, путем отсечения старших битов.

Но что же такое jiffie и как его посчитать? Вопрос сложный и мерзкий. Если кратко, то jiffies - это число срабатываний прерываний таймера в Linux с момента загрузки системы (ключевое слово uptime).

Интерес заключается в том, что для каждой системы частота этого таймера индивидуальна (и зовется общепринято - HZ) и я потратил очень много времени прежде чем узнал, как часто срабатывает этот таймер на моей машине (на вашей показания могут быть совершенно иные!).

Итак, чтобы прекратить растрату времени я решил написать простейший модуль для своего ядра и посмотреть, что он выдает. Код можете найти вот здесь.

Ровно в момент когда я дергал curl я также загрузил этот модуль ядра и получил в dmesg следующие показания:
[680865.248893] Current jiffie: 4465108609
[680865.249188] Current jiffie converted to timestamp: 170141313
[680865.249480] Current HZ: 250
В то время, как все возможные статьи в интернете говорили о том, что HZ либо 100 либо 1000, но уж никак не 250.

Опа! Вы уже заметили. что странное число в поле "current jiffie converted to timestamp" очень похоже на TCP timestamp? Поздравляю! Это он и есть. Осталось понять, как он все-таки получается и как связан с аптаймом машины.

Итак, мы узнали, что таймер работает с частотой 250 герц, то есть срабатывает 1/250 раз в секунду. Чтобы перевести jiffies в секунды нужно jiffies поделить на HZ, получится следующее:
perl -e 'print 170141313/250'
А в свою очередь это время в секундах показывающее, как давно был загружен сервер, его можно также взять в переменной /proc/uptime (первое число):
cat /proc/uptime
681437.68 5443271.52
Также uptimе можно получить с помощью соответствующей команды:
18:39:48 up 7 days, 21:21,  3 users,  load average: 0.11, 0.06, 0.06

Итак, мы теперь можем имея время аптайма в секундах сами сгенерировать TCP timestamp просто умножив на показания из /proc/uptime на 250 и отбросив дробные значения :)

Утилита для мониторинга нагрузки на процессор и диск от контейнеров OpenVZ

Прощу встречать и жаловать:

Тулкит долго время использовался нами для внутренних целей диагностики и недавно решено было поделиться им с Сообществом!

Тулза выдает вот такие крутые отчеты: