Does Jesus Love Technologies? – Telegram
Does Jesus Love Technologies?
270 subscribers
64 photos
1 video
4 files
57 links
Персональный блог с техническим уклоном.
Контакт: https://news.1rj.ru/str/t43RRY
Download Telegram
Интересно, что руководит людьми из boost, когда они проверяют версию ядра на наличие определенного syscall'a, а потом используют функцию из glibc? :_)

Ну вы бы хотя бы на наличие _Nr_* макроса ориентировались, а не на эту магическую цифру...
👍2🤨1
Для тех, кто пишет на C++ и использует vcpkg. Я тут закинул пару системных библиотек, чтобы без боли можно было линковаться статически.

- libcgroup (v3.1.0) https://github.com/microsoft/vcpkg/pull/39647
- libaudit (v4.0.1) https://github.com/microsoft/vcpkg/pull/39587

Обе сильно порезаны при сборке, а libcgroup вообще нужно чинить в апстриме, так как при отключении интеграции с systemd ломается umbrella include, поэтому придется определять _LIBCGROUP_H_INSIDE и писать свой мегаинклуд при использовании.
👍1
Does Jesus Love Technologies?
Интересно, что руководит людьми из boost, когда они проверяют версию ядра на наличие определенного syscall'a, а потом используют функцию из glibc? :_) Ну вы бы хотя бы на наличие _Nr_* макроса ориентировались, а не на эту магическую цифру...
Нет, я знал, что boost частично разрабатывают не иначе как no-life аутсайдеры, но это уже вопиющее ЧСВ.

Морозить PR 2 недели от 2х людей, чтобы потом скопировать изменения, которые были предложены и залить их ПОД СВОИМ именем, да еще и НЕПРАВИЛЬНО, это конченый аутизм.

Сегодняшний герой залил патч в boost/process/v2, который добавляет проверку версии glibc и MUSL при сборке проекта, чтобы понимать, можно использовать close_range() или нет. НО! Во-первых, проверка наличия syscall'a опираясь на версию ядра хоть и имеет место быть, но ненадежна, лучше проверять SYS_close_range. Во-вторых, если сборка будет проходить на новом ядре, НО со старым glibc (а это частый кейс, чтобы расширить совместимость), вся программа сломается к херам и удачи это отладить. Почему так? А потому что он fallback'ается на сырой системный вызов. Нужно добавлять возможность явно отключать такие вещи. Типичный программист "на моей машине работает".

В-третьих, сука, еще и ЧСВ своё тешит тем, что копирует предложенные изменения под своим именем, типа это всё он подумал.
🔥7
Процессы в Linux, и, в частности, распределения pid, tgid, ppid, sid, pgid это та еще путаница, в которой лучше рабираться по исходникам. Почему?

Вот есть большая статья, где чел пишет:
It’s true in general that TIDs and TGIDs are sometimes the same as described above, but it’s possible to construct a fresh userspace process in which the single initial thread has a TID that doesn’t match its TGID. If you execve() in a multithreaded process from any thread other than the initial thread, the kernel will kill all other threads, and make the exec-ing thread the leader of the thread group. The TID of the thread doesn’t change, and so the new process will execute on a thread whose TID doesn’t match its TGID.

Правда ли это? Конечно, нет. И вот, казалось бы, достаточно много ссылок на исходные коды, но вот до этих исходных кодов он, видимо, не добрался.

- Вызов do_thread()
- "Трансфер" всех идентификаторов процесса к исполняемому от лидера группы

/*
* An exec() starts a new thread group with the
* TGID of the previous thread group. Rehash the
* two threads with a switched PID, and release
* the former thread group leader:
*/

/* Become a process group leader with the old leader's pid.
* The old leader becomes a thread of the this thread group.
*/


Просто для справки: после exec() pid всегда равен tgid.

UPD:
Можно проверить даже проще, буквально написав так, как он описал:

int main(int argc, char *argv[]) {
std::cout << "tgid: " << ::getpid() << ", pid: " << ::gettid() << std::endl;

std::thread([&argv] {
std::cout << "tgid: " << ::getpid() << ", pid: " << ::gettid() << std::endl;
char *const args[] = {"/usr/bin/ping", "8.8.8.8", nullptr};
execv("/usr/bin/ping", args);
}).join();
}


А затем посмотреть cat /proc/$(pidof ping)/status

UPD 2:
По всей видимости поведение с "выравниванием" pid и tgid появилось только в 4.19 (патч). Но всё же, на момент написания статьи (5 июня, 2024) поведение уже было иным, нежели описано в статье.
Немного поменяю мораль: проверять нужно всё дважды, особенно, если речь идет о Linux.
👍4
Forwarded from commit -m "better"
Вот мы все любим шутейки про "сделано 90% работы, осталось сделать оставшиеся 90%", "последние 10% качества стоят нам 90% усилий", и так далее.

Я сейчас скажу довольно очевидную вещь, которая мне довольно долго не давалась.

Вот это вот умение вовремя остановиться, и сказать, что "от нас никто не ждет идеального результата, но ждут определенного качества за определенные деньги/ресурсы", пресловутое "и так сойдет" - это очень важно, и нужно иногда бить себя по рукам, и игнорировать свое чувство прекрасного, которое требует "еще немножечко better".
🔥9
Для тех разработчиков и админов, кто столкнулся с проблемой тепловой смерти CentOS 7, но которым до сих пор нужно активно использовать ее в контейнерах/VM.

Скорее всего, просто пересобрать контейнер на CentOS 7 уже не получится, но есть варианты "оживить" ОС и обезопасить себя, отзеркалив некоторые репозитории и перенастроив mirror'ы.

Шаг 1 - Подключаем архивы

На этапе сборки образа переключаем апстрим репозитории на vault archive, который RH любезно держат поднятым (пока что).

#!/bin/bash

sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-*;
sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-*;
sed -i 's|# baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-*;


Шаг 2 - Настраиваем дополнительные репозитории

Апстрим репозитории epel и sclo так же были перенесены в архив, но в архивных репозиториях при установке пакета epel-release устанавливаемые .repo файлы будут продолжать смотреть на мертвый апстрим, так что ручками кладем файлы по пути /etc/yum.repos.d/.

[epel7]
name=Extra Packages for Enterprise Linux 7 - $basearch
baseurl=https://archives.fedoraproject.org/pub/archive/epel/7/$basearch
enabled=1
gpgcheck=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7
metadata_expire=never

[epel7-debuginfo]
name=Extra Packages for Enterprise Linux 7 - $basearch - Debug
baseurl=https://archives.fedoraproject.org/pub/archive/epel/7/$basearch/debug
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7
gpgcheck=0
metadata_expire=never

[epel7-source]
name=Extra Packages for Enterprise Linux 7 - $basearch - Source
baseurl=https://archives.fedoraproject.org/pub/archive/epel/7/SRPMS
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7
gpgcheck=0
metadata_expire=never


[centos-sclo-rh]
name=CentOS-7.9 - SCLo rh
baseurl=https://vault.centos.org/centos/7.9.2009/sclo/$basearch/rh/
gpgcheck=0
enabled=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-SIG-SCLo

[centos-sclo-sclo]
name=CentOS-7.9 - SCLo sclo
baseurl=https://vault.centos.org/centos/7.9.2009/sclo/$basearch/sclo/
gpgcheck=0
enabled=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-SIG-SCLo


*** ПРОДОЛЖЕНИЕ В КОММЕНТАРИЯХ ***
👍5
🫣 Как посчитать биты?

🤗 Это же тривиально!

В жизни каждого программиста наступает момент, когда встречаешься с задачей, эффективное решение которой нужно в 1% случаев, но решить которую всё равно интересно. Об одной из таких сегодня и пойдет речь.

Задача: посчитать количество возведенных битов в 64 битном значении. Просто? Тривиально? Быстрое решение - да.

#include <iostream>
#include <ostream>
#include <bit>
#include <cstdint>

int calc_set_bits(const uint64_t i64v) {
uint8_t bits_set = 0;

for (int i = 0; i < 64; i++) {
if (i64v >> i & 1) {
bits_set++;
}
}

return bits_set;
}

int main(int argc, char **argv) {
uint64_t i64v;
std::cin >> i64v;
std::cout << "Bits set: " << calc_set_bits(i64v) << std::endl;
}


Получаем вот такой ассемблерный выход (порезан до нужного):

calc_set_bits(unsigned long):
push rbp
mov rbp, rsp
mov qword ptr [rbp - 8], rdi
mov byte ptr [rbp - 9], 0
mov dword ptr [rbp - 16], 0
.LBB0_1:
cmp dword ptr [rbp - 16], 64
jge .LBB0_6
mov rax, qword ptr [rbp - 8]
mov ecx, dword ptr [rbp - 16]
shr rax, cl
and rax, 1
cmp rax, 0
je .LBB0_4
mov al, byte ptr [rbp - 9]
add al, 1
mov byte ptr [rbp - 9], al
.LBB0_4:
jmp .LBB0_5
.LBB0_5:
mov eax, dword ptr [rbp - 16]
add eax, 1
mov dword ptr [rbp - 16], eax
jmp .LBB0_1
.LBB0_6:
movzx eax, byte ptr [rbp - 9]
pop rbp
ret


Видим тут простой цикл, и, в принципе, ровно то, что мы написали: смещение значения вправо на n битов и проверка младшего бита в цикле.

        shr     rax, cl
and rax, 1
cmp rax, 0


Но что будет, если мы воспользуемся функцией из стандартной библиотеки?

int calc_set_bits(const uint64_t i64v) {
return std::popcount(i64v);
}


Соберем это дело командой clang++ ./main.cpp -o bcnt.elf -std=c++2a -O0 -g -ggdb и отладим внутрь.


lldb ./bcnt.elf
(lldb) b calc_set_bits(unsigned long)
(lldb) si ... # проваливаемся до std::__popcount<unsigned long>


Вот тут-то мы и увидим нечто непонятное, но очень интересное, что работает очевидно быстрее, чем цикл. Давайте разбираться.

std::__popcount<unsigned long>:
push rbp
mov rbp, rsp
mov qword ptr [rbp - 0x8], rdi
-> mov dword ptr [rbp - 0xc], 0x40
mov dword ptr [rbp - 0x10], 0x40
mov dword ptr [rbp - 0x14], 0x40
mov dword ptr [rbp - 0x18], 0x20
mov rcx, qword ptr [rbp - 0x8]
mov rax, rcx
shr rax
movabs rdx, 0x5555555555555555
and rax, rdx
sub rcx, rax
movabs rdx, 0x3333333333333333
mov rax, rcx
and rax, rdx
shr rcx, 0x2
and rcx, rdx
add rax, rcx
mov rcx, rax
shr rcx, 0x4
add rax, rcx
movabs rcx, 0xf0f0f0f0f0f0f0f
and rax, rcx
movabs rcx, 0x101010101010101
imul rax, rcx
shr rax, 0x38
pop rbp
ret



🤗HAKMEM Item 169

☀️Как это работает?

С чего начать? Мы собирались clang, так что смотреть будем с него. Вот issue на GitHub, где эта оптимизация появилась для 8и битных чисел, интересно почитать, но интересует другое - понять, откуда этот алгоритм взялся и как он работает.

Вот тут чувак дает ссылки на статьи, но мне они не нравятся, зато дают наводку, куда читать (нормальные ссылку дам позже). Быстрым гуглежом констант с "HAKMEM" выясняем, что это HAKMEM Item 169, остается только изучить, как он работает.

Сам алгоритм выглядит так: *ПРОДОЛЖЕНИЕ В КОММЕНТАРИЯХ*
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥3
Как же круто, когда с обновлением Gnome стягивается новый монитор! Очень приятно 😍
🎉7
Does Jesus Love Technologies?
Нет, я знал, что boost частично разрабатывают не иначе как no-life аутсайдеры, но это уже вопиющее ЧСВ. Морозить PR 2 недели от 2х людей, чтобы потом скопировать изменения, которые были предложены и залить их ПОД СВОИМ именем, да еще и НЕПРАВИЛЬНО, это конченый…
Я уж было думал, что это конец истории, но нет!

https://github.com/boostorg/process/pull/378#issuecomment-2436521784

Почти полгода висел мой PR, про который я забыл и забил - почти полгода! 🤡 Как тут объявляется Клеменс Моргерштерн, снова заливает мой патч под своим именем и просит протестировать его изменения. 🤡 Я-то протестирую, мне эти изменения нужны, но пусть сначала в baseline vcpkg протащит. В общем, через полгода и поговорим.

Определенно хорошо то, что они, изменения, хотя бы произошли, но отменяет ли это факт, что Клеменс ведет себя как клоун?
Please open Telegram to view this post
VIEW IN TELEGRAM
💩2
Поздравьте меня с малварой на сервере!
😐3
Does Jesus Love Technologies?
Поздравьте меня с малварой на сервере!
Штош, это было быстро и неинтересно..

Отключал firewall на сервере для своих нужд (от лени). Сервисов у меня там критичных нет, так что проще было не париться. От старых экспериментов у меня остались какие-то огрызки контейнеров, среди которых был тот самый злосчастный postgress, про который я успешно забыл, как показывал лог - 18 месяцев назад. Ну, собственно, я уже спойлернул, чем все кончилось. Ожидаемо - после остановки контейнера система пришла в норму. Попыток эскейпа я не нашел, это был безобидный майнер.

По запросу ресерчеров могу дать доступы и помочь заханипотить семпл, пока я просто опустил контейнер, чтобы VPN сервер работал стабильнее.

Основная причина: кривая конфигурация постгри
Контейнер: 6c6e1ad36106 postgres:14.1-alpine

Какая симптоматика?

- Утилизация CPU 100%
- Процесс из memfd, куда же без него
- Дерево процессов: /var/lib/postgresql/data/postmaster -> /tmp/cpu_hu -> memfd

Что нагуглил:
- https://habr.com/ru/articles/810591/
- https://www.aquasec.com/blog/pg_mem-a-malware-hidden-in-the-postgres-processes/
- https://vms.drweb.ru/virus/?i=25889632
🔥1
Давно ничего не писал, не было ни идей, ни времени, но вот теперь есть повод. (идеи тоже есть, но о них позже).

Недавно я получил первый патент, принимаю поздравления. Сам патент TLDR, да и технический-юридический язык нечитаемый, поэтому вкратце о том, что было придумано и запатентовано.

Так как я являюсь разработчиком EDR, приходится иметь дело с сотнями тысяч событий в минуту, а иногда в несколько секунд. Далеко не все события можно логически отсеять просто не собирая, так как они попадают в логическую группу событий, которую нельзя исключать. Чаще всего это спам от забикса, кубера, баз данных и прочего серверного софта, который делает уж очень много того, что так же может делать и любой другой процесс. Само собой серверная часть такое количество событий тоже не очень любит, так как их приходится хранить, индексировать, обрабатывать детектирующей логикой и так далее. Да и у бекенда к тому же таких хостов не одна сотня тысяч. Приходится выкручиваться.

Когда-то давным-давно мы использовали JSON как формат событий, с ним было много проблем, но главной была то, его нужно парсить. Потом перешли на protobuf, который тоже нужно парсить, но делать это можно кратно быстрее. Храним мы все события в БД, которая поддерживает KQL и тут до меня дошло, что и protobuf из запросов KQL имеют AST, которые можно друг на друга наложить и тут понеслось. Что если выполнять фильтрацию событий по KQL выражениям прямо в рантайме и до того, как событие будет отправлено на сервер?

Сначала я написал свой KQL движок, который выдавал правильное логическое дерево запроса (их много, на наличие своего были причины), а потом начал оптимизировать выполнение. Так появилось кеширование по путям и по значением, затем своеобразная JIT оптимизация за счет перестроения дерева по горячим местам, а следом мой коллега Максим придумал перегонять выполнение в байткод и JIT-ить его!

Очень хочу написать обо всем подробно, так что если интересно, то ставьте 👍 (или не ставьте, а я всё равно напишу).

Посмотреть на патент можно по ссылке
1👍31
Сходил на этот ваш, как его... Хайлод++

Впечатления смешанные, особенно если брать во внимание ценник за билет за 100к. Очень много докладов было либо про склеивание в разном порядке разных баз данных и готовых решений, либо сводилось к "не пишите HTTP запросы в контексте транзакции". В общем, после первого идти на второй уже не хотелось. И да, я понимаю, что это не мой профиль, но, как мне кажется, не обязательно заниматься делом, чтобы о нем было интересно слушать, так как интерес вызывает не сам технологический стек, а человеческая идея, мысль, интеллектуальный труд. А тут рассказывают то, что может посоветовать GPT и гугл.

Но это всё про первый день (с исключениями), но вот второй! В общем, просто оставлю здесь сочные доклады, на которых удалось побывать и какие-то свои мысли.

- Как понимание работы RAM ускорило на 30% пакетный шлюз 4G/5G-сетей и позволило обрабатывать 4M пакетов в секунду на одном ядре и 100 Gbps на NUMA node. Это просто превосходный доклад, такие работы вдохновляют. Человек показал, как скрупулезная отладка, простая (нет) prefetch инстукция, выравнивание по кешлайнам и алгоритмы могут без всяких там корутин распараллелить обработку данных на одном ядре. Результат - ускорение работы там, где я бы даже не подумал, что можно ускориться. Рецепт не универскальный, но запомнить стоит: берем профайлер (Intel vTune), смотрим количество тактов CPU на горячем месте, которые потерялись во время трансляции адресов из-за DRAM cache miss, делаем prefetch перед обращением к памяти, выравниваем всё по кешлайнам и наслаждаемся. Кстати, там был еще похожий доклад от гарды, они решали ту же задачу, но ускорялись за счет векторных инстукций.
- Хайлоад на ровном месте. Крутой доклад для чайников вроде меня, которые знать не знали как работать с БД нормально, прям гайдлайн по "бест практис". Подача спикеров отменная, даже немного театральная (хотя кому-то 100% пришлось не по вкусу), было интересно.
- Поймай меня, если сможешь: эффективный поиск региона, к которому принадлежит точка. Вот тут было прикольно заняться ментальной гимнастикой и помять мозги над задачей, с которой в жизни бы не столкнулся. Честно говоря, у меня есть сомнения в "максимальной эффективности" представленного. Осталось ощущение "недоделанности", есть мысли, как сделать быстрее. Но вот следить за ходом мысли спикера нравилось, да и задача интересная (по крайней мере для меня).
- Perforator: всеядный распределенный профилировщик. Вкуснятина, а не доклад. В отличии от всех докладов яндекса про склеивание очередной кафки с YDB и чего-то там еще, тут рассказывалось про что-то принципиально новое. Ребята придумали как снимать perf в промышленных масштабах без сильного влияния на производительность приложений и системы. Под всё это дело они запрягли eBPF, придумали свой DWARF (доработали GSYM), символизатор... и там вообще много всего. Советую ознакомиться с продуктом. А еще они там еще статью написали, которая по факту и есть весь доклад, тоже очень рекомендую (меня купили за футболку). Так же рад, что лично получилось немного пообщаться с парнями, они реально крутые,

Это не всё, что мне понравилось, а лишь то, что хотелось бы выделить. Стоило ли платить 100к (моей компании) за ~30% КПД - вопрос. Может, просто реально не мой профиль. С другой стороны для меня это как минимум свежий воздух, так как в основном я варюсь в ИБ. Да, я узнал что-то новое, да, эти знания уникальны в своем роде и вряд ли бы я на них наткнулся в готовом виде, и да, я могу их применять, но тот факт, что их приходилось искать с лупой на профильной конфе немного расстраивает. Как пример я тут вставлю SysConf, где сложность информации и ее крутость в каждом докладе была в среднем сильно выше медианы на хайлоде. Я уж молчу про ламповость самой конфы.

В любом случае, полученному опыту рад.
1👍84🔥3
Does Jesus Love Technologies?
Давно ничего не писал, не было ни идей, ни времени, но вот теперь есть повод. (идеи тоже есть, но о них позже). Недавно я получил первый патент, принимаю поздравления. Сам патент TLDR, да и технический-юридический язык нечитаемый, поэтому вкратце о том, что…
В целом, тут всё то же, что и в тексте патента, но человеческим языком. Рассказываю, как работает KQL фильтр в нашем продукте.

Затравочка: это не единственный патент. Остальные в процессе регистрации и рассказывать я о них не могу. Там тоже крутые технологии, которые мы применяем для работы с большими потоками данных. В ближайшее время, надеюсь, о них тоже получится рассказать :)

UPD:
Затравочка 2: больше крутостей вокруг этой технологии я планирую рассказать на конференции уже в следующем годy. Будет мясо.
🔥73👏1