Обзор
Вокруг Unix наросло целое поле терминов, заимствованных из магии и мифологии: daemon, wizard, spell, zombie, само слово «magic». Эта заметка — про культурную половину темы: откуда взялся такой словарь и что он на самом деле обозначает. Технические механизмы, которые носят то же слово в названии, — сигнатуры файловых форматов (magic numbers), magic(5), Magic SysRq, magic cookie аутентификации X — работают по своим правилам и разбираются отдельно; здесь предмет — само слово.
Тезис, ради которого статью стоит держать в базе: «магия» в Unix — не украшение, а рабочий термин с довольно точным значением. Так называют то, что работает по правилам, которые не выводятся из общих принципов и должны быть просто известны. Это отличает магию от «костыля» (kludge), который, наоборот, работает вопреки принципам. В системе, выросшей эволюционно за десятилетия, много поведения держится на неочевидных свойствах — компилятора, железа, исторической реализации, — которые нельзя переоткрыть из первых принципов, а можно только знать. «Магия» — честная метка, которую культура повесила ровно на такое знание. Поэтому ему и место в базе знаний: магия — это то, что передаётся, а не выводится.
Жанр для базы новый — это история и лексикография, а не техническое руководство. Он оправдан тем, что понимание, откуда взялись имена, — та же причинно-следственная связь, которую база и разбирает, только применённая к людям, а не к системам.
Что слово значит на самом деле
Jargon File — словарь хакерского сленга, о котором ниже отдельно, — определяет magic в первом значении как «пока необъяснимое или слишком сложное, чтобы объяснять; то, что работает, хотя никто толком не понимает почему». Термин существует в градациях, и они не синонимы:
| Термин | Значение по Jargon File |
|---|---|
magic |
работает, хотя никто до конца не понимает почему |
deep magic |
арканная техника в основе программы, нигде публично не описанная (отсылка к «Хроникам Нарнии» Льюиса) |
black magic |
техника, которая работает при полном непонимании механизма; темнее, чем voodoo programming |
heavy wizardry |
код, опирающийся на глубокое практическое знание конкретной ОС или интерфейса — драйверы, работа с X без тулкита |
voodoo programming |
применение непонятой фичи по наитию или «по рецепту»; может не сработать, и тогда никогда не узнаешь почему |
Ключевое различие — то, ради чего стоит удерживать эти оттенки в голове, — проходит между «магией» и «костылём». Магия работает по правилам, которые существуют и верны, но не выводятся из общих принципов: их надо знать. Костыль (kludge, в определении Jargon File — «работает по неправильной причине») работает вопреки правилам, как временная подпорка под конкретный случай. Магия — про полноту знания, костыль — про его отсутствие. Смешивать их — значит путать вещь, которую стоит записать и передать, с вещью, которую стоит переписать.
Почему такой термин вообще понадобился. Система, собранная не по единому проекту, а наросшая слоями, полна поведения, которое опирается на частные свойства окружения: как именно компилятор сохраняет регистры, какого размера сектор у диска, что оставалось верным в предыдущей реализации. Это знание нельзя переоткрыть рассуждением — только унаследовать. «Магия» и есть категория для такого знания: маркер того, что здесь работает устная традиция, а не общий принцип.
Классические примеры
«You are not expected to understand this»
Самый известный комментарий в истории исходного кода стоит в ядре Unix V6 — в файле slp.c, в коде переключения контекста (функция swtch), на строке 2238 по нумерации «Lions' Commentary». Он соседствует с кодом savu/retu, сохранявшим и восстанавливавшим состояние процесса при переключении:
/*
* If the new process paused because it was
* swapped out, set the stack level to the last call
* to savu(u_ssav). This means that the return
* which is executed immediately after the call to aretu
* actually returns from the last routine which did the
* savu.
*
* You are not expected to understand this.
*/
Комментарий обычно читают как браваду о сложности кода. Ритчи позже пояснил, что смысл был обратный: фраза означала «этого не будет на экзамене», а не «вам этого не понять». И тут ирония, которая и делает пример показательным: авторы сами не до конца понимали, что происходит. Механизм savu/retu был фундаментально сломан — он полагался на возврат через кадр стека, сохранённый в другой процедуре, и это работало на PDP-11 лишь потому, что компилятор так генерировал код возврата. При переносе на Interdata всё развалилось: другой компилятор сохранял другой набор регистров. Ритчи и Стив Джонсон потратили около недели, убедились, что механизм неисправим правкой компилятора, и переписали примитивы переключения заново.
То есть самый знаменитый «магический» комментарий помечает ровно то, о чём тезис статьи: работающую опору на неочевидное свойство, которое надо знать, а не выводить, — и когда свойство меняется (новый компилятор, другая архитектура), магия перестаёт работать. Jargon File зафиксировал фразу как «канонический комментарий к чему-то магическому или слишком сложному, чтобы толком объяснять».
Магические константы
Слово «magic number» несёт два разных смысла, и путать их не надо. Сигнатура в начале файла, по которой file(1) опознаёт формат, — это техническая тема (разбирается отдельно). Культурно интереснее другой пласт: константы-часовые, которыми заполняют память при отладке. 0xCAFEBABE стоит в начале каждого файла класса Java. По рассказу самого Гослинга, команда обедала в кафе, которое между собой звала «Cafe Dead» (по легенде там когда-то играли Grateful Dead), и, заметив в этих словах шестнадцатеричное число, он пустил CAFEDEAD на формат persistent-object-файлов (позже вытесненный RMI), а классам в пару подобрал CAFEBABE. Версий происхождения две: по второй, от Патрика Нотона, число выбрали ещё до того, как язык назвали Java, и главным конкурентом был 0xDEADBABE. Детали расходятся, но обе сходятся на кофейной теме и ставке на запоминаемость. 0xDEADBEEF, 0xBAADF00D, 0xFEEDFACE широко используют как заполнитель неинициализированной или освобождённой памяти — узнаваемый узор в отладчике говорит больше, чем нули. Это шутки с функцией: запоминаемость и есть цель, а не побочный эффект.
Числа с историей
Некоторые ограничения пережили породившую их причину и стали «магическими» именно в этом смысле — их надо знать, потому что вывести их уже неоткуда.
Предел в 14 символов на имя файла в ранних Unix — не решение, а следствие структуры: запись каталога в V6/V7 занимала ровно 16 байт (2 байта под номер инода плюс 14-байтовое поле имени, DIRSIZ). Ограничение держалось, пока FFS в 4.2BSD не подняла его до 255. Блок в 512 байт — размер сектора диска PDP-11; Unix считал хранилище в 512-байтовых блоках, и df, du, dd до сих пор по умолчанию оперируют этой единицей. Диски давно перешли на физический сектор в 4096 байт (Advanced Format), но продолжают предъявлять системе логический сектор в 512 байт (режим 512e) через эмуляцию с read-modify-write — чисто ради совместимости. Число пережило железо, которое его породило. Его преемник, 4096, сегодня сам стал магическим числом: размер страницы памяти, блока файловой системы, значение PATH_MAX в Linux.
Демоны, волшебники и заклинания
daemon
Термин ввела команда CTSS (группа Корбато в MIT Project MAC, начало 1960-х), и назван он в честь демона Максвелла — воображаемого агента, который в фоне неустанно сортирует молекулы, — а не христианского демона. Расшифровка DAEMON как «Disk And Execution Monitor» придумана задним числом. Jargon File разводит daemon (полноценный фоновый процесс, программа) и demon (дремлющая часть внутри программы, ждущая условия). Маскот BSD, демон Beastie, — визуальный каламбур на это слово. Суффикс -d в именах служб (sshd, httpd, crond) — прямой след того же термина.
wizard
Одно слово разошлось в противоположные стороны. Базовое значение по Jargon File — эксперт, которому позволено то, что запрещено обычным пользователям (wheel-привилегии), Unix-системщик; «Unix Wizard» до сих пор встречается как название вакансии. Из этого корня выросли два расходящихся смысла. В играх (NetHack) «wizard mode» — привилегированный отладочный режим, где игроку доступно всё. В графических интерфейсах «setup wizard» — пошаговый диалог, где эксперт-проводник ведёт пользователя за руку через задачу. Общий предок — «волшебник как знаток», но развилка чёткая: в одном случае власть даётся пользователю, в другом пользователю одалживается чужая компетентность. Точное происхождение интерфейсного «мастера установки» первоисточником не подтверждается; usage связывают с софтом Microsoft начала 1990-х, но это не проверено.
Source Mage: метафора, доведённая до конца
Большинство магических терминов разрозненны, но дистрибутив Source Mage GNU/Linux превратил метафору в цельную систему именования. Инструкции по сборке пакета называются «заклинаниями» (spell), установка — «cast», удаление — «dispel», пакетный менеджер — «sorcery», набор заклинаний — «grimoire», все гримуары вместе — «codex», а утилиты scribe и gaze управляют ими и опрашивают систему. Это не проза, а настоящие имена команд:
cast firefox # собрать и установить пакет
dispel firefox # удалить
scribe update # обновить гримуары
gaze search editor # найти доступные заклинания
Девиз проекта — «Linux so advanced, it may as well be magic» — прямая отсылка к третьему закону Кларка о неотличимости достаточно развитой технологии от магии.
Процессы: zombie, orphan, reaper, kill, nice
Словарь управления процессами — антропоморфный и мрачноватый, и это не случайность: он кодирует модель. Зомби (в ps — defunct) — завершившийся процесс, за которым родитель ещё не пришёл через wait: по определению wait(2), «ребёнок, который завершился, но не был ожидаемым, становится зомби»; ядро держит о нём минимум данных (PID, код завершения), пока его не «пожнут». Сирота (orphan) — процесс, чей родитель завершился; его усыновляет init или ближайший subreaper. Жнец (reaper) собирает мёртвых: init пожинает сирот, а PR_SET_CHILD_SUBREAPER (prctl(2), появился в Linux 3.4) позволяет менеджеру служб стать таким под-init для своих потомков. kill посылает сигнал — не обязательно смертельный, имя тут преувеличивает. nice: высокое значение niceness понижает ваш приоритет — вы «уступаете» другим. За лексикой стоит модель: у процессов есть родители и дети, они умирают, кто-то обязан убирать за ними, а отношения образуют дерево.
Jargon File как памятник
Файл начал Рафаэль Финкель в Стэнфорде (SAIL) в 1975 году под именем AIWORD.RF; в 1976-м Марк Криспин скопировал его в MIT, где его расширяли Криспин, Гай Стил и Ричард Столлман. В 1983-м Гай Стил издал его книгой «The Hacker's Dictionary». После этого файл заглох вместе с культурой AI Lab, а в 1990-х его подхватил Эрик Реймонд и выпустил «The New Hacker's Dictionary» (1991, переиздания 1993 и 1996). Вокруг его редактуры есть споры: критики обвиняли Реймонда в том, что он сместил фокус к Unix-культуре в ущерб более старым культурам, откуда файл вырос, и что после издания 1993 года он добавлял термины, отражающие его собственные взгляды и словарь. Так что «памятник» ещё и оспариваемый — это запись, которую вёл человек со своей позицией.
Ценность файла сейчас в том, что он фиксирует значения, нигде больше не записанные. Часть терминов вышла за пределы субкультуры и стала общеупотребимой: bug, patch, kludge, heisenbug, bit rot, bogon. Здесь же полезно помнить про ложные этимологии, которых в этой области много. «Bug» не пошёл от мотылька, застрявшего в реле Harvard Mark II в 1947 году: сама запись в журнале — «first actual case of bug being found» — показывает, что слово уже было в ходу, а Эдисон называл «жучками» неисправности ещё в 1870-х. «Patch» тоже не про заплату на бумажной ленте: по Jargon File это временная правка, исторически — прямое изменение двоичного кода (тумблерами на передней панели, «абсолютным шестнадцатеричным» на IBM), а не правка исходника.
Язык живой, и часть словаря состарилась: многие термины относятся к машинам, которых давно нет (коинеджи из мира PDP-10 и ITS), а сам Jargon File существенно не обновлялся годами и стал наполовину историческим документом. Это не обесценивает его — но читать его надо как срез, а не как актуальный справочник.
Зачем это знать
Практический смысл прямой: терминология — это интерфейс к чужому коду и переписке. Не зная слоя отсылок, читаешь комментарии в ядре, сообщения коммитов, man-страницы и треды в рассылках с потерями — половина смысла в них держится на общем словаре. Встречается эта лексика сегодня повсюду: комментарии в исходниках ядра, имена утилит (суффикс -d, демон BSD на обложках), тексты сообщений об ошибках, RFC с их отдельной традицией юмора (первоапрельские RFC: 1149 про IP поверх почтовых голубей, 2324 про протокол управления кофейником и код HTTP 418, 1925 про двенадцать сетевых истин).
Обратная сторона тоже реальна. Жаргон — это ещё и барьер для входа, и у культуры «магии» есть законная критика: знание, которое нарочно не документируют и передают только устной традицией, перестаёт быть знанием. «Магия» — честная метка для пробела в документации, но пробелом она быть не перестаёт. И это замыкает круг к тезису и к назначению самой базы: ценность того, чтобы назвать что-то «магией», — в признании, что это надо записать, потому что переоткрыть рассуждением уже нельзя.
Источники
- Jargon File / The New Hacker's Dictionary — словарные статьи
magic,deep magic,black magic,heavy wizardry,voodoo programming,daemon,demon,wizard,kluge,heisenbug,bit rot,bogon,patch,DEADBEEF, «You are not expected to understand this» - Jargon File: Revision History — история файла от SAIL 1975 до редактуры Реймонда
- Dennis Ritchie, «Odd Comments and Strange Doings in Unix» — собственное пояснение Ритчи: смысл фразы, сломанный механизм
savu/retu, перенос на Interdata - То же в репродукции на вики TUHS — дублирующая копия того же текста Ритчи
- Lions' Commentary on UNIX 6th Edition — исходники V6, файл
slp.cс исходным комментарием - wait(2) — определение зомби, усыновление сирот процессом
init - PR_SET_CHILD_SUBREAPER (prctl) — механизм subreaper, появившийся в Linux 3.4
- Source Mage GNU/Linux — Intro и Grimoire — терминология
cast,dispel,sorcery,grimoire,codex,scribe,gaze - Джеймс Гослинг о CAFEBABE и CAFEDEAD — версия автора языка (сообщение Биллу Бамгарнеру): «Cafe Dead»,
CAFEDEADпод persistent-object-формат (позже вытеснен RMI),CAFEBABEдля классов - comp.lang.java: ответ Патрика Нотона о CAFEBABE — вторая версия происхождения (число выбрано до имени Java, конкурент
0xDEADBABE); подборка Билла Веннерса - UNIX V7
sys/dir.h— запись каталога:d_ino(2 байта) иd_name[DIRSIZ]приDIRSIZ= 14, итого 16 байт - McKusick et al., «A Fast File System for UNIX» — FFS в 4.2BSD подняла предел имени файла до 255 символов
- dd(1), du(1) — 512-байтовый блок как единица учёта; для
dd— размер блока по умолчанию - Advanced Format и 512e (IDEMA) — эмуляция 512-байтового сектора (read-modify-write) поверх физических 4096
- Linux
include/uapi/linux/limits.h—PATH_MAX= 4096 (иNAME_MAX= 255) - RFC 1149, RFC 2324, RFC 1925 — традиция первоапрельских RFC
- Corbató о термине daemon — свидетельство о происхождении слова от демона Максвелла (вторичный источник, приводит слова Корбато)
Связанные заметки
- FreeBSD — архитектура и философия — система как единый инженерный продукт и её маскот-демон; корни того же словаря
- Linux — ядро: сборка, модули, параметры — где эта лексика живёт сегодня: комментарии и имена в исходниках ядра
- TLPI — база знаний — механика процессов за терминами
zombie,orphan,reaper,kill,nice
Из библиотеки института уносят только знания. Читателей здесь не считают: посещение не регистрируется, отметок в издании не остаётся, счётчиков нет ни у одного издания фонда.
Издание пополняется и пересверяется. Текст доступен на условиях CC BY-SA 4.0 — унесённое можно передавать дальше на тех же условиях.