== Сопряжение входов/выходов

Демон *chaind* не накладывает каких-либо ограничений на то, чем апеллируют
«шаги»-скрипты, но при составлении цепочки *bootchain=…* в /proc/cmdline
необходимо учитывать, что каждый «шаг» ожидает на «входе» и что формирует
на «выходе». Например, такая цепочка не будет работать:

[,,subs="verbatim,quotes"]
----
bootchain=fg,download,liveboot,rootfs ...
----

потому что на «выходе» шаг «*download*» формирует имя смонтированного
устройства в файле *DEVNAME*, а шаг «*liveboot*» ожидает на «входе»
смонтированный каталог.

Среди обозначенных в документации шагов есть «*noop*» специально выполняющий
функцию «разрыва» цепочки. Есть наоборот, «транзитные» шаги: «*altboot*»,
«*checksum*», «*oemsetup*», «*overlayroot*», связывающие «выход» предыдущего
шага со «входом» следующего шага. Есть служебные и внутренние псевдо-шаги, на
которые даже не тратится каталогов, они никакого влияния на сопряжение других
шагов не оказывают и их не следует учитывать в нумерации шагов: «*debug*»,
«*fg*», «*noretry*» и «*retry*».

.Таблица маркировки входов/выходов:
[valign="top",options="header,compact,pgwide,unbreakable",cols="1,1,1"]
|===========================================================================
|Ожидает на «входе» |Название «шага»   |Формирует на «выходе»
|<bypass>           |<<_altboot>>      |<bypass>
|<multi-1>          |<<_checksum>>     |<bypass>
|—                  |<<_cifs>>         |<mp>
|<mp>               |<<_copyfile>>     |DEVNAME+dev+FILESIZE
|<bypass>           |<<_debug>>        |<bypass>
|[DEVNAME]          |<<_download>>     |DEVNAME+dev+FILESIZE
|<bypass>           |<<_fg>>           |<bypass>
|—                  |<<_getimage>>     |<mp>
|DEVNAME/dev        |<<_iso9660>>      |<mp>
|<mp>               |<<_liveboot>>     |<bypass>
|[DEVNAME/dev]      |<<_localdev>>     |<mp>
|[<resolve>]        |<<_mountfs>>      |<mp>
|—                  |<<_nfs>>          |<mp>
|—                  |<<_noop>>         |<nothing>
|<bypass>           |<<_noretry>>      |<bypass>
|<bypass>           |<<_oemsetup>>     |<bypass>
|[<mp>]             |<<_overlayfs>>    |<mp>
|<bypass>           |<<_overlayroot>>  |<bypass>
|—                  |<<_ping>>         |<nothing>
|<bypass>           |<<_retry>>        |<bypass>
|<mp>               |<<_rootfs>>       |<nothing>
|<mp>/DEVNAME/dev   |<<_squashfs>>     |<mp>
|—                  |<<_wait_resume>>  |<nothing>
|—                  |<<_waitdev>>      |DEVNAME+dev
|===========================================================================

Обозначения в таблице:

* *<bypass>* — «транзитный» шаг: не имеет значения, что на «входе»,
  то же будет и на «выходе»;
* *<mp>* — точка монтирования (каталог с файлами);
* *<nothing>* — на «выходе» НИЧЕГО, пустой результат;
* «**—**» (прочерк) — не имеет значения, что на «входе»;
* *[…]* (в квадратных скобках) — необязательно, т.е. может ничего не быть;
* «**/**» (знак деления) — на «входе»: ИЛИ то, ИЛИ другое;
* «**+**» (плюс) — на «выходе»: И то, И другое;
* *FILESIZE* — файл с таким именем, содержащий размер данных;
* *DEVNAME* — файл с таким именем, содержащий название устройства;
* *dev* — непосредственно сам файл устройства в стиле pipeline;
* *<resolve>* — зависит от результата resolve_target(), обычно файл
  или устройство;
* *<multi-1>* — слишком большой набор вариантов для размещения в одной
  ячейке, так что см. check_prevstep_results() в исходнике.

Стоит заметить, что в таблице не уточняется, о каких устройствах идёт речь
при использовании *dev* или *DEVNAME*. В каких-то случаях подразумеваются
любые устройства, включая символьные, в других случаях явно подразумеваются
только блочные устройства. Такие детали можно исследовать в исходном коде.

