@node FreeBSD proscons
@section Преимущества и недостатки FreeBSD

Сравню FreeBSD с GNU/Linux системами. Всё это исключительно субъективное
мнение! Я буду констатировать факты (я их считаю фактами) без приведения
кучи ссылок на доказательства или примеры. Многое это просто мой опыт.
Почти 100% всего времени я провожу за компьютером и исключительно Unix
системами, примерно поровну с FreeBSD и GNU/Linux, вот уже 20+ лет.

БОльшая часть достоинств FreeBSD также относится и к другим популярным
свободным BSD системам: NetBSD, OpenBSD, DragonflyBSD. Что-то в этих
системах будет получше, многое появилось впервые не в FreeBSD, но
перекочевало в неё. FreeBSD многое наследует
от NetBSD (различные драйвера и подсистемы),
от OpenBSD (сетевые технологии),
DragonflyBSD (лучшая масштабируемость на многопроцессорных платформах),
от Solaris (DTrace, идея Jail-ов, ZFS),
сочетая самое лучшее ото всех.

Если коротко, то FreeBSD это высокое качество, надёжность, удобство и
простота работы. GNU/Linux это зоопарк, помойка малосвязанного кода,
мало чего доделываемое до конца, отсутствие документации, хаос, базар.

@table @strong

@item Главные отличия
@multitable @columnfractions .50 .50
@headitem FreeBSD @tab GNU/Linux

@item

    BSD это @strong{целостные} законченные ОС, разрабатывающиеся как
    единое целое. Если решают добавить поддержку алгоритма сжатия Zstandard,
    то это появляется не только в компрессорах, но и в syslog-ротации и
    других местах. Если есть команды выдачи какой-либо статистики, то
    все они используют библиотеку типа @command{libxo}, унифицируя
    различные варианты вывода. Все команды создаются под одну гребёнку.

    @tab GNU это просто набор ПО, объединённый названием, copyright
    holder-ами, советами по созданию документации и конфигурированию
    сборки. Linux это один из вариантов ядра, наравне с Hurd или
    FreeBSD. Существуют сотни дистрибутивов объединяющих всё
    это вместе, с совершенно разными и отличающимися требованиями,
    пакетными менеджерами, подходами, проверкой качества и тому прочим.
    Есть дистрибутивы и почти не использующие GNU ПО. Есть дистрибутивы
    не использующие Linux.

    Какой-либо унификации документации, конфигурации, вывода информации
    в софте толком нет. Всюду и везде будет явно и отчётливо видно что
    вот эта небольшая программа/утилита написана одним человеком, а вот
    эта другим. Всюду и везде разные подходы ко всему: один считает так,
    другой считает так.

    В основном забота о приведении всего к какому-то одному единому виду
    лежит на плечах distribution maintainer-ов, которым приходится
    править софт, возможно что-то дописывать за автором, ведь не всегда
    автор согласен на любого рода изменения. От maintainer-ов зависит
    удобство работы и качество (аккуратно разложенная документация, учёт
    демонов в системах ротации логов, системе журналирования, периодичных
    заданий, и т.д.) предоставляемого ПО.

    На практике, если сейчас взять одни из последних дистрибутивов
    Ubuntu, то вы не факт что сможете поставить его не на первый жёсткий
    диск, не факт что загрузчик GRUB сможет установится, не факт что вы
    сможете настроить IPv6, не факт что после первого же обновления
    пакетов системы во время установки у вас всё загрузится. Недавно я
    столкнулся с невозможностью штатно настроить MTU на сетевом
    интерфейсе в Ubuntu (серьёзно!?). Всё это я прошёл на практике и
    подобные банальные действия регулярно ломаются и не работают.

    Взяв дистрибутив GNU/Linux, вы можете получить тысячу компонентов ПО
    вместе с GNOME, NetworkManager и чем-то подобным, потом занимаясь
    отключением и удалением последних. А можете получить дистрибутив в
    котором нет и компиляторов и даже @command{netcat} утилит которые бы
    умели IPv6 (и не будет ни @command{telnet}, ни @command{socat}),
    имея на руках мало на что пригодную даже для проверки
    работоспособности сети ОС.

@item

    Качество ПО BSD систем @strong{значительно} лучше. Если разработчики
    говорят что такой-то функционал готов к промышленному использованию,
    то значит это так. Годами многие фичи могут быть включены в ОС с
    громкими пометками о том что это EXPERIMENTAL и только после
    проверки временем и уверенности разработчиков эту пометку снимут.

    @tab Если разработчики GNU/Linux сказали что что-то готово к
    использованию, то стоит подождать ещё лет пять, чтобы хотя бы начать
    смотреть на ту или иную технологию, если, конечно, у вас не критично
    важная работа, где стоит пойти на риск. Например файловая система
    BTRFS давно официально считается стабильной и production ready,
    однако на практике @strong{никто} из серьёзных компаний её не
    использует, так как на практике она всё равно не стабильна.

    Никаких гарантий что та или иная фича вообще когда-либо будет
    достаточно стабильна и надёжна. Например POSIX file locks, по сути,
    до сих пор не работают в GNU/Linux.

@item

    Нет зоопарка утилит, когда одно и то же действие можно потенциально
    выполнить множеством инструментов. Если вам хочется получать разного
    рода статистику и информацию об ОС, то @command{fstat},
    @command{gstat}, @command{ifmcstat}, @command{iostat},
    @command{ipfstat}, @command{kldstat}, @command{lockstat},
    @command{netstat}, @command{nfsstat}, @command{plockstat},
    @command{pmcstat}, @command{procstat}, @command{pstat},
    @command{sockstat}, @command{vmstat} к вашим услугам. Хочется что-то
    настроить? @command{acpiconf}, @command{atmconfig},
    @command{bsdconfig}, @command{ifconfig}, @command{kldconfig},
    @command{mdconfig}, @command{pciconf}, @command{usbconfig},
    @command{sysctl}, @command{sysrc}. Почти все имеют унифицированные
    правила обработки аргументов, конфигурационных файлов, вывода.

    Framework для конфигурирования сети штатный один: настройки в rc
    файле, банально вызывающие @command{ifconfig} команды.

    В FreeBSD есть три firewall-а: @command{ipf}, @command{ipfw},
    @command{pf} -- каждый со своими за/против, но каждый из них
    является полноценным законченным firewall-ом. @command{ipfw} это
    IPv4, IPv6, TCP/UDP/SCTP, ICMP*, Ethernet, traffic shaper/scheduler,
    NAT, NAT64, NPTv6, IPsec, stateless/stateful firewall в одном
    флаконе.

    Почти всё что касается конфигурирования уровня ОС, глобального,
    использует @command{sysctl}.

    @tab Если хотите настроить IP адреса на интерфейсе, используйте
    @command{ifconfig} или @command{ip}. Хотите маршрутизацию
    статическую, используйте @command{route} или @command{ip}. Хотите
    TUN/TAP интерфейсы, используйте @command{tunctl} или @command{ip}.
    Хотите bridge интерфейсы, используйте @command{brctl} или
    @command{ip}. Хотите bond, используйте @command{ifenslave} или
    @command{ip}. Хотите IPsec SA, используйте @command{setkey} или
    @command{ip}. Для беспроводных сетей @command{iwconfig},
    @command{ip}. Хотите различные туннели, то @command{iptunnel},
    @command{ip}. Хотите сменить MAC, то @command{nameif}, @command{ip}.

    Думаете что раз команда @command{ip} призвана всё заменить, то она
    справилась со своей задачей? STP для bridge вы всё равно не
    настроите на данный момент без @command{brctl}, который из коробки
    может и не стоять. Вместо десятка утилит с совершенно отличающимся
    синтаксисом, теперь мы имеем на одну утилиту больше, не отменяющую
    надобность в остальных. В FreeBSD @strong{всё} описанное выше
    делается ровно одним @command{ifconfig}.

    Framework-ов для конфигурирования сети масса: shell-based системы
    как в Debian, @command{NetworkManager}, @command{systemd} средства.
    У всех у них есть какие-нибудь да ограничения на возможные
    конфигурации.

    Думаете можно обойтись одним только @command{iptables}, пришедшим на
    смену @command{ipchains}? Для Ethernet пакетов надо использовать
    @command{ebtables}, для IPv6 @command{ip6tables}, для ARP
    @command{arptables}. И при этом, как мне кажется, ни один здоровый
    человек не сможет сказать что синтаксис правил для
    @command{iptables} удобен -- он выполняет задачу, но все будут
    писать собственные скрипты/обёртки с отличным синтаксисом для
    удобного конфигурирования типа @command{ufw}.

    Используется ли это всё до сих пор? Безусловно. Однако это считается
    deprecated и должно замениться @command{nftables}. Однако и он
    объявлен уже deprecated и @command{bpfilter} его может заменить.
    Однако на практике многие популярные дистрибутивы используют
    @command{firewalld}.

    Кроме @command{sysctl} имеется @file{/sys}, а также ещё и дубляж
    аналогичных ручек управления через специфичные команды.

    Для управления разделами накопителей есть @command{fdisk},
    @command{parted}, @command{gdisk}, @command{sfdisk},
    @command{gparted}. Думаете хотя бы одна из них может сразу же и
    работать с MBR/GPT дисками, давать возможность скриптования, иметь
    удобный интерфейс для пользователя чтобы указывать не конкретное
    количество блоков/байт для размера партиций, а просто сказать
    100%/full? Ни одной. В FreeBSD полностью всему этому удовлетворяющая
    команда @command{gpart} есть, которая, к тому же, ещё и загрузчики
    умеет устанавливать, делать бэкапы/восстановление разделов.

@item

    Уже 12+ лет имеет надёжную работающую ZFS реализацию.

    @tab ZFS-on-Linux, появившись спустя годы, спустя ещё годы начав
    считаться production-ready, мог потерять ваши файлы. ARC под
    Linux-ом, хоть и являясь по сути кэшом, не может по требованию
    освободится, что приводит к тому, что у вас ПО может получить ошибку
    при попытке выделения памяти. В Linux поэтому размер ARC-а
    ограничивают сверху RAM/2 -- из коробки у вас остаётся куча
    свободной памяти. Поддержка TRIM появилась лишь в 2019 году, по
    сути не позволяя достойно использовать ZFS на SSD.

@item

    Имеет богатую документацию в виде огромного количества man-ов для
    каждой команды, каждой подсистемы, каждого модуля ядра и его
    настройки, и в виде FreeBSD Handbook. С последним вы сможете,
    практически ничего не зная о Unix, полностью настроить себе и сети и
    диски и софт и кучу всего ещё. Не знаете с чего начать? @command{man
    intro}, а дальше куча ссылок на другие intro или описания подсистем.
    В OpenBSD вообще почти всё есть в man-ах, без handbook-ов, не требуя
    доступа в Интернет для внешних ссылок.

    @tab GNU/Linux администраторы и разработчики высокооплачиваемы ещё и
    потому, что просто имеют много тайных знаний которые не идут вместе
    с дистрибутивами ОС. Часто даже не знаешь с чего начать и куда
    подглядеть (документация то редко актуальна!) -- многим приходиться
    только лезть в поисковик или на stackexchange.com какой-нибудь. Хотя
    это всё напрямую следует из того, что система не целостна. Качество
    многих дистрибутивов хромает так, что документацию часто не
    приложат, или приложат не полностью.

@item

    Производительность не всегда лучше/выше чем у GNU/Linux (хотя почти
    всегда это связано с более простой архитектурой/кодом, а значит и
    большей надёжностью), но одни из самых высоконагруженных серверов в
    мире -- WhatsApp, держат 2M+ конкурентных TCP соединений. 60%
    трафика в США (сетевая и дисковые подсистемы) генерируется Netflix,
    полностью работающим на FreeBSD. Крупнейшая ИТ компания в РФ --
    Яндекс, для своих ядерных сетевых решений также использует FreeBSD.
    Когда-то Quake3-for-Linux запускаемый в режиме эмуляции под FreeBSD
    давал на 10-15% больше FPS. 

    @tab Производительность GNU/Linux систем может в каких-то случаях
    быть и выше, но это часто зависит от драйверов, версий ядра и тому
    прочего.

@item

    Простое и логичное управление памятью и нехваткой памяти.

    @tab Наверняка любой пользователь сталкивался с тем, что система или
    перестаёт отвечать/работать при нехватке памяти или OOM killer
    убивает какой-нибудь ("наименее", по его мнению) важный процесс типа
    SSH демона или СУБД. Даже делают user-space костыли по управлению
    памятью чтобы хоть как-то иметь работоспособную систему при
    нехватках памяти: @command{earlyoom}, @command{oomd},
    @command{low-memory-monitor}, @command{nohang}.

@item

    Имеет систему портов и параллельно систему бинарных пакетов. Кто
    хочет собирать из исходников -- пожалуйста, кто хочет сразу бинарник
    кем-то собранный скачать -- пожалуйста. При использовании портов
    можно конфигурировать опции сборки: если я не собираюсь печатать, то
    зачем мне поддержка тяжёлого CUPS в каком-нибудь GIMP?

    @tab Дистрибутивы, как правило, предлагают только что-то одно:
    или что-то аналогичное портам или бинарные пакеты. Либо ничего --
    собирайте и ставьте софт как хотите самостоятельно. Одна и та же версия
    пакета может быть разделена на два разных: vim-full или vim-minimal,
    например, но это всё зависит от maintainer-а.

@item

    Как правило, отличная поддержка серверного железа. Драйверы, бывает,
    даже раньше чем для GNU/Linux появляются.

    @tab Поддержка всякого ширпотреба домашнего, ноутбуков, desktop-ов
    наверняка будет лучше.

@item

    IPsec ESP реализация возможно быстрая и стабильная, но не
    поддерживает ни TFC, ни ESN -- последний очень актуален для 10Gbps+
    каналов связи. Security Policies не позволяют задавать
    идентификаторы сторон.

    @tab Поддержка ESPv3 ESN и TFC имеется, как и, судя по коду
    strongSwan, identities в Security Policies. По вопросу
    производительности и стабильности ничего не могу сказать.

@item

    BSD libc или Musl лучше. OpenBSD имеет hardened эффективный memory
    allocator. FreeBSD и NetBSD используют очень дружелюбный для
    многопоточных программ jemalloc.

    @tab
    glibc огромна и сложна. Имеет множество мест вызывающих abort при
    ошибках. Не дружит и не рекомендует статическую линковку. Memory
    allocator прожорливый и медленный на многопоточных программах (можно
    в разы экономить объёмы памяти и время работы с ней). В ней
    полностью отсутствуют @code{*_s} secure-версии различных C11 функций
    типа @code{memset_s}. Нет безопасных и удобных для применения
    @code{strlcat}/@code{strllen}, @code{arc4random}. Из-за этого
    страдают все программы в большинстве GNU/Linux дистрибутивах.

@end multitable

@item Постоянная технологическая отсталость GNU/Linux
@multitable @columnfractions .5 .5
@headitem FreeBSD @tab GNU/Linux @item

    Production-ready ZFS имеется уже 12+ лет.

    UFS2 ФС показывает отличную производительность и устойчивость к
    сбоям. Хотя я часто слышал что теряли данные на UFS2, но у меня за
    всю жизнь с FreeBSD ни разу не было, тогда как на ext3/ext4
    неоднократно.

    @tab До сих пор production ready ZFS нет. Поддержка TRIM появилась
    лишь в прошлом году.

    ext4 появился лет на 10 позже UFS2 и только с ним в Linux появилась
    штатная система в которой хотя бы динамически происходит inode
    allocation. Однако, в ext4 при этом может утекать место занимаемое
    под директории и его невозможно вернуть назад без пересоздания ФС.
    Опыт компании ivi.ru говорит что на очень нагруженной (постоянно
    создание, удаление, тасование файлов) ext4 через месяцы работы
    становится неработоспособной и нужно пересоздавать ФС с нуля.

    Также ext4 имеет смехотворный максимальный размер файла в 16 TiB для
    4K блоков.

    Про ReiserFS ничего не могу сказать, так как я её даже не успел
    попробовать, Райзер уже сел.

    Единственной хорошей работающей достойной ФС в GNU/Linux я видел
    только XFS, творение начала 90-х из SGI IRIX.

@item

    Имеет мощнейшую GEOM дисковую подсистему прозрачно
    позволяющую (как бы) что угодно делать с блочными устройствами. Одни
    из модулей этой подсистемы:
    CACHE -- кэширование;
    CONCAT -- JBOD;
    ELI -- шифрование;
    JOURNAL -- журналирование (независимое от ФС);
    LABEL -- labeling;
    MIRROR -- зеркалирование;
    MULTIPATH -- I/O multipath;
    NOP -- эмуляция ошибок, секторов, размеров;
    RAID, RAID3;
    SCHED -- планировщик I/O;
    SHSEC -- диски с разделяемым секретом;
    STRIPE -- striping. Можно собрать RAID3 из журналируемого
    зашифрованного диска, вместе с stripe-ом из зеркал с дисками с
    разделённым секретом и отдельно диском для кэширования.
    Из коробки полная (и target и initiator) поддержка iSCSI имеется
    вместе с iSER.

    @tab Аналогом пытается быть @command{dm} подсистема, но до сих пор в
    ней всё равно нет всего функционала, например по созданию RAID-ов.
    iSCSI зоопарк реализаций, мало где идущий из коробки.

    Более того, Linux не может полноценно эмулировать блочные устройства
    и если вы сделаете @command{losetup}, то у нового появившегося
    блочного устройства таблица разделов всё равно автоматически не
    будет прочитана.

@item

    Имеет @command{netgraph} сетевую подсистему позволяющую в виде
    графов/деревьев выстраивать какие вам заблагорассудятся потоки
    обработки сетевого трафика. L2TP, ATM, PPP, Bluetooth, PPTP, HDLC
    реализованы в виде модулей этой системы и вы можете делать pipe-ы
    между ними, firewall-ами, аналог @command{tee}, и т.д..

    @tab Аналогов нет.

@item

    Имеет систему трассировки ядра/приложений DTrace (из Solaris).

    @tab Аналогом является @command{eBPF}, появившийся на 6 лет позже.

@item

    Имеет jail подсистему контейнеров с 2000-го года. Позже
    в нём появилась возможность и полной эмуляции сетевого стэка VIMAGE.
    А также управление ограничениями по ресурсам @command{rctl}.

    @tab LXC, как нечто наиболее похожее и близкое, появилось спустя 10 лет.

@item

    Имеет Capsicum -- простой легковесный capability and sandbox
    framework, для создания изолированных ограниченных по возможностям
    компонентов программ. В OpenBSD есть @command{pledge} и @command{unveil}.
    Сотни программ ОС переведены на использование этих систем.

    @tab В GNU/Linux есть @command{seccomp} -- гораздо более сложная
    система, которую мало кто (почти никто из основной системы)
    использует из программ на практике, хоть и появившаяся годами раньше
    решений BSD.

@item

    С 2000-го имеет @command{kqueue} подсистему оповещений
    о события в ядре. Она позволяет эффективно с удобным API
    обрабатывать I/O между сокетами сетевых соединений, файловыми
    дескрипторами, мониторить изменение файлов, состояние дочерних
    процессов и AIO.

    @tab GNU/Linux, глядя на FreeBSD, сказав что мы же всё равно запилим
    что-то своё отличающееся, для сетевых сокетов двумя годами позже
    сделал @command{epoll}.

    Для слежения за изменением файлов был @command{dnotify}, потом его
    сменил @command{inotify} -- отдельная от @command{epoll} подсистема.
    Всё это всё равно не покрывает все возможности @command{kqueue}.

@item

    С начала 2016-го в FreeBSD появились ZFS Boot Environment, что было
    взято у Solaris.

    @tab Какая-то поддержка в загрузчике появилась только во второй
    половине 2019-го.

@item

    DTrace появился в начале 2008-го.

    @tab Стабильная версия @command{bpfTrace} вышла в 2019-ом.

@item

    Как и ZFS, поддерживает NFSv4 ACL, а также POSIX ACL.

    @tab Не имеет стабильной реализации (экспериментальная
    поддержка только для ext3/ext4) NFSv4 ACL.

@item

    Есть OSS4 аудио-подсистема с простым API. Resampling,
    микширование от разных приложений, эквалайзер, объёмный звук,
    независимые настройки громкости для приложений, bit-perfect режим.

    @command{sndio} используемый в OpenBSD умеет resampling,
    микширование от разных приложений, причём микшируя по устройствам
    (одна колонка для одного приложения, другая для другого), запись
    программами того, что играют другие, независимое управление
    громкостью, поддержка MIDI (с кучей фич), near real-time маленькие
    задержки.

    @tab Когда-то был OSS, параллельно с ALSA (зоопарк даже тут). Теперь
    только ALSA, мало чего умеющая из вышеперечисленного, поэтому поверх
    неё ещё добавляют PulseAudio, как костыль. О малых задержках без
    патчей и пересборки ядра можно не мечтать. Ещё есть JACK
    (переставший поддерживать OSS4). А ещё PipeWire грозится заменить
    PulseAudio.

@item

    IPv6 и IPsec (с IKE/ISAKMP) в 1998 году полностью реализовано в
    OpenBSD, пару лет спустя в FreeBSD.

    @tab Заимел IPsec спустя пять лет.

@item

    С начала 2000-х использует криптографически стойкий
    Yarrow PRNG для @file{/dev/random} а потом и вовсе перешла на Fortuna.

    @tab До сих пор в Linux нет Fortuna, а используется самопридуманный
    основанный на ChaCha20 PRNG, с архитектурой схожей с Yarrow, а
    значит его можно отравить.

@item

    Имеет CARP подсистему (портирована из OpenBSD),
    заменяющую проприетарный VRRP, для создания отказоустойчивых сетей.

    @tab @command{ucarp} появился годами позже.

@item

    В 2015-ом GELI мог аутентифицировать шифротекст в полнодисковом
    шифровании.

    @tab @command{dm-integrity} появился через два года.

@item

    Можно собрать IPv6-only ядро.

    @tab Много зависимостей от IPv4-стэка/кода и собрать IPv6-only ядро нельзя.

@end multitable

@end table

Я молчу о том, что преобладающая часть популярных дистрибутивов начала
активно использовать @command{systemd} и один только факт того, что
*BSD его не используют уже является killer-feature. Но если взять
systemd-free дистрибутив, то тогда нормально. При этом в FreeBSD, среди
NetBSD и OpenBSD, самая продвинутая система загрузки, поддерживающая
зависимости между службами, легко конфигурируемая простым текстовым
файлом, написанная на небольшом количестве pure shell.

Неужели у GNU/Linux нет достоинств? С ходу я могу сказать, что некоторый
важный GNU софт работает значительно быстрее BSD вариантов:
@command{sed} и @command{grep} я ставлю GNU-шные. Это, зачастую, ценой
усложнения кода и всяких трюков, но нельзя совершенно отбрасывать со
счетов производительность. Чем, кстати, OpenBSD не может похвалиться --
она плохо масштабируется на несколько процессоров.