diff --git a/documentation/content/ru/articles/rc-scripting/_index.adoc b/documentation/content/ru/articles/rc-scripting/_index.adoc index d95808356b..e75b812ed0 100644 --- a/documentation/content/ru/articles/rc-scripting/_index.adoc +++ b/documentation/content/ru/articles/rc-scripting/_index.adoc @@ -1,775 +1,775 @@ --- authors: - author: 'Yar Tikhiy' email: yar@FreeBSD.org copyright: '2005-2006, 2012 The FreeBSD Project' description: 'Руководство по написанию новых rc.d-скриптов и пониманию уже существующих' tags: ["rc.d", "scripting", "guide", "tutorial", "FreeBSD"] title: 'Практическое руководство по написанию rc.d скриптов в BSD' trademarks: ["freebsd", "netbsd", "general"] --- = Практическое руководство по написанию rc.d скриптов в BSD :doctype: article :toc: macro :toclevels: 1 :icons: font :sectnums: :sectnumlevels: 6 :source-highlighter: rouge :experimental: :images-path: articles/rc-scripting/ ifdef::env-beastie[] ifdef::backend-html5[] include::shared/authors.adoc[] include::shared/mirrors.adoc[] include::shared/releases.adoc[] include::shared/attributes/attributes-{{% lang %}}.adoc[] include::shared/{{% lang %}}/teams.adoc[] include::shared/{{% lang %}}/mailing-lists.adoc[] include::shared/{{% lang %}}/urls.adoc[] :imagesdir: ../../../images/{images-path} endif::[] ifdef::backend-pdf,backend-epub3[] include::../../../../shared/asciidoctor.adoc[] endif::[] endif::[] ifndef::env-beastie[] include::../../../../../shared/asciidoctor.adoc[] endif::[] [.abstract-title] Аннотация Новичкам может быть сложно соотнести факты из официальной документации по фреймворку [.filename]#rc.d# в BSD с практическими задачами написания скриптов для [.filename]#rc.d#. В этой статье мы рассмотрим несколько типичных случаев возрастающей сложности, покажем возможности [.filename]#rc.d#, подходящие для каждого случая, и обсудим, как они работают. Такое рассмотрение должно дать ориентиры для дальнейшего изучения устройства и эффективного применения [.filename]#rc.d#. ''' toc::[] [[rcng-intro]] == Введение Исторически в BSD был монолитный стартовый сценарий [.filename]#/etc/rc#. Он вызывался man:init[8] во время загрузки системы и выполнял все задачи пользовательского пространства, необходимые для многопользовательского режима: проверку и монтирование файловых систем, настройку сети, запуск демонов и так далее. Точный список задач не был одинаковым в каждой системе; администраторам требовалось его настраивать. За редкими исключениями, [.filename]#/etc/rc# приходилось изменять, и настоящим хакерам это нравилось. Основная проблема монолитного подхода заключалась в том, что он не предоставлял контроля над отдельными компонентами, запускаемыми из [.filename]#/etc/rc#. Например, [.filename]#/etc/rc# не мог перезапустить отдельный демон. Администратору системы приходилось вручную находить процесс демона, завершать его, ждать, пока он действительно завершится, затем искать в [.filename]#/etc/rc# нужные флаги и, наконец, вводить полную командную строку для повторного запуска демона. Задача становилась ещё сложнее и более подверженной ошибкам, если служба состояла из нескольких демонов или требовала дополнительных действий. Одним словом, единый скрипт не справлялся с тем, для чего скрипты вообще предназначены: облегчать жизнь администратору системы. Позже была предпринята попытка разделить некоторые части [.filename]#/etc/rc# для возможности отдельного запуска наиболее важных подсистем. Известным примером стал [.filename]#/etc/netstart#, предназначенный для настройки сети. Это позволяло получить доступ к сети в однопользовательском режиме, но плохо интегрировалось в автоматический процесс запуска, так как части его кода требовалось переплетаться с действиями, по сути не связанными с сетью. Именно поэтому [.filename]#/etc/netstart# превратился в [.filename]#/etc/rc.network#. Последний больше не был обычным скриптом; он состоял из больших, запутанных функций man:sh[1], вызываемых из [.filename]#/etc/rc# на разных этапах загрузки системы. Однако по мере того, как задачи при запуске становились разнообразнее и сложнее, "квазимодульный" подход стал ещё большей обузой, чем монолитный [.filename]#/etc/rc#. Без чистого и хорошо продуманного каркаса, стартовые скрипты вынуждены были идти на всевозможные ухищрения, чтобы удовлетворить потребности быстро развивающихся BSD-ориентированных операционных систем. В конце концов стало очевидно, что необходимы дополнительные шаги на пути к детализированной и расширяемой системе [.filename]#rc#. Так появилась BSD [.filename]#rc.d#. Её признанными создателями стали Люк Мьюберн и сообщество NetBSD. Позже она была импортирована в FreeBSD. Её название отсылает к расположению системных скриптов для отдельных служб, которое находится в [.filename]#/etc/rc.d#. Вскоре мы узнаем больше о компонентах системы [.filename]#rc.d# и увидим, как вызываются отдельные скрипты. Основные идеи, лежащие в основе BSD [.filename]#rc.d#, — это _тонкая модульность_ и __повторное использование кода__. _Тонкая модульность_ означает, что каждая базовая «служба», такая как системный демон или примитивная задача запуска, получает собственный сценарий man:sh[1], способный запустить службу, остановить её, перезагрузить или проверить её состояние. Конкретное действие выбирается аргументом командной строки, переданным в сценарий. Сценарий [.filename]#/etc/rc# по-прежнему управляет запуском системы, но теперь он просто вызывает небольшие сценарии один за другим с аргументом `start`. Также легко выполнять задачи завершения работы, запуская тот же набор сценариев с аргументом `stop`, что и делает [.filename]#/etc/rc.shutdown#. Обратите внимание, насколько это близко следует Unix-подходу, где используется набор небольших специализированных инструментов, каждый из которых выполняет свою задачу наилучшим образом. _Повторное использование кода_ означает, что общие операции реализованы как функции man:sh[1] и собраны в [.filename]#/etc/rc.subr#. Теперь типичный сценарий может состоять всего из нескольких строк кода man:sh[1]. Наконец, важной частью инфраструктуры [.filename]#rc.d# является man:rcorder[8], который помогает [.filename]#/etc/rc# упорядоченно запускать небольшие сценарии с учётом зависимостей между ними. Он также может помочь [.filename]#/etc/rc.shutdown#, поскольку правильный порядок завершения работы противоположен порядку запуска. -Дизайн BSD [.filename]#rc.d# описан в crossref:rc-scripting[lukem, оригинальной статье Люка Мьюберна], а компоненты [.filename]#rc.d# подробно документированы в crossref:rc-scripting[manpages, соответствующих страницах Справочника]. Однако новичку в [.filename]#rc.d# может быть неочевидно, как связать многочисленные элементы вместе, чтобы создать хорошо структурированный скрипт для конкретной задачи. Поэтому в этой статье будет предпринята попытка описать [.filename]#rc.d# с другого ракурса. В ней будет показано, какие функции следует использовать в ряде типичных случаев и почему. Обратите внимание, что это не руководство HowTo, поскольку наша цель — не предоставление готовых рецептов, а демонстрация нескольких простых способов входа в мир [.filename]#rc.d#. Также эта статья не заменяет соответствующие страниц Справочника. Не стесняйтесь обращаться к ним для получения более формальной и полной документации во время чтения этой статьи. +Дизайн BSD [.filename]#rc.d# описан в crossref:rc-scripting[lukem, оригинальной статье Люка Мьюберна], а компоненты [.filename]#rc.d# подробно документированы в crossref:rc-scripting[manpages, соответствующих страницах Справочника]. Однако новичку в [.filename]#rc.d# может быть неочевидно, как связать многочисленные элементы вместе, чтобы создать хорошо структурированный скрипт для конкретной задачи. Поэтому в этой статье будет предпринята попытка описать [.filename]#rc.d# с другого ракурса. В ней будет показано, какие функции следует использовать в ряде типичных случаев и почему. Обратите внимание, что это не руководство HowTo, поскольку наша цель — не предоставление готовых рецептов, а демонстрация нескольких простых способов входа в мир [.filename]#rc.d#. Также эта статья не заменяет соответствующие страницы Справочника. Не стесняйтесь обращаться к ним для получения более формальной и полной документации во время чтения этой статьи. Для понимания этой статьи есть предварительные требования. Прежде всего, вы должны быть знакомы с языком написания сценариев man:sh[1], чтобы освоить [.filename]#rc.d#. Кроме того, вы должны знать, как система выполняет задачи запуска и завершения работы пользовательского пространства, что описано в man:rc[8]. Эта статья посвящена ветке FreeBSD в [.filename]#rc.d#. Тем не менее, она может быть полезна и разработчикам NetBSD, потому что две ветки BSD [.filename]#rc.d# не только разделяют одинаковый дизайн, но и остаются схожими в аспектах, видимых авторам скриптов. [[rcng-task]] == Обрисовка задачи Немного размышлений перед запуском `$EDITOR` не повредит. Чтобы написать хорошо продуманный скрипт [.filename]#rc.d# для системной службы, сначала нужно ответить на следующие вопросы: * Является ли служба обязательной или опциональной? * Будет ли скрипт обслуживать одну программу, например, демон, или выполнять более сложные действия? * От каких других служб зависит наша служба, и наоборот? Из следующих примеров мы увидим, почему важно знать ответы на эти вопросы. [[rcng-dummy]] == Примитивный скрипт Следующий скрипт просто выводит сообщение каждый раз при загрузке системы: [.programlisting] .... #!/bin/sh <.> . /etc/rc.subr <.> name="dummy" <.> start_cmd="${name}_start" <.> stop_cmd=":" <.> dummy_start() <.> { echo "Nothing started." } load_rc_config $name <.> run_rc_command "$1" <.> .... Вот что следует учитывать: ➊ Интерпретируемый скрипт должен начинаться с "волшебной" строки shebang. Эта строка указывает программу-интерпретатор для скрипта. Благодаря строке shebang скрипт может быть запущен точно так же, как бинарная программа, при условии что у него установлен бит выполнения. (См. man:chmod[1].) Например, системный администратор может запустить наш скрипт вручную из командной строки: [source, shell] .... # /etc/rc.d/dummy start .... [NOTE] ==== Для корректного управления в рамках [.filename]#rc.d# скрипты должны быть написаны на языке man:sh[1]. Если у вас есть служба или порт, который использует двоичную утилиту управления или процедуру запуска, написанную на другом языке, установите этот компонент в [.filename]#/usr/sbin# (для системы) или [.filename]#/usr/local/sbin# (для портов) и вызовите его из man:sh[1] скрипта в соответствующем каталоге [.filename]#rc.d#. ==== [TIP] ==== Если вы хотите узнать подробности о том, почему скрипты [.filename]#rc.d# должны быть написаны на языке man:sh[1], изучите, как [.filename]#/etc/rc# вызывает их с помощью `run_rc_script`, а затем изучите реализацию `run_rc_script` в [.filename]#/etc/rc.subr#. ==== ➋ В файле [.filename]#/etc/rc.subr# определено несколько функций man:sh[1], которые могут использоваться скриптами [.filename]#rc.d#. Эти функции описаны в man:rc.subr[8]. Хотя теоретически возможно написать скрипт [.filename]#rc.d# без использования man:rc.subr[8], его функции оказываются чрезвычайно полезными и значительно упрощают задачу. Поэтому неудивительно, что все используют man:rc.subr[8] в скриптах [.filename]#rc.d#. Мы не будем исключением. Файл [.filename]#rc.d# должен "подгрузить" ([.filename]#/etc/rc.subr#, включить его с помощью "`.`") _до_ вызова функций man:rc.subr[8], чтобы у man:sh[1] была возможность знать об этих функциях заранее. Предпочтительный стиль — подгружать [.filename]#/etc/rc.subr# в самом начале. [NOTE] ==== Некоторые полезные функции, связанные с сетью, предоставляются другим включаемым файлом — [.filename]#/etc/network.subr#. ==== ➌ [[name-var]]Обязательная переменная `name` определяет имя нашего скрипта. Она требуется man:rc.subr[8]. То есть, каждый скрипт в [.filename]#rc.d# _должен_ установить `name` перед вызовом функций man:rc.subr[8]. Теперь самое время раз и навсегда выбрать уникальное имя для нашего скрипта. Мы будем использовать его в нескольких местах при разработке скрипта. Содержимое переменной name должно соответствовать имени скрипта, так как некоторые части FreeBSD (например, crossref:rc-scripting[rcng-service-jails, сервисные клетки (jail)] и функция cpuset в rc framework) зависят от этого. Таким образом, имя файла также не должно содержать символов, которые могут вызвать проблемы в скриптах (например, не используйте дефис "-" и другие). [NOTE] ==== Текущий стиль написания скриптов в [.filename]#rc.d# заключается в заключении значений, присваиваемых переменным, в двойные кавычки. Имейте в виду, что это всего лишь вопрос стиля, который может быть не всегда применим. Вы можете безопасно опустить кавычки вокруг простых слов без метасимволов man:sh[1], тогда как в некоторых случаях вам понадобятся одинарные кавычки, чтобы предотвратить интерпретацию значения man:sh[1]. Программист должен уметь отличать синтаксис языка от стилевых соглашений и разумно использовать и то, и другое. ==== ➍ Основная идея man:rc.subr[8] заключается в том, что скрипт [.filename]#rc.d# предоставляет обработчики (или методы) для вызова man:rc.subr[8]. В частности, аргументы `start`, `stop` и другие, передаваемые в скрипт [.filename]#rc.d#, обрабатываются таким образом. Метод представляет собой выражение man:sh[1], сохранённое в переменной с именем `argument_cmd`, где _argument_ соответствует тому, что может быть указано в командной строке скрипта. Далее мы увидим, как man:rc.subr[8] предоставляет стандартные методы для типовых аргументов. [NOTE] ==== Чтобы сделать код в [.filename]#rc.d# более единообразным, обычно используют `${name}` везде, где это уместно. Таким образом, множество строк можно просто копировать из одного скрипта в другой. ==== ➎ Следует помнить, что man:rc.subr[8] предоставляет методы по умолчанию для стандартных аргументов. Следовательно, если мы хотим, чтобы стандартный метод ничего не делал, мы должны переопределить его с помощью no-op man:sh[1] выражения. ➏ Тело сложного метода может быть реализовано в виде функции. Хорошей практикой является использование осмысленного имени функции. [IMPORTANT] ==== Настоятельно рекомендуется добавлять префикс `${name}` к именам всех функций, определённых в нашем скрипте, чтобы они никогда не конфликтовали с функциями из man:rc.subr[8] или другого общего включаемого файла. ==== ➐ Этот вызов man:rc.subr[8] загружает переменные man:rc.conf[5]. Наш скрипт пока их не использует, но всё равно рекомендуется загружать man:rc.conf[5], потому что могут быть переменные man:rc.conf[5], управляющие самим man:rc.subr[8]. ➑ Обычно это последняя команда в скрипте [.filename]#rc.d#. Она вызывает механизм man:rc.subr[8] для выполнения запрошенного действия, используя переменные и методы, предоставленные нашим скриптом. [[rcng-confdummy]] == Настраиваемый фиктивный скрипт Теперь добавим некоторые элементы управления в наш тестовый скрипт. Как вам может быть известно, скрипты [.filename]#rc.d# управляются с помощью man:rc.conf[5]. К счастью, man:rc.subr[8] скрывает от нас все сложности. Следующий скрипт использует man:rc.conf[5] через man:rc.subr[8], чтобы проверить, включен ли он вообще, и получить сообщение для отображения во время загрузки. Эти две задачи на самом деле независимы. С одной стороны, скрипт [.filename]#rc.d# может просто поддерживать включение и выключение своего сервиса. С другой стороны, обязательный скрипт [.filename]#rc.d# может иметь переменные конфигурации. Однако мы реализуем обе возможности в одном скрипте: [.programlisting] .... #!/bin/sh . /etc/rc.subr name=dummy rcvar=dummy_enable <.> start_cmd="${name}_start" stop_cmd=":" load_rc_config $name <.> : ${dummy_enable:=no} <.> : ${dummy_msg="Nothing started."} <.> dummy_start() { echo "$dummy_msg" <.> } run_rc_command "$1" .... Что изменилось в этом примере? ➊ Переменная `rcvar` определяет имя переменной-переключателя ON/OFF. ➋ Теперь `load_rc_config` вызывается раньше в скрипте, до обращения к любым переменным man:rc.conf[5]. [NOTE] ==== При изучении скриптов в [.filename]#rc.d# следует помнить, что man:sh[1] откладывает вычисление выражений в функции до её вызова. Поэтому не будет ошибкой вызвать `load_rc_config` непосредственно перед `run_rc_command` и при этом обращаться к переменным man:rc.conf[5] из функций методов, экспортируемых в `run_rc_command`. Это связано с тем, что функции методов вызываются `run_rc_command`, который выполняется _после_ `load_rc_config`. ==== ➌ `run_rc_command` выдаст предупреждение, если переменная `rcvar` установлена, но указанная переменная-флаг не задана. Если ваш скрипт [.filename]#rc.d# предназначен для базовой системы, вы должны добавить значение по умолчанию для флага в [.filename]#/etc/defaults/rc.conf# и задокументировать его в man:rc.conf[5]. В противном случае ваш скрипт должен предоставить значение по умолчанию для флага. Канонический подход для последнего случая показан в примере. [NOTE] ==== Вы можете заставить man:rc.subr[8] действовать так, как если бы переключатель установлен в `ON`, независимо от его текущего значения, добавив перед аргументом скрипта префикс `one` или `force`, например `onestart` или `forcestop`. Однако учтите, что `force` имеет другие опасные эффекты, которые мы затронем ниже, тогда как `one` просто переопределяет переключатель ON/OFF. Например, предположим, что `dummy_enable` установлен в `OFF`. Следующая команда выполнит метод `start`, несмотря на настройку: [source, shell] .... # /etc/rc.d/dummy onestart .... ==== ➍ Теперь сообщение, отображаемое при загрузке, больше не жёстко закодировано в скрипте. Оно задается переменной `dummy_msg` в man:rc.conf[5]. Это простой пример того, как переменные man:rc.conf[5] могут управлять скриптом в [.filename]#rc.d#. [IMPORTANT] ==== Имена всех переменных man:rc.conf[5], используемых исключительно нашим скриптом, _должны_ иметь один и тот же префикс: `${name}_`. Например: `dummy_mode`, `dummy_state_file` и так далее. ==== [NOTE] ==== Хотя можно использовать более короткое имя внутри, например, просто `msg`, добавление уникального префикса `${name}_` ко всем глобальным именам, вводимым нашим скриптом, избавит нас от возможных конфликтов с пространством имён man:rc.subr[8]. Как правило, скрипты [.filename]#rc.d# базовой системы не должны предоставлять значения по умолчанию для своих переменных man:rc.conf[5], поскольку значения по умолчанию должны быть установлены в [.filename]#/etc/defaults/rc.conf#. С другой стороны, скрипты [.filename]#rc.d# для портов должны предоставлять значения по умолчанию, как показано в примере. ==== ➎ Здесь мы используем `dummy_msg` для фактического управления нашим скриптом, т.е., для выдачи переменного сообщения. Использование shell-функции здесь избыточно, так как она выполняет только одну команду; равнозначной альтернативой является: [.programlisting] .... start_cmd="echo \"$dummy_msg\"" .... [[rcng-daemon]] == Запуск и остановка простого демона Мы ранее говорили, что man:rc.subr[8] может предоставлять методы по умолчанию. Очевидно, что такие методы не могут быть слишком общими. Они подходят для стандартного случая запуска и остановки простого демона. Предположим, что нам нужно написать скрипт [.filename]#rc.d# для такого демона с именем `mumbled`. Вот он: [.programlisting] .... #!/bin/sh . /etc/rc.subr name=mumbled rcvar=mumbled_enable command="/usr/sbin/${name}" <.> load_rc_config $name run_rc_command "$1" .... Приятно просто, не так ли? Давайте рассмотрим наш небольшой скрипт. Единственное новое, на что стоит обратить внимание, это следующее: ➊ Переменная `command` имеет значение для man:rc.subr[8]. Если она установлена, man:rc.subr[8] будет действовать по сценарию обслуживания обычного демона. В частности, будут предоставлены стандартные методы для таких аргументов: `start`, `stop`, `restart`, `poll` и `status`. Демон будет запущен выполнением `$command` с флагами командной строки, указанными в `$mumbled_flags`. Таким образом, все входные данные для метода `start` по умолчанию доступны в переменных, установленных нашим скриптом. В отличие от `start`, другие методы могут требовать дополнительной информации о запущенном процессе. Например, `stop` должен знать PID процесса, чтобы завершить его. В данном случае, man:rc.subr[8] будет просматривать список всех процессов, ища процесс с именем, равным `procname`. Последний является ещё одной значимой переменной для man:rc.subr[8], и её значение по умолчанию совпадает со значением `command`. Другими словами, когда мы устанавливаем `command`, `procname` фактически устанавливается в то же значение. Это позволяет нашему скрипту завершить демон и проверить, запущен ли он вообще. [NOTE] ==== Некоторые программы на самом деле являются исполняемыми скриптами. Система запускает такие скрипты, запуская их интерпретатор и передавая ему имя скрипта в качестве аргумента командной строки. Это отражается в списке процессов, что может сбить с толку man:rc.subr[8]. Дополнительно следует установить `command_interpreter`, чтобы man:rc.subr[8] знал фактическое имя процесса, если `$command` является скриптом. Для каждого скрипта [.filename]#rc.d# существует необязательная переменная man:rc.conf[5], которая имеет приоритет над `command`. Её имя формируется следующим образом: `${name}_program`, где `name` — это обязательная переменная, которую мы обсуждали crossref:rc-scripting[name-var, ранее]. Например, в данном случае это будет `mumbled_program`. Именно man:rc.subr[8] обеспечивает переопределение `command` с помощью `${name}_program`. Конечно, man:sh[1] позволяет установить `${name}_program` из man:rc.conf[5] или самого скрипта, даже если `command` не задан. В этом случае специальные свойства `${name}_program` теряются, и она становится обычной переменной, которую ваш скрипт может использовать для своих целей. Однако использование `${name}_program` в одиночку не рекомендуется, так как совместное использование с `command` стало идиомой в [.filename]#rc.d# скриптах. ==== Для получения более подробной информации о стандартных методах обратитесь к man:rc.subr[8]. [[rcng-daemon-adv]] == Запуск и остановка продвинутого демона Добавим немного мяса к костям предыдущего скрипта и сделаем его более сложным и функциональным. Стандартные методы могут хорошо справляться с задачами, но иногда требуется их тонкая настройка. Теперь мы узнаем, как адаптировать стандартные методы под наши нужды. [.programlisting] .... #!/bin/sh . /etc/rc.subr name=mumbled rcvar=mumbled_enable command="/usr/sbin/${name}" command_args="mock arguments > /dev/null 2>&1" <.> pidfile="/var/run/${name}.pid" <.> required_files="/etc/${name}.conf /usr/share/misc/${name}.rules" <.> sig_reload="USR1" <.> start_precmd="${name}_prestart" <.> stop_postcmd="echo Bye-bye" <.> extra_commands="reload plugh xyzzy" <.> plugh_cmd="mumbled_plugh" <.> xyzzy_cmd="echo 'Nothing happens.'" mumbled_prestart() { if checkyesno mumbled_smart; then <.> rc_flags="-o smart ${rc_flags}" <.> fi case "$mumbled_mode" in foo) rc_flags="-frotz ${rc_flags}" ;; bar) rc_flags="-baz ${rc_flags}" ;; *) warn "Invalid value for mumbled_mode" <.> return 1 <.> ;; esac run_rc_command xyzzy <.> return 0 } mumbled_plugh() <.> { echo 'A hollow voice says "plugh".' } load_rc_config $name run_rc_command "$1" .... ➊ Дополнительные аргументы для `$command` могут быть переданы в `command_args`. Они будут добавлены в командную строку после `$mumbled_flags`. Поскольку итоговая командная строка передаётся в `eval` для фактического выполнения, перенаправления ввода и вывода могут быть указаны в `command_args`. [NOTE] ==== Никогда не включайте параметры с дефисами, такие как `-X` или `--foo`, в `command_args`. Содержимое `command_args` будет добавлено в конец итоговой командной строки, поэтому, скорее всего, окажется после аргументов, указанных в `${name}_flags`; однако большинство команд не распознают параметры с дефисами после обычных аргументов. Лучший способ передать дополнительные параметры в `$command` — добавить их в начало `${name}_flags`. Другой способ — изменить `rc_flags` crossref:rc-scripting[rc-flags, как показано далее]. ==== ➋ Вежливый демон должен создавать _pidfile_, чтобы его процесс можно было найти проще и надёжнее. Переменная `pidfile`, если она установлена, указывает man:rc.subr[8], где можно найти pidfile для использования его стандартными методами. [NOTE] ==== На самом деле, man:rc.subr[8] также использует pidfile для проверки, запущен ли демон, перед его запуском. Эту проверку можно пропустить, используя аргумент `faststart`. ==== ➌ Если демон не может работать без определённых файлов, просто укажите их в `required_files`, и man:rc.subr[8] проверит их наличие перед запуском демона. Также существуют `required_dirs` и `required_vars` для каталогов и переменных окружения соответственно. Все они подробно описаны в man:rc.subr[8]. [NOTE] ==== Метод по умолчанию из man:rc.subr[8] можно принудительно заставить пропустить проверки предварительных условий, используя аргумент `forcestart` в скрипте. ==== ➍ Мы можем настроить сигналы, отправляемые демону, если они отличаются от общеизвестных. В частности, `sig_reload` указывает сигнал, который заставляет демона перезагрузить свою конфигурацию; по умолчанию это SIGHUP. Другой сигнал отправляется для остановки процесса демона; по умолчанию используется SIGTERM, но это можно изменить, установив `sig_stop` соответствующим образом. [NOTE] ==== Имена сигналов должны указываться для man:rc.subr[8] без префикса `SIG`, как показано в примере. Версия man:kill[1] в FreeBSD может распознавать префикс `SIG`, но версии из других типов ОС могут не поддерживать его. ==== ➎➏ Выполнение дополнительных задач до или после стандартных методов — это просто. Для каждого аргумента команды, поддерживаемого нашим скриптом, мы можем определить `argument_precmd` и `argument_postcmd`. Эти команды man:sh[1] вызываются до и после соответствующего метода, что очевидно из их названий. [NOTE] ==== Переопределение стандартного метода с помощью пользовательского `argument_cmd` всё равно не мешает нам использовать `argument_precmd` или `argument_postcmd`, если это необходимо. В частности, первый полезен для проверки пользовательских сложных условий, которые должны быть выполнены перед выполнением самой команды. Использование `argument_precmd` вместе с `argument_cmd` позволяет логически разделить проверки от действия. Не забывайте, что вы можете вставлять любые допустимые выражения из man:sh[1] в определяемые вами методы, а также команды pre- и post-. Просто вызывать функцию, которая выполняет основную работу, — это хороший стиль в большинстве случаев, но никогда не позволяйте стилю ограничивать ваше понимание того, что происходит за кулисами. ==== ➐ Если мы хотим реализовать пользовательские аргументы, которые также можно рассматривать как _команды_ для нашего скрипта, необходимо перечислить их в `extra_commands` и предоставить методы для их обработки. [NOTE] ==== Команда `reload` является особенной. С одной стороны, у неё есть предустановленный метод в man:rc.subr[8]. С другой стороны, `reload` не предлагается по умолчанию. Причина в том, что не все демоны используют одинаковый механизм перезагрузки, а у некоторых вообще нет ничего для перезагрузки. Поэтому нам нужно явно запросить предоставление встроенной функциональности. Это можно сделать с помощью `extra_commands`. Что мы получаем от метода по умолчанию для `reload`? Довольно часто демоны перезагружают свою конфигурацию при получении сигнала — обычно, SIGHUP. Поэтому man:rc.subr[8] пытается перезагрузить демона, отправляя ему сигнал. Сигнал предустановлен на SIGHUP, но может быть изменён через `sig_reload` при необходимости. ==== ➑⓮ Наш скрипт поддерживает две нестандартные команды: `plugh` и `xyzzy`. Мы видели их в списке `extra_commands`, и теперь пришло время реализовать методы для них. Метод для `xyzzy` просто встроен в код, а для `plugh` он реализован как функция `mumbled_plugh`. Нестандартные команды не вызываются во время запуска или завершения работы. Обычно они предназначены для удобства системного администратора. Они также могут использоваться другими подсистемами, например, man:devd[8], если указаны в man:devd.conf[5]. Полный список доступных команд можно найти в строке использования, выводимой man:rc.subr[8], когда скрипт вызывается без аргументов. Например, вот строка использования из изучаемого скрипта: [source, shell] .... # /etc/rc.d/mumbled Usage: /etc/rc.d/mumbled [fast|force|one](start|stop|restart|rcvar|reload|plugh|xyzzy|status|poll) .... ⓭ Скрипт может вызывать свои собственные стандартные или нестандартные команды, если это необходимо. Это может выглядеть похоже на вызов функций, но мы знаем, что команды и функции оболочки не всегда одно и то же. Например, `xyzzy` не реализован как функция в данном случае. Кроме того, могут существовать пред-команда и пост-команда, которые должны вызываться в определённом порядке. Поэтому правильный способ для скрипта выполнить свою собственную команду — с помощью man:rc.subr[8], как показано в примере. ➒ Полезная функция `checkyesno` предоставляется man:rc.subr[8]. Она принимает имя переменной в качестве аргумента и возвращает нулевой код выхода только если переменная установлена в `YES`, `TRUE`, `ON` или `1`, без учёта регистра; в противном случае возвращается ненулевой код выхода. В последнем случае функция проверяет, установлена ли переменная в `NO`, `FALSE`, `OFF` или `0`, также без учёта регистра; если переменная содержит что-то иное (т.е. мусор), функция выводит предупреждение. Имейте в виду, что для man:sh[1] нулевой код возврата означает истину, а ненулевой код возврата означает ложь. [IMPORTANT] ==== Функция `checkyesno` принимает __имя переменной__. Не передавайте ей _значение_ переменной; это не будет работать, как ожидается. Ниже приведено правильное использование `checkyesno`: [.programlisting] .... if checkyesno mumbled_enable; then foo fi .... Напротив, вызов `checkyesno`, как показано ниже, не сработает — по крайней мере, не так, как ожидается: [.programlisting] .... if checkyesno "${mumbled_enable}"; then foo fi .... ==== ➓ [[rc-flags]] Мы можем влиять на флаги, передаваемые команде `$command`, изменяя `rc_flags` в `$start_precmd`. ⓫ В некоторых случаях может потребоваться вывести важное сообщение, которое также должно попасть в `syslog`. Это можно легко сделать с помощью следующих функций man:rc.subr[8]: `debug`, `info`, `warn` и `err`. Последняя функция завершает выполнение скрипта с указанным кодом. ⓬ Коды выхода из методов и их предварительных команд не просто игнорируются по умолчанию. Если `argument_precmd` возвращает ненулевой код выхода, основной метод не будет выполнен. В свою очередь, `argument_postcmd` не будет вызван, если основной метод возвращает ненулевой код выхода. [NOTE] ==== Однако man:rc.subr[8] можно указать из командной строки игнорировать эти коды завершения и выполнять все команды в любом случае, добавив префикс `force` к аргументу, например `forcestart`. ==== [[rcng-hookup]] == Подключение скрипта к инфраструктуре rc.d После написания скрипта его необходимо интегрировать в [.filename]#rc.d#. Ключевой шаг — установка скрипта в [.filename]#/etc/rc.d# (для базовой системы) или [.filename]#/usr/local/etc/rc.d# (для портов). И [.filename]#bsd.prog.mk#, и [.filename]#bsd.port.mk# предоставляют удобные механизмы для этого, и обычно вам не нужно беспокоиться о правильных правах доступа и режиме. Системные скрипты должны устанавливаться из [.filename]#src/libexec/rc/rc.d# через [.filename]#Makefile#, находящийся там. Скрипты портов можно установить с помощью `USE_RC_SUBR`, как описано extref:{porters-handbook}special[в Руководстве FreeBSD по созданию портов, rc-scripts]. Однако следует заранее продумать место нашего скрипта в последовательности запуска системы. Скорее всего, обслуживаемый нашим скриптом сервис зависит от других сервисов. Например, сетевой демон не может работать без поднятых сетевых интерфейсов и маршрутизации. Даже если сервис, казалось бы, ничего не требует, он вряд ли сможет запуститься до проверки и монтирования основных файловых систем. Мы уже упоминали man:rcorder[8]. Теперь пришло время рассмотреть его подробнее. В двух словах, man:rcorder[8] принимает набор файлов, анализирует их содержимое и выводит на `stdout` список этих файлов, упорядоченный по зависимостям. Главная идея заключается в том, чтобы хранить информацию о зависимостях _внутри_ файлов, чтобы каждый файл мог описывать только себя. Файл может содержать следующую информацию: * имена "условий" (что для нас означает сервисы), которые он __предоставляет__; * имена "условий", которые он __требует__; * имена "условий", перед которыми должен выполняться этот файл; * дополнительные _ключевые слова_, которые могут использоваться для выбора подмножества из всего набора файлов (man:rcorder[8] может быть настроен с помощью опций для включения или исключения файлов, содержащих указанные ключевые слова.) Неудивительно, что man:rcorder[8] может обрабатывать только текстовые файлы с синтаксисом, близким к man:sh[1]. То есть специальные строки, понимаемые man:rcorder[8], выглядят как комментарии в man:sh[1]. Синтаксис таких специальных строк довольно жёсткий, чтобы упростить их обработку. Подробности см. в man:rcorder[8]. Помимо использования специальных строк man:rcorder[8], скрипт может настаивать на своей зависимости от другой службы, просто принудительно запуская её. Это может быть необходимо, когда другая служба является опциональной и не запускается самостоятельно, потому что системный администратор ошибочно отключил её в man:rc.conf[5]. С учётом этих общих знаний рассмотрим простой скрипт демона, дополненный зависимостями: [.programlisting] .... #!/bin/sh # PROVIDE: mumbled oldmumble <.> # REQUIRE: DAEMON cleanvar frotz <.> # BEFORE: LOGIN <.> # KEYWORD: nojail shutdown <.> . /etc/rc.subr name=mumbled rcvar=mumbled_enable command="/usr/sbin/${name}" start_precmd="${name}_prestart" mumbled_prestart() { if ! checkyesno frotz_enable && \ ! /etc/rc.d/frotz forcestatus 1>/dev/null 2>&1; then force_depend frotz || return 1 <.> fi return 0 } load_rc_config $name run_rc_command "$1" .... Как и ранее, следует детальный анализ: ➊ Эта строка объявляет названия "условий", которые предоставляет наш скрипт. Теперь другие скрипты могут указывать зависимость от нашего скрипта по этим именам. [NOTE] ==== Обычно скрипт указывает одно предоставленное условие. Однако ничто не мешает нам перечислить несколько условий, например, по причинам совместимости. В любом случае, название основного или единственного условия `PROVIDE:` должно совпадать с `${name}`. ==== ➋➌ Таким образом, наш скрипт указывает, от каких "условий", предоставляемых другими скриптами, он зависит. Согласно строкам, наш скрипт просит man:rcorder[8] разместить его после скрипта(ов), предоставляющих [.filename]#DAEMON# и [.filename]#cleanvar#, но перед тем, который предоставляет [.filename]#LOGIN#. [NOTE] ==== Строку `BEFORE:` не следует использовать для обхода неполного списка зависимостей в другом скрипте. Правильный случай для использования `BEFORE:` — когда другой скрипт не зависит от нашего, но наш скрипт может выполнить свою задачу лучше, если запустится до другого. Типичный пример из реальной жизни — сетевые интерфейсы и межсетевой экран: хотя интерфейсы не зависят от межсетевого экрана при выполнении своей работы, безопасность системы выиграет, если межсетевой экран будет готов до начала сетевого трафика. Помимо условий, соответствующих отдельным службам, существуют метаусловия и их "заглушки" скриптов, используемые для обеспечения выполнения определённых групп операций в заданном порядке. Они обозначаются именами в [.filename]#ВЕРХНЕМ РЕГИСТРЕ#. Их список и назначение можно найти в man:rc[8]. Имейте в виду, что указание имени службы в строке `REQUIRE:` не гарантирует, что служба действительно будет запущена к моменту старта нашего скрипта. Требуемая служба может не запуститься или быть отключена в man:rc.conf[5]. Очевидно, man:rcorder[8] не может отслеживать такие детали, и man:rc[8] тоже этого не делает. Следовательно, приложение, запускаемое нашим скриптом, должно быть способно обрабатывать ситуации, когда требуемые службы недоступны. В некоторых случаях мы можем помочь ему, как описано в crossref:rc-scripting[forcedep, ниже] ==== [[keywords]]➍ Как мы помним из текста выше, ключевые слова man:rcorder[8] могут использоваться для выбора или исключения некоторых скриптов. А именно, любой потребитель man:rcorder[8] может указать с помощью опций `-k` и `-s`, какие ключевые слова находятся в "списке сохранения" и "списке пропуска" соответственно. Из всех файлов, подлежащих сортировке по зависимостям, man:rcorder[8] выберет только те, которые имеют ключевое слово из списка сохранения (если он не пуст) и не имеют ключевого слова из списка пропуска. В FreeBSD, man:rcorder[8] используется [.filename]#/etc/rc# и [.filename]#/etc/rc.shutdown#. Эти два скрипта определяют стандартный список ключевых слов [.filename]#rc.d# FreeBSD и их значения следующим образом: nojail:: Сервис не предназначен для окружения man:jail[8]. Процедуры автоматического запуска и остановки будут игнорировать скрипт, если он находится внутри клетки. nostart:: Служба должна запускаться вручную или не запускаться вовсе. Процедура автоматического запуска проигнорирует скрипт. В сочетании с ключевым словом [.filename]#shutdown# это может использоваться для написания скриптов, выполняющих действия только при выключении системы. shutdown:: Этот ключевой параметр должен быть указан __явно__, если службу необходимо остановить перед завершением работы системы. [NOTE] ==== Когда система собирается завершить работу, выполняется [.filename]#/etc/rc.shutdown#. Предполагается, что большинству скриптов [.filename]#rc.d# в этот момент нечего делать. Поэтому [.filename]#/etc/rc.shutdown# выборочно запускает скрипты [.filename]#rc.d# с ключевым словом [.filename]#shutdown#, фактически игнорируя остальные скрипты. Для ещё более быстрого завершения работы [.filename]#/etc/rc.shutdown# передаёт команду [.filename]#faststop# запускаемым скриптам, чтобы они пропускали предварительные проверки, например, проверку pid-файла. Поскольку зависимые службы должны быть остановлены до своих зависимостей, [.filename]#/etc/rc.shutdown# запускает скрипты в обратном порядке зависимостей. Если вы пишете настоящий скрипт [.filename]#rc.d#, стоит подумать, актуален ли он во время завершения работы системы. Например, если ваш скрипт выполняет свою работу только в ответ на команду [.filename]#start#, то включать это ключевое слово не нужно. Однако если ваш скрипт управляет службой, вероятно, стоит остановить её до того, как система перейдёт к финальной стадии завершения работы, описанной в man:halt[8]. В частности, службу следует останавливать явно, если для её корректного завершения требуется значительное время или специальные действия. Типичный пример такой службы — система управления базами данных. ==== [[forcedep]]➎ Прежде всего, `force_depend` следует использовать с большой осторожностью. Обычно лучше пересмотреть иерархию конфигурационных переменных для ваших [.filename]#rc.d# скриптов, если они взаимозависимы. Если вам всё ещё не обойтись без `force_depend`, в примере показано, как вызвать его условно. В примере наш демон `mumbled` требует, чтобы другой демон, `frotz`, был запущен заранее. Однако `frotz` также является опциональным, и man:rcorder[8] ничего не знает о таких деталях. К счастью, наш скрипт имеет доступ ко всем переменным man:rc.conf[5]. Если `frotz_enable` имеет значение true, мы надеемся на лучшее и полагаемся на [.filename]#rc.d#, что `frotz` был запущен. В противном случае мы принудительно проверяем статус `frotz`. Наконец, мы принудительно устанавливаем зависимость от `frotz`, если обнаруживаем, что он не запущен. `force_depend` выдаст предупреждение, так как его следует вызывать только в случае обнаружения неправильной конфигурации. [[rcng-args]] == Придание большей гибкости скрипту rc.d При вызове во время запуска или завершения работы скрипт [.filename]#rc.d# должен воздействовать на всю подсистему, за которую он отвечает. Например, [.filename]#/etc/rc.d/netif# должен запускать или останавливать все сетевые интерфейсы, описанные в man:rc.conf[5]. Любая из этих задач может быть однозначно указана единственным аргументом команды, таким как `start` или `stop`. Между запуском и завершением работы скрипты [.filename]#rc.d# помогают администратору управлять работающей системой, и именно тогда возникает потребность в большей гибкости и точности. Например, администратор может добавить настройки нового сетевого интерфейса в man:rc.conf[5], а затем запустить его, не затрагивая работу существующих интерфейсов. В следующий раз администратору может потребоваться остановить отдельный сетевой интерфейс. В духе командной строки, соответствующий скрипт [.filename]#rc.d# требует дополнительного аргумента — имени интерфейса. К счастью, man:rc.subr[8] позволяет передавать любое количество аргументов (в пределах системных ограничений) методам скрипта. Благодаря этому изменения в самом скрипте могут быть минимальными. Как man:rc.subr[8] может получить доступ к дополнительным аргументам командной строки. Должен ли он просто захватывать их напрямую? Ни в коем случае. Во-первых, функция man:sh[1] не имеет доступа к позиционным параметрам своего вызывающего объекта, но man:rc.subr[8] — это просто набор таких функций. Во-вторых, хороший стиль [.filename]#rc.d# предписывает, что именно главный скрипт должен решать, какие аргументы передавать его методам. Итак, подход, принятый в man:rc.subr[8], следующий: `run_rc_command` передаёт все свои аргументы, кроме первого, в соответствующий метод в неизменном виде. Первый, опущенный аргумент — это имя самого метода: `start`, `stop` и т.д. Он будет удалён с помощью `shift` в `run_rc_command`, так что то, что было `$2` в оригинальной командной строке, будет представлено как `$1` в методе, и так далее. Чтобы проиллюстрировать эту возможность, давайте изменим примитивный скрипт-заглушку так, чтобы его сообщения зависели от дополнительных переданных аргументов. Вот как это выглядит: [.programlisting] .... #!/bin/sh . /etc/rc.subr name="dummy" start_cmd="${name}_start" stop_cmd=":" kiss_cmd="${name}_kiss" extra_commands="kiss" dummy_start() { if [ $# -gt 0 ]; then <.> echo "Greeting message: $*" else echo "Nothing started." fi } dummy_kiss() { echo -n "A ghost gives you a kiss" if [ $# -gt 0 ]; then <.> echo -n " and whispers: $*" fi case "$*" in *[.!?]) echo ;; *) echo . ;; esac } load_rc_config $name run_rc_command "$@" <.> .... Какие основные изменения мы можем заметить в скрипте? ➊ Все аргументы, которые вы вводите после `start`, могут стать позиционными параметрами для соответствующего метода. Мы можем использовать их любым способом в соответствии с нашей задачей, навыками и предпочтениями. В текущем примере мы просто передаем все их в man:echo[1] как одну строку в следующей строке — обратите внимание на `$*` в двойных кавычках. Вот как теперь можно вызывать этот скрипт: [source, shell] .... # /etc/rc.d/dummy start Nothing started. # /etc/rc.d/dummy start Hello world! Greeting message: Hello world! .... ➋ То же самое относится к любому методу, который предоставляет наш скрипт, не только к стандартному. Мы добавили пользовательский метод с именем `kiss`, и он может использовать дополнительные аргументы не меньше, чем `start`. Например: [source, shell] .... # /etc/rc.d/dummy kiss A ghost gives you a kiss. # /etc/rc.d/dummy kiss Once I was Etaoin Shrdlu... A ghost gives you a kiss and whispers: Once I was Etaoin Shrdlu... .... ➌ Если мы хотим просто передать все дополнительные аргументы любому методу, мы можем просто заменить `"$@"` на `"$1"` в последней строке нашего скрипта, где мы вызываем `run_rc_command`. [IMPORTANT] ==== Программист man:sh[1] должен понимать тонкую разницу между `$*` и `$@` как способами обозначения всех позиционных параметров. Для детального обсуждения обратитесь к хорошему руководству по написанию скриптов на man:sh[1]. _Не используйте_ эти выражения, пока полностью не поймёте их, так как их неправильное применение приведёт к созданию ненадёжных и небезопасных скриптов. ==== [NOTE] ==== В настоящее время в `run_rc_command` может присутствовать ошибка, которая мешает ему сохранять исходные границы между аргументами. То есть аргументы с встроенными пробелами могут обрабатываться некорректно. Ошибка возникает из-за неправильного использования `$*`. ==== [[rcng-service-jails]] == Подготовка скрипта для сервисных клеток Скрипты, запускающие долго работающую службу, подходят для служебных клеток и должны поставляться с соответствующей конфигурацией сервисной клетки. Некоторые примеры скриптов, которые не подходят для запуска в сервисной клетке: * любой скрипт, который в команде start только изменяет настройки времени выполнения для программ или ядра, * или пытается что-то смонтировать, * или находит и удаляет файлы Необходимо предотвратить использование внутри сервисных клеток скриптов, не предназначенных для запуска в сервисной клетке. Скрипт с долго работающей службой, которому необходимо выполнить одно из перечисленных выше действий перед запуском или после остановки, может быть разделён на два скрипта с зависимостями или использовать части `precommand` и `postcommand` скрипта для выполнения этого действия. По умолчанию только части `start` и `stop` скрипта выполняются внутри сервисной клетки, остальное выполняется вне клетки. Таким образом, любые настройки, используемые в частях `start`/`stop` скрипта, не могут быть заданы, например, из `precommand`. Чтобы сделать скрипт готовым к использованию с extref:{handbook}jails[Сервисными Клетками, service-jails], необходимо добавить всего лишь одну дополнительную конфигурационную строку: [.programlisting] .... #!/bin/sh . /etc/rc.subr name="dummy" start_cmd="${name}_start" stop_cmd=":" : ${dummy_svcj_options:=""} <.> dummy_start() { echo "Nothing started." } load_rc_config $name run_rc_command "$1" .... ➊ Если имеет смысл, чтобы скрипт выполнялся в клетке, он должен иметь переопределяемую конфигурацию сервисных клеток. Если ему не требуется доступ к сети или любым другим ресурсам, которые ограничены в клетках, достаточно пустой конфигурации, как показано. Строго говоря, пустая конфигурация не обязательна, но она явно указывает, что скрипт готов к работе с сервисными клетками и не требует дополнительных разрешений для клеток. Поэтому настоятельно рекомендуется добавить такую пустую конфигурацию в таком случае. Наиболее распространённая опция — "net_basic", которая позволяет использовать IPv4 и IPv6 адреса хоста. Все возможные опции описаны в man:rc.conf[5]. Если настройка запуска/остановки зависит от переменных из rc-фреймворка (например, заданных в man:rc.conf[5]), это должно обрабатываться с помощью ``load_rc_config`` и ``run_rc_command``, а не внутри precommand. Если по какой-то причине скрипт не может быть запущен внутри сервисной клетки, например, потому что его невозможно запустить или нет смысла запускать его в клетке, используйте следующее: [.programlisting] .... #!/bin/sh . /etc/rc.subr name="dummy" start_cmd="${name}_start" stop_cmd=":" dummy_start() { echo "Nothing started." } load_rc_config $name dummy_svcj="NO" # does not make sense to run in a svcj <.> run_rc_command "$1" .... ➊ Отключение должно происходить после вызова ``load_rc_config``, иначе параметр из man:rc.conf[5] может переопределить его. [[rcng-instancing]] == Продвинутые сценарии rc: запуск нескольких экземпляров Иногда полезно запускать несколько экземпляров службы. Обычно требуется иметь возможность независимо запускать/останавливать такие экземпляры, а также иметь отдельный файл конфигурации для каждого из них. Каждый экземпляр должен запускаться при загрузке, после обновления каждый экземпляр должен оставаться, и при этом должен обновиться. Вот пример rc-скрипта, который поддерживает это: [.programlisting] .... #!/bin/sh # # PROVIDE: dummy # REQUIRE: NETWORKING SERVERS # KEYWORD: shutdown # # Add these following line to /etc/rc.conf.local or /etc/rc.conf # to enable this service: # # dummy_enable (bool): Set it to YES to enable dummy on startup. # Default: NO # dummy_user (string): User account to run with. # Default: www # . /etc/rc.subr case $0 in <.> /etc/rc*) # during boot (shutdown) $0 is /etc/rc (/etc/rc.shutdown), # so get the name of the script from $_file name=$_file ;; *) name=$0 ;; esac name=${name##*/} <.> rcvar="${name}_enable" <.> desc="Short description of this service" command="/usr/local/sbin/dummy" load_rc_config "$name" eval "${rcvar}=\${${rcvar}:-'NO'}" <.> eval "${name}_svcj_options=\${${name}_svcj_options:-'net_basic'}" <.> eval "_dummy_user=\${${name}_user:-'www'}" <.> _dummy_configname=/usr/local/etc/${name}.cfg <.> pidfile=/var/run/dummy/${name}.pid required_files ${_dummy_configname} command_args="-u ${_dummy_user} -c ${_dummy_configfile} -p ${pidfile}" run_rc_command "$1" .... ➊ и ➋ убедитесь, что переменная name установлена в значение man:basename[1] имени скрипта. Если имя файла — [.filename]#/usr/local/etc/rc.d/dummy#, то name будет установлено в [.filename]#dummy#. Таким образом, изменение имени rc-скрипта автоматически изменит содержимое переменной name. ➌ указывает имя переменной, которая используется в [.filename]#rc.conf# для включения этой службы на основе имени файла этого скрипта. В данном примере это преобразуется в dummy_enable. ➍ убеждается, что значение по умолчанию для переменной _enable установлено в NO. ➎ Вот пример установки некоторых значений по умолчанию для переменных фреймворка, специфичных для службы, в данном случае — опций клетки службы. ➏ и ➐ устанавливают переменные, внутренние для скрипта (обратите внимание на подчёркивание в начале _dummy_user, чтобы отличать её от dummy_user, которая может быть задана в [.filename]#rc.conf#). Часть в ➎ предназначена для переменных, которые не используются внутри самого скрипта, но используются в рамках rc. Все переменные, которые используются как параметры в скрипте, присваиваются общей переменной, как в ➐, чтобы упростить их использование (нет необходимости выполнять eval при каждом обращении). Этот скрипт теперь будет вести себя по-другому, если скрипт запуска имеет другое имя. Это позволяет создавать символьные ссылки на него: [source, shell] .... # ln -s dummy /usr/local/etc/rc.d/dummy_foo # sysrc dummy_foo_enable=YES # service dummy_foo start .... -Вышеприведённое создает экземпляр службы dummy с именем dummy_foo. Он использует не файл конфигурации [.filename]#/usr/local/etc/dummy.cfg#, а файл конфигурации [.filename]#/usr/local/etc/dummy_foo.cfg# (➐), и использует PID-файл [.filename]#/var/run/dummy/dummy_foo.pid# вместо [.filename]#/var/run/dummy/dummy.pid#. +Вышеприведённое создаёт экземпляр службы dummy с именем dummy_foo. Он использует не файл конфигурации [.filename]#/usr/local/etc/dummy.cfg#, а файл конфигурации [.filename]#/usr/local/etc/dummy_foo.cfg# (➐), и использует PID-файл [.filename]#/var/run/dummy/dummy_foo.pid# вместо [.filename]#/var/run/dummy/dummy.pid#. Сервисы dummy и dummy_foo могут управляться независимо друг от друга, при этом скрипт запуска обновляется автоматически при обновлении пакета (благодаря символьной ссылке). Это не обновляет строку REQUIRE, поэтому нет простого способа зависеть от конкретного экземпляра. Чтобы зависеть от конкретного экземпляра в порядке запуска, необходимо создать копию вместо использования символьной ссылки. Это предотвращает автоматическое применение изменений в скрипте запуска при установке обновления. [[rcng-furthur]] == Дополнительная литература [[lukem]]http://www.mewburn.net/luke/papers/rc.d.pdf[Оригинальная статья Люка Мьюберна] предлагает общий обзор [.filename]#rc.d# и подробное обоснование принятых при его проектировании решений. В ней представлено понимание всего фреймворка [.filename]#rc.d# и его места в современной BSD-системе. [[manpages]]Руководства man:rc[8], man:rc.subr[8] и man:rcorder[8] подробно описывают компоненты [.filename]#rc.d#. Без изучения этих руководств и обращения к ним при написании собственных скриптов невозможно в полной мере использовать возможности [.filename]#rc.d#. Основным источником рабочих, жизненных примеров является [.filename]#/etc/rc.d# в работающей системе. Его содержимое легко и приятно читать, поскольку большинство сложных моментов скрыто глубоко в man:rc.subr[8]. Однако помните, что скрипты в [.filename]#/etc/rc.d# были написаны не ангелами, поэтому они могут содержать ошибки и неоптимальные решения. Теперь вы можете их улучшить! diff --git a/documentation/content/ru/articles/rc-scripting/_index.po b/documentation/content/ru/articles/rc-scripting/_index.po index 0eeb313a8b..4986e76dd3 100644 --- a/documentation/content/ru/articles/rc-scripting/_index.po +++ b/documentation/content/ru/articles/rc-scripting/_index.po @@ -1,2766 +1,2766 @@ # SOME DESCRIPTIVE TITLE # Copyright (C) YEAR The FreeBSD Project # This file is distributed under the same license as the FreeBSD Documentation package. # Vladlen Popolitov , 2025, 2026. msgid "" msgstr "" "Project-Id-Version: FreeBSD Documentation VERSION\n" "POT-Creation-Date: 2025-11-08 16:17+0000\n" -"PO-Revision-Date: 2026-03-08 09:11+0000\n" +"PO-Revision-Date: 2026-04-05 04:45+0000\n" "Last-Translator: Vladlen Popolitov \n" "Language-Team: Russian \n" "Language: ru\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && " "n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" "X-Generator: Weblate 4.17\n" #. type: YAML Front Matter: description #: documentation/content/en/articles/rc-scripting/_index.adoc:1 #, no-wrap msgid "A guide to writing new rc.d scripts and understanding those already written" msgstr "Руководство по написанию новых rc.d-скриптов и пониманию уже существующих" #. type: Title = #: documentation/content/en/articles/rc-scripting/_index.adoc:1 #: documentation/content/en/articles/rc-scripting/_index.adoc:12 #, no-wrap msgid "Practical rc.d scripting in BSD" msgstr "Практическое руководство по написанию rc.d скриптов в BSD" #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:45 msgid "Abstract" msgstr "Аннотация" #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:49 msgid "" "Beginners may find it difficult to relate the facts from the formal " "documentation on the BSD [.filename]#rc.d# framework with the practical " "tasks of [.filename]#rc.d# scripting. In this article, we consider a few " "typical cases of increasing complexity, show [.filename]#rc.d# features " "suited for each case, and discuss how they work. Such an examination should " "provide reference points for further study of the design and efficient " "application of [.filename]#rc.d#." msgstr "" "Новичкам может быть сложно соотнести факты из официальной документации по " "фреймворку [.filename]#rc.d# в BSD с практическими задачами написания " "скриптов для [.filename]#rc.d#. В этой статье мы рассмотрим несколько " "типичных случаев возрастающей сложности, покажем возможности [.filename]#rc." "d#, подходящие для каждого случая, и обсудим, как они работают. Такое " "рассмотрение должно дать ориентиры для дальнейшего изучения устройства и " "эффективного применения [.filename]#rc.d#." #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:51 msgid "'''" msgstr "'''" #. type: Title == #: documentation/content/en/articles/rc-scripting/_index.adoc:55 #, no-wrap msgid "Introduction" msgstr "Введение" #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:61 msgid "" "The historical BSD had a monolithic startup script, [.filename]#/etc/rc#. " "It was invoked by man:init[8] at system boot time and performed all userland " "tasks required for multi-user operation: checking and mounting file systems, " "setting up the network, starting daemons, and so on. The precise list of " "tasks was not the same in every system; admins needed to customize it. With " "few exceptions, [.filename]#/etc/rc# had to be modified, and true hackers " "liked it." msgstr "" "Исторически в BSD был монолитный стартовый сценарий [.filename]#/etc/rc#. Он " "вызывался man:init[8] во время загрузки системы и выполнял все задачи " "пользовательского пространства, необходимые для многопользовательского " "режима: проверку и монтирование файловых систем, настройку сети, запуск " "демонов и так далее. Точный список задач не был одинаковым в каждой системе; " "администраторам требовалось его настраивать. За редкими исключениями, [." "filename]#/etc/rc# приходилось изменять, и настоящим хакерам это нравилось." #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:67 msgid "" "The real problem with the monolithic approach was that it provided no " "control over the individual components started from [.filename]#/etc/rc#. " "For instance, [.filename]#/etc/rc# could not restart a single daemon. The " "system admin had to find the daemon process by hand, kill it, wait until it " "actually exited, then browse through [.filename]#/etc/rc# for the flags, and " "finally type the full command line to start the daemon again. The task " "would become even more difficult and prone to errors if the service to " "restart consisted of more than one daemon or demanded additional actions. " "In a few words, the single script failed to fulfil what scripts are for: to " "make the system admin's life easier." msgstr "" "Основная проблема монолитного подхода заключалась в том, что он не " "предоставлял контроля над отдельными компонентами, запускаемыми из [." "filename]#/etc/rc#. Например, [.filename]#/etc/rc# не мог перезапустить " "отдельный демон. Администратору системы приходилось вручную находить процесс " "демона, завершать его, ждать, пока он действительно завершится, затем искать " "в [.filename]#/etc/rc# нужные флаги и, наконец, вводить полную командную " "строку для повторного запуска демона. Задача становилась ещё сложнее и более " "подверженной ошибкам, если служба состояла из нескольких демонов или " "требовала дополнительных действий. Одним словом, единый скрипт не справлялся " "с тем, для чего скрипты вообще предназначены: облегчать жизнь администратору " "системы." #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:74 msgid "" "Later there was an attempt to split out some parts of [.filename]#/etc/rc# " "for the sake of starting the most important subsystems separately. The " "notorious example was [.filename]#/etc/netstart# to bring up networking. It " "did allow for accessing the network from single-user mode, but it did not " "integrate well into the automatic startup process because parts of its code " "needed to interleave with actions essentially unrelated to networking. That " "was why [.filename]#/etc/netstart# mutated into [.filename]#/etc/rc." "network#. The latter was no longer an ordinary script; it comprised of " "large, tangled man:sh[1] functions called from [.filename]#/etc/rc# at " "different stages of system startup. However, as the startup tasks grew " "diverse and sophisticated, the \"quasi-modular\" approach became even more " "of a drag than the monolithic [.filename]#/etc/rc# had been." msgstr "" "Позже была предпринята попытка разделить некоторые части [.filename]#/etc/" "rc# для возможности отдельного запуска наиболее важных подсистем. Известным " "примером стал [.filename]#/etc/netstart#, предназначенный для настройки " "сети. Это позволяло получить доступ к сети в однопользовательском режиме, но " "плохо интегрировалось в автоматический процесс запуска, так как части его " "кода требовалось переплетаться с действиями, по сути не связанными с сетью. " "Именно поэтому [.filename]#/etc/netstart# превратился в [.filename]#/etc/rc." "network#. Последний больше не был обычным скриптом; он состоял из больших, " "запутанных функций man:sh[1], вызываемых из [.filename]#/etc/rc# на разных " "этапах загрузки системы. Однако по мере того, как задачи при запуске " "становились разнообразнее и сложнее, \"квазимодульный\" подход стал ещё " "большей обузой, чем монолитный [.filename]#/etc/rc#." #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:82 msgid "" "Without a clean and well-designed framework, the startup scripts had to bend " "over backwards to satisfy the needs of rapidly developing BSD-based " "operating systems. It became obvious at last that more steps are necessary " "on the way to a fine-grained and extensible [.filename]#rc# system. Thus " "BSD [.filename]#rc.d# was born. Its acknowledged fathers were Luke Mewburn " "and the NetBSD community. Later it was imported into FreeBSD. Its name " "refers to the location of system scripts for individual services, which is " "in [.filename]#/etc/rc.d#. Soon we will learn about more components of the " "[.filename]#rc.d# system and see how the individual scripts are invoked." msgstr "" "Без чистого и хорошо продуманного каркаса, стартовые скрипты вынуждены были " "идти на всевозможные ухищрения, чтобы удовлетворить потребности быстро " "развивающихся BSD-ориентированных операционных систем. В конце концов стало " "очевидно, что необходимы дополнительные шаги на пути к детализированной и " "расширяемой системе [.filename]#rc#. Так появилась BSD [.filename]#rc.d#. Её " "признанными создателями стали Люк Мьюберн и сообщество NetBSD. Позже она " "была импортирована в FreeBSD. Её название отсылает к расположению системных " "скриптов для отдельных служб, которое находится в [.filename]#/etc/rc.d#. " "Вскоре мы узнаем больше о компонентах системы [.filename]#rc.d# и увидим, " "как вызываются отдельные скрипты." #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:93 msgid "" "The basic ideas behind BSD [.filename]#rc.d# are _fine modularity_ and " "__code reuse__. _Fine modularity_ means that each basic \"service\" such as " "a system daemon or primitive startup task gets its own man:sh[1] script able " "to start the service, stop it, reload it, check its status. A particular " "action is chosen by the command-line argument to the script. The [." "filename]#/etc/rc# script still drives system startup, but now it merely " "invokes the smaller scripts one by one with the `start` argument. It is " "easy to perform shutdown tasks as well by running the same set of scripts " "with the `stop` argument, which is done by [.filename]#/etc/rc.shutdown#. " "Note how closely this follows the Unix way of having a set of small " "specialized tools, each fulfilling its task as well as possible. _Code " "reuse_ means that common operations are implemented as man:sh[1] functions " "and collected in [.filename]#/etc/rc.subr#. Now a typical script can be " "just a few lines' worth of man:sh[1] code. Finally, an important part of " "the [.filename]#rc.d# framework is man:rcorder[8], which helps [.filename]#/" "etc/rc# to run the small scripts orderly with respect to dependencies " "between them. It can help [.filename]#/etc/rc.shutdown#, too, because the " "proper order for the shutdown sequence is opposite to that of startup." msgstr "" "Основные идеи, лежащие в основе BSD [.filename]#rc.d#, — это _тонкая " "модульность_ и __повторное использование кода__. _Тонкая модульность_ " "означает, что каждая базовая «служба», такая как системный демон или " "примитивная задача запуска, получает собственный сценарий man:sh[1], " "способный запустить службу, остановить её, перезагрузить или проверить её " "состояние. Конкретное действие выбирается аргументом командной строки, " "переданным в сценарий. Сценарий [.filename]#/etc/rc# по-прежнему управляет " "запуском системы, но теперь он просто вызывает небольшие сценарии один за " "другим с аргументом `start`. Также легко выполнять задачи завершения работы, " "запуская тот же набор сценариев с аргументом `stop`, что и делает [." "filename]#/etc/rc.shutdown#. Обратите внимание, насколько это близко следует " "Unix-подходу, где используется набор небольших специализированных " "инструментов, каждый из которых выполняет свою задачу наилучшим образом. " "_Повторное использование кода_ означает, что общие операции реализованы как " "функции man:sh[1] и собраны в [.filename]#/etc/rc.subr#. Теперь типичный " "сценарий может состоять всего из нескольких строк кода man:sh[1]. Наконец, " "важной частью инфраструктуры [.filename]#rc.d# является man:rcorder[8], " "который помогает [.filename]#/etc/rc# упорядоченно запускать небольшие " "сценарии с учётом зависимостей между ними. Он также может помочь [." "filename]#/etc/rc.shutdown#, поскольку правильный порядок завершения работы " "противоположен порядку запуска." #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:101 msgid "" "The BSD [.filename]#rc.d# design is described in crossref:rc-" "scripting[lukem, the original article by Luke Mewburn], and the [." "filename]#rc.d# components are documented in great detail in crossref:rc-" "scripting[manpages, the respective manual pages]. However, it might not " "appear obvious to an [.filename]#rc.d# newbie how to tie the numerous bits " "and pieces together to create a well-styled script for a particular task. " "Therefore this article will try a different approach to describe [." "filename]#rc.d#. It will show which features should be used in a number of " "typical cases, and why. Note that this is not a how-to document because our " "aim is not at giving ready-made recipes, but at showing a few easy entrances " "into the [.filename]#rc.d# realm. Neither is this article a replacement for " "the relevant manual pages. Do not hesitate to refer to them for more formal " "and complete documentation while reading this article." msgstr "" "Дизайн BSD [.filename]#rc.d# описан в crossref:rc-scripting[lukem, " "оригинальной статье Люка Мьюберна], а компоненты [.filename]#rc.d# подробно " "документированы в crossref:rc-scripting[manpages, соответствующих страницах " "Справочника]. Однако новичку в [.filename]#rc.d# может быть неочевидно, как " "связать многочисленные элементы вместе, чтобы создать хорошо " "структурированный скрипт для конкретной задачи. Поэтому в этой статье будет " "предпринята попытка описать [.filename]#rc.d# с другого ракурса. В ней будет " "показано, какие функции следует использовать в ряде типичных случаев и " "почему. Обратите внимание, что это не руководство HowTo, поскольку наша цель " "— не предоставление готовых рецептов, а демонстрация нескольких простых " "способов входа в мир [.filename]#rc.d#. Также эта статья не заменяет " -"соответствующие страниц Справочника. Не стесняйтесь обращаться к ним для " +"соответствующие страницы Справочника. Не стесняйтесь обращаться к ним для " "получения более формальной и полной документации во время чтения этой статьи." #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:105 msgid "" "There are prerequisites to understanding this article. First of all, you " "should be familiar with the man:sh[1] scripting language to master [." "filename]#rc.d#. In addition, you should know how the system performs " "userland startup and shutdown tasks, which is described in man:rc[8]." msgstr "" "Для понимания этой статьи есть предварительные требования. Прежде всего, вы " "должны быть знакомы с языком написания сценариев man:sh[1], чтобы освоить [." "filename]#rc.d#. Кроме того, вы должны знать, как система выполняет задачи " "запуска и завершения работы пользовательского пространства, что описано в " "man:rc[8]." #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:108 msgid "" "This article focuses on the FreeBSD branch of [.filename]#rc.d#. " "Nevertheless, it may be useful to NetBSD developers, too, because the two " "branches of BSD [.filename]#rc.d# not only share the same design but also " "stay similar in their aspects visible to script authors." msgstr "" "Эта статья посвящена ветке FreeBSD в [.filename]#rc.d#. Тем не менее, она " "может быть полезна и разработчикам NetBSD, потому что две ветки BSD [." "filename]#rc.d# не только разделяют одинаковый дизайн, но и остаются схожими " "в аспектах, видимых авторам скриптов." #. type: Title == #: documentation/content/en/articles/rc-scripting/_index.adoc:110 #, no-wrap msgid "Outlining the task" msgstr "Обрисовка задачи" #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:114 msgid "" "A little consideration before starting `$EDITOR` will not hurt. To write a " "well-tempered [.filename]#rc.d# script for a system service, we should be " "able to answer the following questions first:" msgstr "" "Немного размышлений перед запуском `$EDITOR` не повредит. Чтобы написать " "хорошо продуманный скрипт [.filename]#rc.d# для системной службы, сначала " "нужно ответить на следующие вопросы:" #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:116 msgid "Is the service mandatory or optional?" msgstr "Является ли служба обязательной или опциональной?" #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:117 msgid "" "Will the script serve a single program, e.g., a daemon, or perform more " "complex actions?" msgstr "" "Будет ли скрипт обслуживать одну программу, например, демон, или выполнять " "более сложные действия?" #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:118 msgid "Which other services will our service depend on, and vice versa?" msgstr "От каких других служб зависит наша служба, и наоборот?" #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:120 msgid "" "From the examples that follow we will see why it is important to know the " "answers to these questions." msgstr "" "Из следующих примеров мы увидим, почему важно знать ответы на эти вопросы." #. type: Title == #: documentation/content/en/articles/rc-scripting/_index.adoc:122 #, no-wrap msgid "A dummy script" msgstr "Примитивный скрипт" #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:125 msgid "" "The following script just emits a message each time the system boots up:" msgstr "" "Следующий скрипт просто выводит сообщение каждый раз при загрузке системы:" #. type: delimited block . 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:129 #, no-wrap msgid "#!/bin/sh <.>\n" msgstr "#!/bin/sh <.>\n" #. type: delimited block . 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:131 #, no-wrap msgid ". /etc/rc.subr <.>\n" msgstr ". /etc/rc.subr <.>\n" #. type: delimited block . 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:135 #, no-wrap msgid "" "name=\"dummy\" <.>\n" "start_cmd=\"${name}_start\" <.>\n" "stop_cmd=\":\" <.>\n" msgstr "" "name=\"dummy\" <.>\n" "start_cmd=\"${name}_start\" <.>\n" "stop_cmd=\":\" <.>\n" #. type: delimited block . 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:140 #, no-wrap msgid "" "dummy_start() <.>\n" "{\n" "\techo \"Nothing started.\"\n" "}\n" msgstr "" "dummy_start() <.>\n" "{\n" "\techo \"Nothing started.\"\n" "}\n" #. type: delimited block . 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:143 #, no-wrap msgid "" "load_rc_config $name <.>\n" "run_rc_command \"$1\" <.>\n" msgstr "" "load_rc_config $name <.>\n" "run_rc_command \"$1\" <.>\n" #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:146 msgid "Things to note are:" msgstr "Вот что следует учитывать:" #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:152 msgid "" "➊ An interpreted script should begin with the magic \"shebang\" " "line. That line specifies the interpreter program for the script. Due to " "the shebang line, the script can be invoked exactly like a binary program " "provided that it has the execute bit set. (See man:chmod[1].) For example, " "a system admin can run our script manually, from the command line:" msgstr "" "➊ Интерпретируемый скрипт должен начинаться с \"волшебной\" строки " "shebang. Эта строка указывает программу-интерпретатор для скрипта. Благодаря " "строке shebang скрипт может быть запущен точно так же, как бинарная " "программа, при условии что у него установлен бит выполнения. (См. man:" "chmod[1].) Например, системный администратор может запустить наш скрипт " "вручную из командной строки:" #. type: delimited block . 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:156 #, no-wrap msgid "# /etc/rc.d/dummy start\n" msgstr "# /etc/rc.d/dummy start\n" #. type: delimited block = 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:162 msgid "" "To be properly managed by the [.filename]#rc.d# framework, its scripts need " "to be written in the man:sh[1] language. If you have a service or port that " "uses a binary control utility or a startup routine written in another " "language, install that element in [.filename]#/usr/sbin# (for the system) or " "[.filename]#/usr/local/sbin# (for ports) and call it from a man:sh[1] script " "in the appropriate [.filename]#rc.d# directory." msgstr "" "Для корректного управления в рамках [.filename]#rc.d# скрипты должны быть " "написаны на языке man:sh[1]. Если у вас есть служба или порт, который " "использует двоичную утилиту управления или процедуру запуска, написанную на " "другом языке, установите этот компонент в [.filename]#/usr/sbin# (для " "системы) или [.filename]#/usr/local/sbin# (для портов) и вызовите его из man:" "sh[1] скрипта в соответствующем каталоге [.filename]#rc.d#." #. type: delimited block = 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:167 msgid "" "If you would like to learn the details of why [.filename]#rc.d# scripts must " "be written in the man:sh[1] language, see how [.filename]#/etc/rc# invokes " "them by means of `run_rc_script`, then study the implementation of " "`run_rc_script` in [.filename]#/etc/rc.subr#." msgstr "" "Если вы хотите узнать подробности о том, почему скрипты [.filename]#rc.d# " "должны быть написаны на языке man:sh[1], изучите, как [.filename]#/etc/rc# " "вызывает их с помощью `run_rc_script`, а затем изучите реализацию " "`run_rc_script` в [.filename]#/etc/rc.subr#." #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:173 msgid "" "➋ In [.filename]#/etc/rc.subr#, a number of man:sh[1] functions are " "defined for an [.filename]#rc.d# script to use. The functions are " "documented in man:rc.subr[8]. While it is theoretically possible to write " "an [.filename]#rc.d# script without ever using man:rc.subr[8], its functions " "prove extremely handy and make the job an order of magnitude easier. So it " "is no surprise that everybody resorts to man:rc.subr[8] in [.filename]#rc.d# " "scripts. We are not going to be an exception." msgstr "" "➋ В файле [.filename]#/etc/rc.subr# определено несколько функций man:" "sh[1], которые могут использоваться скриптами [.filename]#rc.d#. Эти функции " "описаны в man:rc.subr[8]. Хотя теоретически возможно написать скрипт [." "filename]#rc.d# без использования man:rc.subr[8], его функции оказываются " "чрезвычайно полезными и значительно упрощают задачу. Поэтому неудивительно, " "что все используют man:rc.subr[8] в скриптах [.filename]#rc.d#. Мы не будем " "исключением." #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:176 msgid "" "An [.filename]#rc.d# script must \"source\"[.filename]#/etc/rc.subr# " "(include it using \"`.`\") _before_ it calls man:rc.subr[8] functions so " "that man:sh[1] has an opportunity to learn the functions. The preferred " "style is to source [.filename]#/etc/rc.subr# first of all." msgstr "" "Файл [.filename]#rc.d# должен \"подгрузить\" ([.filename]#/etc/rc.subr#, " "включить его с помощью \"`.`\") _до_ вызова функций man:rc.subr[8], чтобы у " "man:sh[1] была возможность знать об этих функциях заранее. Предпочтительный " "стиль — подгружать [.filename]#/etc/rc.subr# в самом начале." #. type: delimited block = 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:180 msgid "" "Some useful functions related to networking are provided by another include " "file, [.filename]#/etc/network.subr#." msgstr "" "Некоторые полезные функции, связанные с сетью, предоставляются другим " "включаемым файлом — [.filename]#/etc/network.subr#." #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:185 msgid "" "➌ [[name-var]]The mandatory variable `name` specifies the name of our " "script. It is required by man:rc.subr[8]. That is, each [.filename]#rc.d# " "script _must_ set `name` before it calls man:rc.subr[8] functions." msgstr "" "➌ [[name-var]]Обязательная переменная `name` определяет имя нашего " "скрипта. Она требуется man:rc.subr[8]. То есть, каждый скрипт в [." "filename]#rc.d# _должен_ установить `name` перед вызовом функций man:rc." "subr[8]." #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:191 msgid "" "Now it is the right time to choose a unique name for our script once and for " "all. We will use it in a number of places while developing the script. The " "content of the name variable needs to match the script name, some parts of " "FreeBSD (e.g., crossref:rc-scripting[rcng-service-jails, service jails] and " "the cpuset feature of the rc framework) depend upon this. As such the " "filename shall also not contain characters which may be troublesome in " "scripting (e.g., do not use a hyphen \"-\" and others)." msgstr "" "Теперь самое время раз и навсегда выбрать уникальное имя для нашего скрипта. " "Мы будем использовать его в нескольких местах при разработке скрипта. " "Содержимое переменной name должно соответствовать имени скрипта, так как " "некоторые части FreeBSD (например, crossref:rc-scripting[rcng-service-jails, " "сервисные клетки (jail)] и функция cpuset в rc framework) зависят от этого. " "Таким образом, имя файла также не должно содержать символов, которые могут " "вызвать проблемы в скриптах (например, не используйте дефис \"-\" и другие)." #. type: delimited block = 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:198 msgid "" "The current style of [.filename]#rc.d# scripting is to enclose values " "assigned to variables in double quotes. Keep in mind that it is just a " "style issue that may not always be applicable. You can safely omit quotes " "from around simple words without man:sh[1] metacharacters in them, while in " "certain cases you will need single quotes to prevent any interpretation of " "the value by man:sh[1]. A programmer should be able to tell the language " "syntax from style conventions and use both of them wisely." msgstr "" "Текущий стиль написания скриптов в [.filename]#rc.d# заключается в " "заключении значений, присваиваемых переменным, в двойные кавычки. Имейте в " "виду, что это всего лишь вопрос стиля, который может быть не всегда " "применим. Вы можете безопасно опустить кавычки вокруг простых слов без " "метасимволов man:sh[1], тогда как в некоторых случаях вам понадобятся " "одинарные кавычки, чтобы предотвратить интерпретацию значения man:sh[1]. " "Программист должен уметь отличать синтаксис языка от стилевых соглашений и " "разумно использовать и то, и другое." #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:204 msgid "" "➍ The main idea behind man:rc.subr[8] is that an [.filename]#rc.d# " "script provides handlers, or methods, for man:rc.subr[8] to invoke. In " "particular, `start`, `stop`, and other arguments to an [.filename]#rc.d# " "script are handled this way. A method is a man:sh[1] expression stored in a " "variable named `argument_cmd`, where _argument_ corresponds to what can be " "specified on the script's command line. We will see later how man:rc." "subr[8] provides default methods for the standard arguments." msgstr "" "➍ Основная идея man:rc.subr[8] заключается в том, что скрипт [." "filename]#rc.d# предоставляет обработчики (или методы) для вызова man:rc." "subr[8]. В частности, аргументы `start`, `stop` и другие, передаваемые в " "скрипт [.filename]#rc.d#, обрабатываются таким образом. Метод представляет " "собой выражение man:sh[1], сохранённое в переменной с именем `argument_cmd`, " "где _argument_ соответствует тому, что может быть указано в командной строке " "скрипта. Далее мы увидим, как man:rc.subr[8] предоставляет стандартные " "методы для типовых аргументов." #. type: delimited block = 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:209 msgid "" "To make the code in [.filename]#rc.d# more uniform, it is common to use `" "${name}` wherever appropriate. Thus a number of lines can be just copied " "from one script to another." msgstr "" "Чтобы сделать код в [.filename]#rc.d# более единообразным, обычно используют " "`${name}` везде, где это уместно. Таким образом, множество строк можно " "просто копировать из одного скрипта в другой." #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:213 msgid "" "➎ We should keep in mind that man:rc.subr[8] provides default methods " "for the standard arguments. Consequently, we must override a standard " "method with a no-op man:sh[1] expression if we want it to do nothing." msgstr "" "➎ Следует помнить, что man:rc.subr[8] предоставляет методы по " "умолчанию для стандартных аргументов. Следовательно, если мы хотим, чтобы " "стандартный метод ничего не делал, мы должны переопределить его с помощью no-" "op man:sh[1] выражения." #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:216 msgid "" "➏ The body of a sophisticated method can be implemented as a " "function. It is a good idea to make the function name meaningful." msgstr "" "➏ Тело сложного метода может быть реализовано в виде функции. Хорошей " "практикой является использование осмысленного имени функции." #. type: delimited block = 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:220 msgid "" "It is strongly recommended to add the prefix `${name}` to the names of all " "functions defined in our script so they never clash with the functions from " "man:rc.subr[8] or another common include file." msgstr "" "Настоятельно рекомендуется добавлять префикс `${name}` к именам всех " "функций, определённых в нашем скрипте, чтобы они никогда не конфликтовали с " "функциями из man:rc.subr[8] или другого общего включаемого файла." #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:224 msgid "" "➐ This call to man:rc.subr[8] loads man:rc.conf[5] variables. Our " "script makes no use of them yet, but it still is recommended to load man:rc." "conf[5] because there can be man:rc.conf[5] variables controlling man:rc." "subr[8] itself." msgstr "" "➐ Этот вызов man:rc.subr[8] загружает переменные man:rc.conf[5]. Наш " "скрипт пока их не использует, но всё равно рекомендуется загружать man:rc." "conf[5], потому что могут быть переменные man:rc.conf[5], управляющие самим " "man:rc.subr[8]." #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:227 msgid "" "➑ Usually this is the last command in an [.filename]#rc.d# script. " "It invokes the man:rc.subr[8] machinery to perform the requested action " "using the variables and methods our script has provided." msgstr "" "➑ Обычно это последняя команда в скрипте [.filename]#rc.d#. Она " "вызывает механизм man:rc.subr[8] для выполнения запрошенного действия, " "используя переменные и методы, предоставленные нашим скриптом." #. type: Title == #: documentation/content/en/articles/rc-scripting/_index.adoc:229 #, no-wrap msgid "A configurable dummy script" msgstr "Настраиваемый фиктивный скрипт" #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:239 msgid "" "Now let us add some controls to our dummy script. As you may know, [." "filename]#rc.d# scripts are controlled with man:rc.conf[5]. Fortunately, " "man:rc.subr[8] hides all the complications from us. The following script " "uses man:rc.conf[5] via man:rc.subr[8] to see whether it is enabled in the " "first place, and to fetch a message to show at boot time. These two tasks " "in fact are independent. On the one hand, an [.filename]#rc.d# script can " "just support enabling and disabling its service. On the other hand, a " "mandatory [.filename]#rc.d# script can have configuration variables. We " "will do both things in the same script though:" msgstr "" "Теперь добавим некоторые элементы управления в наш тестовый скрипт. Как вам " "может быть известно, скрипты [.filename]#rc.d# управляются с помощью man:rc." "conf[5]. К счастью, man:rc.subr[8] скрывает от нас все сложности. Следующий " "скрипт использует man:rc.conf[5] через man:rc.subr[8], чтобы проверить, " "включен ли он вообще, и получить сообщение для отображения во время " "загрузки. Эти две задачи на самом деле независимы. С одной стороны, скрипт [." "filename]#rc.d# может просто поддерживать включение и выключение своего " "сервиса. С другой стороны, обязательный скрипт [.filename]#rc.d# может иметь " "переменные конфигурации. Однако мы реализуем обе возможности в одном скрипте:" #. type: delimited block . 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:243 #: documentation/content/en/articles/rc-scripting/_index.adoc:334 #: documentation/content/en/articles/rc-scripting/_index.adoc:392 #: documentation/content/en/articles/rc-scripting/_index.adoc:624 #: documentation/content/en/articles/rc-scripting/_index.adoc:755 #: documentation/content/en/articles/rc-scripting/_index.adoc:860 #: documentation/content/en/articles/rc-scripting/_index.adoc:893 #: documentation/content/en/articles/rc-scripting/_index.adoc:927 #, no-wrap msgid "#!/bin/sh\n" msgstr "#!/bin/sh\n" #. type: delimited block . 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:245 #: documentation/content/en/articles/rc-scripting/_index.adoc:336 #: documentation/content/en/articles/rc-scripting/_index.adoc:394 #: documentation/content/en/articles/rc-scripting/_index.adoc:631 #: documentation/content/en/articles/rc-scripting/_index.adoc:757 #: documentation/content/en/articles/rc-scripting/_index.adoc:862 #: documentation/content/en/articles/rc-scripting/_index.adoc:895 #: documentation/content/en/articles/rc-scripting/_index.adoc:943 #, no-wrap msgid ". /etc/rc.subr\n" msgstr ". /etc/rc.subr\n" #. type: delimited block . 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:248 #, no-wrap msgid "" "name=dummy\n" "rcvar=dummy_enable <.>\n" msgstr "" "name=dummy\n" "rcvar=dummy_enable <.>\n" #. type: delimited block . 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:251 #, no-wrap msgid "" "start_cmd=\"${name}_start\"\n" "stop_cmd=\":\"\n" msgstr "" "start_cmd=\"${name}_start\"\n" "stop_cmd=\":\"\n" #. type: delimited block . 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:255 #, no-wrap msgid "" "load_rc_config $name <.>\n" ": ${dummy_enable:=no} <.>\n" ": ${dummy_msg=\"Nothing started.\"} <.>\n" msgstr "" "load_rc_config $name <.>\n" ": ${dummy_enable:=no} <.>\n" ": ${dummy_msg=\"Nothing started.\"} <.>\n" #. type: delimited block . 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:260 #, no-wrap msgid "" "dummy_start()\n" "{\n" "\techo \"$dummy_msg\" <.>\n" "}\n" msgstr "" "dummy_start()\n" "{\n" "\techo \"$dummy_msg\" <.>\n" "}\n" #. type: delimited block . 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:262 #: documentation/content/en/articles/rc-scripting/_index.adoc:972 #, no-wrap msgid "run_rc_command \"$1\"\n" msgstr "run_rc_command \"$1\"\n" #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:265 msgid "What changed in this example?" msgstr "Что изменилось в этом примере?" #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:267 msgid "" "➊ The variable `rcvar` specifies the name of the ON/OFF knob variable." msgstr "" "➊ Переменная `rcvar` определяет имя переменной-переключателя ON/OFF." #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:269 msgid "" "➋ Now `load_rc_config` is invoked earlier in the script, before any " "man:rc.conf[5] variables are accessed." msgstr "" "➋ Теперь `load_rc_config` вызывается раньше в скрипте, до обращения к " "любым переменным man:rc.conf[5]." #. type: delimited block = 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:275 msgid "" "While examining [.filename]#rc.d# scripts, keep in mind that man:sh[1] " "defers the evaluation of expressions in a function until the latter is " "called. Therefore it is not an error to invoke `load_rc_config` as late as " "just before `run_rc_command` and still access man:rc.conf[5] variables from " "the method functions exported to `run_rc_command`. This is because the " "method functions are to be called by `run_rc_command`, which is invoked " "_after_ `load_rc_config`." msgstr "" "При изучении скриптов в [.filename]#rc.d# следует помнить, что man:sh[1] " "откладывает вычисление выражений в функции до её вызова. Поэтому не будет " "ошибкой вызвать `load_rc_config` непосредственно перед `run_rc_command` и " "при этом обращаться к переменным man:rc.conf[5] из функций методов, " "экспортируемых в `run_rc_command`. Это связано с тем, что функции методов " "вызываются `run_rc_command`, который выполняется _после_ `load_rc_config`." #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:281 msgid "" "➌ A warning will be emitted by `run_rc_command` if `rcvar` itself is " "set, but the indicated knob variable is unset. If your [.filename]#rc.d# " "script is for the base system, you should add a default setting for the knob " "to [.filename]#/etc/defaults/rc.conf# and document it in man:rc.conf[5]. " "Otherwise it is your script that should provide a default setting for the " "knob. The canonical approach to the latter case is shown in the example." msgstr "" "➌ `run_rc_command` выдаст предупреждение, если переменная `rcvar` " "установлена, но указанная переменная-флаг не задана. Если ваш скрипт [." "filename]#rc.d# предназначен для базовой системы, вы должны добавить " "значение по умолчанию для флага в [.filename]#/etc/defaults/rc.conf# и " "задокументировать его в man:rc.conf[5]. В противном случае ваш скрипт должен " "предоставить значение по умолчанию для флага. Канонический подход для " "последнего случая показан в примере." #. type: delimited block = 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:288 msgid "" "You can make man:rc.subr[8] act as though the knob is set to `ON`, " "irrespective of its current setting, by prefixing the argument to the script " "with `one` or `force`, as in `onestart` or `forcestop`. Keep in mind though " "that `force` has other dangerous effects we will touch upon below, while " "`one` just overrides the ON/OFF knob. E.g., assume that `dummy_enable` is " "`OFF`. The following command will run the `start` method in spite of the " "setting:" msgstr "" "Вы можете заставить man:rc.subr[8] действовать так, как если бы " "переключатель установлен в `ON`, независимо от его текущего значения, " "добавив перед аргументом скрипта префикс `one` или `force`, например " "`onestart` или `forcestop`. Однако учтите, что `force` имеет другие опасные " "эффекты, которые мы затронем ниже, тогда как `one` просто переопределяет " "переключатель ON/OFF. Например, предположим, что `dummy_enable` установлен в " "`OFF`. Следующая команда выполнит метод `start`, несмотря на настройку:" #. type: delimited block . 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:292 #, no-wrap msgid "# /etc/rc.d/dummy onestart\n" msgstr "# /etc/rc.d/dummy onestart\n" #. type: delimited block = 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:299 msgid "" "➍ Now the message to be shown at boot time is no longer hard-coded in " "the script. It is specified by an man:rc.conf[5] variable named " "`dummy_msg`. This is a trivial example of how man:rc.conf[5] variables can " "control an [.filename]#rc.d# script." msgstr "" "➍ Теперь сообщение, отображаемое при загрузке, больше не жёстко " "закодировано в скрипте. Оно задается переменной `dummy_msg` в man:rc.conf[5]" ". Это простой пример того, как переменные man:rc.conf[5] могут управлять " "скриптом в [.filename]#rc.d#." #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:304 msgid "" "The names of all man:rc.conf[5] variables used exclusively by our script " "_must_ have the same prefix: `${name}_`. For example: `dummy_mode`, " "`dummy_state_file`, and so on." msgstr "" "Имена всех переменных man:rc.conf[5], используемых исключительно нашим " "скриптом, _должны_ иметь один и тот же префикс: `${name}_`. Например: " "`dummy_mode`, `dummy_state_file` и так далее." #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:309 msgid "" "While it is possible to use a shorter name internally, e.g., just `msg`, " "adding the unique prefix `${name}_` to all global names introduced by our " "script will save us from possible collisions with the man:rc.subr[8] " "namespace." msgstr "" "Хотя можно использовать более короткое имя внутри, например, просто `msg`, " "добавление уникального префикса `${name}_` ко всем глобальным именам, " "вводимым нашим скриптом, избавит нас от возможных конфликтов с пространством " "имён man:rc.subr[8]." #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:312 msgid "" "As a rule, [.filename]#rc.d# scripts of the base system need not provide " "defaults for their man:rc.conf[5] variables because the defaults should be " "set in [.filename]#/etc/defaults/rc.conf# instead. On the other hand, [." "filename]#rc.d# scripts for ports should provide the defaults as shown in " "the example." msgstr "" "Как правило, скрипты [.filename]#rc.d# базовой системы не должны " "предоставлять значения по умолчанию для своих переменных man:rc.conf[5], " "поскольку значения по умолчанию должны быть установлены в [.filename]#/etc/" "defaults/rc.conf#. С другой стороны, скрипты [.filename]#rc.d# для портов " "должны предоставлять значения по умолчанию, как показано в примере." #. type: delimited block = 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:316 msgid "" "➎ Here we use `dummy_msg` to actually control our script, i.e., to " "emit a variable message. Use of a shell function is overkill here, since it " "only runs a single command; an equally valid alternative is:" msgstr "" "➎ Здесь мы используем `dummy_msg` для фактического управления нашим " "скриптом, т.е., для выдачи переменного сообщения. Использование shell-" "функции здесь избыточно, так как она выполняет только одну команду; " "равнозначной альтернативой является:" #. type: delimited block . 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:320 #, no-wrap msgid "start_cmd=\"echo \\\"$dummy_msg\\\"\"\n" msgstr "start_cmd=\"echo \\\"$dummy_msg\\\"\"\n" #. type: Title == #: documentation/content/en/articles/rc-scripting/_index.adoc:323 #, no-wrap msgid "Startup and shutdown of a simple daemon" msgstr "Запуск и остановка простого демона" #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:330 msgid "" "We said earlier that man:rc.subr[8] could provide default methods. " "Obviously, such defaults cannot be too general. They are suited for the " "common case of starting and shutting down a simple daemon program. Let us " "assume now that we need to write an [.filename]#rc.d# script for such a " "daemon called `mumbled`. Here it is:" msgstr "" "Мы ранее говорили, что man:rc.subr[8] может предоставлять методы по " "умолчанию. Очевидно, что такие методы не могут быть слишком общими. Они " "подходят для стандартного случая запуска и остановки простого демона. " "Предположим, что нам нужно написать скрипт [.filename]#rc.d# для такого " "демона с именем `mumbled`. Вот он:" #. type: delimited block . 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:339 #: documentation/content/en/articles/rc-scripting/_index.adoc:397 #: documentation/content/en/articles/rc-scripting/_index.adoc:634 #, no-wrap msgid "" "name=mumbled\n" "rcvar=mumbled_enable\n" msgstr "" "name=mumbled\n" "rcvar=mumbled_enable\n" #. type: delimited block . 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:341 #, no-wrap msgid "command=\"/usr/sbin/${name}\" <.>\n" msgstr "command=\"/usr/sbin/${name}\" <.>\n" #. type: delimited block . 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:344 #: documentation/content/en/articles/rc-scripting/_index.adoc:443 #: documentation/content/en/articles/rc-scripting/_index.adoc:649 #: documentation/content/en/articles/rc-scripting/_index.adoc:876 #, no-wrap msgid "" "load_rc_config $name\n" "run_rc_command \"$1\"\n" msgstr "" "load_rc_config $name\n" "run_rc_command \"$1\"\n" #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:348 msgid "" "Pleasingly simple, isn't it? Let us examine our little script. The only new " "thing to note is as follows:" msgstr "" "Приятно просто, не так ли? Давайте рассмотрим наш небольшой скрипт. " "Единственное новое, на что стоит обратить внимание, это следующее:" #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:352 msgid "" "➊ The `command` variable is meaningful to man:rc.subr[8]. If it is " "set, man:rc.subr[8] will act according to the scenario of serving a " "conventional daemon. In particular, the default methods will be provided " "for such arguments: `start`, `stop`, `restart`, `poll`, and `status`." msgstr "" "➊ Переменная `command` имеет значение для man:rc.subr[8]. Если она " "установлена, man:rc.subr[8] будет действовать по сценарию обслуживания " "обычного демона. В частности, будут предоставлены стандартные методы для " "таких аргументов: `start`, `stop`, `restart`, `poll` и `status`." #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:361 msgid "" "The daemon will be started by running `$command` with command-line flags " "specified by `$mumbled_flags`. Thus all the input data for the default " "`start` method are available in the variables set by our script. Unlike " "`start`, other methods may require additional information about the process " "started. For instance, `stop` must know the PID of the process to terminate " "it. In the present case, man:rc.subr[8] will scan through the list of all " "processes, looking for a process with its name equal to `procname`. The " "latter is another variable of meaning to man:rc.subr[8], and its value " "defaults to that of `command`. In other words, when we set `command`, " "`procname` is effectively set to the same value. This enables our script to " "kill the daemon and to check if it is running in the first place." msgstr "" "Демон будет запущен выполнением `$command` с флагами командной строки, " "указанными в `$mumbled_flags`. Таким образом, все входные данные для метода " "`start` по умолчанию доступны в переменных, установленных нашим скриптом. В " "отличие от `start`, другие методы могут требовать дополнительной информации " "о запущенном процессе. Например, `stop` должен знать PID процесса, чтобы " "завершить его. В данном случае, man:rc.subr[8] будет просматривать список " "всех процессов, ища процесс с именем, равным `procname`. Последний является " "ещё одной значимой переменной для man:rc.subr[8], и её значение по умолчанию " "совпадает со значением `command`. Другими словами, когда мы устанавливаем " "`command`, `procname` фактически устанавливается в то же значение. Это " "позволяет нашему скрипту завершить демон и проверить, запущен ли он вообще." #. type: delimited block = 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:368 msgid "" "Some programs are in fact executable scripts. The system runs such a script " "by starting its interpreter and passing the name of the script to it as a " "command-line argument. This is reflected in the list of processes, which " "can confuse man:rc.subr[8]. You should additionally set " "`command_interpreter` to let man:rc.subr[8] know the actual name of the " "process if `$command` is a script." msgstr "" "Некоторые программы на самом деле являются исполняемыми скриптами. Система " "запускает такие скрипты, запуская их интерпретатор и передавая ему имя " "скрипта в качестве аргумента командной строки. Это отражается в списке " "процессов, что может сбить с толку man:rc.subr[8]. Дополнительно следует " "установить `command_interpreter`, чтобы man:rc.subr[8] знал фактическое имя " "процесса, если `$command` является скриптом." #. type: delimited block = 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:374 msgid "" "For each [.filename]#rc.d# script, there is an optional man:rc.conf[5] " "variable that takes precedence over `command`. Its name is constructed as " "follows: `${name}_program`, where `name` is the mandatory variable we " "discussed crossref:rc-scripting[name-var, earlier]. E.g., in this case it " "will be `mumbled_program`. It is man:rc.subr[8] that arranges `${name}" "_program` to override `command`." msgstr "" "Для каждого скрипта [.filename]#rc.d# существует необязательная переменная " "man:rc.conf[5], которая имеет приоритет над `command`. Её имя формируется " "следующим образом: `${name}_program`, где `name` — это обязательная " "переменная, которую мы обсуждали crossref:rc-scripting[name-var, ранее]. " "Например, в данном случае это будет `mumbled_program`. Именно man:rc.subr[8] " "обеспечивает переопределение `command` с помощью `${name}_program`." #. type: delimited block = 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:378 msgid "" "Of course, man:sh[1] will permit you to set `${name}_program` from man:rc." "conf[5] or the script itself even if `command` is unset. In that case, the " "special properties of `${name}_program` are lost, and it becomes an ordinary " "variable your script can use for its own purposes. However, the sole use of " "`${name}_program` is discouraged because using it together with `command` " "became an idiom of [.filename]#rc.d# scripting." msgstr "" "Конечно, man:sh[1] позволяет установить `${name}_program` из man:rc.conf[5] " "или самого скрипта, даже если `command` не задан. В этом случае специальные " "свойства `${name}_program` теряются, и она становится обычной переменной, " "которую ваш скрипт может использовать для своих целей. Однако использование `" "${name}_program` в одиночку не рекомендуется, так как совместное " "использование с `command` стало идиомой в [.filename]#rc.d# скриптах." #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:381 msgid "" "For more detailed information on default methods, refer to man:rc.subr[8]." msgstr "" "Для получения более подробной информации о стандартных методах обратитесь к " "man:rc.subr[8]." #. type: Title == #: documentation/content/en/articles/rc-scripting/_index.adoc:383 #, no-wrap msgid "Startup and shutdown of an advanced daemon" msgstr "Запуск и остановка продвинутого демона" #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:388 msgid "" "Let us add some meat onto the bones of the previous script and make it more " "complex and featureful. The default methods can do a good job for us, but " "we may need some of their aspects tweaked. Now we will learn how to tune " "the default methods to our needs." msgstr "" "Добавим немного мяса к костям предыдущего скрипта и сделаем его более " "сложным и функциональным. Стандартные методы могут хорошо справляться с " "задачами, но иногда требуется их тонкая настройка. Теперь мы узнаем, как " "адаптировать стандартные методы под наши нужды." #. type: delimited block . 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:400 #, no-wrap msgid "" "command=\"/usr/sbin/${name}\"\n" "command_args=\"mock arguments > /dev/null 2>&1\" <.>\n" msgstr "" "command=\"/usr/sbin/${name}\"\n" "command_args=\"mock arguments > /dev/null 2>&1\" <.>\n" #. type: delimited block . 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:402 #, no-wrap msgid "pidfile=\"/var/run/${name}.pid\" <.>\n" msgstr "pidfile=\"/var/run/${name}.pid\" <.>\n" #. type: delimited block . 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:404 #, no-wrap msgid "required_files=\"/etc/${name}.conf /usr/share/misc/${name}.rules\" <.>\n" msgstr "required_files=\"/etc/${name}.conf /usr/share/misc/${name}.rules\" <.>\n" #. type: delimited block . 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:406 #, no-wrap msgid "sig_reload=\"USR1\" <.>\n" msgstr "sig_reload=\"USR1\" <.>\n" #. type: delimited block . 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:409 #, no-wrap msgid "" "start_precmd=\"${name}_prestart\" <.>\n" "stop_postcmd=\"echo Bye-bye\" <.>\n" msgstr "" "start_precmd=\"${name}_prestart\" <.>\n" "stop_postcmd=\"echo Bye-bye\" <.>\n" #. type: delimited block . 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:411 #, no-wrap msgid "extra_commands=\"reload plugh xyzzy\" <.>\n" msgstr "extra_commands=\"reload plugh xyzzy\" <.>\n" #. type: delimited block . 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:414 #, no-wrap msgid "" "plugh_cmd=\"mumbled_plugh\" <.>\n" "xyzzy_cmd=\"echo 'Nothing happens.'\"\n" msgstr "" "plugh_cmd=\"mumbled_plugh\" <.>\n" "xyzzy_cmd=\"echo 'Nothing happens.'\"\n" #. type: delimited block . 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:435 #, no-wrap msgid "" "mumbled_prestart()\n" "{\n" "\tif checkyesno mumbled_smart; then <.>\n" "\t\trc_flags=\"-o smart ${rc_flags}\" <.>\n" "\tfi\n" "\tcase \"$mumbled_mode\" in\n" "\tfoo)\n" "\t\trc_flags=\"-frotz ${rc_flags}\"\n" "\t\t;;\n" "\tbar)\n" "\t\trc_flags=\"-baz ${rc_flags}\"\n" "\t\t;;\n" "\t*)\n" "\t\twarn \"Invalid value for mumbled_mode\" <.>\n" "\t\treturn 1 <.>\n" "\t\t;;\n" "\tesac\n" "\trun_rc_command xyzzy <.>\n" "\treturn 0\n" "}\n" msgstr "" "mumbled_prestart()\n" "{\n" "\tif checkyesno mumbled_smart; then <.>\n" "\t\trc_flags=\"-o smart ${rc_flags}\" <.>\n" "\tfi\n" "\tcase \"$mumbled_mode\" in\n" "\tfoo)\n" "\t\trc_flags=\"-frotz ${rc_flags}\"\n" "\t\t;;\n" "\tbar)\n" "\t\trc_flags=\"-baz ${rc_flags}\"\n" "\t\t;;\n" "\t*)\n" "\t\twarn \"Invalid value for mumbled_mode\" <.>\n" "\t\treturn 1 <.>\n" "\t\t;;\n" "\tesac\n" "\trun_rc_command xyzzy <.>\n" "\treturn 0\n" "}\n" #. type: delimited block . 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:440 #, no-wrap msgid "" "mumbled_plugh() <.>\n" "{\n" "\techo 'A hollow voice says \"plugh\".'\n" "}\n" msgstr "" "mumbled_plugh() <.>\n" "{\n" "\techo 'A hollow voice says \"plugh\".'\n" "}\n" #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:448 msgid "" "➊ Additional arguments to `$command` can be passed in " "`command_args`. They will be added to the command line after `" "$mumbled_flags`. Since the final command line is passed to `eval` for its " "actual execution, input and output redirections can be specified in " "`command_args`." msgstr "" "➊ Дополнительные аргументы для `$command` могут быть переданы в " "`command_args`. Они будут добавлены в командную строку после `" "$mumbled_flags`. Поскольку итоговая командная строка передаётся в `eval` для " "фактического выполнения, перенаправления ввода и вывода могут быть указаны в " "`command_args`." #. type: delimited block = 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:455 msgid "" "_Never_ include dashed options, like `-X` or `--foo`, in `command_args`. " "The contents of `command_args` will appear at the end of the final command " "line, hence they are likely to follow arguments present in `${name}_flags`; " "but most commands will not recognize dashed options after ordinary " "arguments. A better way of passing additional options to `$command` is to " "add them to the beginning of `${name}_flags`. Another way is to modify " "`rc_flags` crossref:rc-scripting[rc-flags, as shown later]." msgstr "" "Никогда не включайте параметры с дефисами, такие как `-X` или `--foo`, в " "`command_args`. Содержимое `command_args` будет добавлено в конец итоговой " "командной строки, поэтому, скорее всего, окажется после аргументов, " "указанных в `${name}_flags`; однако большинство команд не распознают " "параметры с дефисами после обычных аргументов. Лучший способ передать " "дополнительные параметры в `$command` — добавить их в начало `${name}" "_flags`. Другой способ — изменить `rc_flags` crossref:rc-scripting[rc-flags, " "как показано далее]." #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:459 msgid "" "➋ A good-mannered daemon should create a _pidfile_ so that its " "process can be found more easily and reliably. The variable `pidfile`, if " "set, tells man:rc.subr[8] where it can find the pidfile for its default " "methods to use." msgstr "" "➋ Вежливый демон должен создавать _pidfile_, чтобы его процесс можно " "было найти проще и надёжнее. Переменная `pidfile`, если она установлена, " "указывает man:rc.subr[8], где можно найти pidfile для использования его " "стандартными методами." #. type: delimited block = 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:464 msgid "" "In fact, man:rc.subr[8] will also use the pidfile to see if the daemon is " "already running before starting it. This check can be skipped by using the " "`faststart` argument." msgstr "" "На самом деле, man:rc.subr[8] также использует pidfile для проверки, запущен " "ли демон, перед его запуском. Эту проверку можно пропустить, используя " "аргумент `faststart`." #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:469 msgid "" "➌ If the daemon cannot run unless certain files exist, just list them " "in `required_files`, and man:rc.subr[8] will check that those files do exist " "before starting the daemon. There also are `required_dirs` and " "`required_vars` for directories and environment variables, respectively. " "They all are described in detail in man:rc.subr[8]." msgstr "" "➌ Если демон не может работать без определённых файлов, просто " "укажите их в `required_files`, и man:rc.subr[8] проверит их наличие перед " "запуском демона. Также существуют `required_dirs` и `required_vars` для " "каталогов и переменных окружения соответственно. Все они подробно описаны в " "man:rc.subr[8]." #. type: delimited block = 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:473 msgid "" "The default method from man:rc.subr[8] can be forced to skip the " "prerequisite checks by using `forcestart` as the argument to the script." msgstr "" "Метод по умолчанию из man:rc.subr[8] можно принудительно заставить " "пропустить проверки предварительных условий, используя аргумент `forcestart` " "в скрипте." #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:479 msgid "" "➍ We can customize signals to send to the daemon in case they differ " "from the well-known ones. In particular, `sig_reload` specifies the signal " "that makes the daemon reload its configuration; it is SIGHUP by default. " "Another signal is sent to stop the daemon process; the default is SIGTERM, " "but this can be changed by setting `sig_stop` appropriately." msgstr "" "➍ Мы можем настроить сигналы, отправляемые демону, если они " "отличаются от общеизвестных. В частности, `sig_reload` указывает сигнал, " "который заставляет демона перезагрузить свою конфигурацию; по умолчанию это " "SIGHUP. Другой сигнал отправляется для остановки процесса демона; по " "умолчанию используется SIGTERM, но это можно изменить, установив `sig_stop` " "соответствующим образом." #. type: delimited block = 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:484 msgid "" "The signal names should be specified to man:rc.subr[8] without the `SIG` " "prefix, as it is shown in the example. The FreeBSD version of man:kill[1] " "can recognize the `SIG` prefix, but the versions from other OS types may not." msgstr "" "Имена сигналов должны указываться для man:rc.subr[8] без префикса `SIG`, как " "показано в примере. Версия man:kill[1] в FreeBSD может распознавать префикс " "`SIG`, но версии из других типов ОС могут не поддерживать его." #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:489 msgid "" "➎➏ Performing additional tasks before or after the default " "methods is easy. For each command-argument supported by our script, we can " "define `argument_precmd` and `argument_postcmd`. These man:sh[1] commands " "are invoked before and after the respective method, as it is evident from " "their names." msgstr "" "➎➏ Выполнение дополнительных задач до или после стандартных " "методов — это просто. Для каждого аргумента команды, поддерживаемого нашим " "скриптом, мы можем определить `argument_precmd` и `argument_postcmd`. Эти " "команды man:sh[1] вызываются до и после соответствующего метода, что " "очевидно из их названий." #. type: delimited block = 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:495 msgid "" "Overriding a default method with a custom `argument_cmd` still does not " "prevent us from making use of `argument_precmd` or `argument_postcmd` if we " "need to. In particular, the former is good for checking custom, " "sophisticated conditions that should be met before performing the command " "itself. Using `argument_precmd` along with `argument_cmd` lets us logically " "separate the checks from the action." msgstr "" "Переопределение стандартного метода с помощью пользовательского " "`argument_cmd` всё равно не мешает нам использовать `argument_precmd` или " "`argument_postcmd`, если это необходимо. В частности, первый полезен для " "проверки пользовательских сложных условий, которые должны быть выполнены " "перед выполнением самой команды. Использование `argument_precmd` вместе с " "`argument_cmd` позволяет логически разделить проверки от действия." #. type: delimited block = 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:498 msgid "" "Do not forget that you can cram any valid man:sh[1] expressions into the " "methods, pre-, and post-commands you define. Just invoking a function that " "makes the real job is a good style in most cases, but never let style limit " "your understanding of what is going on behind the curtain." msgstr "" "Не забывайте, что вы можете вставлять любые допустимые выражения из man:" "sh[1] в определяемые вами методы, а также команды pre- и post-. Просто " "вызывать функцию, которая выполняет основную работу, — это хороший стиль в " "большинстве случаев, но никогда не позволяйте стилю ограничивать ваше " "понимание того, что происходит за кулисами." #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:501 msgid "" "➐ If we would like to implement custom arguments, which can also be " "thought of as _commands_ to our script, we need to list them in " "`extra_commands` and provide methods to handle them." msgstr "" "➐ Если мы хотим реализовать пользовательские аргументы, которые также " "можно рассматривать как _команды_ для нашего скрипта, необходимо перечислить " "их в `extra_commands` и предоставить методы для их обработки." #. type: delimited block = 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:509 msgid "" "The `reload` command is special. On the one hand, it has a preset method in " "man:rc.subr[8]. On the other hand, `reload` is not offered by default. The " "reason is that not all daemons use the same reload mechanism and some have " "nothing to reload at all. So we need to ask explicitly that the builtin " "functionality be provided. We can do so via `extra_commands`." msgstr "" "Команда `reload` является особенной. С одной стороны, у неё есть " "предустановленный метод в man:rc.subr[8]. С другой стороны, `reload` не " "предлагается по умолчанию. Причина в том, что не все демоны используют " "одинаковый механизм перезагрузки, а у некоторых вообще нет ничего для " "перезагрузки. Поэтому нам нужно явно запросить предоставление встроенной " "функциональности. Это можно сделать с помощью `extra_commands`." #. type: delimited block = 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:513 msgid "" "What do we get from the default method for `reload`? Quite often daemons " "reload their configuration upon reception of a signal - typically, SIGHUP. " "Therefore man:rc.subr[8] attempts to reload the daemon by sending a signal " "to it. The signal is preset to SIGHUP but can be customized via " "`sig_reload` if necessary." msgstr "" "Что мы получаем от метода по умолчанию для `reload`? Довольно часто демоны " "перезагружают свою конфигурацию при получении сигнала — обычно, SIGHUP. " "Поэтому man:rc.subr[8] пытается перезагрузить демона, отправляя ему сигнал. " "Сигнал предустановлен на SIGHUP, но может быть изменён через `sig_reload` " "при необходимости." #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:518 msgid "" "➑⓮ Our script supports two non-standard commands, `plugh` and " "`xyzzy`. We saw them listed in `extra_commands`, and now it is time to " "provide methods for them. The method for `xyzzy` is just inlined while that " "for `plugh` is implemented as the `mumbled_plugh` function." msgstr "" "➑⓮ Наш скрипт поддерживает две нестандартные команды: `plugh` и " "`xyzzy`. Мы видели их в списке `extra_commands`, и теперь пришло время " "реализовать методы для них. Метод для `xyzzy` просто встроен в код, а для " "`plugh` он реализован как функция `mumbled_plugh`." #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:522 msgid "" "Non-standard commands are not invoked during startup or shutdown. Usually " "they are for the system admin's convenience. They can also be used from " "other subsystems, e.g., man:devd[8] if specified in man:devd.conf[5]." msgstr "" "Нестандартные команды не вызываются во время запуска или завершения работы. " "Обычно они предназначены для удобства системного администратора. Они также " "могут использоваться другими подсистемами, например, man:devd[8], если " "указаны в man:devd.conf[5]." #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:525 msgid "" "The full list of available commands can be found in the usage line printed " "by man:rc.subr[8] when the script is invoked without arguments. For " "example, here is the usage line from the script under study:" msgstr "" "Полный список доступных команд можно найти в строке использования, выводимой " "man:rc.subr[8], когда скрипт вызывается без аргументов. Например, вот строка " "использования из изучаемого скрипта:" #. type: delimited block . 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:530 #, no-wrap msgid "" "# /etc/rc.d/mumbled\n" "Usage: /etc/rc.d/mumbled [fast|force|one](start|stop|restart|rcvar|reload|plugh|xyzzy|status|poll)\n" msgstr "" "# /etc/rc.d/mumbled\n" "Usage: /etc/rc.d/mumbled [fast|force|one](start|stop|restart|rcvar|reload|plugh|xyzzy|status|poll)\n" #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:537 msgid "" "⓭ A script can invoke its own standard or non-standard commands if " "needed. This may look similar to calling functions, but we know that " "commands and shell functions are not always the same thing. For instance, " "`xyzzy` is not implemented as a function here. In addition, there can be a " "pre-command and post-command, which should be invoked orderly. So the " "proper way for a script to run its own command is by means of man:rc." "subr[8], as shown in the example." msgstr "" "⓭ Скрипт может вызывать свои собственные стандартные или нестандартные " "команды, если это необходимо. Это может выглядеть похоже на вызов функций, " "но мы знаем, что команды и функции оболочки не всегда одно и то же. " "Например, `xyzzy` не реализован как функция в данном случае. Кроме того, " "могут существовать пред-команда и пост-команда, которые должны вызываться в " "определённом порядке. Поэтому правильный способ для скрипта выполнить свою " "собственную команду — с помощью man:rc.subr[8], как показано в примере." #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:543 msgid "" "➒ A handy function named `checkyesno` is provided by man:rc.subr[8]. " "It takes a variable name as its argument and returns a zero exit code if and " "only if the variable is set to `YES`, or `TRUE`, or `ON`, or `1`, case " "insensitive; a non-zero exit code is returned otherwise. In the latter " "case, the function tests the variable for being set to `NO`, `FALSE`, `OFF`, " "or `0`, case insensitive; it prints a warning message if the variable " "contains anything else, i.e., junk." msgstr "" "➒ Полезная функция `checkyesno` предоставляется man:rc.subr[8]. Она " "принимает имя переменной в качестве аргумента и возвращает нулевой код " "выхода только если переменная установлена в `YES`, `TRUE`, `ON` или `1`, без " "учёта регистра; в противном случае возвращается ненулевой код выхода. В " "последнем случае функция проверяет, установлена ли переменная в `NO`, " "`FALSE`, `OFF` или `0`, также без учёта регистра; если переменная содержит " "что-то иное (т.е. мусор), функция выводит предупреждение." #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:545 msgid "" "Keep in mind that for man:sh[1] a zero exit code means true and a non-zero " "exit code means false." msgstr "" "Имейте в виду, что для man:sh[1] нулевой код возврата означает истину, а " "ненулевой код возврата означает ложь." #. type: delimited block = 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:550 msgid "" "The `checkyesno` function takes a __variable name__. Do not pass the " "expanded _value_ of a variable to it; it will not work as expected." msgstr "" "Функция `checkyesno` принимает __имя переменной__. Не передавайте ей " "_значение_ переменной; это не будет работать, как ожидается." #. type: delimited block = 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:552 msgid "The following is the correct usage of `checkyesno`:" msgstr "Ниже приведено правильное использование `checkyesno`:" #. type: delimited block . 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:558 #, no-wrap msgid "" "if checkyesno mumbled_enable; then\n" " foo\n" "fi\n" msgstr "" "if checkyesno mumbled_enable; then\n" " foo\n" "fi\n" #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:561 msgid "" "On the contrary, calling `checkyesno` as shown below will not work - at " "least not as expected:" msgstr "" "Напротив, вызов `checkyesno`, как показано ниже, не сработает — по крайней " "мере, не так, как ожидается:" #. type: delimited block . 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:567 #, no-wrap msgid "" "if checkyesno \"${mumbled_enable}\"; then\n" " foo\n" "fi\n" msgstr "" "if checkyesno \"${mumbled_enable}\"; then\n" " foo\n" "fi\n" #. type: delimited block = 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:572 msgid "" "➓ [[rc-flags]]We can affect the flags to be passed to `$command` by " "modifying `rc_flags` in `$start_precmd`." msgstr "" "➓ [[rc-flags]] Мы можем влиять на флаги, передаваемые команде `" "$command`, изменяя `rc_flags` в `$start_precmd`." #. type: delimited block = 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:576 msgid "" "⓫ In certain cases we may need to emit an important message that " "should go to `syslog` as well. This can be done easily with the following " "man:rc.subr[8] functions: `debug`, `info`, `warn`, and `err`. The latter " "function then exits the script with the code specified." msgstr "" "⓫ В некоторых случаях может потребоваться вывести важное сообщение, " "которое также должно попасть в `syslog`. Это можно легко сделать с помощью " "следующих функций man:rc.subr[8]: `debug`, `info`, `warn` и `err`. Последняя " "функция завершает выполнение скрипта с указанным кодом." #. type: delimited block = 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:580 msgid "" "⓬ The exit codes from methods and their pre-commands are not just " "ignored by default. If `argument_precmd` returns a non-zero exit code, the " "main method will not be performed. In turn, `argument_postcmd` will not be " "invoked unless the main method returns a zero exit code." msgstr "" "⓬ Коды выхода из методов и их предварительных команд не просто " "игнорируются по умолчанию. Если `argument_precmd` возвращает ненулевой код " "выхода, основной метод не будет выполнен. В свою очередь, `argument_postcmd` " "не будет вызван, если основной метод возвращает ненулевой код выхода." #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:584 msgid "" "However, man:rc.subr[8] can be instructed from the command line to ignore " "those exit codes and invoke all commands anyway by prefixing an argument " "with `force`, as in `forcestart`." msgstr "" "Однако man:rc.subr[8] можно указать из командной строки игнорировать эти " "коды завершения и выполнять все команды в любом случае, добавив префикс " "`force` к аргументу, например `forcestart`." #. type: Title == #: documentation/content/en/articles/rc-scripting/_index.adoc:587 #, no-wrap msgid "Connecting a script to the rc.d framework" msgstr "Подключение скрипта к инфраструктуре rc.d" #. type: delimited block = 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:594 msgid "" "After a script has been written, it needs to be integrated into [." "filename]#rc.d#. The crucial step is to install the script in [.filename]#/" "etc/rc.d# (for the base system) or [.filename]#/usr/local/etc/rc.d# (for " "ports). Both [.filename]#bsd.prog.mk# and [.filename]#bsd.port.mk# provide " "convenient hooks for that, and usually you do not have to worry about the " "proper ownership and mode. System scripts should be installed from [." "filename]#src/libexec/rc/rc.d# through the [.filename]#Makefile# found " "there. Port scripts can be installed using `USE_RC_SUBR` as described " "extref:{porters-handbook}special[in the Porter's Handbook, rc-scripts]." msgstr "" "После написания скрипта его необходимо интегрировать в [.filename]#rc.d#. " "Ключевой шаг — установка скрипта в [.filename]#/etc/rc.d# (для базовой " "системы) или [.filename]#/usr/local/etc/rc.d# (для портов). И [.filename]#bsd" ".prog.mk#, и [.filename]#bsd.port.mk# предоставляют удобные механизмы для " "этого, и обычно вам не нужно беспокоиться о правильных правах доступа и " "режиме. Системные скрипты должны устанавливаться из [.filename]#src/libexec/" "rc/rc.d# через [.filename]#Makefile#, находящийся там. Скрипты портов можно " "установить с помощью `USE_RC_SUBR`, как описано extref:{porters-" "handbook}special[в Руководстве FreeBSD по созданию портов, rc-scripts]." #. type: delimited block = 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:599 msgid "" "However, we should consider beforehand the place of our script in the system " "startup sequence. The service handled by our script is likely to depend on " "other services. For instance, a network daemon cannot function without the " "network interfaces and routing up and running. Even if a service seems to " "demand nothing, it can hardly start before the basic filesystems have been " "checked and mounted." msgstr "" "Однако следует заранее продумать место нашего скрипта в последовательности " "запуска системы. Скорее всего, обслуживаемый нашим скриптом сервис зависит " "от других сервисов. Например, сетевой демон не может работать без поднятых " "сетевых интерфейсов и маршрутизации. Даже если сервис, казалось бы, ничего " "не требует, он вряд ли сможет запуститься до проверки и монтирования " "основных файловых систем." #. type: delimited block = 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:605 msgid "" "We mentioned man:rcorder[8] already. Now it is time to have a close look at " "it. In a nutshell, man:rcorder[8] takes a set of files, examines their " "contents, and prints a dependency-ordered list of files from the set to " "`stdout`. The point is to keep dependency information _inside_ the files so " "that each file can speak for itself only. A file can specify the following " "information:" msgstr "" "Мы уже упоминали man:rcorder[8]. Теперь пришло время рассмотреть его " "подробнее. В двух словах, man:rcorder[8] принимает набор файлов, анализирует " "их содержимое и выводит на `stdout` список этих файлов, упорядоченный по " "зависимостям. Главная идея заключается в том, чтобы хранить информацию о " "зависимостях _внутри_ файлов, чтобы каждый файл мог описывать только себя. " "Файл может содержать следующую информацию:" #. type: delimited block = 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:607 msgid "" "the names of the \"conditions\" (which means services to us) it __provides__;" msgstr "" "имена \"условий\" (что для нас означает сервисы), которые он " "__предоставляет__;" #. type: delimited block = 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:608 msgid "the names of the \"conditions\" it __requires__;" msgstr "имена \"условий\", которые он __требует__;" #. type: delimited block = 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:609 msgid "the names of the \"conditions\" this file should run __before__;" msgstr "имена \"условий\", перед которыми должен выполняться этот файл;" #. type: delimited block = 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:610 msgid "" "additional _keywords_ that can be used to select a subset from the whole set " "of files (man:rcorder[8] can be instructed via options to include or omit " "the files having particular keywords listed.)" msgstr "" "дополнительные _ключевые слова_, которые могут использоваться для выбора " "подмножества из всего набора файлов (man:rcorder[8] может быть настроен с " "помощью опций для включения или исключения файлов, содержащих указанные " "ключевые слова.)" #. type: delimited block = 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:615 msgid "" "It is no surprise that man:rcorder[8] can handle only text files with a " "syntax close to that of man:sh[1]. That is, special lines understood by man:" "rcorder[8] look like man:sh[1] comments. The syntax of such special lines " "is rather rigid to simplify their processing. See man:rcorder[8] for " "details." msgstr "" "Неудивительно, что man:rcorder[8] может обрабатывать только текстовые файлы " "с синтаксисом, близким к man:sh[1]. То есть специальные строки, понимаемые " "man:rcorder[8], выглядят как комментарии в man:sh[1]. Синтаксис таких " "специальных строк довольно жёсткий, чтобы упростить их обработку. " "Подробности см. в man:rcorder[8]." #. type: delimited block = 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:618 msgid "" "Besides using man:rcorder[8] special lines, a script can insist on its " "dependency upon another service by just starting it forcibly. This can be " "needed when the other service is optional and will not start by itself " "because the system admin has disabled it mistakenly in man:rc.conf[5]." msgstr "" "Помимо использования специальных строк man:rcorder[8], скрипт может " "настаивать на своей зависимости от другой службы, просто принудительно " "запуская её. Это может быть необходимо, когда другая служба является " "опциональной и не запускается самостоятельно, потому что системный " "администратор ошибочно отключил её в man:rc.conf[5]." #. type: delimited block = 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:620 msgid "" "With this general knowledge in mind, let us consider the simple daemon " "script enhanced with dependency stuff:" msgstr "" "С учётом этих общих знаний рассмотрим простой скрипт демона, дополненный " "зависимостями:" #. type: delimited block . 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:629 #, no-wrap msgid "" "# PROVIDE: mumbled oldmumble <.>\n" "# REQUIRE: DAEMON cleanvar frotz <.>\n" "# BEFORE: LOGIN <.>\n" "# KEYWORD: nojail shutdown <.>\n" msgstr "" "# PROVIDE: mumbled oldmumble <.>\n" "# REQUIRE: DAEMON cleanvar frotz <.>\n" "# BEFORE: LOGIN <.>\n" "# KEYWORD: nojail shutdown <.>\n" #. type: delimited block . 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:637 #, no-wrap msgid "" "command=\"/usr/sbin/${name}\"\n" "start_precmd=\"${name}_prestart\"\n" msgstr "" "command=\"/usr/sbin/${name}\"\n" "start_precmd=\"${name}_prestart\"\n" #. type: delimited block . 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:646 #, no-wrap msgid "" "mumbled_prestart()\n" "{\n" "\tif ! checkyesno frotz_enable && \\\n" "\t ! /etc/rc.d/frotz forcestatus 1>/dev/null 2>&1; then\n" "\t\tforce_depend frotz || return 1 <.>\n" "\tfi\n" "\treturn 0\n" "}\n" msgstr "" "mumbled_prestart()\n" "{\n" "\tif ! checkyesno frotz_enable && \\\n" "\t ! /etc/rc.d/frotz forcestatus 1>/dev/null 2>&1; then\n" "\t\tforce_depend frotz || return 1 <.>\n" "\tfi\n" "\treturn 0\n" "}\n" #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:652 msgid "As before, detailed analysis follows:" msgstr "Как и ранее, следует детальный анализ:" #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:655 msgid "" "➊ That line declares the names of \"conditions\" our script " "provides. Now other scripts can record a dependency on our script by those " "names." msgstr "" "➊ Эта строка объявляет названия \"условий\", которые предоставляет " "наш скрипт. Теперь другие скрипты могут указывать зависимость от нашего " "скрипта по этим именам." #. type: delimited block = 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:660 msgid "" "Usually a script specifies a single condition provided. However, nothing " "prevents us from listing several conditions there, e.g., for compatibility " "reasons." msgstr "" "Обычно скрипт указывает одно предоставленное условие. Однако ничто не мешает " "нам перечислить несколько условий, например, по причинам совместимости." #. type: delimited block = 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:662 msgid "" "In any case, the name of the main, or the only, `PROVIDE:` condition should " "be the same as `${name}`." msgstr "" "В любом случае, название основного или единственного условия `PROVIDE:` " "должно совпадать с `${name}`." #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:666 msgid "" "➋➌ So our script indicates which \"conditions\" provided by " "other scripts it depends on. According to the lines, our script asks man:" "rcorder[8] to put it after the script(s) providing [.filename]#DAEMON# and [." "filename]#cleanvar#, but before that providing [.filename]#LOGIN#." msgstr "" "➋➌ Таким образом, наш скрипт указывает, от каких \"условий\", " "предоставляемых другими скриптами, он зависит. Согласно строкам, наш скрипт " "просит man:rcorder[8] разместить его после скрипта(ов), предоставляющих [." "filename]#DAEMON# и [.filename]#cleanvar#, но перед тем, который " "предоставляет [.filename]#LOGIN#." #. type: delimited block = 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:672 msgid "" "The `BEFORE:` line should not be abused to work around an incomplete " "dependency list in the other script. The appropriate case for using `BEFORE:" "` is when the other script does not care about ours, but our script can do " "its task better if run before the other one. A typical real-life example is " "the network interfaces vs. the firewall: While the interfaces do not depend " "on the firewall in doing their job, the system security will benefit from " "the firewall being ready before there is any network traffic." msgstr "" "Строку `BEFORE:` не следует использовать для обхода неполного списка " "зависимостей в другом скрипте. Правильный случай для использования `BEFORE:` " "— когда другой скрипт не зависит от нашего, но наш скрипт может выполнить " "свою задачу лучше, если запустится до другого. Типичный пример из реальной " "жизни — сетевые интерфейсы и межсетевой экран: хотя интерфейсы не зависят от " "межсетевого экрана при выполнении своей работы, безопасность системы " "выиграет, если межсетевой экран будет готов до начала сетевого трафика." #. type: delimited block = 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:676 msgid "" "Besides conditions corresponding to a single service each, there are meta-" "conditions and their \"placeholder\" scripts used to ensure that certain " "groups of operations are performed before others. These are denoted by [." "filename]#UPPERCASE# names. Their list and purposes can be found in man:" "rc[8]." msgstr "" "Помимо условий, соответствующих отдельным службам, существуют метаусловия и " "их \"заглушки\" скриптов, используемые для обеспечения выполнения " "определённых групп операций в заданном порядке. Они обозначаются именами в [." "filename]#ВЕРХНЕМ РЕГИСТРЕ#. Их список и назначение можно найти в man:rc[8]." #. type: delimited block = 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:682 msgid "" "Keep in mind that putting a service name in the `REQUIRE:` line does not " "guarantee that the service will actually be running by the time our script " "starts. The required service may fail to start or just be disabled in man:" "rc.conf[5]. Obviously, man:rcorder[8] cannot track such details, and man:" "rc[8] will not do that either. Consequently, the application started by our " "script should be able to cope with any required services being unavailable. " "In certain cases, we can help it as discussed crossref:rc-" "scripting[forcedep, below]" msgstr "" "Имейте в виду, что указание имени службы в строке `REQUIRE:` не гарантирует, " "что служба действительно будет запущена к моменту старта нашего скрипта. " "Требуемая служба может не запуститься или быть отключена в man:rc.conf[5]. " "Очевидно, man:rcorder[8] не может отслеживать такие детали, и man:rc[8] тоже " "этого не делает. Следовательно, приложение, запускаемое нашим скриптом, " "должно быть способно обрабатывать ситуации, когда требуемые службы " "недоступны. В некоторых случаях мы можем помочь ему, как описано в crossref:" "rc-scripting[forcedep, ниже]" #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:687 msgid "" "[[keywords]]➍ As we remember from the above text, man:rcorder[8] " "keywords can be used to select or leave out some scripts. Namely any man:" "rcorder[8] consumer can specify through `-k` and `-s` options which keywords " "are on the \"keep list\" and \"skip list\", respectively. From all the " "files to be dependency sorted, man:rcorder[8] will pick only those having a " "keyword from the keep list (unless empty) and not having a keyword from the " "skip list." msgstr "" "[[keywords]]➍ Как мы помним из текста выше, ключевые слова man:" "rcorder[8] могут использоваться для выбора или исключения некоторых " "скриптов. А именно, любой потребитель man:rcorder[8] может указать с помощью " "опций `-k` и `-s`, какие ключевые слова находятся в \"списке сохранения\" и " "\"списке пропуска\" соответственно. Из всех файлов, подлежащих сортировке по " "зависимостям, man:rcorder[8] выберет только те, которые имеют ключевое слово " "из списка сохранения (если он не пуст) и не имеют ключевого слова из списка " "пропуска." #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:690 msgid "" "In FreeBSD, man:rcorder[8] is used by [.filename]#/etc/rc# and [.filename]#/" "etc/rc.shutdown#. These two scripts define the standard list of FreeBSD [." "filename]#rc.d# keywords and their meanings as follows:" msgstr "" "В FreeBSD, man:rcorder[8] используется [.filename]#/etc/rc# и [.filename]#/" "etc/rc.shutdown#. Эти два скрипта определяют стандартный список ключевых " "слов [.filename]#rc.d# FreeBSD и их значения следующим образом:" #. type: Labeled list #: documentation/content/en/articles/rc-scripting/_index.adoc:691 #, no-wrap msgid "nojail" msgstr "nojail" #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:693 msgid "" "The service is not for man:jail[8] environment. The automatic startup and " "shutdown procedures will ignore the script if inside a jail." msgstr "" "Сервис не предназначен для окружения man:jail[8]. Процедуры автоматического " "запуска и остановки будут игнорировать скрипт, если он находится внутри " "клетки." #. type: Labeled list #: documentation/content/en/articles/rc-scripting/_index.adoc:694 #, no-wrap msgid "nostart" msgstr "nostart" #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:697 msgid "" "The service is to be started manually or not started at all. The automatic " "startup procedure will ignore the script. In conjunction with the [." "filename]#shutdown# keyword, this can be used to write scripts that do " "something only at system shutdown." msgstr "" "Служба должна запускаться вручную или не запускаться вовсе. Процедура " "автоматического запуска проигнорирует скрипт. В сочетании с ключевым словом " "[.filename]#shutdown# это может использоваться для написания скриптов, " "выполняющих действия только при выключении системы." #. type: Labeled list #: documentation/content/en/articles/rc-scripting/_index.adoc:698 #, no-wrap msgid "shutdown" msgstr "shutdown" #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:699 msgid "" "This keyword is to be listed __explicitly__ if the service needs to be " "stopped before system shutdown." msgstr "" "Этот ключевой параметр должен быть указан __явно__, если службу необходимо " "остановить перед завершением работы системы." #. type: delimited block = 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:712 msgid "" "When the system is going to shut down, [.filename]#/etc/rc.shutdown# runs. " "It assumes that most [.filename]#rc.d# scripts have nothing to do at that " "time. Therefore [.filename]#/etc/rc.shutdown# selectively invokes [." "filename]#rc.d# scripts with the [.filename]#shutdown# keyword, effectively " "ignoring the rest of the scripts. For even faster shutdown, [.filename]#/" "etc/rc.shutdown# passes the [.filename]#faststop# command to the scripts it " "runs so that they skip preliminary checks, e.g., the pidfile check. As " "dependent services should be stopped before their prerequisites, [." "filename]#/etc/rc.shutdown# runs the scripts in reverse dependency order. " "If writing a real [.filename]#rc.d# script, you should consider whether it " "is relevant at system shutdown time. E.g., if your script does its work in " "response to the [.filename]#start# command only, then you need not to " "include this keyword. However, if your script manages a service, it is " "probably a good idea to stop it before the system proceeds to the final " "stage of its shutdown sequence described in man:halt[8]. In particular, a " "service should be stopped explicitly if it needs considerable time or " "special actions to shut down cleanly. A typical example of such a service " "is a database engine." msgstr "" "Когда система собирается завершить работу, выполняется [.filename]#/etc/rc." "shutdown#. Предполагается, что большинству скриптов [.filename]#rc.d# в этот " "момент нечего делать. Поэтому [.filename]#/etc/rc.shutdown# выборочно " "запускает скрипты [.filename]#rc.d# с ключевым словом [.filename]#shutdown#, " "фактически игнорируя остальные скрипты. Для ещё более быстрого завершения " "работы [.filename]#/etc/rc.shutdown# передаёт команду [.filename]#faststop# " "запускаемым скриптам, чтобы они пропускали предварительные проверки, " "например, проверку pid-файла. Поскольку зависимые службы должны быть " "остановлены до своих зависимостей, [.filename]#/etc/rc.shutdown# запускает " "скрипты в обратном порядке зависимостей. Если вы пишете настоящий скрипт [." "filename]#rc.d#, стоит подумать, актуален ли он во время завершения работы " "системы. Например, если ваш скрипт выполняет свою работу только в ответ на " "команду [.filename]#start#, то включать это ключевое слово не нужно. Однако " "если ваш скрипт управляет службой, вероятно, стоит остановить её до того, " "как система перейдёт к финальной стадии завершения работы, описанной в man:" "halt[8]. В частности, службу следует останавливать явно, если для её " "корректного завершения требуется значительное время или специальные " "действия. Типичный пример такой службы — система управления базами данных." #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:716 msgid "" "[[forcedep]]➎ To begin with, `force_depend` should be used with much " "care. It is generally better to revise the hierarchy of configuration " "variables for your [.filename]#rc.d# scripts if they are interdependent." msgstr "" "[[forcedep]]➎ Прежде всего, `force_depend` следует использовать с " "большой осторожностью. Обычно лучше пересмотреть иерархию конфигурационных " "переменных для ваших [.filename]#rc.d# скриптов, если они взаимозависимы." #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:725 msgid "" "If you still cannot do without `force_depend`, the example offers an idiom " "of how to invoke it conditionally. In the example, our `mumbled` daemon " "requires that another one, `frotz`, be started in advance. However, `frotz` " "is optional, too; and man:rcorder[8] knows nothing about such details. " "Fortunately, our script has access to all man:rc.conf[5] variables. If " "`frotz_enable` is true, we hope for the best and rely on [.filename]#rc.d# " "to have started `frotz`. Otherwise we forcibly check the status of " "`frotz`. Finally, we enforce our dependency on `frotz` if it is found to be " "not running. A warning message will be emitted by `force_depend` because it " "should be invoked only if a misconfiguration has been detected." msgstr "" "Если вам всё ещё не обойтись без `force_depend`, в примере показано, как " "вызвать его условно. В примере наш демон `mumbled` требует, чтобы другой " "демон, `frotz`, был запущен заранее. Однако `frotz` также является " "опциональным, и man:rcorder[8] ничего не знает о таких деталях. К счастью, " "наш скрипт имеет доступ ко всем переменным man:rc.conf[5]. Если " "`frotz_enable` имеет значение true, мы надеемся на лучшее и полагаемся на [." "filename]#rc.d#, что `frotz` был запущен. В противном случае мы " "принудительно проверяем статус `frotz`. Наконец, мы принудительно " "устанавливаем зависимость от `frotz`, если обнаруживаем, что он не запущен. " "`force_depend` выдаст предупреждение, так как его следует вызывать только в " "случае обнаружения неправильной конфигурации." #. type: Title == #: documentation/content/en/articles/rc-scripting/_index.adoc:727 #, no-wrap msgid "Giving more flexibility to an rc.d script" msgstr "Придание большей гибкости скрипту rc.d" #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:736 msgid "" "When invoked during startup or shutdown, an [.filename]#rc.d# script is " "supposed to act on the entire subsystem it is responsible for. E.g., [." "filename]#/etc/rc.d/netif# should start or stop all network interfaces " "described by man:rc.conf[5]. Either task can be uniquely indicated by a " "single command argument such as `start` or `stop`. Between startup and " "shutdown, [.filename]#rc.d# scripts help the admin to control the running " "system, and it is when the need for more flexibility and precision arises. " "For instance, the admin may want to add the settings of a new network " "interface to man:rc.conf[5] and then to start it without interfering with " "the operation of the existing interfaces. Next time the admin may need to " "shut down a single network interface. In the spirit of the command line, " "the respective [.filename]#rc.d# script calls for an extra argument, the " "interface name." msgstr "" "При вызове во время запуска или завершения работы скрипт [.filename]#rc.d# " "должен воздействовать на всю подсистему, за которую он отвечает. Например, [." "filename]#/etc/rc.d/netif# должен запускать или останавливать все сетевые " "интерфейсы, описанные в man:rc.conf[5]. Любая из этих задач может быть " "однозначно указана единственным аргументом команды, таким как `start` или " "`stop`. Между запуском и завершением работы скрипты [.filename]#rc.d# " "помогают администратору управлять работающей системой, и именно тогда " "возникает потребность в большей гибкости и точности. Например, администратор " "может добавить настройки нового сетевого интерфейса в man:rc.conf[5], а " "затем запустить его, не затрагивая работу существующих интерфейсов. В " "следующий раз администратору может потребоваться остановить отдельный " "сетевой интерфейс. В духе командной строки, соответствующий скрипт [." "filename]#rc.d# требует дополнительного аргумента — имени интерфейса." #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:739 msgid "" "Fortunately, man:rc.subr[8] allows for passing any number of arguments to " "script's methods (within the system limits). Due to that, the changes in " "the script itself can be minimal." msgstr "" "К счастью, man:rc.subr[8] позволяет передавать любое количество аргументов " "(в пределах системных ограничений) методам скрипта. Благодаря этому " "изменения в самом скрипте могут быть минимальными." #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:744 msgid "" "How can man:rc.subr[8] gain access to the extra command-line arguments. " "Should it just grab them directly? Not by any means. Firstly, an man:sh[1] " "function has no access to the positional parameters of its caller, but man:" "rc.subr[8] is just a sack of such functions. Secondly, the good manner of [." "filename]#rc.d# dictates that it is for the main script to decide which " "arguments are to be passed to its methods." msgstr "" "Как man:rc.subr[8] может получить доступ к дополнительным аргументам " "командной строки. Должен ли он просто захватывать их напрямую? Ни в коем " "случае. Во-первых, функция man:sh[1] не имеет доступа к позиционным " "параметрам своего вызывающего объекта, но man:rc.subr[8] — это просто набор " "таких функций. Во-вторых, хороший стиль [.filename]#rc.d# предписывает, что " "именно главный скрипт должен решать, какие аргументы передавать его методам." #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:748 msgid "" "So the approach adopted by man:rc.subr[8] is as follows: `run_rc_command` " "passes on all its arguments but the first one to the respective method " "verbatim. The first, omitted, argument is the name of the method itself: " "`start`, `stop`, etc. It will be shifted out by `run_rc_command`, so what " "is `$2` in the original command line will be presented as `$1` to the " "method, and so on." msgstr "" "Итак, подход, принятый в man:rc.subr[8], следующий: `run_rc_command` " "передаёт все свои аргументы, кроме первого, в соответствующий метод в " "неизменном виде. Первый, опущенный аргумент — это имя самого метода: " "`start`, `stop` и т.д. Он будет удалён с помощью `shift` в `run_rc_command`, " "так что то, что было `$2` в оригинальной командной строке, будет " "представлено как `$1` в методе, и так далее." #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:751 msgid "" "To illustrate this opportunity, let us modify the primitive dummy script so " "that its messages depend on the additional arguments supplied. Here we go:" msgstr "" "Чтобы проиллюстрировать эту возможность, давайте изменим примитивный скрипт-" "заглушку так, чтобы его сообщения зависели от дополнительных переданных " "аргументов. Вот как это выглядит:" #. type: delimited block . 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:763 #, no-wrap msgid "" "name=\"dummy\"\n" "start_cmd=\"${name}_start\"\n" "stop_cmd=\":\"\n" "kiss_cmd=\"${name}_kiss\"\n" "extra_commands=\"kiss\"\n" msgstr "" "name=\"dummy\"\n" "start_cmd=\"${name}_start\"\n" "stop_cmd=\":\"\n" "kiss_cmd=\"${name}_kiss\"\n" "extra_commands=\"kiss\"\n" #. type: delimited block . 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:772 #, no-wrap msgid "" "dummy_start()\n" "{\n" " if [ $# -gt 0 ]; then <.>\n" " echo \"Greeting message: $*\"\n" " else\n" " echo \"Nothing started.\"\n" " fi\n" "}\n" msgstr "" "dummy_start()\n" "{\n" " if [ $# -gt 0 ]; then <.>\n" " echo \"Greeting message: $*\"\n" " else\n" " echo \"Nothing started.\"\n" " fi\n" "}\n" #. type: delimited block . 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:788 #, no-wrap msgid "" "dummy_kiss()\n" "{\n" " echo -n \"A ghost gives you a kiss\"\n" " if [ $# -gt 0 ]; then <.>\n" " echo -n \" and whispers: $*\"\n" " fi\n" " case \"$*\" in\n" " *[.!?])\n" " echo\n" " ;;\n" " *)\n" " echo .\n" " ;;\n" " esac\n" "}\n" msgstr "" "dummy_kiss()\n" "{\n" " echo -n \"A ghost gives you a kiss\"\n" " if [ $# -gt 0 ]; then <.>\n" " echo -n \" and whispers: $*\"\n" " fi\n" " case \"$*\" in\n" " *[.!?])\n" " echo\n" " ;;\n" " *)\n" " echo .\n" " ;;\n" " esac\n" "}\n" #. type: delimited block . 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:791 #, no-wrap msgid "" "load_rc_config $name\n" "run_rc_command \"$@\" <.>\n" msgstr "" "load_rc_config $name\n" "run_rc_command \"$@\" <.>\n" #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:794 msgid "What essential changes can we notice in the script?" msgstr "Какие основные изменения мы можем заметить в скрипте?" #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:799 msgid "" "➊ All arguments you type after `start` can end up as positional " "parameters to the respective method. We can use them in any way according " "to our task, skills, and fancy. In the current example, we just pass all of " "them to man:echo[1] as one string in the next line - note `$*` within the " "double quotes. Here is how the script can be invoked now:" msgstr "" "➊ Все аргументы, которые вы вводите после `start`, могут стать " "позиционными параметрами для соответствующего метода. Мы можем использовать " "их любым способом в соответствии с нашей задачей, навыками и предпочтениями. " "В текущем примере мы просто передаем все их в man:echo[1] как одну строку в " "следующей строке — обратите внимание на `$*` в двойных кавычках. Вот как " "теперь можно вызывать этот скрипт:" #. type: delimited block . 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:804 #, no-wrap msgid "" "# /etc/rc.d/dummy start\n" "Nothing started.\n" msgstr "" "# /etc/rc.d/dummy start\n" "Nothing started.\n" #. type: delimited block . 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:807 #, no-wrap msgid "" "# /etc/rc.d/dummy start Hello world!\n" "Greeting message: Hello world!\n" msgstr "" "# /etc/rc.d/dummy start Hello world!\n" "Greeting message: Hello world!\n" #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:811 msgid "" "➋ The same applies to any method our script provides, not only to a " "standard one. We have added a custom method named `kiss`, and it can take " "advantage of the extra arguments not less than `start` does. E.g.:" msgstr "" "➋ То же самое относится к любому методу, который предоставляет наш " "скрипт, не только к стандартному. Мы добавили пользовательский метод с " "именем `kiss`, и он может использовать дополнительные аргументы не меньше, " "чем `start`. Например:" #. type: delimited block . 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:816 #, no-wrap msgid "" "# /etc/rc.d/dummy kiss\n" "A ghost gives you a kiss.\n" msgstr "" "# /etc/rc.d/dummy kiss\n" "A ghost gives you a kiss.\n" #. type: delimited block . 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:819 #, no-wrap msgid "" "# /etc/rc.d/dummy kiss Once I was Etaoin Shrdlu...\n" "A ghost gives you a kiss and whispers: Once I was Etaoin Shrdlu...\n" msgstr "" "# /etc/rc.d/dummy kiss Once I was Etaoin Shrdlu...\n" "A ghost gives you a kiss and whispers: Once I was Etaoin Shrdlu...\n" #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:822 msgid "" "➌ If we want just to pass all extra arguments to any method, we can " "merely substitute `\"$@\"` for `\"$1\"` in the last line of our script, " "where we invoke `run_rc_command`." msgstr "" "➌ Если мы хотим просто передать все дополнительные аргументы любому " "методу, мы можем просто заменить `\"$@\"` на `\"$1\"` в последней строке " "нашего скрипта, где мы вызываем `run_rc_command`." #. type: delimited block = 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:828 msgid "" "An man:sh[1] programmer ought to understand the subtle difference between `" "$*` and `$@` as the ways to designate all positional parameters. For its in-" "depth discussion, refer to a good handbook on man:sh[1] scripting. _Do not_ " "use the expressions until you fully understand them because their misuse " "will result in buggy and insecure scripts." msgstr "" "Программист man:sh[1] должен понимать тонкую разницу между `$*` и `$@` как " "способами обозначения всех позиционных параметров. Для детального обсуждения " "обратитесь к хорошему руководству по написанию скриптов на man:sh[1]. _Не " "используйте_ эти выражения, пока полностью не поймёте их, так как их " "неправильное применение приведёт к созданию ненадёжных и небезопасных " "скриптов." #. type: delimited block = 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:835 msgid "" "Currently `run_rc_command` may have a bug that prevents it from keeping the " "original boundaries between arguments. That is, arguments with embedded " "whitespace may not be processed correctly. The bug stems from `$*` misuse." msgstr "" "В настоящее время в `run_rc_command` может присутствовать ошибка, которая " "мешает ему сохранять исходные границы между аргументами. То есть аргументы с " "встроенными пробелами могут обрабатываться некорректно. Ошибка возникает из-" "за неправильного использования `$*`." #. type: Title == #: documentation/content/en/articles/rc-scripting/_index.adoc:838 #, no-wrap msgid "Making a script ready for Service Jails" msgstr "Подготовка скрипта для сервисных клеток" #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:841 msgid "" "Scripts which start a long running service are suitable for service jails, " "and should come with a suitable service jail configuration." msgstr "" "Скрипты, запускающие долго работающую службу, подходят для служебных клеток " "и должны поставляться с соответствующей конфигурацией сервисной клетки." #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:843 msgid "" "Some examples of scripts which are not suitable to run in a service jail:" msgstr "" "Некоторые примеры скриптов, которые не подходят для запуска в сервисной " "клетке:" #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:845 msgid "" "any script which in the start command only changes a runtime setting for " "programs or the kernel," msgstr "" "любой скрипт, который в команде start только изменяет настройки времени " "выполнения для программ или ядра," #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:846 msgid "or tries to mount something," msgstr "или пытается что-то смонтировать," #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:847 msgid "or finds and deletes files" msgstr "или находит и удаляет файлы" #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:849 msgid "" "Scripts not suitable to run in a service jail need to prevent the use within " "service jails." msgstr "" "Необходимо предотвратить использование внутри сервисных клеток скриптов, не " "предназначенных для запуска в сервисной клетке." #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:851 msgid "" "A script with a long running service which needs to do something listed " "above before the start or after the stop, can either be split-up into two " "scripts with dependencies, or use the precommand and postcommand parts of " "the script to perform this action." msgstr "" "Скрипт с долго работающей службой, которому необходимо выполнить одно из " "перечисленных выше действий перед запуском или после остановки, может быть " "разделён на два скрипта с зависимостями или использовать части `precommand` " "и `postcommand` скрипта для выполнения этого действия." #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:854 msgid "" "By default, only the start and stop parts of a script are run within a " "service jail, the rest is run outside the jail. As such any setting used in " "the start/stop parts of the script can not be set from e.g. a precommand." msgstr "" "По умолчанию только части `start` и `stop` скрипта выполняются внутри " "сервисной клетки, остальное выполняется вне клетки. Таким образом, любые " "настройки, используемые в частях `start`/`stop` скрипта, не могут быть " "заданы, например, из `precommand`." #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:856 msgid "" "To make a script ready for use with extref:{handbook}jails[Service Jails, " "service-jails], only one more config line needs to be inserted:" msgstr "" "Чтобы сделать скрипт готовым к использованию с extref:{handbook}jails[" "Сервисными Клетками, service-jails], необходимо добавить всего лишь одну " "дополнительную конфигурационную строку:" #. type: delimited block . 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:866 #: documentation/content/en/articles/rc-scripting/_index.adoc:899 #, no-wrap msgid "" "name=\"dummy\"\n" "start_cmd=\"${name}_start\"\n" "stop_cmd=\":\"\n" msgstr "" "name=\"dummy\"\n" "start_cmd=\"${name}_start\"\n" "stop_cmd=\":\"\n" #. type: delimited block . 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:868 #, no-wrap msgid ": ${dummy_svcj_options:=\"\"} <.>\n" msgstr ": ${dummy_svcj_options:=\"\"} <.>\n" #. type: delimited block . 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:873 #: documentation/content/en/articles/rc-scripting/_index.adoc:904 #, no-wrap msgid "" "dummy_start()\n" "{\n" " echo \"Nothing started.\"\n" "}\n" msgstr "" "dummy_start()\n" "{\n" " echo \"Nothing started.\"\n" "}\n" #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:880 msgid "" "➊ If it makes sense that the script runs in a jail, it must have an " "overridable service jails configuration. If it does not need network access " "or access to any other resource which is restricted in jails, an empty " "config like displayed is enough." msgstr "" "➊ Если имеет смысл, чтобы скрипт выполнялся в клетке, он должен иметь " "переопределяемую конфигурацию сервисных клеток. Если ему не требуется доступ " "к сети или любым другим ресурсам, которые ограничены в клетках, достаточно " "пустой конфигурации, как показано." #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:885 msgid "" "Strictly speaking an empty config is not needed, but it explicitly describes " "that the script is service jails ready, and that it does not need additional " "jail permissions. As such it is highly recommended to add such an empty " "config in such a case. The most common option to use is \"net_basic\", " "which enables the use of the hosts IPv4 and IPv6 addresses. All possible " "options are explained in man:rc.conf[5]." msgstr "" "Строго говоря, пустая конфигурация не обязательна, но она явно указывает, " "что скрипт готов к работе с сервисными клетками и не требует дополнительных " "разрешений для клеток. Поэтому настоятельно рекомендуется добавить такую " "пустую конфигурацию в таком случае. Наиболее распространённая опция — " "\"net_basic\", которая позволяет использовать IPv4 и IPv6 адреса хоста. Все " "возможные опции описаны в man:rc.conf[5]." #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:887 msgid "" "If a setting for the start/stop depends on variables from the rc-framework " "(e.g., set inside man:rc.conf[5]), this needs to be handled by " "``load_rc_config`` and ``run_rc_command`` instead of inside a precommand." msgstr "" "Если настройка запуска/остановки зависит от переменных из rc-фреймворка " "(например, заданных в man:rc.conf[5]), это должно обрабатываться с помощью " "``load_rc_config`` и ``run_rc_command``, а не внутри precommand." #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:889 msgid "" "If for some reason a script can not be run within a service jail, e.g., " "because it is not possible to run or it does not make sense to run it in a " "jail, use the following:" msgstr "" "Если по какой-то причине скрипт не может быть запущен внутри сервисной " "клетки, например, потому что его невозможно запустить или нет смысла " "запускать его в клетке, используйте следующее:" #. type: delimited block . 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:908 #, no-wrap msgid "" "load_rc_config $name\n" "dummy_svcj=\"NO\"\t\t# does not make sense to run in a svcj <.>\n" "run_rc_command \"$1\"\n" msgstr "" "load_rc_config $name\n" "dummy_svcj=\"NO\"\t\t# does not make sense to run in a svcj <.>\n" "run_rc_command \"$1\"\n" #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:911 msgid "" "➊ The disabling needs to happen after the ``load_rc_config`` call, " "else a man:rc.conf[5] setting may override it." msgstr "" "➊ Отключение должно происходить после вызова ``load_rc_config``, " "иначе параметр из man:rc.conf[5] может переопределить его." #. type: Title == #: documentation/content/en/articles/rc-scripting/_index.adoc:913 #, no-wrap msgid "Advanced rc-scripting: Instancing" msgstr "Продвинутые сценарии rc: запуск нескольких экземпляров" #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:921 msgid "" "Sometimes it is useful to run several instances of a service. Typically you " "want to be able to start/stop such instances independently, and you want to " "have a separate config file for each instance. Each instance should be " "started at boot, survive updates, and benefit from updates." msgstr "" "Иногда полезно запускать несколько экземпляров службы. Обычно требуется " "иметь возможность независимо запускать/останавливать такие экземпляры, а " "также иметь отдельный файл конфигурации для каждого из них. Каждый экземпляр " "должен запускаться при загрузке, после обновления каждый экземпляр должен " "оставаться, и при этом должен обновиться." #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:923 msgid "Here is an example of a rc script which supports this:" msgstr "Вот пример rc-скрипта, который поддерживает это:" #. type: delimited block . 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:941 #, no-wrap msgid "" "#\n" "# PROVIDE: dummy\n" "# REQUIRE: NETWORKING SERVERS\n" "# KEYWORD: shutdown\n" "#\n" "# Add these following line to /etc/rc.conf.local or /etc/rc.conf\n" "# to enable this service:\n" "#\n" "# dummy_enable (bool):\tSet it to YES to enable dummy on startup.\n" "#\t\t\tDefault: NO\n" "# dummy_user (string):\tUser account to run with.\n" "#\t\t\tDefault: www\n" "#\n" msgstr "" "#\n" "# PROVIDE: dummy\n" "# REQUIRE: NETWORKING SERVERS\n" "# KEYWORD: shutdown\n" "#\n" "# Add these following line to /etc/rc.conf.local or /etc/rc.conf\n" "# to enable this service:\n" "#\n" "# dummy_enable (bool):\tSet it to YES to enable dummy on startup.\n" "#\t\t\tDefault: NO\n" "# dummy_user (string):\tUser account to run with.\n" "#\t\t\tDefault: www\n" "#\n" #. type: delimited block . 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:954 #, no-wrap msgid "" "case $0 in <.>\n" "/etc/rc*)\n" "\t# during boot (shutdown) $0 is /etc/rc (/etc/rc.shutdown),\n" "\t# so get the name of the script from $_file\n" "\tname=$_file\n" "\t;;\n" "*)\n" "\tname=$0\n" "\t;;\n" "esac\n" msgstr "" "case $0 in <.>\n" "/etc/rc*)\n" "\t# during boot (shutdown) $0 is /etc/rc (/etc/rc.shutdown),\n" "\t# so get the name of the script from $_file\n" "\tname=$_file\n" "\t;;\n" "*)\n" "\tname=$0\n" "\t;;\n" "esac\n" #. type: delimited block . 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:959 #, no-wrap msgid "" "name=${name##*/} <.>\n" "rcvar=\"${name}_enable\" <.>\n" "desc=\"Short description of this service\"\n" "command=\"/usr/local/sbin/dummy\"\n" msgstr "" "name=${name##*/} <.>\n" "rcvar=\"${name}_enable\" <.>\n" "desc=\"Short description of this service\"\n" "command=\"/usr/local/sbin/dummy\"\n" #. type: delimited block . 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:961 #, no-wrap msgid "load_rc_config \"$name\"\n" msgstr "load_rc_config \"$name\"\n" #. type: delimited block . 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:965 #, no-wrap msgid "" "eval \"${rcvar}=\\${${rcvar}:-'NO'}\" <.>\n" "eval \"${name}_svcj_options=\\${${name}_svcj_options:-'net_basic'}\" <.>\n" "eval \"_dummy_user=\\${${name}_user:-'www'}\" <.>\n" msgstr "" "eval \"${rcvar}=\\${${rcvar}:-'NO'}\" <.>\n" "eval \"${name}_svcj_options=\\${${name}_svcj_options:-'net_basic'}\" <.>\n" "eval \"_dummy_user=\\${${name}_user:-'www'}\" <.>\n" #. type: delimited block . 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:970 #, no-wrap msgid "" "_dummy_configname=/usr/local/etc/${name}.cfg <.>\n" "pidfile=/var/run/dummy/${name}.pid\n" "required_files ${_dummy_configname}\n" "command_args=\"-u ${_dummy_user} -c ${_dummy_configfile} -p ${pidfile}\"\n" msgstr "" "_dummy_configname=/usr/local/etc/${name}.cfg <.>\n" "pidfile=/var/run/dummy/${name}.pid\n" "required_files ${_dummy_configname}\n" "command_args=\"-u ${_dummy_user} -c ${_dummy_configfile} -p ${pidfile}\"\n" #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:978 msgid "" "➊ and ➋ make sure to set the name variable to the man:" "basename[1] of the script name. If the filename is [.filename]#/usr/local/" "etc/rc.d/dummy#, name is set to [.filename]#dummy#. This way changing the " "filename of the rc script changes automatically the content of the name " "variable." msgstr "" "➊ и ➋ убедитесь, что переменная name установлена в значение " "man:basename[1] имени скрипта. Если имя файла — [.filename]#/usr/local/etc/" "rc.d/dummy#, то name будет установлено в [.filename]#dummy#. Таким образом, " "изменение имени rc-скрипта автоматически изменит содержимое переменной name." #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:981 msgid "" "➌ specifies the variable name which is used in [.filename]#rc.conf# " "to enable this service based upon the filename of this script. In this " "example this resolves to dummy_enable." msgstr "" "➌ указывает имя переменной, которая используется в [.filename]#rc." "conf# для включения этой службы на основе имени файла этого скрипта. В " "данном примере это преобразуется в dummy_enable." #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:983 msgid "➍ makes sure the default for the _enable variable is NO." msgstr "" "➍ убеждается, что значение по умолчанию для переменной _enable " "установлено в NO." #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:986 msgid "" "➎ is an example of having some defaults for service specific " "framework variables, in this case the service jails options." msgstr "" "➎ Вот пример установки некоторых значений по умолчанию для переменных " "фреймворка, специфичных для службы, в данном случае — опций клетки службы." #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:988 msgid "" "➏ and ➐ set variables internal to the script (pay attention to " "the underscore in front of _dummy_user to make it different from dummy_user " "which can be set in [.filename]#rc.conf#)." msgstr "" "➏ и ➐ устанавливают переменные, внутренние для скрипта " "(обратите внимание на подчёркивание в начале _dummy_user, чтобы отличать её " "от dummy_user, которая может быть задана в [.filename]#rc.conf#)." #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:991 msgid "" "The part in ➎ is for variables which are not used inside the script " "itself but in the rc framework. All the variables which are used as " "parameters somewhere in the script are assigned to a generic variable like " "in ➐ to make it more easy to reference them (no need to eval them at " "each place of use)." msgstr "" "Часть в ➎ предназначена для переменных, которые не используются " "внутри самого скрипта, но используются в рамках rc. Все переменные, которые " "используются как параметры в скрипте, присваиваются общей переменной, как в " "➐, чтобы упростить их использование (нет необходимости выполнять eval " "при каждом обращении)." #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:994 msgid "" "This script will now behave differently if the start script has a different " "name. This allows to create symlinks to it:" msgstr "" "Этот скрипт теперь будет вести себя по-другому, если скрипт запуска имеет " "другое имя. Это позволяет создавать символьные ссылки на него:" #. type: delimited block . 4 #: documentation/content/en/articles/rc-scripting/_index.adoc:1000 #, no-wrap msgid "" "# ln -s dummy /usr/local/etc/rc.d/dummy_foo\n" "# sysrc dummy_foo_enable=YES\n" "# service dummy_foo start\n" msgstr "" "# ln -s dummy /usr/local/etc/rc.d/dummy_foo\n" "# sysrc dummy_foo_enable=YES\n" "# service dummy_foo start\n" #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:1005 msgid "" "The above creates an instance of the dummy service with the name dummy_foo. " "It does not use the config file [.filename]#/usr/local/etc/dummy.cfg# but " "the config file [.filename]#/usr/local/etc/dummy_foo.cfg# (➐), and it " "uses the PID file [.filename]#/var/run/dummy/dummy_foo.pid# instead of [." "filename]#/var/run/dummy/dummy.pid#." msgstr "" -"Вышеприведённое создает экземпляр службы dummy с именем dummy_foo. Он " +"Вышеприведённое создаёт экземпляр службы dummy с именем dummy_foo. Он " "использует не файл конфигурации [.filename]#/usr/local/etc/dummy.cfg#, а " "файл конфигурации [.filename]#/usr/local/etc/dummy_foo.cfg# (➐), и " "использует PID-файл [.filename]#/var/run/dummy/dummy_foo.pid# вместо [." "filename]#/var/run/dummy/dummy.pid#." #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:1012 msgid "" "The services dummy and dummy_foo can be managed independently of each other, " "while having the start script update itself on package update (due to the " "symlink). This does not update the REQUIRE line, as such there is no easy " "way of depending on a specific instance. To depend upon a specific instance " "in the startup order a copy needs to be made instead of using a symlink. " "This prevents the automatic pick-up of changes to the start script when an " "update is installed." msgstr "" "Сервисы dummy и dummy_foo могут управляться независимо друг от друга, при " "этом скрипт запуска обновляется автоматически при обновлении пакета " "(благодаря символьной ссылке). Это не обновляет строку REQUIRE, поэтому нет " "простого способа зависеть от конкретного экземпляра. Чтобы зависеть от " "конкретного экземпляра в порядке запуска, необходимо создать копию вместо " "использования символьной ссылки. Это предотвращает автоматическое применение " "изменений в скрипте запуска при установке обновления." #. type: Title == #: documentation/content/en/articles/rc-scripting/_index.adoc:1014 #, no-wrap msgid "Further reading" msgstr "Дополнительная литература" #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:1018 msgid "" "[[lukem]]http://www.mewburn.net/luke/papers/rc.d.pdf[The original article by " "Luke Mewburn] offers a general overview of [.filename]#rc.d# and detailed " "rationale for its design decisions. It provides insight on the whole [." "filename]#rc.d# framework and its place in a modern BSD operating system." msgstr "" "[[lukem]]http://www.mewburn.net/luke/papers/rc.d.pdf[Оригинальная статья " "Люка Мьюберна] предлагает общий обзор [.filename]#rc.d# и подробное " "обоснование принятых при его проектировании решений. В ней представлено " "понимание всего фреймворка [.filename]#rc.d# и его места в современной BSD-" "системе." #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:1021 msgid "" "[[manpages]]The manual pages man:rc[8], man:rc.subr[8], and man:rcorder[8] " "document the [.filename]#rc.d# components in great detail. You cannot fully " "use the [.filename]#rc.d# power without studying the manual pages and " "referring to them while writing your own scripts." msgstr "" "[[manpages]]Руководства man:rc[8], man:rc.subr[8] и man:rcorder[8] подробно " "описывают компоненты [.filename]#rc.d#. Без изучения этих руководств и " "обращения к ним при написании собственных скриптов невозможно в полной мере " "использовать возможности [.filename]#rc.d#." #. type: Plain text #: documentation/content/en/articles/rc-scripting/_index.adoc:1025 msgid "" "The major source of working, real-life examples is [.filename]#/etc/rc.d# in " "a live system. Its contents are easy and pleasant to read because most " "rough corners are hidden deep in man:rc.subr[8]. Keep in mind though that " "the [.filename]#/etc/rc.d# scripts were not written by angels, so they might " "suffer from bugs and suboptimal design decisions. Now you can improve them!" msgstr "" "Основным источником рабочих, жизненных примеров является [.filename]#/etc/rc." "d# в работающей системе. Его содержимое легко и приятно читать, поскольку " "большинство сложных моментов скрыто глубоко в man:rc.subr[8]. Однако " "помните, что скрипты в [.filename]#/etc/rc.d# были написаны не ангелами, " "поэтому они могут содержать ошибки и неоптимальные решения. Теперь вы можете " "их улучшить!" diff --git a/documentation/content/ru/articles/releng/_index.adoc b/documentation/content/ru/articles/releng/_index.adoc index 1ccbba5108..6ec8b123c5 100644 --- a/documentation/content/ru/articles/releng/_index.adoc +++ b/documentation/content/ru/articles/releng/_index.adoc @@ -1,358 +1,358 @@ --- authors: - author: 'Murray Stokely' email: murray@FreeBSD.org webpage: https://people.FreeBSD.org/~murray/ description: 'В этом документе описывается подход, ранее использовавшийся командой разработки релизов FreeBSD для создания релизов операционной системы FreeBSD производственного качества' tags: ["Release", "Engineering", "Historical", "FreeBSD"] title: 'Устаревшая разработка релизов FreeBSD' trademarks: ["freebsd", "intel", "general"] --- = Подготовка релизов FreeBSD :doctype: article :toc: macro :toclevels: 1 :icons: font :sectnums: :sectnumlevels: 6 :source-highlighter: rouge :experimental: :images-path: articles/releng/ ifdef::env-beastie[] ifdef::backend-html5[] include::shared/authors.adoc[] include::shared/mirrors.adoc[] include::shared/releases.adoc[] include::shared/attributes/attributes-{{% lang %}}.adoc[] include::shared/{{% lang %}}/teams.adoc[] include::shared/{{% lang %}}/mailing-lists.adoc[] include::shared/{{% lang %}}/urls.adoc[] :imagesdir: ../../../images/{images-path} endif::[] ifdef::backend-pdf,backend-epub3[] include::../../../../shared/asciidoctor.adoc[] endif::[] endif::[] ifndef::env-beastie[] include::../../../../../shared/asciidoctor.adoc[] endif::[] [.abstract-title] Аннотация [NOTE] ==== Этот документ устарел и не точно описывает текущие процедуры выпуска релизов команды FreeBSD Release Engineering. Он сохранен в исторических целях. Текущие процедуры, используемые командой FreeBSD Release Engineering, доступны в статье extref:{freebsd-releng}[FreeBSD Release Engineering]. ==== В этом документе описывается подход, используемый командой разработки релизов FreeBSD для создания релизов операционной системы FreeBSD производственного качества. Подробно излагается методология, применяемая для официальных выпусков FreeBSD, а также описываются инструменты, доступные тем, кто заинтересован в создании собственных релизов FreeBSD для корпоративного внедрения или использования в коммерческой деятельности. ''' toc::[] [[introduction]] == Введение -Разработка FreeBSD — это очень открытый процесс. FreeBSD создается благодаря вкладу тысяч людей по всему миру. Проект FreeBSD предоставляет доступ к Subversion footnote:[Subversion, http://subversion.apache.org] для широкой публики, чтобы другие могли просматривать сообщения журнала, различия (патчи) между ветками разработки и другие улучшения производительности, которые предоставляет система управления исходным кодом. Это значительно помогло привлечь больше талантливых разработчиков в FreeBSD. Однако, я думаю, все согласятся, что хаос быстро воцарился бы, если бы право записи в основной репозиторий было открыто для всех в Интернете. Поэтому только «избранная» группа из почти 300 человек имеет право записи в репозиторий Subversion. Эти extref:{contributors}[коммиттеры FreeBSD, staff-committers]footnote:[extref:{contributors}[коммиттеры FreeBSD, staff-committers]] обычно являются людьми, которые выполняют основную часть разработки FreeBSD. Выбранная группа разработчиков — link:https://www.FreeBSD.org/administration/#t-core[Основная команда (Core Team)]footnote:[link:https://www.FreeBSD.org/administration/#t-core[Основная команда FreeBSD]] — обеспечивает некоторый уровень руководства проектом. +Разработка FreeBSD — это очень открытый процесс. FreeBSD создаётся благодаря вкладу тысяч людей по всему миру. Проект FreeBSD предоставляет доступ к Subversion footnote:[Subversion, http://subversion.apache.org] для широкой публики, чтобы другие могли просматривать сообщения журнала, различия (патчи) между ветками разработки и другие улучшения производительности, которые предоставляет система управления исходным кодом. Это значительно помогло привлечь больше талантливых разработчиков в FreeBSD. Однако, я думаю, все согласятся, что хаос быстро воцарился бы, если бы право записи в основной репозиторий было открыто для всех в Интернете. Поэтому только «избранная» группа из почти 300 человек имеет право записи в репозиторий Subversion. Эти extref:{contributors}[коммиттеры FreeBSD, staff-committers]footnote:[extref:{contributors}[коммиттеры FreeBSD, staff-committers]] обычно являются людьми, которые выполняют основную часть разработки FreeBSD. Выбранная группа разработчиков — link:https://www.FreeBSD.org/administration/#t-core[Основная команда (Core Team)]footnote:[link:https://www.FreeBSD.org/administration/#t-core[Основная команда FreeBSD]] — обеспечивает некоторый уровень руководства проектом. Быстрый темп разработки `FreeBSD` делает основную ветку разработки непригодной для повседневного использования широкой публикой. В частности, требуются усилия по стабилизации для доведения системы разработки до релиза производственного качества. Для решения этого конфликта разработка продолжается по нескольким параллельным направлениям. Основная ветка разработки — это _HEAD_ или _trunk_ нашего дерева Subversion, известная как "FreeBSD-CURRENT" или сокращённо "-CURRENT". Набор более стабильных ветвей поддерживается под названием "FreeBSD-STABLE" или сокращённо "-STABLE". Все ветви находятся в главном хранилище Subversion, которое поддерживается проектом FreeBSD. FreeBSD-CURRENT — это "передний край" разработки FreeBSD, куда сначала попадают все новые изменения. FreeBSD-STABLE — это ветвь разработки, на основе которой выпускаются основные релизы. Изменения попадают в эту ветвь с другой скоростью и с общим предположением, что они сначала попали в FreeBSD-CURRENT и были тщательно протестированы сообществом пользователей. Термин _stable_ в названии ветки относится к предполагаемой стабильности бинарного интерфейса приложений (ABI), которую гарантирует проект. Это означает, что пользовательское приложение, скомпилированное на более старой версии системы из той же ветки, будет работать на более новой системе из той же ветки. Стабильность ABI значительно улучшилась по сравнению с предыдущими выпусками. В большинстве случаев бинарные файлы со старых систем _STABLE_ работают без изменений на более новых системах, включая __HEAD__, при условии, что не используются интерфейсы управления системой. В промежуточный период между выпусками еженедельные снимки состояния системы автоматически создаются сборщиками FreeBSD Project и доступны для загрузки по адресу `https:/download.FreeBSD.org/snapshots/`. Широкое распространение бинарных снимков выпусков, а также склонность нашего сообщества пользователей следить за разработкой -STABLE с помощью Subversion и команды "`make buildworld`" footnote:[extref:{handbook}cutting-edge[Пересборка world, makeworld]] помогает поддерживать FreeBSD-STABLE в очень надёжном состоянии даже до того, как будут запущены мероприятия по обеспечению качества перед основным выпуском. Помимо снимков установочных ISO, также предоставляются еженедельные образы виртуальных машин для использования с VirtualBox, qemu или другим популярным эмуляционным программным обеспечением. Образы виртуальных машин можно загрузить с `https://download.FreeBSD.org/snapshots/VM-IMAGES/`. Образы виртуальных машин сжаты с помощью man:xz[1] и занимают примерно 150 МБ, а при подключении к виртуальной машине содержат разреженную файловую систему размером 10 ГБ. Отчёты об ошибках и запросы функций постоянно отправляются пользователями в течение цикла выпуска. Сообщения о проблемах вносятся в нашу базу данных Bugzilla через веб-интерфейс, доступный по адресу https://www.freebsd.org/support/bugreports/[https://www.freebsd.org/support/bugreports/]. Для обслуживания наиболее консервативных пользователей, начиная с FreeBSD 4.3, были введены индивидуальные ветки релизов. Эти ветки создаются незадолго до выпуска финального релиза. После выхода релиза на ветку вносятся только самые критические исправления безопасности и дополнения. Помимо обновлений исходного кода через Subversion, доступны бинарные патч-наборы для поддержания актуальности систем на ветках _releng/X.Y_. === Что описывает эта статья Следующие разделы этой статьи описывают: crossref:releng[release-proc, Процесс выпуска релиза]:: Различные этапы процесса разработки релиза, предшествующие непосредственной сборке системы. crossref:releng[release-build, Сборка релиза]:: Фактический процесс сборки. crossref:releng[extensibility, Расширяемость]:: Как базовый выпуск может быть расширен третьими сторонами. crossref:releng[lessons-learned, Уроки, извлеченные из FreeBSD 4.4]:: Некоторые уроки, извлеченные в процессе выпуска FreeBSD 4.4. crossref:releng[future, Перспективы развития]:: Перспективные направления развития. [[release-proc]] == Процесс выпуска релиза Новые выпуски FreeBSD выходят из ветки -STABLE примерно с интервалом в четыре месяца. Процесс выпуска FreeBSD начинает набирать обороты за 70-80 дней до предполагаемой даты выпуска, когда инженер выпуска отправляет электронное письмо в списки рассылки разработчиков, напоминая им, что у них осталось всего 15 дней для интеграции новых изменений до заморозки кода. В это время многие разработчики выполняют так называемые "MFC-проверки". MFC означает "Merge From CURRENT" и описывает процесс переноса проверенного изменения из нашей ветки разработки -CURRENT в ветку -STABLE. Политика проекта требует, чтобы любое изменение сначала было применено к основной ветке, а затем перенесено в ветки -STABLE после достаточного внешнего тестирования пользователями -CURRENT (ожидается, что разработчики тщательно проверят изменение перед внесением в -CURRENT, но невозможно для одного человека проверить все варианты использования универсальной операционной системы). Минимальный срок для MFC составляет 3 дня, который обычно используется только для тривиальных или критических исправлений ошибок. === Проверка кода За шестьдесят дней до предполагаемого релиза репозиторий исходного кода переходит в режим «заморозки кода». В этот период все коммиты в ветку -STABLE должны быть одобрены `{re}`. Процесс утверждения технически обеспечивается предкоммитным хуком. В этот период допускаются следующие виды изменений: * Исправления ошибок. * Обновления документации. * Исправления, связанные с безопасностью, любого рода. * Незначительные изменения в драйверах устройств, такие как добавление новых идентификаторов устройств. * Обновления драйверов от поставщиков. * Любое дополнительное изменение, которое команда разработки релизов сочтет оправданным, учитывая потенциальный риск. Вскоре после начала заморозки кода создаётся образ _BETA1_ и выпускается для широкого тестирования. В период заморозки кода не реже чем раз в две недели выпускается как минимум один бета-образ или кандидат в релизы, пока не будет готов финальный выпуск. В дни, предшествующие финальному релизу, команда разработки выпусков постоянно взаимодействует с командой security-officer, сопровождающими документации и сопровождающими портов, чтобы убедиться, что все необходимые компоненты для успешного релиза доступны. -После того, как качество BETA-образов становится достаточно удовлетворительным и не планируется крупных и потенциально рискованных изменений, создается ветка релиза, и образы _Release Candidate_ (RC) собираются из ветки релиза, вместо BETA-образов из ветки STABLE. Также снимается заморозка изменений в ветке STABLE, а ветка релиза переходит в режим "жёсткой заморозки кода", когда становится значительно сложнее обосновать новые изменения в системе, за исключением исправления серьезных ошибок или проблем безопасности. +После того, как качество BETA-образов становится достаточно удовлетворительным и не планируется крупных и потенциально рискованных изменений, создаётся ветка релиза, и образы _Release Candidate_ (RC) собираются из ветки релиза, вместо BETA-образов из ветки STABLE. Также снимается заморозка изменений в ветке STABLE, а ветка релиза переходит в режим "жёсткой заморозки кода", когда становится значительно сложнее обосновать новые изменения в системе, за исключением исправления серьезных ошибок или проблем безопасности. === Контрольный список финального выпуска Когда несколько образов BETA станут доступны для широкого тестирования и все основные проблемы будут устранены, можно приступать к финальной "доводке" выпуска. [[rel-branch]] ==== Создание ветки релиза [NOTE] ==== Во всех примерах ниже `$FSVN` указывает на расположение репозитория Subversion FreeBSD, `svn+ssh://svn.FreeBSD.org/base/`. ==== Расположение веток FreeBSD в Subversion описано в extref:{committers-guide}[Руководстве коммиттера, subversion-primer-base-layout]. Первым шагом в создании ветки является определение ревизии исходников `stable/_X_`, от которой вы хотите сделать _ответвление_. [source, shell] .... # svn log -v $FSVN/stable/9 .... Следующий шаг — создание _ветки релиза_ [source, shell] .... # svn cp $FSVN/stable/9@REVISION $FSVN/releng/9.2 .... Эту ветку можно извлечь: [source, shell] .... # svn co $FSVN/releng/9.2 src .... [NOTE] ==== Создание ветки `releng` и тегов `release` выполняется командой link:https://www.FreeBSD.org/administration/#t-re[Release Engineering Team]. ==== image::branches-head.png["Ветка разработки FreeBSD"] image::branches-releng3.png["Ветка STABLE FreeBSD 3.x"] image::branches-releng4.png["Ветка FreeBSD 4.x STABLE"] image::branches-releng5.png["Ветка STABLE FreeBSD 5.x"] image::branches-releng6.png["Ветка FreeBSD 6.x STABLE"] image::branches-releng7.png["Ветка FreeBSD 7.x STABLE"] image::branches-releng8.png["Ветка FreeBSD 8.x STABLE"] image::branches-releng9.png["Ветка FreeBSD 9.x STABLE"] [[versionbump]] ==== Увеличение номера версии Перед тем как финальный выпуск может быть помечен, собран и выпущен, следующие файлы должны быть изменены, чтобы отражать корректную версию FreeBSD: * [.filename]#doc/en_US.ISO8859-1/books/handbook/mirrors/chapter.xml# * [.filename]#doc/en_US.ISO8859-1/books/porters-handbook/book.xml# * [.filename]#doc/en_US.ISO8859-1/htdocs/cgi/ports.cgi# * [.filename]#ports/Tools/scripts/release/config# * [.filename]#doc/shared/xml/freebsd.ent# * [.filename]#src/Makefile.inc1# * [.filename]#src/UPDATING# * [.filename]#src/gnu/usr.bin/groff/tmac/mdoc.local# * [.filename]#src/release/Makefile# * [.filename]#src/release/doc/en_US.ISO8859-1/shared/xml/release.dsl# * [.filename]#src/release/doc/shared/examples/Makefile.relnotesng# * [.filename]#src/release/doc/shared/xml/release.ent# * [.filename]#src/sys/conf/newvers.sh# * [.filename]#src/sys/sys/param.h# * [.filename]#src/usr.sbin/pkg_install/add/main.c# * [.filename]#doc/en_US.ISO8859-1/htdocs/search/opensearch/man.xml# Заметки о выпуске и файлы с опечатками также необходимо адаптировать для нового выпуска (в ветке выпуска) и соответствующим образом обрезать (в ветке stable/current): * [.filename]#src/release/doc/en_US.ISO8859-1/relnotes/common/new.xml# * [.filename]#src/release/doc/en_US.ISO8859-1/errata/article.xml# В Sysinstall следует добавить информацию о количестве доступных портов и объёме дискового пространства, необходимого для коллекции портов. footnote:[Коллекция портов FreeBSD https://ports.FreeBSD.org] В настоящее время эта информация хранится в [.filename]#src/usr.sbin/bsdinstall/dist.c#. После сборки выпуска следует обновить ряд файлов, чтобы объявить о выпуске. Эти файлы находятся относительно `head/` в поддереве `doc/` Subversion. * [.filename]#share/images/articles/releng/branches-relengX.pic# * [.filename]#head/shared/xml/release.ent# * [.filename]#en_US.ISO8859-1/htdocs/releases/*# * [.filename]#en_US.ISO8859-1/htdocs/releng/index.xml# * [.filename]#share/xml/news.xml# Кроме того, обновите файл "Генеалогическое древо BSD": * [.filename]#src/shared/misc/bsd-family-tree# ==== Создание тега релиза Когда финальный выпуск будет готов, следующая команда создаст тег `release/9.2.0`. [source, shell] .... # svn cp $FSVN/releng/9.2 $FSVN/release/9.2.0 .... Менеджеры документации и портов ответственны за добавление тега `tags/RELEASE_9_2_0` в соответствующие деревья. Когда команда Subversion `svn cp` используется для создания __тега релиза (release tag)__, это идентифицирует исходный код на определённый момент времени. Создавая теги, мы гарантируем, что будущие сборщики релизов всегда смогут использовать тот же исходный код, который использовался для создания официальных релизов проекта FreeBSD. [[release-build]] == Сборка релиза Сборка "релизов" FreeBSD может быть выполнена любым пользователем, имеющим быстрый компьютер и доступ к репозиторию исходного кода. (Это должно быть доступно каждому, так как мы предоставляем доступ через Subversion! Подробности см. в extref:{handbook}[разделе Subversion в Руководстве, svn].) _Единственное_ специальное требование — доступность устройства man:md[4]. Если устройство не загружено в ваше ядро, то модуль ядра должен автоматически загрузиться при выполнении man:mdconfig[8] во время этапа создания загрузочного носителя. Все необходимые инструменты для сборки релиза доступны в репозитории Subversion в [.filename]#src/release#. Эти инструменты предназначены для обеспечения единообразного способа сборки релизов FreeBSD. Полный релиз может быть собран всего одной командой, включая создание ISO-образов, пригодных для записи на CDROM или DVD, а также каталога для установки по FTP. man:release[7] полностью документирует скрипт `src/release/generate-release.sh`, который используется для сборки релиза. `generate-release.sh` является обёрткой для цели Makefile: `make release`. === Сборка релиза man:release[7] документирует точные команды, необходимые для сборки релиза FreeBSD. Следующая последовательность команд может собрать релиз 9.2.0: [source, shell] .... # cd /usr/src/release # sh generate-release.sh release/9.2.0 /local3/release .... После выполнения этих команд все подготовленные файлы релиза будут доступны в каталоге [.filename]#/local3/release/R#. Файл [.filename]#Makefile# для выпуска можно разбить на несколько отдельных этапов. * Создание изолированного окружения системы в отдельной иерархии каталогов с помощью "`make installworld`". * Извлечение из Subversion чистой версии исходного кода системы, документации и портов в иерархию сборки релиза. * Заполнение каталогов [.filename]#/etc# и [.filename]#/dev# в chroot-окружении. * Изменение корневого каталога на верхний каталог иерархии сборки релиза с помощью `chroot`, чтобы усложнить влияние внешней среды на эту сборку. * Запуск `make world` в окружении `chroot`. * Сборка связанных с Kerberos бинарных файлов. * Сборка ядра [.filename]#GENERIC#. * Создание промежуточной структуры каталогов, в которой будут собираться и упаковываться бинарные дистрибутивы. * Сборка и установка инструментария для документации, необходимого для преобразования исходников документации (SGML) в HTML и текстовые документы, которые будут поставляться с релизом. * Сборка и установка непосредственно документации (руководства пользователя, учебные пособия, примечания к выпуску, списки совместимого оборудования и так далее). * Создание распространяемых tar-архивов с бинарными файлами и исходными кодами. * Создание иерархии установки FTP. * _(необязательно)_ Создание ISO-образов для носителей CDROM/DVD. Для получения дополнительной информации о инфраструктуре сборки релизов, обратитесь к man:release[7]. [NOTE] ==== Важно удалить все специфичные для сайта настройки из [.filename]#/etc/make.conf#. Например, было бы неразумно распространять бинарные файлы, собранные на системе с установленным `CPUTYPE` для конкретного процессора. ==== === Предоставленное программное обеспечение ("порты") https://ports.FreeBSD.org[Коллекция портов FreeBSD] представляет собой набор из более чем {numports} сторонних программных пакетов, доступных для FreeBSD. `{portmgr}` отвечает за поддержание согласованного дерева портов, которое может быть использовано для создания бинарных пакетов, поставляемых с официальными выпусками FreeBSD. === Релизные ISO-образы Начиная с FreeBSD 4.4, проект FreeBSD решил выпустить все четыре образа ISO, которые ранее продавались на «официальных» дистрибутивах CDROM от _BSDi/Wind River Systems/FreeBSD Mall_. Каждый из четырёх дисков должен содержать файл [.filename]#README.TXT#, объясняющий содержимое диска, файл [.filename]#CDROM.INF#, предоставляющий метаданные для диска, чтобы man:bsdinstall[8] мог проверить и использовать содержимое, и файл [.filename]#filename.txt#, содержащий манифест диска. Этот _манифест_ можно создать простой командой: [source, shell] .... /stage/cdrom# find . -type f | sed -e 's/^\.\///' | sort > filename.txt .... Конкретные требования для каждого CD приведены ниже. ==== Диск 1 Первый диск почти полностью создаётся командой `make release`. Единственные изменения, которые следует внести в каталог [.filename]#disc1#, — это добавление каталога [.filename]#tools# и как можно большего количества популярных сторонних программных пакетов, которые поместятся на диск. В каталоге [.filename]#tools# содержится программное обеспечение, позволяющее пользователям создавать установочные дискеты из других операционных систем. Этот диск должен быть загрузочным, чтобы пользователям современных ПК не требовалось создавать установочные дискеты. Если требуется включить пользовательское ядро FreeBSD, необходимо обновить man:bsdinstall[8] и man:release[7], чтобы включить инструкции по установке. Соответствующий код содержится в [.filename]#src/release# и [.filename]#src/usr.sbin/bsdinstall#. В частности, потребуется обновить файл [.filename]#src/release/Makefile#, а также [.filename]#dist.c#, [.filename]#dist.h#, [.filename]#menus.c#, [.filename]#install.c# и [.filename]#Makefile# в каталоге [.filename]#src/usr.sbin/bsdinstall#. При желании можно также обновить [.filename]#bsdinstall.8#. ==== Диск 2 Второй диск также в основном создаётся командой `make release`. Этот диск содержит «живую файловую систему», которая может использоваться через man:bsdinstall[8] для диагностики установки FreeBSD. Этот диск должен быть загрузочным и также содержать сжатую копию репозитория CVS в каталоге [.filename]#CVSROOT# и демонстрационные версии коммерческого ПО в каталоге [.filename]#commerce#. ==== Поддержка нескольких томов Sysinstall поддерживает установку пакетов с нескольких томов. Для этого каждый диск должен содержать файл [.filename]#INDEX#, в котором перечислены все пакеты на всех томах набора, а также дополнительное поле, указывающее, на каком именно томе находится конкретный пакет. Каждый том в наборе также должен иметь установленную переменную `CD_VOLUME` в файле [.filename]#cdrom.inf#, чтобы bsdinstall мог определить, какой том является каким. Когда пользователь пытается установить пакет, которого нет на текущем диске, bsdinstall предложит ему вставить соответствующий диск. [[distribution]] == Распространение [[dist-ftp]] === Сайты FTP Когда выпуск тщательно протестирован и упакован для распространения, необходимо обновить главный FTP-сайт. Официальные публичные FTP-сайты FreeBSD являются зеркалами главного сервера, который доступен только другим FTP-сайтам. Этот сервер известен как `ftp-master`. Когда выпуск готов, следующие файлы должны быть изменены на `ftp-master`: [.filename]#/pub/FreeBSD/releases/arch/X.Y-RELEASE/#:: Устанавливаемый каталог FTP, полученный в результате выполнения `make release`. [.filename]#/pub/FreeBSD/ports/arch/packages-X.Y-release/#:: Полная сборка пакетов для этого выпуска. [.filename]#/pub/FreeBSD/releases/arch/X.Y-RELEASE/tools#:: Символическая ссылка на [.filename]#../../../tools#. [.filename]#/pub/FreeBSD/releases/arch/X.Y-RELEASE/packages#:: Символическая ссылка на [.filename]#../../../ports/arch/packages-X.Y-release#. [.filename]#/pub/FreeBSD/releases/arch/ISO-IMAGES/X.Y/X.Y-RELEASE-arch-*.iso#:: Образы ISO. Символ "*" обозначает [.filename]#disc1#, [.filename]#disc2# и так далее. Только если существует [.filename]#disc1# и есть альтернативный первый установочный CD (например, упрощённая установка без графической оболочки), может также присутствовать [.filename]#mini#. Для получения дополнительной информации об архитектуре зеркал распространения FTP-сайтов FreeBSD, пожалуйста, ознакомьтесь со статьей extref:{hubs}[Поддержка зеркал FreeBSD]. Может потребоваться от нескольких часов до двух дней после обновления `ftp-master`, прежде чем большинство FTP-сайтов Tier-1 получат новое программное обеспечение, в зависимости от того, был ли загружен набор пакетов одновременно. Крайне важно, чтобы инженеры по выпуску скоординировались с {mirror-announce} перед объявлением общей доступности нового программного обеспечения на FTP-сайтах. В идеале набор пакетов для выпуска должен быть загружен как минимум за четыре дня до дня выпуска. Выпускные файлы должны быть загружены за 24–48 часов до запланированного времени выпуска с отключёнными разрешениями для "других" пользователей. Это позволит зеркальным сайтам загрузить их, но широкая публика не сможет скачать их с зеркальных сайтов. Письмо должно быть отправлено в {mirror-announce} в момент публикации выпускных файлов, уведомляя о том, что выпуск подготовлен, и указывая время, когда зеркальные сайты должны начать разрешать доступ. Обязательно укажите часовой пояс для указанного времени, например, относительно GMT. [[dist-cdrom]] === Репликация CD-ROM Скоро: Советы по отправке ISO-образов FreeBSD репликатору и меры по обеспечению качества. [[extensibility]] == Расширяемость Хотя FreeBSD представляет собой законченную операционную систему, ничто не обязывает вас использовать её именно в том виде, в каком мы упаковали её для распространения. Мы постарались разработать систему максимально расширяемой, чтобы она могла служить платформой для создания других коммерческих продуктов. Единственное «правило», которое у нас есть на этот счёт, — если вы собираетесь распространять FreeBSD с существенными изменениями, мы рекомендуем документировать ваши улучшения! Сообщество FreeBSD может оказывать поддержку только пользователям того программного обеспечения, которое мы предоставляем. Мы, безусловно, приветствуем инновации, такие как продвинутые инструменты установки и администрирования, но не можем отвечать на вопросы о них. === Скриптинг `bsdinstall` Инструмент установки и настройки системы FreeBSD, man:bsdinstall[8], может быть настроен для автоматизированной установки на крупных площадках. Эта функциональность может использоваться совместно с Intel(R) PXE footnote:[extref:{handbook}advanced-networking[Запуск системы по сети (PXE) без использования локальных накопителей, network-diskless]] для загрузки систем по сети. [[lessons-learned]] == Уроки, извлеченные из FreeBSD 4.4 Процесс разработки релиза 4.4 официально начался 1 августа 2001 года. После этой даты все коммиты в ветку `RELENG_4` FreeBSD должны были быть явно одобрены `{re}`. Первый релиз-кандидат для архитектуры x86 был выпущен 16 августа, за ним последовали ещё 4 релиз-кандидата, что привело к финальному релизу 18 сентября. Сотрудник по безопасности был очень вовлечён в последнюю неделю процесса, так как несколько проблем безопасности было обнаружено в ранних релиз-кандидатах. Всего за чуть более месяца было отправлено более _500_ писем `{re}`. Наше сообщество пользователей ясно дало понять, что безопасность и стабильность выпуска FreeBSD не должны приноситься в жертву из-за самостоятельно установленных сроков или целевых дат выпуска. Проект FreeBSD значительно вырос за время своего существования, и необходимость стандартизированных процедур управления выпусками никогда не была столь очевидной. Это станет ещё более важным по мере переноса FreeBSD на новые платформы. [[future]] == Перспективы развития Для обеспечения масштабирования наших процессов релиз-инжиниринга с растущей пользовательской базой мы прилагаем значительные усилия по документированию процедур, связанных с созданием выпусков FreeBSD. * _Параллелизм_ — Некоторые этапы сборки релиза действительно "тривиально параллельны". Большинство задач очень интенсивно используют ввод-вывод, поэтому наличие нескольких высокоскоростных дисков важнее, чем использование нескольких процессоров для ускорения процесса `make release`. Если в среде man:chroot[2] разные иерархии размещены на разных дисках, то выгрузка CVS для деревьев [.filename]#ports# и [.filename]#doc# может происходить одновременно с выполнением `make world` на другом диске. Использование RAID (аппаратного или программного) может значительно сократить общее время сборки. * _Кросс-сборка релизов_ - Сборка релиза для IA-64 или Alpha на x86 оборудовании? `make TARGET=ia64 release`. * _Регрессионное тестирование_ - Нам необходимы более совершенные автоматизированные тесты на корректность для FreeBSD. * _Инструменты установки_ - Наша программа установки уже давно вышла за рамки своего первоначального срока службы. В разработке находится несколько проектов, призванных обеспечить более продвинутый механизм установки. Проект libh был одним из таких проектов, целью которого было создание интеллектуальной новой системы управления пакетами и программы установки с графическим интерфейсом. [[ackno]] == Благодарности Я хотел бы поблагодарить Джордана Хаббарда за предоставленную мне возможность взять на себя часть обязанностей по управлению выпусками для FreeBSD 4.4, а также за всю его работу на протяжении многих лет, которая сделала FreeBSD такой, какая она есть сегодня. Конечно, выпуск не состоялся бы без всей работы, связанной с выпуском, выполненной `{asami}`, `{steve}`, `{bmah}`, `{nik}`, `{obrien}`, `{kris}`, `{jhb}` и остальным сообществом разработчиков FreeBSD. Я также хотел бы поблагодарить `{rgrimes}`, `{phk}` и других, кто работал над инструментами управления выпусками в самые ранние дни FreeBSD. На эту статью повлияли документы по управлению выпусками от CSRG footnote:[Маршалл Кирк МакКузик, Майкл Дж. Карелс и Кит Бостик: link:http://docs.FreeBSD.org/44doc/papers/releng.html[Управление выпусками 4.3BSD]], проекта NetBSD footnote:[Документация разработчика NetBSD: Управление выпусками http://www.NetBSD.org/developers/releng/index.html] и заметки Джона Болдуина с предложениями по процессу управления выпусками. footnote:[Предложение Джона Болдуина по управлению выпусками FreeBSD https://people.FreeBSD.org/~jhb/docs/releng.txt] diff --git a/documentation/content/ru/articles/releng/_index.po b/documentation/content/ru/articles/releng/_index.po index 706a94cf6b..6b4ace4815 100644 --- a/documentation/content/ru/articles/releng/_index.po +++ b/documentation/content/ru/articles/releng/_index.po @@ -1,1596 +1,1596 @@ # SOME DESCRIPTIVE TITLE # Copyright (C) YEAR The FreeBSD Project # This file is distributed under the same license as the FreeBSD Documentation package. # Vladlen Popolitov , 2025, 2026. msgid "" msgstr "" "Project-Id-Version: FreeBSD Documentation VERSION\n" "POT-Creation-Date: 2025-11-08 16:17+0000\n" -"PO-Revision-Date: 2026-03-08 09:11+0000\n" +"PO-Revision-Date: 2026-04-05 04:45+0000\n" "Last-Translator: Vladlen Popolitov \n" "Language-Team: Russian \n" "Language: ru\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && " "n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" "X-Generator: Weblate 4.17\n" #. type: YAML Front Matter: description #: documentation/content/en/articles/releng/_index.adoc:1 #, no-wrap msgid "This paper describes the approach previously used by the FreeBSD release engineering team to make production quality releases of the FreeBSD Operating System" msgstr "В этом документе описывается подход, ранее использовавшийся командой разработки релизов FreeBSD для создания релизов операционной системы FreeBSD производственного качества" #. type: YAML Front Matter: title #: documentation/content/en/articles/releng/_index.adoc:1 #, no-wrap msgid "Legacy FreeBSD Release Engineering" msgstr "Устаревшая разработка релизов FreeBSD" #. type: Title = #: documentation/content/en/articles/releng/_index.adoc:12 #, no-wrap msgid "FreeBSD Release Engineering" msgstr "Подготовка релизов FreeBSD" #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:45 msgid "Abstract" msgstr "Аннотация" #. type: delimited block = 4 #: documentation/content/en/articles/releng/_index.adoc:51 msgid "" "This document is outdated and does not accurately describe the current " "release procedures of the FreeBSD Release Engineering team. It is retained " "for historical purposes. The current procedures used by the FreeBSD Release " "Engineering team are available in the extref:{freebsd-releng}[FreeBSD " "Release Engineering] article." msgstr "" "Этот документ устарел и не точно описывает текущие процедуры выпуска релизов " "команды FreeBSD Release Engineering. Он сохранен в исторических целях. " "Текущие процедуры, используемые командой FreeBSD Release Engineering, " "доступны в статье extref:{freebsd-releng}[FreeBSD Release Engineering]." #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:55 msgid "" "This paper describes the approach used by the FreeBSD release engineering " "team to make production quality releases of the FreeBSD Operating System. " "It details the methodology used for the official FreeBSD releases and " "describes the tools available for those interested in producing customized " "FreeBSD releases for corporate rollouts or commercial productization." msgstr "" "В этом документе описывается подход, используемый командой разработки " "релизов FreeBSD для создания релизов операционной системы FreeBSD " "производственного качества. Подробно излагается методология, применяемая для " "официальных выпусков FreeBSD, а также описываются инструменты, доступные " "тем, кто заинтересован в создании собственных релизов FreeBSD для " "корпоративного внедрения или использования в коммерческой деятельности." #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:57 msgid "'''" msgstr "'''" #. type: Title == #: documentation/content/en/articles/releng/_index.adoc:61 #, no-wrap msgid "Introduction" msgstr "Введение" #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:71 msgid "" "The development of FreeBSD is a very open process. FreeBSD is comprised of " "contributions from thousands of people around the world. The FreeBSD " "Project provides Subversion footnote:[Subversion, http://subversion.apache." "org] access to the general public so that others can have access to log " "messages, diffs (patches) between development branches, and other " "productivity enhancements that formal source code management provides. This " "has been a huge help in attracting more talented developers to FreeBSD. " "However, I think everyone would agree that chaos would soon manifest if " "write access to the main repository was opened up to everyone on the " "Internet. Therefore only a \"select\" group of nearly 300 people are given " "write access to the Subversion repository. These extref:{contributors}" "[FreeBSD committers, staff-committers]footnote:[extref:{contributors}" "[FreeBSD committers, staff-committers]] are usually the people who do the " "bulk of FreeBSD development. An elected link:https://www.FreeBSD.org/" "administration/#t-core[Core Team]footnote:[link:https://www.FreeBSD.org/" "administration/#t-core[FreeBSD Core Team]] of developers provide some level " "of direction over the project." msgstr "" -"Разработка FreeBSD — это очень открытый процесс. FreeBSD создается благодаря " +"Разработка FreeBSD — это очень открытый процесс. FreeBSD создаётся благодаря " "вкладу тысяч людей по всему миру. Проект FreeBSD предоставляет доступ к " "Subversion footnote:[Subversion, http://subversion.apache.org] для широкой " "публики, чтобы другие могли просматривать сообщения журнала, различия (патчи)" " между ветками разработки и другие улучшения производительности, которые " "предоставляет система управления исходным кодом. Это значительно помогло " "привлечь больше талантливых разработчиков в FreeBSD. Однако, я думаю, все " "согласятся, что хаос быстро воцарился бы, если бы право записи в основной " "репозиторий было открыто для всех в Интернете. Поэтому только «избранная» " "группа из почти 300 человек имеет право записи в репозиторий Subversion. Эти " "extref:{contributors}[коммиттеры FreeBSD, staff-" "committers]footnote:[extref:{contributors}[коммиттеры FreeBSD, staff-" "committers]] обычно являются людьми, которые выполняют основную часть " "разработки FreeBSD. Выбранная группа разработчиков — link:https://www.FreeBSD" ".org/administration/#t-core[Основная команда (Core " "Team)]footnote:[link:https://www.FreeBSD.org/administration/#t-core[Основная " "команда FreeBSD]] — обеспечивает некоторый уровень руководства проектом." #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:76 msgid "" "The rapid pace of `FreeBSD` development makes the main development branch " "unsuitable for the everyday use by the general public. In particular, " "stabilizing efforts are required for polishing the development system into a " "production quality release. To solve this conflict, development continues " "on several parallel tracks. The main development branch is the _HEAD_ or " "_trunk_ of our Subversion tree, known as \"FreeBSD-CURRENT\" or \"-CURRENT\" " "for short." msgstr "" "Быстрый темп разработки `FreeBSD` делает основную ветку разработки " "непригодной для повседневного использования широкой публикой. В частности, " "требуются усилия по стабилизации для доведения системы разработки до релиза " "производственного качества. Для решения этого конфликта разработка " "продолжается по нескольким параллельным направлениям. Основная ветка " "разработки — это _HEAD_ или _trunk_ нашего дерева Subversion, известная как " "\"FreeBSD-CURRENT\" или сокращённо \"-CURRENT\"." #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:82 msgid "" "A set of more stable branches are maintained, known as \"FreeBSD-STABLE\" or " "\"-STABLE\" for short. All branches live in a master Subversion repository " "maintained by the FreeBSD Project. FreeBSD-CURRENT is the \"bleeding-edge\" " "of FreeBSD development where all new changes first enter the system. " "FreeBSD-STABLE is the development branch from which major releases are " "made. Changes go into this branch at a different pace, and with the general " "assumption that they have first gone into FreeBSD-CURRENT and have been " "thoroughly tested by our user community." msgstr "" "Набор более стабильных ветвей поддерживается под названием \"FreeBSD-STABLE" "\" или сокращённо \"-STABLE\". Все ветви находятся в главном хранилище " "Subversion, которое поддерживается проектом FreeBSD. FreeBSD-CURRENT — это " "\"передний край\" разработки FreeBSD, куда сначала попадают все новые " "изменения. FreeBSD-STABLE — это ветвь разработки, на основе которой " "выпускаются основные релизы. Изменения попадают в эту ветвь с другой " "скоростью и с общим предположением, что они сначала попали в FreeBSD-CURRENT " "и были тщательно протестированы сообществом пользователей." #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:87 msgid "" "The term _stable_ in the name of the branch refers to the presumed " "Application Binary Interface stability, which is promised by the project. " "This means that a user application compiled on an older version of the " "system from the same branch works on a newer system from the same branch. " "The ABI stability has improved greatly from the compared to previous " "releases. In most cases, binaries from the older _STABLE_ systems run " "unmodified on newer systems, including __HEAD__, assuming that the system " "management interfaces are not used." msgstr "" "Термин _stable_ в названии ветки относится к предполагаемой стабильности " "бинарного интерфейса приложений (ABI), которую гарантирует проект. Это " "означает, что пользовательское приложение, скомпилированное на более старой " "версии системы из той же ветки, будет работать на более новой системе из той " "же ветки. Стабильность ABI значительно улучшилась по сравнению с предыдущими " "выпусками. В большинстве случаев бинарные файлы со старых систем _STABLE_ " "работают без изменений на более новых системах, включая __HEAD__, при " "условии, что не используются интерфейсы управления системой." #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:90 msgid "" "In the interim period between releases, weekly snapshots are built " "automatically by the FreeBSD Project build machines and made available for " "download from `https:/download.FreeBSD.org/snapshots/`. The widespread " "availability of binary release snapshots, and the tendency of our user " "community to keep up with -STABLE development with Subversion and \"`make " "buildworld`\" footnote:[extref:{handbook}cutting-edge[Rebuilding world, " "makeworld]] helps to keep FreeBSD-STABLE in a very reliable condition even " "before the quality assurance activities ramp up pending a major release." msgstr "" "В промежуточный период между выпусками еженедельные снимки состояния системы " "автоматически создаются сборщиками FreeBSD Project и доступны для загрузки " "по адресу `https:/download.FreeBSD.org/snapshots/`. Широкое распространение " "бинарных снимков выпусков, а также склонность нашего сообщества " "пользователей следить за разработкой -STABLE с помощью Subversion и команды " "\"`make buildworld`\" footnote:[extref:{handbook}cutting-edge[Пересборка " "world, makeworld]] помогает поддерживать FreeBSD-STABLE в очень надёжном " "состоянии даже до того, как будут запущены мероприятия по обеспечению " "качества перед основным выпуском." #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:93 msgid "" "In addition to installation ISO snapshots, weekly virtual machine images are " "also provided for use with VirtualBox, qemu, or other popular emulation " "software. The virtual machine images can be downloaded from `https://" "download.FreeBSD.org/snapshots/VM-IMAGES/`." msgstr "" "Помимо снимков установочных ISO, также предоставляются еженедельные образы " "виртуальных машин для использования с VirtualBox, qemu или другим популярным " "эмуляционным программным обеспечением. Образы виртуальных машин можно " "загрузить с `https://download.FreeBSD.org/snapshots/VM-IMAGES/`." #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:95 msgid "" "The virtual machine images are approximately 150MB man:xz[1] compressed, and " "contain a 10GB sparse filesystem when attached to a virtual machine." msgstr "" "Образы виртуальных машин сжаты с помощью man:xz[1] и занимают примерно 150 " "МБ, а при подключении к виртуальной машине содержат разреженную файловую " "систему размером 10 ГБ." #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:98 msgid "" "Bug reports and feature requests are continuously submitted by users " "throughout the release cycle. Problems reports are entered into our " "Bugzilla database through the web interface provided at https://www.freebsd." "org/support/bugreports/[https://www.freebsd.org/support/bugreports/]." msgstr "" "Отчёты об ошибках и запросы функций постоянно отправляются пользователями в " "течение цикла выпуска. Сообщения о проблемах вносятся в нашу базу данных " "Bugzilla через веб-интерфейс, доступный по адресу https://www.freebsd.org/" "support/bugreports/[https://www.freebsd.org/support/bugreports/]." #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:103 msgid "" "To service our most conservative users, individual release branches were " "introduced with FreeBSD 4.3. These release branches are created shortly " "before a final release is made. After the release goes out, only the most " "critical security fixes and additions are merged onto the release branch. " "In addition to source updates via Subversion, binary patchkits are available " "to keep systems on the _releng/X.Y_ branches updated." msgstr "" "Для обслуживания наиболее консервативных пользователей, начиная с FreeBSD " "4.3, были введены индивидуальные ветки релизов. Эти ветки создаются " "незадолго до выпуска финального релиза. После выхода релиза на ветку " "вносятся только самые критические исправления безопасности и дополнения. " "Помимо обновлений исходного кода через Subversion, доступны бинарные патч-" "наборы для поддержания актуальности систем на ветках _releng/X.Y_." #. type: Title === #: documentation/content/en/articles/releng/_index.adoc:104 #, no-wrap msgid "What This Article Describes" msgstr "Что описывает эта статья" #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:107 msgid "The following sections of this article describe:" msgstr "Следующие разделы этой статьи описывают:" #. type: Labeled list #: documentation/content/en/articles/releng/_index.adoc:108 #, no-wrap msgid "crossref:releng[release-proc, Release Process]" msgstr "crossref:releng[release-proc, Процесс выпуска релиза]" #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:110 msgid "" "The different phases of the release engineering process leading up to the " "actual system build." msgstr "" "Различные этапы процесса разработки релиза, предшествующие непосредственной " "сборке системы." #. type: Labeled list #: documentation/content/en/articles/releng/_index.adoc:111 #, no-wrap msgid "crossref:releng[release-build, Release Building]" msgstr "crossref:releng[release-build, Сборка релиза]" #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:113 msgid "The actual build process." msgstr "Фактический процесс сборки." #. type: Labeled list #: documentation/content/en/articles/releng/_index.adoc:114 #, no-wrap msgid "crossref:releng[extensibility, Extensibility]" msgstr "crossref:releng[extensibility, Расширяемость]" #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:116 msgid "How the base release may be extended by third parties." msgstr "Как базовый выпуск может быть расширен третьими сторонами." #. type: Labeled list #: documentation/content/en/articles/releng/_index.adoc:117 #, no-wrap msgid "crossref:releng[lessons-learned, Lessons Learned from FreeBSD 4.4]" msgstr "crossref:releng[lessons-learned, Уроки, извлеченные из FreeBSD 4.4]" #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:119 msgid "Some of the lessons learned through the release of FreeBSD 4.4." msgstr "Некоторые уроки, извлеченные в процессе выпуска FreeBSD 4.4." #. type: Labeled list #: documentation/content/en/articles/releng/_index.adoc:120 #, no-wrap msgid "crossref:releng[future, Future Directions]" msgstr "crossref:releng[future, Перспективы развития]" #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:122 msgid "Future directions of development." msgstr "Перспективные направления развития." #. type: Title == #: documentation/content/en/articles/releng/_index.adoc:124 #, no-wrap msgid "Release Process" msgstr "Процесс выпуска релиза" #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:129 msgid "" "New releases of FreeBSD are released from the -STABLE branch at " "approximately four month intervals. The FreeBSD release process begins to " "ramp up 70-80 days before the anticipated release date when the release " "engineer sends an email to the development mailing lists to remind " "developers that they only have 15 days to integrate new changes before the " "code freeze. During this time, many developers perform what have become " "known as \"MFC sweeps\"." msgstr "" "Новые выпуски FreeBSD выходят из ветки -STABLE примерно с интервалом в " "четыре месяца. Процесс выпуска FreeBSD начинает набирать обороты за 70-80 " "дней до предполагаемой даты выпуска, когда инженер выпуска отправляет " "электронное письмо в списки рассылки разработчиков, напоминая им, что у них " "осталось всего 15 дней для интеграции новых изменений до заморозки кода. В " "это время многие разработчики выполняют так называемые \"MFC-проверки\"." #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:133 msgid "" "MFC stands for \"Merge From CURRENT\" and it describes the process of " "merging a tested change from our -CURRENT development branch to our -STABLE " "branch. Project policy requires any change to be first applied to trunk, " "and merged to the -STABLE branches after sufficient external testing was " "done by -CURRENT users (developers are expected to extensively test the " "change before committing to -CURRENT, but it is impossible for a person to " "exercise all usages of the general-purpose operating system). Minimal MFC " "period is 3 days, which is typically used only for trivial or critical " "bugfixes." msgstr "" "MFC означает \"Merge From CURRENT\" и описывает процесс переноса " "проверенного изменения из нашей ветки разработки -CURRENT в ветку -STABLE. " "Политика проекта требует, чтобы любое изменение сначала было применено к " "основной ветке, а затем перенесено в ветки -STABLE после достаточного " "внешнего тестирования пользователями -CURRENT (ожидается, что разработчики " "тщательно проверят изменение перед внесением в -CURRENT, но невозможно для " "одного человека проверить все варианты использования универсальной " "операционной системы). Минимальный срок для MFC составляет 3 дня, который " "обычно используется только для тривиальных или критических исправлений " "ошибок." #. type: Title === #: documentation/content/en/articles/releng/_index.adoc:134 #, no-wrap msgid "Code Review" msgstr "Проверка кода" #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:140 msgid "" "Sixty days before the anticipated release, the source repository enters a " "\"code freeze\". During this time, all commits to the -STABLE branch must " "be approved by `{re}`. The approval process is technically enforced by a " "pre-commit hook. The kinds of changes that are allowed during this period " "include:" msgstr "" "За шестьдесят дней до предполагаемого релиза репозиторий исходного кода " "переходит в режим «заморозки кода». В этот период все коммиты в ветку -" "STABLE должны быть одобрены `{re}`. Процесс утверждения технически " "обеспечивается предкоммитным хуком. В этот период допускаются следующие виды " "изменений:" #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:142 msgid "Bug fixes." msgstr "Исправления ошибок." #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:143 msgid "Documentation updates." msgstr "Обновления документации." #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:144 msgid "Security-related fixes of any kind." msgstr "Исправления, связанные с безопасностью, любого рода." #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:145 msgid "Minor changes to device drivers, such as adding new Device IDs." msgstr "" "Незначительные изменения в драйверах устройств, такие как добавление новых " "идентификаторов устройств." #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:146 msgid "Driver updates from the vendors." msgstr "Обновления драйверов от поставщиков." #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:147 msgid "" "Any additional change that the release engineering team feels is justified, " "given the potential risk." msgstr "" "Любое дополнительное изменение, которое команда разработки релизов сочтет " "оправданным, учитывая потенциальный риск." #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:151 msgid "" "Shortly after the code freeze is started, a _BETA1_ image is built and " "released for widespread testing. During the code freeze, at least one beta " "image or release candidate is released every two weeks until the final " "release is ready. During the days preceding the final release, the release " "engineering team is in constant communication with the security-officer " "team, the documentation maintainers, and the port maintainers to ensure that " "all of the different components required for a successful release are " "available." msgstr "" "Вскоре после начала заморозки кода создаётся образ _BETA1_ и выпускается для " "широкого тестирования. В период заморозки кода не реже чем раз в две недели " "выпускается как минимум один бета-образ или кандидат в релизы, пока не будет " "готов финальный выпуск. В дни, предшествующие финальному релизу, команда " "разработки выпусков постоянно взаимодействует с командой security-officer, " "сопровождающими документации и сопровождающими портов, чтобы убедиться, что " "все необходимые компоненты для успешного релиза доступны." #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:154 msgid "" "After the quality of the BETA images is satisfying enough, and no large and " "potentially risky changes are planned, the release branch is created and " "_Release Candidate_ (RC) images are built from the release branch, instead " "of the BETA images from the STABLE branch. Also, the freeze on the STABLE " "branch is lifted and release branch enters a \"hard code freeze\" where it " "becomes much harder to justify new changes to the system unless a serious " "bug-fix or security issue is involved." msgstr "" "После того, как качество BETA-образов становится достаточно " "удовлетворительным и не планируется крупных и потенциально рискованных " -"изменений, создается ветка релиза, и образы _Release Candidate_ (RC) " +"изменений, создаётся ветка релиза, и образы _Release Candidate_ (RC) " "собираются из ветки релиза, вместо BETA-образов из ветки STABLE. Также " "снимается заморозка изменений в ветке STABLE, а ветка релиза переходит в " "режим \"жёсткой заморозки кода\", когда становится значительно сложнее " "обосновать новые изменения в системе, за исключением исправления серьезных " "ошибок или проблем безопасности." #. type: Title === #: documentation/content/en/articles/releng/_index.adoc:155 #, no-wrap msgid "Final Release Checklist" msgstr "Контрольный список финального выпуска" #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:158 msgid "" "When several BETA images have been made available for widespread testing and " "all major issues have been resolved, the final release \"polishing\" can " "begin." msgstr "" "Когда несколько образов BETA станут доступны для широкого тестирования и все " "основные проблемы будут устранены, можно приступать к финальной \"доводке\" " "выпуска." #. type: Title ==== #: documentation/content/en/articles/releng/_index.adoc:160 #, no-wrap msgid "Creating the Release Branch" msgstr "Создание ветки релиза" #. type: delimited block = 4 #: documentation/content/en/articles/releng/_index.adoc:165 msgid "" "In all examples below, `$FSVN` refers to the location of the FreeBSD " "Subversion repository, `svn+ssh://svn.FreeBSD.org/base/`." msgstr "" "Во всех примерах ниже `$FSVN` указывает на расположение репозитория " "Subversion FreeBSD, `svn+ssh://svn.FreeBSD.org/base/`." #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:169 msgid "" "The layout of FreeBSD branches in Subversion is described in the extref:" "{committers-guide}[Committer's Guide, subversion-primer-base-layout]. The " "first step in creating a branch is to identify the revision of the `stable/" "_X_` sources that you want to branch _from_." msgstr "" "Расположение веток FreeBSD в Subversion описано в extref:{committers-guide}" "[Руководстве коммиттера, subversion-primer-base-layout]. Первым шагом в " "создании ветки является определение ревизии исходников `stable/_X_`, от " "которой вы хотите сделать _ответвление_." #. type: delimited block . 4 #: documentation/content/en/articles/releng/_index.adoc:173 #, no-wrap msgid "# svn log -v $FSVN/stable/9\n" msgstr "# svn log -v $FSVN/stable/9\n" #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:176 msgid "The next step is to create the _release branch_" msgstr "Следующий шаг — создание _ветки релиза_" #. type: delimited block . 4 #: documentation/content/en/articles/releng/_index.adoc:180 #, no-wrap msgid "# svn cp $FSVN/stable/9@REVISION $FSVN/releng/9.2\n" msgstr "# svn cp $FSVN/stable/9@REVISION $FSVN/releng/9.2\n" #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:183 msgid "This branch can be checked out:" msgstr "Эту ветку можно извлечь:" #. type: delimited block . 4 #: documentation/content/en/articles/releng/_index.adoc:187 #, no-wrap msgid "# svn co $FSVN/releng/9.2 src\n" msgstr "# svn co $FSVN/releng/9.2 src\n" #. type: delimited block = 4 #: documentation/content/en/articles/releng/_index.adoc:192 msgid "" "Creating the `releng` branch and `release` tags is done by the link:https://" "www.FreeBSD.org/administration/#t-re[Release Engineering Team]." msgstr "" "Создание ветки `releng` и тегов `release` выполняется командой link:https://" "www.FreeBSD.org/administration/#t-re[Release Engineering Team]." #. type: Positional ($1) AttributeList argument for macro 'image' #: documentation/content/en/articles/releng/_index.adoc:194 #, no-wrap msgid "FreeBSD Development Branch" msgstr "Ветка разработки FreeBSD" #. type: Target for macro image #: documentation/content/en/articles/releng/_index.adoc:194 #, no-wrap msgid "branches-head.png" msgstr "branches-head.png" #. type: Positional ($1) AttributeList argument for macro 'image' #: documentation/content/en/articles/releng/_index.adoc:196 #, no-wrap msgid "FreeBSD 3.x STABLE Branch" msgstr "Ветка STABLE FreeBSD 3.x" #. type: Target for macro image #: documentation/content/en/articles/releng/_index.adoc:196 #, no-wrap msgid "branches-releng3.png" msgstr "branches-releng3.png" #. type: Positional ($1) AttributeList argument for macro 'image' #: documentation/content/en/articles/releng/_index.adoc:198 #, no-wrap msgid "FreeBSD 4.x STABLE Branch" msgstr "Ветка FreeBSD 4.x STABLE" #. type: Target for macro image #: documentation/content/en/articles/releng/_index.adoc:198 #, no-wrap msgid "branches-releng4.png" msgstr "branches-releng4.png" #. type: Positional ($1) AttributeList argument for macro 'image' #: documentation/content/en/articles/releng/_index.adoc:200 #, no-wrap msgid "FreeBSD 5.x STABLE Branch" msgstr "Ветка STABLE FreeBSD 5.x" #. type: Target for macro image #: documentation/content/en/articles/releng/_index.adoc:200 #, no-wrap msgid "branches-releng5.png" msgstr "branches-releng5.png" #. type: Positional ($1) AttributeList argument for macro 'image' #: documentation/content/en/articles/releng/_index.adoc:202 #, no-wrap msgid "FreeBSD 6.x STABLE Branch" msgstr "Ветка FreeBSD 6.x STABLE" #. type: Target for macro image #: documentation/content/en/articles/releng/_index.adoc:202 #, no-wrap msgid "branches-releng6.png" msgstr "branches-releng6.png" #. type: Positional ($1) AttributeList argument for macro 'image' #: documentation/content/en/articles/releng/_index.adoc:204 #, no-wrap msgid "FreeBSD 7.x STABLE Branch" msgstr "Ветка FreeBSD 7.x STABLE" #. type: Target for macro image #: documentation/content/en/articles/releng/_index.adoc:204 #, no-wrap msgid "branches-releng7.png" msgstr "branches-releng7.png" #. type: Positional ($1) AttributeList argument for macro 'image' #: documentation/content/en/articles/releng/_index.adoc:206 #, no-wrap msgid "FreeBSD 8.x STABLE Branch" msgstr "Ветка FreeBSD 8.x STABLE" #. type: Target for macro image #: documentation/content/en/articles/releng/_index.adoc:206 #, no-wrap msgid "branches-releng8.png" msgstr "branches-releng8.png" #. type: Positional ($1) AttributeList argument for macro 'image' #: documentation/content/en/articles/releng/_index.adoc:208 #, no-wrap msgid "FreeBSD 9.x STABLE Branch" msgstr "Ветка FreeBSD 9.x STABLE" #. type: Target for macro image #: documentation/content/en/articles/releng/_index.adoc:208 #, no-wrap msgid "branches-releng9.png" msgstr "branches-releng9.png" #. type: Title ==== #: documentation/content/en/articles/releng/_index.adoc:211 #, no-wrap msgid "Bumping up the Version Number" msgstr "Увеличение номера версии" #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:214 msgid "" "Before the final release can be tagged, built, and released, the following " "files need to be modified to reflect the correct version of FreeBSD:" msgstr "" "Перед тем как финальный выпуск может быть помечен, собран и выпущен, " "следующие файлы должны быть изменены, чтобы отражать корректную версию " "FreeBSD:" #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:216 msgid "[.filename]#doc/en_US.ISO8859-1/books/handbook/mirrors/chapter.xml#" msgstr "[.filename]#doc/en_US.ISO8859-1/books/handbook/mirrors/chapter.xml#" #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:217 msgid "[.filename]#doc/en_US.ISO8859-1/books/porters-handbook/book.xml#" msgstr "[.filename]#doc/en_US.ISO8859-1/books/porters-handbook/book.xml#" #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:218 msgid "[.filename]#doc/en_US.ISO8859-1/htdocs/cgi/ports.cgi#" msgstr "[.filename]#doc/en_US.ISO8859-1/htdocs/cgi/ports.cgi#" #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:219 msgid "[.filename]#ports/Tools/scripts/release/config#" msgstr "[.filename]#ports/Tools/scripts/release/config#" #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:220 msgid "[.filename]#doc/shared/xml/freebsd.ent#" msgstr "[.filename]#doc/shared/xml/freebsd.ent#" #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:221 msgid "[.filename]#src/Makefile.inc1#" msgstr "[.filename]#src/Makefile.inc1#" #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:222 msgid "[.filename]#src/UPDATING#" msgstr "[.filename]#src/UPDATING#" #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:223 msgid "[.filename]#src/gnu/usr.bin/groff/tmac/mdoc.local#" msgstr "[.filename]#src/gnu/usr.bin/groff/tmac/mdoc.local#" #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:224 msgid "[.filename]#src/release/Makefile#" msgstr "[.filename]#src/release/Makefile#" #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:225 msgid "[.filename]#src/release/doc/en_US.ISO8859-1/shared/xml/release.dsl#" msgstr "[.filename]#src/release/doc/en_US.ISO8859-1/shared/xml/release.dsl#" #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:226 msgid "[.filename]#src/release/doc/shared/examples/Makefile.relnotesng#" msgstr "[.filename]#src/release/doc/shared/examples/Makefile.relnotesng#" #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:227 msgid "[.filename]#src/release/doc/shared/xml/release.ent#" msgstr "[.filename]#src/release/doc/shared/xml/release.ent#" #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:228 msgid "[.filename]#src/sys/conf/newvers.sh#" msgstr "[.filename]#src/sys/conf/newvers.sh#" #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:229 msgid "[.filename]#src/sys/sys/param.h#" msgstr "[.filename]#src/sys/sys/param.h#" #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:230 msgid "[.filename]#src/usr.sbin/pkg_install/add/main.c#" msgstr "[.filename]#src/usr.sbin/pkg_install/add/main.c#" #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:231 msgid "[.filename]#doc/en_US.ISO8859-1/htdocs/search/opensearch/man.xml#" msgstr "[.filename]#doc/en_US.ISO8859-1/htdocs/search/opensearch/man.xml#" #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:233 msgid "" "The release notes and errata files also need to be adjusted for the new " "release (on the release branch) and truncated appropriately (on the stable/" "current branch):" msgstr "" "Заметки о выпуске и файлы с опечатками также необходимо адаптировать для " "нового выпуска (в ветке выпуска) и соответствующим образом обрезать (в ветке " "stable/current):" #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:235 msgid "[.filename]#src/release/doc/en_US.ISO8859-1/relnotes/common/new.xml#" msgstr "[.filename]#src/release/doc/en_US.ISO8859-1/relnotes/common/new.xml#" #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:236 msgid "[.filename]#src/release/doc/en_US.ISO8859-1/errata/article.xml#" msgstr "[.filename]#src/release/doc/en_US.ISO8859-1/errata/article.xml#" #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:240 msgid "" "Sysinstall should be updated to note the number of available ports and the " "amount of disk space required for the Ports Collection. footnote:[FreeBSD " "Ports Collection https://ports.FreeBSD.org] This information is currently " "kept in [.filename]#src/usr.sbin/bsdinstall/dist.c#." msgstr "" "В Sysinstall следует добавить информацию о количестве доступных портов и " "объёме дискового пространства, необходимого для коллекции портов. footnote:[" "Коллекция портов FreeBSD https://ports.FreeBSD.org] В настоящее время эта " "информация хранится в [.filename]#src/usr.sbin/bsdinstall/dist.c#." #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:243 msgid "" "After the release has been built, a number of files should be updated to " "announce the release to the world. These files are relative to `head/` " "within the `doc/` subversion tree." msgstr "" "После сборки выпуска следует обновить ряд файлов, чтобы объявить о выпуске. " "Эти файлы находятся относительно `head/` в поддереве `doc/` Subversion." #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:245 msgid "[.filename]#share/images/articles/releng/branches-relengX.pic#" msgstr "[.filename]#share/images/articles/releng/branches-relengX.pic#" #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:246 msgid "[.filename]#head/shared/xml/release.ent#" msgstr "[.filename]#head/shared/xml/release.ent#" #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:247 msgid "[.filename]#en_US.ISO8859-1/htdocs/releases/*#" msgstr "[.filename]#en_US.ISO8859-1/htdocs/releases/*#" #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:248 msgid "[.filename]#en_US.ISO8859-1/htdocs/releng/index.xml#" msgstr "[.filename]#en_US.ISO8859-1/htdocs/releng/index.xml#" #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:249 msgid "[.filename]#share/xml/news.xml#" msgstr "[.filename]#share/xml/news.xml#" #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:251 msgid "Additionally, update the \"BSD Family Tree\" file:" msgstr "Кроме того, обновите файл \"Генеалогическое древо BSD\":" #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:253 msgid "[.filename]#src/shared/misc/bsd-family-tree#" msgstr "[.filename]#src/shared/misc/bsd-family-tree#" #. type: Title ==== #: documentation/content/en/articles/releng/_index.adoc:254 #, no-wrap msgid "Creating the Release Tag" msgstr "Создание тега релиза" #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:257 msgid "" "When the final release is ready, the following command will create the " "`release/9.2.0` tag." msgstr "" "Когда финальный выпуск будет готов, следующая команда создаст тег " "`release/9.2.0`." #. type: delimited block . 4 #: documentation/content/en/articles/releng/_index.adoc:261 #, no-wrap msgid "# svn cp $FSVN/releng/9.2 $FSVN/release/9.2.0\n" msgstr "# svn cp $FSVN/releng/9.2 $FSVN/release/9.2.0\n" #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:264 msgid "" "The Documentation and Ports managers are responsible for tagging their " "respective trees with the `tags/RELEASE_9_2_0` tag." msgstr "" "Менеджеры документации и портов ответственны за добавление тега `tags/" "RELEASE_9_2_0` в соответствующие деревья." #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:267 msgid "" "When the Subversion `svn cp` command is used to create a __release tag__, " "this identifies the source at a specific point in time. By creating tags, " "we ensure that future release builders will always be able to use the same " "source we used to create the official FreeBSD Project releases." msgstr "" "Когда команда Subversion `svn cp` используется для создания __тега релиза " "(release tag)__, это идентифицирует исходный код на определённый момент " "времени. Создавая теги, мы гарантируем, что будущие сборщики релизов всегда " "смогут использовать тот же исходный код, который использовался для создания " "официальных релизов проекта FreeBSD." #. type: Title == #: documentation/content/en/articles/releng/_index.adoc:269 #, no-wrap msgid "Release Building" msgstr "Сборка релиза" #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:280 msgid "" "FreeBSD \"releases\" can be built by anyone with a fast machine and access " "to a source repository. (That should be everyone, since we offer Subversion " "access! See the extref:{handbook}[Subversion section in the Handbook, svn] " "for details.) The _only_ special requirement is that the man:md[4] device " "must be available. If the device is not loaded into your kernel, then the " "kernel module should be automatically loaded when man:mdconfig[8] is " "executed during the boot media creation phase. All of the tools necessary " "to build a release are available from the Subversion repository in [." "filename]#src/release#. These tools aim to provide a consistent way to " "build FreeBSD releases. A complete release can actually be built with only " "a single command, including the creation of ISO images suitable for burning " "to CDROM or DVD, and an FTP install directory. man:release[7] fully " "documents the `src/release/generate-release.sh` script which is used to " "build a release. `generate-release.sh` is a wrapper around the Makefile " "target: `make release`." msgstr "" "Сборка \"релизов\" FreeBSD может быть выполнена любым пользователем, имеющим " "быстрый компьютер и доступ к репозиторию исходного кода. (Это должно быть " "доступно каждому, так как мы предоставляем доступ через Subversion! " "Подробности см. в extref:{handbook}[разделе Subversion в Руководстве, svn].) " "_Единственное_ специальное требование — доступность устройства man:md[4]. " "Если устройство не загружено в ваше ядро, то модуль ядра должен " "автоматически загрузиться при выполнении man:mdconfig[8] во время этапа " "создания загрузочного носителя. Все необходимые инструменты для сборки " "релиза доступны в репозитории Subversion в [.filename]#src/release#. Эти " "инструменты предназначены для обеспечения единообразного способа сборки " "релизов FreeBSD. Полный релиз может быть собран всего одной командой, " "включая создание ISO-образов, пригодных для записи на CDROM или DVD, а также " "каталога для установки по FTP. man:release[7] полностью документирует скрипт " "`src/release/generate-release.sh`, который используется для сборки релиза. " "`generate-release.sh` является обёрткой для цели Makefile: `make release`." #. type: Title === #: documentation/content/en/articles/releng/_index.adoc:281 #, no-wrap msgid "Building a Release" msgstr "Сборка релиза" #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:285 msgid "" "man:release[7] documents the exact commands required to build a FreeBSD " "release. The following sequences of commands can build an 9.2.0 release:" msgstr "" "man:release[7] документирует точные команды, необходимые для сборки релиза " "FreeBSD. Следующая последовательность команд может собрать релиз 9.2.0:" #. type: delimited block . 4 #: documentation/content/en/articles/releng/_index.adoc:290 #, no-wrap msgid "" "# cd /usr/src/release\n" "# sh generate-release.sh release/9.2.0 /local3/release\n" msgstr "" "# cd /usr/src/release\n" "# sh generate-release.sh release/9.2.0 /local3/release\n" #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:293 msgid "" "After running these commands, all prepared release files are available in [." "filename]#/local3/release/R# directory." msgstr "" "После выполнения этих команд все подготовленные файлы релиза будут доступны " "в каталоге [.filename]#/local3/release/R#." #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:295 msgid "" "The release [.filename]#Makefile# can be broken down into several distinct " "steps." msgstr "" "Файл [.filename]#Makefile# для выпуска можно разбить на несколько отдельных " "этапов." #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:297 msgid "" "Creation of a sanitized system environment in a separate directory hierarchy " "with \"`make installworld`\"." msgstr "" "Создание изолированного окружения системы в отдельной иерархии каталогов с " "помощью \"`make installworld`\"." #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:298 msgid "" "Checkout from Subversion of a clean version of the system source, " "documentation, and ports into the release build hierarchy." msgstr "" "Извлечение из Subversion чистой версии исходного кода системы, документации " "и портов в иерархию сборки релиза." #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:299 msgid "" "Population of [.filename]#/etc# and [.filename]#/dev# in the chrooted " "environment." msgstr "" "Заполнение каталогов [.filename]#/etc# и [.filename]#/dev# в chroot-" "окружении." #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:300 msgid "" "chroot into the release build hierarchy, to make it harder for the outside " "environment to taint this build." msgstr "" "Изменение корневого каталога на верхний каталог иерархии сборки релиза с " "помощью `chroot`, чтобы усложнить влияние внешней среды на эту сборку." #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:301 msgid "`make world` in the chrooted environment." msgstr "Запуск `make world` в окружении `chroot`." #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:302 msgid "Build of Kerberos-related binaries." msgstr "Сборка связанных с Kerberos бинарных файлов." #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:303 msgid "Build [.filename]#GENERIC# kernel." msgstr "Сборка ядра [.filename]#GENERIC#." #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:304 msgid "" "Creation of a staging directory tree where the binary distributions will be " "built and packaged." msgstr "" "Создание промежуточной структуры каталогов, в которой будут собираться и " "упаковываться бинарные дистрибутивы." #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:305 msgid "" "Build and installation of the documentation toolchain needed to convert the " "documentation source (SGML) into HTML and text documents that will accompany " "the release." msgstr "" "Сборка и установка инструментария для документации, необходимого для " "преобразования исходников документации (SGML) в HTML и текстовые документы, " "которые будут поставляться с релизом." #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:306 msgid "" "Build and installation of the actual documentation (user manuals, tutorials, " "release notes, hardware compatibility lists, and so on.)" msgstr "" "Сборка и установка непосредственно документации (руководства пользователя, " "учебные пособия, примечания к выпуску, списки совместимого оборудования и " "так далее)." #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:307 msgid "Package up distribution tarballs of the binaries and sources." msgstr "" "Создание распространяемых tar-архивов с бинарными файлами и исходными кодами." #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:308 msgid "Create FTP installation hierarchy." msgstr "Создание иерархии установки FTP." #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:309 msgid "_(optionally)_ Create ISO images for CDROM/DVD media." msgstr "_(необязательно)_ Создание ISO-образов для носителей CDROM/DVD." #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:311 msgid "" "For more information about the release build infrastructure, please see man:" "release[7]." msgstr "" "Для получения дополнительной информации о инфраструктуре сборки релизов, " "обратитесь к man:release[7]." #. type: delimited block = 4 #: documentation/content/en/articles/releng/_index.adoc:316 msgid "" "It is important to remove any site-specific settings from [.filename]#/etc/" "make.conf#. For example, it would be unwise to distribute binaries that " "were built on a system with `CPUTYPE` set to a specific processor." msgstr "" "Важно удалить все специфичные для сайта настройки из [.filename]#/etc/make." "conf#. Например, было бы неразумно распространять бинарные файлы, собранные " "на системе с установленным `CPUTYPE` для конкретного процессора." #. type: Title === #: documentation/content/en/articles/releng/_index.adoc:318 #, no-wrap msgid "Contributed Software (\"ports\")" msgstr "Предоставленное программное обеспечение (\"порты\")" #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:322 msgid "" "The https://ports.FreeBSD.org[FreeBSD Ports collection] is a collection of " "over {numports} third-party software packages available for FreeBSD. The " "`{portmgr}` is responsible for maintaining a consistent ports tree that can " "be used to create the binary packages that accompany official FreeBSD " "releases." msgstr "" "https://ports.FreeBSD.org[Коллекция портов FreeBSD] представляет собой набор " "из более чем {numports} сторонних программных пакетов, доступных для " "FreeBSD. `{portmgr}` отвечает за поддержание согласованного дерева портов, " "которое может быть использовано для создания бинарных пакетов, поставляемых " "с официальными выпусками FreeBSD." #. type: Title === #: documentation/content/en/articles/releng/_index.adoc:323 #, no-wrap msgid "Release ISOs" msgstr "Релизные ISO-образы" #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:328 msgid "" "Starting with FreeBSD 4.4, the FreeBSD Project decided to release all four " "ISO images that were previously sold on the _BSDi/Wind River Systems/FreeBSD " "Mall_ \"official\" CDROM distributions. Each of the four discs must contain " "a [.filename]#README.TXT# file that explains the contents of the disc, a [." "filename]#CDROM.INF# file that provides meta-data for the disc so that man:" "bsdinstall[8] can validate and use the contents, and a [.filename]#filename." "txt# file that provides a manifest for the disc. This _manifest_ can be " "created with a simple command:" msgstr "" "Начиная с FreeBSD 4.4, проект FreeBSD решил выпустить все четыре образа ISO, " "которые ранее продавались на «официальных» дистрибутивах CDROM от _BSDi/Wind " "River Systems/FreeBSD Mall_. Каждый из четырёх дисков должен содержать файл " "[.filename]#README.TXT#, объясняющий содержимое диска, файл [." "filename]#CDROM.INF#, предоставляющий метаданные для диска, чтобы man:" "bsdinstall[8] мог проверить и использовать содержимое, и файл [." "filename]#filename.txt#, содержащий манифест диска. Этот _манифест_ можно " "создать простой командой:" #. type: delimited block . 4 #: documentation/content/en/articles/releng/_index.adoc:332 #, no-wrap msgid "/stage/cdrom# find . -type f | sed -e 's/^\\.\\///' | sort > filename.txt\n" msgstr "/stage/cdrom# find . -type f | sed -e 's/^\\.\\///' | sort > filename.txt\n" #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:335 msgid "The specific requirements of each CD are outlined below." msgstr "Конкретные требования для каждого CD приведены ниже." #. type: Title ==== #: documentation/content/en/articles/releng/_index.adoc:336 #, no-wrap msgid "Disc 1" msgstr "Диск 1" #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:342 msgid "" "The first disc is almost completely created by `make release`. The only " "changes that should be made to the [.filename]#disc1# directory are the " "addition of a [.filename]#tools# directory, and as many popular third party " "software packages as will fit on the disc. The [.filename]#tools# directory " "contains software that allow users to create installation floppies from " "other operating systems. This disc should be made bootable so that users of " "modern PCs do not need to create installation floppy disks." msgstr "" "Первый диск почти полностью создаётся командой `make release`. Единственные " "изменения, которые следует внести в каталог [.filename]#disc1#, — это " "добавление каталога [.filename]#tools# и как можно большего количества " "популярных сторонних программных пакетов, которые поместятся на диск. В " "каталоге [.filename]#tools# содержится программное обеспечение, позволяющее " "пользователям создавать установочные дискеты из других операционных систем. " "Этот диск должен быть загрузочным, чтобы пользователям современных ПК не " "требовалось создавать установочные дискеты." #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:347 msgid "" "If a custom kernel of FreeBSD is to be included, then man:bsdinstall[8] and " "man:release[7] must be updated to include installation instructions. The " "relevant code is contained in [.filename]#src/release# and [.filename]#src/" "usr.sbin/bsdinstall#. Specifically, the file [.filename]#src/release/" "Makefile#, and [.filename]#dist.c#, [.filename]#dist.h#, [.filename]#menus." "c#, [.filename]#install.c#, and [.filename]#Makefile# will need to be " "updated under [.filename]#src/usr.sbin/bsdinstall#. Optionally, you may " "choose to update [.filename]#bsdinstall.8#." msgstr "" "Если требуется включить пользовательское ядро FreeBSD, необходимо обновить " "man:bsdinstall[8] и man:release[7], чтобы включить инструкции по установке. " "Соответствующий код содержится в [.filename]#src/release# и [.filename]#src/" "usr.sbin/bsdinstall#. В частности, потребуется обновить файл [.filename]#src/" "release/Makefile#, а также [.filename]#dist.c#, [.filename]#dist.h#, [." "filename]#menus.c#, [.filename]#install.c# и [.filename]#Makefile# в " "каталоге [.filename]#src/usr.sbin/bsdinstall#. При желании можно также " "обновить [.filename]#bsdinstall.8#." #. type: Title ==== #: documentation/content/en/articles/releng/_index.adoc:348 #, no-wrap msgid "Disc 2" msgstr "Диск 2" #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:353 msgid "" "The second disc is also largely created by `make release`. This disc " "contains a \"live filesystem\" that can be used from man:bsdinstall[8] to " "troubleshoot a FreeBSD installation. This disc should be bootable and " "should also contain a compressed copy of the CVS repository in the [." "filename]#CVSROOT# directory and commercial software demos in the [." "filename]#commerce# directory." msgstr "" "Второй диск также в основном создаётся командой `make release`. Этот диск " "содержит «живую файловую систему», которая может использоваться через " "man:bsdinstall[8] для диагностики установки FreeBSD. Этот диск должен быть " "загрузочным и также содержать сжатую копию репозитория CVS в каталоге [." "filename]#CVSROOT# и демонстрационные версии коммерческого ПО в каталоге [." "filename]#commerce#." #. type: Title ==== #: documentation/content/en/articles/releng/_index.adoc:354 #, no-wrap msgid "Multi-volume Support" msgstr "Поддержка нескольких томов" #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:360 msgid "" "Sysinstall supports multiple volume package installations. This requires " "that each disc have an [.filename]#INDEX# file containing all of the " "packages on all volumes of a set, along with an extra field that indicates " "which volume that particular package is on. Each volume in the set must " "also have the `CD_VOLUME` variable set in the [.filename]#cdrom.inf# file so " "that bsdinstall can tell which volume is which. When a user attempts to " "install a package that is not on the current disc, bsdinstall will prompt " "the user to insert the appropriate one." msgstr "" "Sysinstall поддерживает установку пакетов с нескольких томов. Для этого " "каждый диск должен содержать файл [.filename]#INDEX#, в котором перечислены " "все пакеты на всех томах набора, а также дополнительное поле, указывающее, " "на каком именно томе находится конкретный пакет. Каждый том в наборе также " "должен иметь установленную переменную `CD_VOLUME` в файле [.filename]#cdrom." "inf#, чтобы bsdinstall мог определить, какой том является каким. Когда " "пользователь пытается установить пакет, которого нет на текущем диске, " "bsdinstall предложит ему вставить соответствующий диск." #. type: Title == #: documentation/content/en/articles/releng/_index.adoc:362 #, no-wrap msgid "Distribution" msgstr "Распространение" #. type: Title === #: documentation/content/en/articles/releng/_index.adoc:365 #, no-wrap msgid "FTP Sites" msgstr "Сайты FTP" #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:371 msgid "" "When the release has been thoroughly tested and packaged for distribution, " "the master FTP site must be updated. The official FreeBSD public FTP sites " "are all mirrors of a master server that is open only to other FTP sites. " "This site is known as `ftp-master`. When the release is ready, the " "following files must be modified on `ftp-master`:" msgstr "" "Когда выпуск тщательно протестирован и упакован для распространения, " "необходимо обновить главный FTP-сайт. Официальные публичные FTP-сайты " "FreeBSD являются зеркалами главного сервера, который доступен только другим " "FTP-сайтам. Этот сервер известен как `ftp-master`. Когда выпуск готов, " "следующие файлы должны быть изменены на `ftp-master`:" #. type: Labeled list #: documentation/content/en/articles/releng/_index.adoc:372 #, no-wrap msgid "[.filename]#/pub/FreeBSD/releases/arch/X.Y-RELEASE/#" msgstr "[.filename]#/pub/FreeBSD/releases/arch/X.Y-RELEASE/#" #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:374 msgid "The installable FTP directory as output from `make release`." msgstr "" "Устанавливаемый каталог FTP, полученный в результате выполнения `make " "release`." #. type: Labeled list #: documentation/content/en/articles/releng/_index.adoc:375 #, no-wrap msgid "[.filename]#/pub/FreeBSD/ports/arch/packages-X.Y-release/#" msgstr "[.filename]#/pub/FreeBSD/ports/arch/packages-X.Y-release/#" #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:377 msgid "The complete package build for this release." msgstr "Полная сборка пакетов для этого выпуска." #. type: Labeled list #: documentation/content/en/articles/releng/_index.adoc:378 #, no-wrap msgid "[.filename]#/pub/FreeBSD/releases/arch/X.Y-RELEASE/tools#" msgstr "[.filename]#/pub/FreeBSD/releases/arch/X.Y-RELEASE/tools#" #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:380 msgid "A symlink to [.filename]#../../../tools#." msgstr "Символическая ссылка на [.filename]#../../../tools#." #. type: Labeled list #: documentation/content/en/articles/releng/_index.adoc:381 #, no-wrap msgid "[.filename]#/pub/FreeBSD/releases/arch/X.Y-RELEASE/packages#" msgstr "[.filename]#/pub/FreeBSD/releases/arch/X.Y-RELEASE/packages#" #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:383 msgid "A symlink to [.filename]#../../../ports/arch/packages-X.Y-release#." msgstr "" "Символическая ссылка на [.filename]#../../../ports/arch/packages-X.Y-" "release#." #. type: Labeled list #: documentation/content/en/articles/releng/_index.adoc:384 #, no-wrap msgid "[.filename]#/pub/FreeBSD/releases/arch/ISO-IMAGES/X.Y/X.Y-RELEASE-arch-*.iso#" msgstr "[.filename]#/pub/FreeBSD/releases/arch/ISO-IMAGES/X.Y/X.Y-RELEASE-arch-*.iso#" #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:387 msgid "" "The ISO images. The \"*\" is [.filename]#disc1#, [.filename]#disc2#, etc. " "Only if there is a [.filename]#disc1# and there is an alternative first " "installation CD (for example a stripped-down install with no windowing " "system) there may be a [.filename]#mini# as well." msgstr "" "Образы ISO. Символ \"*\" обозначает [.filename]#disc1#, [.filename]#disc2# и " "так далее. Только если существует [.filename]#disc1# и есть альтернативный " "первый установочный CD (например, упрощённая установка без графической " "оболочки), может также присутствовать [.filename]#mini#." #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:389 msgid "" "For more information about the distribution mirror architecture of the " "FreeBSD FTP sites, please see the extref:{hubs}[Mirroring FreeBSD] article." msgstr "" "Для получения дополнительной информации об архитектуре зеркал " "распространения FTP-сайтов FreeBSD, пожалуйста, ознакомьтесь со статьей " "extref:{hubs}[Поддержка зеркал FreeBSD]." #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:397 msgid "" "It may take many hours to two days after updating `ftp-master` before a " "majority of the Tier-1 FTP sites have the new software depending on whether " "or not a package set got loaded at the same time. It is imperative that the " "release engineers coordinate with the {mirror-announce} before announcing " "the general availability of new software on the FTP sites. Ideally the " "release package set should be loaded at least four days prior to release " "day. The release bits should be loaded between 24 and 48 hours before the " "planned release time with \"other\" file permissions turned off. This will " "allow the mirror sites to download it but the general public will not be " "able to download it from the mirror sites. Mail should be sent to {mirror-" "announce} at the time the release bits get posted saying the release has " "been staged and giving the time that the mirror sites should begin allowing " "access. Be sure to include a time zone with the time, for example make it " "relative to GMT." msgstr "" "Может потребоваться от нескольких часов до двух дней после обновления `ftp-" "master`, прежде чем большинство FTP-сайтов Tier-1 получат новое программное " "обеспечение, в зависимости от того, был ли загружен набор пакетов " "одновременно. Крайне важно, чтобы инженеры по выпуску скоординировались с " "{mirror-announce} перед объявлением общей доступности нового программного " "обеспечения на FTP-сайтах. В идеале набор пакетов для выпуска должен быть " "загружен как минимум за четыре дня до дня выпуска. Выпускные файлы должны " "быть загружены за 24–48 часов до запланированного времени выпуска с " "отключёнными разрешениями для \"других\" пользователей. Это позволит " "зеркальным сайтам загрузить их, но широкая публика не сможет скачать их с " "зеркальных сайтов. Письмо должно быть отправлено в {mirror-announce} в " "момент публикации выпускных файлов, уведомляя о том, что выпуск подготовлен, " "и указывая время, когда зеркальные сайты должны начать разрешать доступ. " "Обязательно укажите часовой пояс для указанного времени, например, " "относительно GMT." #. type: Title === #: documentation/content/en/articles/releng/_index.adoc:399 #, no-wrap msgid "CD-ROM Replication" msgstr "Репликация CD-ROM" #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:402 msgid "" "Coming soon: Tips for sending FreeBSD ISOs to a replicator and quality " "assurance measures to be taken." msgstr "" "Скоро: Советы по отправке ISO-образов FreeBSD репликатору и меры по " "обеспечению качества." #. type: Title == #: documentation/content/en/articles/releng/_index.adoc:404 #, no-wrap msgid "Extensibility" msgstr "Расширяемость" #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:411 msgid "" "Although FreeBSD forms a complete operating system, there is nothing that " "forces you to use the system exactly as we have packaged it up for " "distribution. We have tried to design the system to be as extensible as " "possible so that it can serve as a platform that other commercial products " "can be built on top of. The only \"rule\" we have about this is that if you " "are going to distribute FreeBSD with non-trivial changes, we encourage you " "to document your enhancements! The FreeBSD community can only help support " "users of the software we provide. We certainly encourage innovation in the " "form of advanced installation and administration tools, for example, but we " "cannot be expected to answer questions about it." msgstr "" "Хотя FreeBSD представляет собой законченную операционную систему, ничто не " "обязывает вас использовать её именно в том виде, в каком мы упаковали её для " "распространения. Мы постарались разработать систему максимально расширяемой, " "чтобы она могла служить платформой для создания других коммерческих " "продуктов. Единственное «правило», которое у нас есть на этот счёт, — если " "вы собираетесь распространять FreeBSD с существенными изменениями, мы " "рекомендуем документировать ваши улучшения! Сообщество FreeBSD может " "оказывать поддержку только пользователям того программного обеспечения, " "которое мы предоставляем. Мы, безусловно, приветствуем инновации, такие как " "продвинутые инструменты установки и администрирования, но не можем отвечать " "на вопросы о них." #. type: Title === #: documentation/content/en/articles/releng/_index.adoc:412 #, no-wrap msgid "Scripting `bsdinstall`" msgstr "Скриптинг `bsdinstall`" #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:416 msgid "" "The FreeBSD system installation and configuration tool, man:bsdinstall[8], " "can be scripted to provide automated installs for large sites. This " "functionality can be used in conjunction with Intel(R) PXE footnote:[extref:" "{handbook}advanced-networking[Diskless Operation with PXE, network-" "diskless]] to bootstrap systems from the network." msgstr "" "Инструмент установки и настройки системы FreeBSD, man:bsdinstall[8], может " "быть настроен для автоматизированной установки на крупных площадках. Эта " "функциональность может использоваться совместно с Intel(R) PXE " "footnote:[extref:{handbook}advanced-networking[Запуск системы по сети (PXE) " "без использования локальных накопителей, network-diskless]] для загрузки " "систем по сети." #. type: Title == #: documentation/content/en/articles/releng/_index.adoc:418 #, no-wrap msgid "Lessons Learned from FreeBSD 4.4" msgstr "Уроки, извлеченные из FreeBSD 4.4" #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:425 msgid "" "The release engineering process for 4.4 formally began on August 1st, 2001. " "After that date all commits to the `RELENG_4` branch of FreeBSD had to be " "explicitly approved by the `{re}`. The first release candidate for the x86 " "architecture was released on August 16, followed by 4 more release " "candidates leading up to the final release on September 18th. The security " "officer was very involved in the last week of the process as several " "security issues were found in the earlier release candidates. A total of " "over _500_ emails were sent to the `{re}` in little over a month." msgstr "" "Процесс разработки релиза 4.4 официально начался 1 августа 2001 года. После " "этой даты все коммиты в ветку `RELENG_4` FreeBSD должны были быть явно " "одобрены `{re}`. Первый релиз-кандидат для архитектуры x86 был выпущен 16 " "августа, за ним последовали ещё 4 релиз-кандидата, что привело к финальному " "релизу 18 сентября. Сотрудник по безопасности был очень вовлечён в последнюю " "неделю процесса, так как несколько проблем безопасности было обнаружено в " "ранних релиз-кандидатах. Всего за чуть более месяца было отправлено более " "_500_ писем `{re}`." #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:429 msgid "" "Our user community has made it very clear that the security and stability of " "a FreeBSD release should not be sacrificed for any self-imposed deadlines or " "target release dates. The FreeBSD Project has grown tremendously over its " "lifetime and the need for standardized release engineering procedures has " "never been more apparent. This will become even more important as FreeBSD " "is ported to new platforms." msgstr "" "Наше сообщество пользователей ясно дало понять, что безопасность и " "стабильность выпуска FreeBSD не должны приноситься в жертву из-за " "самостоятельно установленных сроков или целевых дат выпуска. Проект FreeBSD " "значительно вырос за время своего существования, и необходимость " "стандартизированных процедур управления выпусками никогда не была столь " "очевидной. Это станет ещё более важным по мере переноса FreeBSD на новые " "платформы." #. type: Title == #: documentation/content/en/articles/releng/_index.adoc:431 #, no-wrap msgid "Future Directions" msgstr "Перспективы развития" #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:435 msgid "" "It is imperative for our release engineering activities to scale with our " "growing userbase. Along these lines we are working very hard to document " "the procedures involved in producing FreeBSD releases." msgstr "" "Для обеспечения масштабирования наших процессов релиз-инжиниринга с растущей " "пользовательской базой мы прилагаем значительные усилия по документированию " "процедур, связанных с созданием выпусков FreeBSD." #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:437 msgid "" "_Parallelism_ - Certain portions of the release build are actually " "\"embarrassingly parallel\". Most of the tasks are very I/O intensive, so " "having multiple high-speed disk drives is actually more important than using " "multiple processors in speeding up the `make release` process. If multiple " "disks are used for different hierarchies in the man:chroot[2] environment, " "then the CVS checkout of the [.filename]#ports# and [.filename]#doc# trees " "can be happening simultaneously as the `make world` on another disk. Using a " "RAID solution (hardware or software) can significantly decrease the overall " "build time." msgstr "" "_Параллелизм_ — Некоторые этапы сборки релиза действительно \"тривиально " "параллельны\". Большинство задач очень интенсивно используют ввод-вывод, " "поэтому наличие нескольких высокоскоростных дисков важнее, чем использование " "нескольких процессоров для ускорения процесса `make release`. Если в среде " "man:chroot[2] разные иерархии размещены на разных дисках, то выгрузка CVS " "для деревьев [.filename]#ports# и [.filename]#doc# может происходить " "одновременно с выполнением `make world` на другом диске. Использование RAID " "(аппаратного или программного) может значительно сократить общее время " "сборки." #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:438 msgid "" "_Cross-building releases_ - Building IA-64 or Alpha release on x86 hardware? " "`make TARGET=ia64 release`." msgstr "" "_Кросс-сборка релизов_ - Сборка релиза для IA-64 или Alpha на x86 " "оборудовании? `make TARGET=ia64 release`." #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:439 msgid "" "_Regression Testing_ - We need better automated correctness testing for " "FreeBSD." msgstr "" "_Регрессионное тестирование_ - Нам необходимы более совершенные " "автоматизированные тесты на корректность для FreeBSD." #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:440 msgid "" "_Installation Tools_ - Our installation program has long since outlived its " "intended life span. Several projects are under development to provide a more " "advanced installation mechanism. The libh project was one such project that " "aimed to provide an intelligent new package framework and GUI installation " "program." msgstr "" "_Инструменты установки_ - Наша программа установки уже давно вышла за рамки " "своего первоначального срока службы. В разработке находится несколько " "проектов, призванных обеспечить более продвинутый механизм установки. Проект " "libh был одним из таких проектов, целью которого было создание " "интеллектуальной новой системы управления пакетами и программы установки с " "графическим интерфейсом." #. type: Title == #: documentation/content/en/articles/releng/_index.adoc:442 #, no-wrap msgid "Acknowledgements" msgstr "Благодарности" #. type: Plain text #: documentation/content/en/articles/releng/_index.adoc:447 msgid "" "I would like to thank Jordan Hubbard for giving me the opportunity to take " "on some of the release engineering responsibilities for FreeBSD 4.4 and also " "for all of his work throughout the years making FreeBSD what it is today. " "Of course the release would not have been possible without all of the " "release-related work done by `{asami}`, `{steve}`, `{bmah}`, `{nik}`, " "`{obrien}`, `{kris}`, `{jhb}` and the rest of the FreeBSD development " "community. I would also like to thank `{rgrimes}`, `{phk}`, and others who " "worked on the release engineering tools in the very early days of FreeBSD. " "This article was influenced by release engineering documents from the CSRG " "footnote:[Marshall Kirk McKusick, Michael J. Karels, and Keith Bostic: link:" "http://docs.FreeBSD.org/44doc/papers/releng.html[The Release Engineering of " "4.3BSD]] , the NetBSD Project, footnote:[NetBSD Developer Documentation: " "Release Engineering http://www.NetBSD.org/developers/releng/index.html] , " "and John Baldwin's proposed release engineering process notes. footnote:" "[John Baldwin's FreeBSD Release Engineering Proposal https://people.FreeBSD." "org/~jhb/docs/releng.txt]" msgstr "" "Я хотел бы поблагодарить Джордана Хаббарда за предоставленную мне " "возможность взять на себя часть обязанностей по управлению выпусками для " "FreeBSD 4.4, а также за всю его работу на протяжении многих лет, которая " "сделала FreeBSD такой, какая она есть сегодня. Конечно, выпуск не состоялся " "бы без всей работы, связанной с выпуском, выполненной `{asami}`, `{steve}`, " "`{bmah}`, `{nik}`, `{obrien}`, `{kris}`, `{jhb}` и остальным сообществом " "разработчиков FreeBSD. Я также хотел бы поблагодарить `{rgrimes}`, `{phk}` и " "других, кто работал над инструментами управления выпусками в самые ранние " "дни FreeBSD. На эту статью повлияли документы по управлению выпусками от " "CSRG footnote:[Маршалл Кирк МакКузик, Майкл Дж. Карелс и Кит Бостик: link:" "http://docs.FreeBSD.org/44doc/papers/releng.html[Управление выпусками " "4.3BSD]], проекта NetBSD footnote:[Документация разработчика NetBSD: " "Управление выпусками http://www.NetBSD.org/developers/releng/index.html] и " "заметки Джона Болдуина с предложениями по процессу управления выпусками. " "footnote:[Предложение Джона Болдуина по управлению выпусками FreeBSD https://" "people.FreeBSD.org/~jhb/docs/releng.txt]" diff --git a/documentation/content/ru/articles/remote-install/_index.adoc b/documentation/content/ru/articles/remote-install/_index.adoc index ee38155597..ba345cfc22 100644 --- a/documentation/content/ru/articles/remote-install/_index.adoc +++ b/documentation/content/ru/articles/remote-install/_index.adoc @@ -1,347 +1,347 @@ --- authors: - author: 'Daniel Gerzo' email: danger@FreeBSD.org copyright: '2008-2021 The FreeBSD Documentation Project' description: 'Описывает удалённую установку операционной системы FreeBSD, когда консоль удалённой системы недоступна' tags: ["Remote", "Installation", "FreeBSD"] title: 'Удалённая установка операционной системы FreeBSD без удалённой консоли' trademarks: ["freebsd", "general"] --- = Удалённая установка операционной системы FreeBSD без удалённой консоли :doctype: article :toc: macro :toclevels: 1 :icons: font :sectnums: :sectnumlevels: 6 :source-highlighter: rouge :experimental: :images-path: articles/remote-install/ ifdef::env-beastie[] ifdef::backend-html5[] include::shared/authors.adoc[] include::shared/mirrors.adoc[] include::shared/releases.adoc[] include::shared/attributes/attributes-{{% lang %}}.adoc[] include::shared/{{% lang %}}/teams.adoc[] include::shared/{{% lang %}}/mailing-lists.adoc[] include::shared/{{% lang %}}/urls.adoc[] :imagesdir: ../../../images/{images-path} endif::[] ifdef::backend-pdf,backend-epub3[] include::../../../../shared/asciidoctor.adoc[] endif::[] endif::[] ifndef::env-beastie[] include::../../../../../shared/asciidoctor.adoc[] endif::[] [.abstract-title] Аннотация В этой статье описывается удалённая установка операционной системы FreeBSD, когда консоль удалённой системы недоступна. Основная идея этой статьи является результатом сотрудничества с `{mm}` при ценных вкладах от `{pjd}`. ''' toc::[] [[background]] == Пояснения В мире существует множество хостинг-провайдеров, но лишь немногие из них официально поддерживают FreeBSD. Обычно они предоставляют поддержку для дистрибутивов Linux(R), которые можно установить на предлагаемые серверы. В некоторых случаях эти компании могут установить предпочитаемый вами дистрибутив Linux(R) по вашему запросу. Используя эту опцию, мы попытаемся установить FreeBSD. В других случаях они могут предложить систему восстановления, которая используется в чрезвычайных ситуациях. Её также можно использовать для наших целей. В этой статье описаны основные шаги установки и настройки, необходимые для удалённой установки FreeBSD с поддержкой RAID-1 и ZFS. [[intro]] == Введение В этом разделе будет коротко расскажем о цели данной статьи и будет дано более подробное объяснение того, что в ней рассматривается. Инструкции, приведённые в статье, будут полезны тем, кто использует услуги колокационных центров, не поддерживающих FreeBSD. [.procedure] ==== . Как мы упоминали в разделе crossref:remote-install[background, Предыстория], многие авторитетные компании, предоставляющие хостинг серверов, предлагают своего рода систему восстановления, которая загружается из их локальной сети и доступна через SSH. Обычно они предоставляют эту возможность, чтобы помочь клиентам восстановить повреждённые операционные системы. Как будет объяснено в этой статье, с помощью таких систем восстановления можно установить FreeBSD. + -. Следующий раздел этой статьи описывает, как настроить и собрать минималистичную FreeBSD на локальной машине. Эта версия в конечном итоге будет запущена на удаленной машине с ramdisk, что позволит нам установить полную операционную систему FreeBSD с FTP-зеркала с помощью утилиты sysinstall. +. Следующий раздел этой статьи описывает, как настроить и собрать минималистичную FreeBSD на локальной машине. Эта версия в конечном итоге будет запущена на удалённой машине с ramdisk, что позволит нам установить полную операционную систему FreeBSD с FTP-зеркала с помощью утилиты sysinstall. . Оставшаяся часть статьи описывает процедуру установки, а также настройку файловой системы ZFS. ==== [[requirements]] === Требования Для успешного продолжения необходимо: * Иметь операционную систему с доступом по сети и доступом по SSH * Понимать процесса установки FreeBSD * Быть знакомым с утилитой man:sysinstall[8] * Иметь под рукой установочный образ SO или CD с FreeBSD [[preparation]] == Подготовка - mfsBSD Прежде чем FreeBSD может быть установлена на целевую систему, необходимо собрать минимальный образ операционной системы FreeBSD, который будет загружаться с жёсткого диска. Таким образом, новая система будет доступна из сети, а остальная часть установки может быть выполнена без удалённого доступа к консоли системы. Набор инструментов mfsBSD можно использовать для создания компактного образа FreeBSD. Как следует из названия mfsBSD («mfs» означает «файловая система в памяти»), итоговый образ полностью запускается с RAM-диска. Благодаря этой особенности не будет ограничений на работу с жёсткими дисками, что позволит установить полноценную операционную систему FreeBSD. На http://mfsbsd.vx.sk/[домашней странице] mfsBSD есть ссылки на последнюю версию набора инструментов. Обратите внимание, что внутреннее устройство mfsBSD и принципы его работы выходят за рамки данной статьи. Заинтересованным читателям следует обратиться к оригинальной документации mfsBSD для получения более подробной информации. Скачайте и распакуйте последний выпуск mfsBSD и перейдите в рабочий каталог, где будут находиться скрипты mfsBSD: [source, shell] .... # fetch http://mfsbsd.vx.sk/release/mfsbsd-2.1.tar.gz # tar xvzf mfsbsd-2.1.tar.gz # cd mfsbsd-2.1/ .... [[mfsbsd-config]] === Конфигурация mfsBSD Прежде чем загрузить mfsBSD, необходимо установить несколько важных параметров конфигурации. Самое важное, что нужно правильно настроить, — это, естественно, сеть. Наиболее подходящий метод настройки параметров сети зависит от того, знаем ли мы заранее тип используемого сетевого интерфейса и драйвер сетевого интерфейса, который нужно загрузить для нашего оборудования. Мы рассмотрим, как можно настроить mfsBSD в обоих случаях. Еще одна важная настройка — установка пароля `root`. Это можно сделать, отредактировав файл [.filename]#conf/loader.conf#. Пожалуйста, ознакомьтесь с приложенными комментариями. ==== Метод [.filename]#conf/interfaces.conf# Если установленная сетевая карта неизвестна, можно использовать функцию автоматического определения в mfsBSD. Скрипты запуска mfsBSD могут определить правильный драйвер для использования на основе MAC-адреса интерфейса, если установить следующие параметры в [.filename]#conf/interfaces.conf#: [.programlisting] .... mac_interfaces="ext1" ifconfig_ext1_mac="00:00:00:00:00:00" ifconfig_ext1="inet 192.168.0.2/24" .... Не забудьте добавить информацию о `defaultrouter` в [.filename]#conf/rc.conf#: [.programlisting] .... defaultrouter="192.168.0.1" .... ==== Метод [.filename]#conf/rc.conf# Когда драйвер сетевого интерфейса известен, удобнее использовать [.filename]#conf/rc.conf# для настройки сети. Синтаксис этого файла такой же, как в стандартном файле man:rc.conf[5] FreeBSD. Например, если известно, что сетевой интерфейс man:re[4] будет доступен, можно задать следующие параметры в [.filename]#conf/rc.conf#: [.programlisting] .... defaultrouter="192.168.0.1" ifconfig_re0="inet 192.168.0.2/24" .... [[mfsbsd-build]] === Создание образа mfsBSD Процесс создания образа mfsBSD довольно прост. Первым шагом необходимо подключить установочный CD FreeBSD или образ ISO установки к [.filename]#/cdrom#. В качестве примера в этой статье мы будем предполагать, что вы загрузили образ ISO FreeBSD 10.1-RELEASE. Подключение этого образа ISO к каталогу [.filename]#/cdrom# легко выполняется с помощью утилиты man:mdconfig[8]: [source, shell] .... # mdconfig -a -t vnode -u 10 -f FreeBSD-10.1-RELEASE-amd64-disc1.iso # mount_cd9660 /dev/md10 /cdrom .... Поскольку последние выпуски FreeBSD не содержат обычных наборов дистрибутивов, необходимо извлечь файлы дистрибутива FreeBSD из архивов дистрибутива, расположенных на образе ISO: [source, shell] .... # mkdir DIST # tar -xvf /cdrom/usr/freebsd-dist/base.txz -C DIST # tar -xvf /cdrom/usr/freebsd-dist/kernel.txz -C DIST .... Далее соберите загружаемый образ mfsBSD: [source, shell] .... # make BASE=DIST .... [NOTE] ==== Указанную команду `make` необходимо выполнять из корневого уровня дерева каталогов mfsBSD, например, [.filename]#~/mfsbsd-2.1/#. ==== === Загрузка mfsBSD Теперь, когда образ mfsBSD готов, его необходимо загрузить на удалённую систему, работающую под управлением live-системы восстановления или предустановленного дистрибутива Linux(R). Наиболее подходящий инструмент для этой задачи — scp: [source, shell] .... # scp disk.img root@192.168.0.2:. .... Для правильной загрузки образа mfsBSD он должен быть размещен на первом (загрузочном) устройстве данной машины. Это может быть выполнено с помощью следующего примера, при условии что [.filename]#sda# является первым загрузочным дисковым устройством: [source, shell] .... # dd if=/root/disk.img of=/dev/sda bs=1m .... Если всё прошло успешно, образ теперь должен находиться в MBR первого устройства, и машину можно перезагрузить. Следите за корректной загрузкой системы с помощью инструмента man:ping[8]. Как только машина снова окажется в сети, к ней можно будет подключиться через man:ssh[1] под пользователем `root` с настроенным паролем. [[installation]] == Установка операционной системы FreeBSD Система mfsBSD успешно загружена, и теперь можно войти через man:ssh[1]. В этом разделе будет описано, как создавать и размечать разделы, настраивать `gmirror` для RAID-1, а также как использовать `sysinstall` для установки минимальной дистрибуции операционной системы FreeBSD. === Подготовка жёстких дисков Первая задача — выделить дисковое пространство для FreeBSD, т.е.: создать слайсы и разделы. Очевидно, что текущая работающая система полностью загружена в оперативную память, поэтому не будет проблем с манипуляциями жёсткими дисками. Для выполнения этой задачи можно использовать либо `sysinstall`, либо man:fdisk[8] в сочетании с man:bsdlabel[8]. В начале пометьте все системные диски как пустые. Повторите следующую команду для каждого жёсткого диска: [source, shell] .... # dd if=/dev/zero of=/dev/ad0 count=2 .... Далее создайте разделы и пометьте их с помощью предпочитаемого инструмента. Хотя использование `sysinstall` считается более простым, но мощным и, вероятно, менее подверженным ошибкам методом будет использование стандартных текстовых инструментов UNIX(R), таких как man:fdisk[8] и man:bsdlabel[8], которые также будут рассмотрены в этом разделе. Первый вариант хорошо документирован в главе extref:{handbook}install[Установка FreeBSD, install-steps] Руководства FreeBSD. Как упоминалось во введении, в этой статье будет показано, как настроить систему с возможностями RAID-1 и ZFS. Наша конфигурация будет состоять из небольшого зеркального раздела man:gmirror[8] для [.filename]#/# (корневого), [.filename]#/usr# и [.filename]#/var#, а остальное место на диске будет выделено для зеркальной файловой системы ZFS man:zpool[8]. Обратите внимание, что файловая система ZFS будет настроена после успешной установки и загрузки операционной системы FreeBSD. Следующий пример описывает, как создать слайсы и метки, инициализировать man:gmirror[8] на каждом разделе и как создать файловую систему UFS2 в каждом зеркальном разделе: [source, shell] .... # fdisk -BI /dev/ad0 <.> # fdisk -BI /dev/ad1 # bsdlabel -wB /dev/ad0s1 <.> # bsdlabel -wB /dev/ad1s1 # bsdlabel -e /dev/ad0s1 <.> # bsdlabel /dev/ad0s1 > /tmp/bsdlabel.txt && bsdlabel -R /dev/ad1s1 /tmp/bsdlabel.txt <.> # gmirror label root /dev/ad[01]s1a <.> # gmirror label var /dev/ad[01]s1d # gmirror label usr /dev/ad[01]s1e # gmirror label -F swap /dev/ad[01]s1b <.> # newfs /dev/mirror/root <.> # newfs /dev/mirror/var # newfs /dev/mirror/usr .... <.> Создайте раздел, охватывающий весь диск, и инициализируйте загрузочный код, содержащийся в секторе 0 данного диска. Повторите эту команду для всех жёстких дисков в системе. <.> Запишите стандартную метку для каждого диска, включая загрузочный код. <.> Теперь вручную отредактируйте метку указанного диска. Обратитесь к странице руководства man:bsdlabel[8], чтобы узнать, как создавать разделы. Создайте раздел `a` для [.filename]#/# — корневой файловой системы, `b` для раздела подкачки, `d` для [.filename]#/var#, `e` для [.filename]#/usr# и, наконец, `f`, который позже будет использоваться для ZFS. <.> Импортируйте только что созданную метку для второго жёсткого диска, чтобы оба жёстких диска были размечены одинаковым образом. <.> Инициализируйте man:gmirror[8] на каждом разделе. <.> Обратите внимание, что `-F` используется для раздела подкачки. Это указывает man:gmirror[8] предполагать, что устройство находится в согласованном состоянии после сбоя питания/системы. <.> Создайте файловую систему UFS2 на каждом зеркальном разделе. === Установка системы Это самая важная часть. В этом разделе будет описано, как фактически установить минимальный дистрибутив FreeBSD на жёсткие диски, которые мы подготовили в предыдущем разделе. Для достижения этой цели необходимо смонтировать все файловые системы, чтобы `sysinstall` мог записать содержимое FreeBSD на жёсткие диски: [source, shell] .... # mount /dev/mirror/root /mnt # mkdir /mnt/var /mnt/usr # mount /dev/mirror/var /mnt/var # mount /dev/mirror/usr /mnt/usr .... Когда вы закончите, запустите man:sysinstall[8]. Выберите установку [.guimenuitem]#Custom# в главном меню. Выберите [.guimenuitem]#Options# и нажмите kbd:[Enter]. С помощью клавиш со стрелками переместите курсор на пункт `Install Root`, нажмите kbd:[Space] и измените его на [.filename]#/mnt#. Нажмите kbd:[Enter], чтобы подтвердить изменения, и выйдите из меню [.guimenuitem]#Options#, нажав kbd:[q]. [WARNING] ==== Обратите внимание, что этот шаг очень важен, и если его пропустить, `sysinstall` не сможет установить FreeBSD. ==== Перейдите в меню [.guimenuitem]#Distributions#, с помощью клавиш со стрелками переместите курсор к пункту `Minimal` и отметьте его, нажав kbd:[Space]. В этой статье используется дистрибутив Minimal для экономии сетевого трафика, так как сама система будет устанавливаться через ftp. Выйдите из этого меню, выбрав `Exit`. [NOTE] ==== [.guimenuitem]#Partition# и [.guimenuitem]#Label# будут пропущены, так как сейчас они бесполезны. ==== В меню [.guimenuitem]#Media# выберите `FTP`. Выберите ближайший зеркальный сервер и позвольте `sysinstall` предположить, что сеть уже настроена. Вы вернётесь обратно в меню [.guimenuitem]#Custom#. Наконец, выполните установку системы, выбрав последний пункт [.guimenuitem]#Commit#. Выйдите из `sysinstall` после завершения установки. === Шаги после установки Операционная система FreeBSD теперь должна быть установлена; однако процесс ещё не завершен. Необходимо выполнить несколько шагов после установки, чтобы FreeBSD могла загружаться в будущем и чтобы можно было войти в систему. Вы должны теперь выполнить man:chroot[8] в только что установленную систему, чтобы завершить установку. Используйте следующую команду: [source, shell] .... # chroot /mnt .... Для достижения нашей цели выполните следующие шаги: * Скопируйте ядро `GENERIC` в каталог [.filename]#/boot/kernel#: + [source, shell] .... # cp -Rp /boot/GENERIC/* /boot/kernel .... * Создайте файлы [.filename]#/etc/rc.conf#, [.filename]#/etc/resolv.conf# и [.filename]#/etc/fstab#. Не забудьте правильно настроить сетевые параметры и включить sshd в [.filename]#/etc/rc.conf#. Содержимое [.filename]#/etc/fstab# будет выглядеть примерно следующим образом: + [.programlisting] .... # Device Mountpoint FStype Options Dump Pass# /dev/mirror/swap none swap sw 0 0 /dev/mirror/root / ufs rw 1 1 /dev/mirror/usr /usr ufs rw 2 2 /dev/mirror/var /var ufs rw 2 2 /dev/cd0 /cdrom cd9660 ro,noauto 0 0 .... * Создайте файл [.filename]#/boot/loader.conf# со следующим содержимым: + [.programlisting] .... geom_mirror_load="YES" zfs_load="YES" .... * Выполните следующую команду, чтобы сделать ZFS доступным при следующей загрузке: + [source, shell] .... # sysrc zfs_enable="YES" .... * Добавьте дополнительных пользователей в систему с помощью инструмента man:adduser[8]. Не забудьте добавить пользователя в группу `wheel`, чтобы получить доступ к root после перезагрузки. * Перепроверьте все ваши настройки. Система теперь должна быть готова к следующей загрузке. Используйте команду man:reboot[8] для перезагрузки системы. [[zfs]] == ZFS Если ваша система пережила перезагрузку, теперь должно быть возможно войти в систему. Добро пожаловать в новую установку FreeBSD, выполненную удалённо без использования удалённой консоли! Остался только последний шаг — настроить man:zpool[8] и создать несколько файловых систем man:zfs[8]. Создание и администрирование ZFS очень просто. Сначала создайте зеркальный пул: [source, shell] .... # zpool create tank mirror /dev/ad[01]s1f .... Далее создайте несколько файловых систем: [source, shell] .... # zfs create tank/ports # zfs create tank/src # zfs set compression=gzip tank/ports # zfs set compression=on tank/src # zfs set mountpoint=/usr/ports tank/ports # zfs set mountpoint=/usr/src tank/src .... Вот и все. Если вас интересуют более подробные сведения о ZFS в FreeBSD, обратитесь к разделу https://wiki.freebsd.org/ZFS[ZFS] на вики FreeBSD. diff --git a/documentation/content/ru/articles/remote-install/_index.po b/documentation/content/ru/articles/remote-install/_index.po index db1d88a41d..2021791a89 100644 --- a/documentation/content/ru/articles/remote-install/_index.po +++ b/documentation/content/ru/articles/remote-install/_index.po @@ -1,1007 +1,1007 @@ # SOME DESCRIPTIVE TITLE # Copyright (C) YEAR The FreeBSD Project # This file is distributed under the same license as the FreeBSD Documentation package. # Vladlen Popolitov , 2025, 2026. msgid "" msgstr "" "Project-Id-Version: FreeBSD Documentation VERSION\n" "POT-Creation-Date: 2025-11-08 16:17+0000\n" -"PO-Revision-Date: 2026-03-08 09:11+0000\n" +"PO-Revision-Date: 2026-04-05 04:45+0000\n" "Last-Translator: Vladlen Popolitov \n" "Language-Team: Russian \n" "Language: ru\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && " "n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" "X-Generator: Weblate 4.17\n" #. type: YAML Front Matter: description #: documentation/content/en/articles/remote-install/_index.adoc:1 #, no-wrap msgid "Describes the remote installation of the FreeBSD operating system when the console of the remote system is unavailable" msgstr "Описывает удалённую установку операционной системы FreeBSD, когда консоль удалённой системы недоступна" #. type: Title = #: documentation/content/en/articles/remote-install/_index.adoc:1 #: documentation/content/en/articles/remote-install/_index.adoc:12 #, no-wrap msgid "Remote Installation of the FreeBSD Operating System Without a Remote Console" msgstr "Удалённая установка операционной системы FreeBSD без удалённой консоли" #. type: Plain text #: documentation/content/en/articles/remote-install/_index.adoc:45 msgid "Abstract" msgstr "Аннотация" #. type: Plain text #: documentation/content/en/articles/remote-install/_index.adoc:48 msgid "" "This article documents the remote installation of the FreeBSD operating " "system when the console of the remote system is unavailable. The main idea " "behind this article is the result of a collaboration with `{mm}` with " "valuable input provided by `{pjd}`." msgstr "" "В этой статье описывается удалённая установка операционной системы FreeBSD, " "когда консоль удалённой системы недоступна. Основная идея этой статьи " "является результатом сотрудничества с `{mm}` при ценных вкладах от `{pjd}`." #. type: Plain text #: documentation/content/en/articles/remote-install/_index.adoc:50 msgid "'''" msgstr "'''" #. type: Title == #: documentation/content/en/articles/remote-install/_index.adoc:54 #, no-wrap msgid "Background" msgstr "Пояснения" #. type: Plain text #: documentation/content/en/articles/remote-install/_index.adoc:58 msgid "" "There are many server hosting providers in the world, but very few of them " "are officially supporting FreeBSD. They usually provide support for a " "Linux(R) distribution to be installed on the servers they offer." msgstr "" "В мире существует множество хостинг-провайдеров, но лишь немногие из них " "официально поддерживают FreeBSD. Обычно они предоставляют поддержку для " "дистрибутивов Linux(R), которые можно установить на предлагаемые серверы." #. type: Plain text #: documentation/content/en/articles/remote-install/_index.adoc:62 msgid "" "In some cases, these companies will install your preferred Linux(R) " "distribution if you request it. Using this option, we will attempt to " "install FreeBSD. In other cases, they may offer a rescue system which would " "be used in an emergency. It is possible to use this for our purposes as " "well." msgstr "" "В некоторых случаях эти компании могут установить предпочитаемый вами " "дистрибутив Linux(R) по вашему запросу. Используя эту опцию, мы попытаемся " "установить FreeBSD. В других случаях они могут предложить систему " "восстановления, которая используется в чрезвычайных ситуациях. Её также " "можно использовать для наших целей." #. type: Plain text #: documentation/content/en/articles/remote-install/_index.adoc:64 msgid "" "This article covers the basic installation and configuration steps required " "to bootstrap a remote installation of FreeBSD with RAID-1 and ZFS " "capabilities." msgstr "" "В этой статье описаны основные шаги установки и настройки, необходимые для " "удалённой установки FreeBSD с поддержкой RAID-1 и ZFS." #. type: Title == #: documentation/content/en/articles/remote-install/_index.adoc:66 #, no-wrap msgid "Introduction" msgstr "Введение" #. type: Plain text #: documentation/content/en/articles/remote-install/_index.adoc:70 msgid "" "This section will summarize the purpose of this article and better explain " "what is covered herein. The instructions included in this article will " "benefit those using services provided by colocation facilities not " "supporting FreeBSD." msgstr "" "В этом разделе будет коротко расскажем о цели данной статьи и будет дано " "более подробное объяснение того, что в ней рассматривается. Инструкции, " "приведённые в статье, будут полезны тем, кто использует услуги колокационных " "центров, не поддерживающих FreeBSD." #. type: delimited block = 4 #: documentation/content/en/articles/remote-install/_index.adoc:74 msgid "" "As we have mentioned in the crossref:remote-install[background, Background] " "section, many of the reputable server hosting companies provide some kind of " "rescue system, which is booted from their LAN and accessible over SSH. They " "usually provide this support to help their customers fix broken operating " "systems. As this article will explain, it is possible to install FreeBSD " "with the help of these rescue systems." msgstr "" "Как мы упоминали в разделе crossref:remote-install[background, Предыстория], " "многие авторитетные компании, предоставляющие хостинг серверов, предлагают " "своего рода систему восстановления, которая загружается из их локальной сети " "и доступна через SSH. Обычно они предоставляют эту возможность, чтобы помочь " "клиентам восстановить повреждённые операционные системы. Как будет объяснено " "в этой статье, с помощью таких систем восстановления можно установить " "FreeBSD." #. type: delimited block = 4 #: documentation/content/en/articles/remote-install/_index.adoc:76 msgid "" "The next section of this article will describe how to configure, and build " "minimalistic FreeBSD on the local machine. That version will eventually be " "running on the remote machine from a ramdisk, which will allow us to install " "a complete FreeBSD operating system from an FTP mirror using the sysinstall " "utility." msgstr "" "Следующий раздел этой статьи описывает, как настроить и собрать " "минималистичную FreeBSD на локальной машине. Эта версия в конечном итоге " -"будет запущена на удаленной машине с ramdisk, что позволит нам установить " +"будет запущена на удалённой машине с ramdisk, что позволит нам установить " "полную операционную систему FreeBSD с FTP-зеркала с помощью утилиты " "sysinstall." #. type: delimited block = 4 #: documentation/content/en/articles/remote-install/_index.adoc:77 msgid "" "The rest of this article will describe the installation procedure itself, as " "well as the configuration of the ZFS file system." msgstr "" "Оставшаяся часть статьи описывает процедуру установки, а также настройку " "файловой системы ZFS." #. type: Title === #: documentation/content/en/articles/remote-install/_index.adoc:80 #, no-wrap msgid "Requirements" msgstr "Требования" #. type: Plain text #: documentation/content/en/articles/remote-install/_index.adoc:83 msgid "To continue successfully, you must:" msgstr "Для успешного продолжения необходимо:" #. type: Plain text #: documentation/content/en/articles/remote-install/_index.adoc:85 msgid "Have a network accessible operating system with SSH access" msgstr "Иметь операционную систему с доступом по сети и доступом по SSH" #. type: Plain text #: documentation/content/en/articles/remote-install/_index.adoc:86 msgid "Understand the FreeBSD installation process" msgstr "Понимать процесса установки FreeBSD" #. type: Plain text #: documentation/content/en/articles/remote-install/_index.adoc:87 msgid "Be familiar with the man:sysinstall[8] utility" msgstr "Быть знакомым с утилитой man:sysinstall[8]" #. type: Plain text #: documentation/content/en/articles/remote-install/_index.adoc:88 msgid "Have the FreeBSD installation SO image or CD handy" msgstr "Иметь под рукой установочный образ SO или CD с FreeBSD" #. type: Title == #: documentation/content/en/articles/remote-install/_index.adoc:90 #, no-wrap msgid "Preparation - mfsBSD" msgstr "Подготовка - mfsBSD" #. type: Plain text #: documentation/content/en/articles/remote-install/_index.adoc:94 msgid "" "Before FreeBSD may be installed on the target system, it is necessary to " "build the minimal FreeBSD operating system image which will boot from the " "hard drive. This way the new system can be accessed from the network, and " "the rest of the installation can be done without remote access to the system " "console." msgstr "" "Прежде чем FreeBSD может быть установлена на целевую систему, необходимо " "собрать минимальный образ операционной системы FreeBSD, который будет " "загружаться с жёсткого диска. Таким образом, новая система будет доступна из " "сети, а остальная часть установки может быть выполнена без удалённого " "доступа к консоли системы." #. type: Plain text #: documentation/content/en/articles/remote-install/_index.adoc:99 msgid "" "The mfsBSD tool-set can be used to build a tiny FreeBSD image. As the name " "of mfsBSD suggests (\"mfs\" means \"memory file system\"), the resulting " "image runs entirely from a ramdisk. Thanks to this feature, the " "manipulation of hard drives will not be limited, therefore it will be " "possible to install a complete FreeBSD operating system. The mfsBSD http://" "mfsbsd.vx.sk/[home page] includes pointers to the latest release of the " "toolset." msgstr "" "Набор инструментов mfsBSD можно использовать для создания компактного образа " "FreeBSD. Как следует из названия mfsBSD («mfs» означает «файловая система в " "памяти»), итоговый образ полностью запускается с RAM-диска. Благодаря этой " "особенности не будет ограничений на работу с жёсткими дисками, что позволит " "установить полноценную операционную систему FreeBSD. На http://mfsbsd.vx.sk/" "[домашней странице] mfsBSD есть ссылки на последнюю версию набора " "инструментов." #. type: Plain text #: documentation/content/en/articles/remote-install/_index.adoc:102 msgid "" "Please note that the internals of mfsBSD and how it all fits together is " "beyond the scope of this article. The interested reader should consult the " "original documentation of mfsBSD for more details." msgstr "" "Обратите внимание, что внутреннее устройство mfsBSD и принципы его работы " "выходят за рамки данной статьи. Заинтересованным читателям следует " "обратиться к оригинальной документации mfsBSD для получения более подробной " "информации." #. type: Plain text #: documentation/content/en/articles/remote-install/_index.adoc:104 msgid "" "Download and extract the latest mfsBSD release and change your working " "directory to the directory where the mfsBSD scripts will reside:" msgstr "" "Скачайте и распакуйте последний выпуск mfsBSD и перейдите в рабочий каталог, " "где будут находиться скрипты mfsBSD:" #. type: delimited block . 4 #: documentation/content/en/articles/remote-install/_index.adoc:110 #, no-wrap msgid "" "# fetch http://mfsbsd.vx.sk/release/mfsbsd-2.1.tar.gz\n" "# tar xvzf mfsbsd-2.1.tar.gz\n" "# cd mfsbsd-2.1/\n" msgstr "" "# fetch http://mfsbsd.vx.sk/release/mfsbsd-2.1.tar.gz\n" "# tar xvzf mfsbsd-2.1.tar.gz\n" "# cd mfsbsd-2.1/\n" #. type: Title === #: documentation/content/en/articles/remote-install/_index.adoc:113 #, no-wrap msgid "Configuration of mfsBSD" msgstr "Конфигурация mfsBSD" #. type: Plain text #: documentation/content/en/articles/remote-install/_index.adoc:119 msgid "" "Before booting mfsBSD, a few important configuration options have to be " "set. The most important that we have to get right is, naturally, the " "network setup. The most suitable method to configure networking options " "depends on whether we know beforehand the type of the network interface we " "will use, and the network interface driver to be loaded for our hardware. " "We will see how mfsBSD can be configured in either case." msgstr "" "Прежде чем загрузить mfsBSD, необходимо установить несколько важных " "параметров конфигурации. Самое важное, что нужно правильно настроить, — это, " "естественно, сеть. Наиболее подходящий метод настройки параметров сети " "зависит от того, знаем ли мы заранее тип используемого сетевого интерфейса и " "драйвер сетевого интерфейса, который нужно загрузить для нашего " "оборудования. Мы рассмотрим, как можно настроить mfsBSD в обоих случаях." #. type: Plain text #: documentation/content/en/articles/remote-install/_index.adoc:123 msgid "" "Another important thing to set is the `root` password. This can be done by " "editing [.filename]#conf/loader.conf#. Please see the included comments." msgstr "" "Еще одна важная настройка — установка пароля `root`. Это можно сделать, " "отредактировав файл [.filename]#conf/loader.conf#. Пожалуйста, ознакомьтесь " "с приложенными комментариями." #. type: Title ==== #: documentation/content/en/articles/remote-install/_index.adoc:124 #, no-wrap msgid "The [.filename]#conf/interfaces.conf# method" msgstr "Метод [.filename]#conf/interfaces.conf#" #. type: Plain text #: documentation/content/en/articles/remote-install/_index.adoc:128 msgid "" "When the installed network interface card is unknown, it is possible to use " "the auto-detection features of mfsBSD. The startup scripts of mfsBSD can " "detect the correct driver to use, based on the MAC address of the interface, " "if we set the following options in [.filename]#conf/interfaces.conf#:" msgstr "" "Если установленная сетевая карта неизвестна, можно использовать функцию " "автоматического определения в mfsBSD. Скрипты запуска mfsBSD могут " "определить правильный драйвер для использования на основе MAC-адреса " "интерфейса, если установить следующие параметры в [.filename]#conf/" "interfaces.conf#:" #. type: delimited block . 4 #: documentation/content/en/articles/remote-install/_index.adoc:134 #, no-wrap msgid "" "mac_interfaces=\"ext1\"\n" "ifconfig_ext1_mac=\"00:00:00:00:00:00\"\n" "ifconfig_ext1=\"inet 192.168.0.2/24\"\n" msgstr "" "mac_interfaces=\"ext1\"\n" "ifconfig_ext1_mac=\"00:00:00:00:00:00\"\n" "ifconfig_ext1=\"inet 192.168.0.2/24\"\n" #. type: Plain text #: documentation/content/en/articles/remote-install/_index.adoc:137 msgid "" "Do not forget to add the `defaultrouter` information to [.filename]#conf/rc." "conf#:" msgstr "" "Не забудьте добавить информацию о `defaultrouter` в [.filename]#conf/rc." "conf#:" #. type: delimited block . 4 #: documentation/content/en/articles/remote-install/_index.adoc:141 #, no-wrap msgid "defaultrouter=\"192.168.0.1\"\n" msgstr "defaultrouter=\"192.168.0.1\"\n" #. type: Title ==== #: documentation/content/en/articles/remote-install/_index.adoc:143 #, no-wrap msgid "The [.filename]#conf/rc.conf# Method" msgstr "Метод [.filename]#conf/rc.conf#" #. type: Plain text #: documentation/content/en/articles/remote-install/_index.adoc:147 msgid "" "When the network interface driver is known, it is more convenient to use [." "filename]#conf/rc.conf# for networking options. The syntax of this file is " "the same as the one used in the standard man:rc.conf[5] file of FreeBSD." msgstr "" "Когда драйвер сетевого интерфейса известен, удобнее использовать [." "filename]#conf/rc.conf# для настройки сети. Синтаксис этого файла такой же, " "как в стандартном файле man:rc.conf[5] FreeBSD." #. type: Plain text #: documentation/content/en/articles/remote-install/_index.adoc:149 msgid "" "For example, if you know that a man:re[4] network interface is going to be " "available, you can set the following options in [.filename]#conf/rc.conf#:" msgstr "" "Например, если известно, что сетевой интерфейс man:re[4] будет доступен, " "можно задать следующие параметры в [.filename]#conf/rc.conf#:" #. type: delimited block . 4 #: documentation/content/en/articles/remote-install/_index.adoc:154 #, no-wrap msgid "" "defaultrouter=\"192.168.0.1\"\n" "ifconfig_re0=\"inet 192.168.0.2/24\"\n" msgstr "" "defaultrouter=\"192.168.0.1\"\n" "ifconfig_re0=\"inet 192.168.0.2/24\"\n" #. type: Title === #: documentation/content/en/articles/remote-install/_index.adoc:157 #, no-wrap msgid "Building an mfsBSD Image" msgstr "Создание образа mfsBSD" #. type: Plain text #: documentation/content/en/articles/remote-install/_index.adoc:160 msgid "The process of building an mfsBSD image is pretty straightforward." msgstr "Процесс создания образа mfsBSD довольно прост." #. type: Plain text #: documentation/content/en/articles/remote-install/_index.adoc:164 msgid "" "The first step is to mount the FreeBSD installation CD, or the installation " "ISO image to [.filename]#/cdrom#. For the sake of example, in this article " "we will assume that you have downloaded the FreeBSD 10.1-RELEASE ISO. " "Mounting this ISO image to the [.filename]#/cdrom# directory is easy with " "the man:mdconfig[8] utility:" msgstr "" "Первым шагом необходимо подключить установочный CD FreeBSD или образ ISO " "установки к [.filename]#/cdrom#. В качестве примера в этой статье мы будем " "предполагать, что вы загрузили образ ISO FreeBSD 10.1-RELEASE. Подключение " "этого образа ISO к каталогу [.filename]#/cdrom# легко выполняется с помощью " "утилиты man:mdconfig[8]:" #. type: delimited block . 4 #: documentation/content/en/articles/remote-install/_index.adoc:169 #, no-wrap msgid "" "# mdconfig -a -t vnode -u 10 -f FreeBSD-10.1-RELEASE-amd64-disc1.iso\n" "# mount_cd9660 /dev/md10 /cdrom\n" msgstr "" "# mdconfig -a -t vnode -u 10 -f FreeBSD-10.1-RELEASE-amd64-disc1.iso\n" "# mount_cd9660 /dev/md10 /cdrom\n" #. type: Plain text #: documentation/content/en/articles/remote-install/_index.adoc:172 msgid "" "Since the recent FreeBSD releases do not contain regular distribution sets, " "it is required to extract the FreeBSD distribution files from the " "distribution archives located on the ISO image:" msgstr "" "Поскольку последние выпуски FreeBSD не содержат обычных наборов " "дистрибутивов, необходимо извлечь файлы дистрибутива FreeBSD из архивов " "дистрибутива, расположенных на образе ISO:" #. type: delimited block . 4 #: documentation/content/en/articles/remote-install/_index.adoc:178 #, no-wrap msgid "" "# mkdir DIST\n" "# tar -xvf /cdrom/usr/freebsd-dist/base.txz -C DIST\n" "# tar -xvf /cdrom/usr/freebsd-dist/kernel.txz -C DIST\n" msgstr "" "# mkdir DIST\n" "# tar -xvf /cdrom/usr/freebsd-dist/base.txz -C DIST\n" "# tar -xvf /cdrom/usr/freebsd-dist/kernel.txz -C DIST\n" #. type: Plain text #: documentation/content/en/articles/remote-install/_index.adoc:181 msgid "Next, build the bootable mfsBSD image:" msgstr "Далее соберите загружаемый образ mfsBSD:" #. type: delimited block . 4 #: documentation/content/en/articles/remote-install/_index.adoc:185 #, no-wrap msgid "# make BASE=DIST\n" msgstr "# make BASE=DIST\n" #. type: delimited block = 4 #: documentation/content/en/articles/remote-install/_index.adoc:190 msgid "" "The above `make` has to be run from the top level of the mfsBSD directory " "tree, for example [.filename]#~/mfsbsd-2.1/#." msgstr "" "Указанную команду `make` необходимо выполнять из корневого уровня дерева " "каталогов mfsBSD, например, [.filename]#~/mfsbsd-2.1/#." #. type: Title === #: documentation/content/en/articles/remote-install/_index.adoc:192 #, no-wrap msgid "Booting mfsBSD" msgstr "Загрузка mfsBSD" #. type: Plain text #: documentation/content/en/articles/remote-install/_index.adoc:196 msgid "" "Now that the mfsBSD image is ready, it must be uploaded to the remote system " "running a live rescue system or pre-installed Linux(R) distribution. The " "most suitable tool for this task is scp:" msgstr "" "Теперь, когда образ mfsBSD готов, его необходимо загрузить на удалённую " "систему, работающую под управлением live-системы восстановления или " "предустановленного дистрибутива Linux(R). Наиболее подходящий инструмент для " "этой задачи — scp:" #. type: delimited block . 4 #: documentation/content/en/articles/remote-install/_index.adoc:200 #, no-wrap msgid "# scp disk.img root@192.168.0.2:.\n" msgstr "# scp disk.img root@192.168.0.2:.\n" #. type: Plain text #: documentation/content/en/articles/remote-install/_index.adoc:204 msgid "" "To boot mfsBSD image properly, it must be placed on the first (bootable) " "device of the given machine. This may be accomplished using this example " "providing that [.filename]#sda# is the first bootable disk device:" msgstr "" "Для правильной загрузки образа mfsBSD он должен быть размещен на первом " "(загрузочном) устройстве данной машины. Это может быть выполнено с помощью " "следующего примера, при условии что [.filename]#sda# является первым " "загрузочным дисковым устройством:" #. type: delimited block . 4 #: documentation/content/en/articles/remote-install/_index.adoc:208 #, no-wrap msgid "# dd if=/root/disk.img of=/dev/sda bs=1m\n" msgstr "# dd if=/root/disk.img of=/dev/sda bs=1m\n" #. type: Plain text #: documentation/content/en/articles/remote-install/_index.adoc:213 msgid "" "If all went well, the image should now be in the MBR of the first device and " "the machine can be rebooted. Watch for the machine to boot up properly with " "the man:ping[8] tool. Once it has came back on-line, it should be possible " "to access it over man:ssh[1] as user `root` with the configured password." msgstr "" "Если всё прошло успешно, образ теперь должен находиться в MBR первого " "устройства, и машину можно перезагрузить. Следите за корректной загрузкой " "системы с помощью инструмента man:ping[8]. Как только машина снова окажется " "в сети, к ней можно будет подключиться через man:ssh[1] под пользователем " "`root` с настроенным паролем." #. type: Title == #: documentation/content/en/articles/remote-install/_index.adoc:215 #, no-wrap msgid "Installation of the FreeBSD Operating System" msgstr "Установка операционной системы FreeBSD" #. type: Plain text #: documentation/content/en/articles/remote-install/_index.adoc:219 msgid "" "The mfsBSD has been successfully booted and it should be possible to log in " "through man:ssh[1]. This section will describe how to create and label " "slices, set up `gmirror` for RAID-1, and how to use `sysinstall` to install " "a minimal distribution of the FreeBSD operating system." msgstr "" "Система mfsBSD успешно загружена, и теперь можно войти через man:ssh[1]. В " "этом разделе будет описано, как создавать и размечать разделы, настраивать " "`gmirror` для RAID-1, а также как использовать `sysinstall` для установки " "минимальной дистрибуции операционной системы FreeBSD." #. type: Title === #: documentation/content/en/articles/remote-install/_index.adoc:220 #, no-wrap msgid "Preparation of Hard Drives" msgstr "Подготовка жёстких дисков" #. type: Plain text #: documentation/content/en/articles/remote-install/_index.adoc:225 msgid "" "The first task is to allocate disk space for FreeBSD, i.e.: to create slices " "and partitions. Obviously, the currently running system is fully loaded in " "system memory and therefore there will be no problems with manipulating hard " "drives. To complete this task, it is possible to use either `sysinstall` or " "man:fdisk[8] in conjunction to man:bsdlabel[8]." msgstr "" "Первая задача — выделить дисковое пространство для FreeBSD, т.е.: создать " "слайсы и разделы. Очевидно, что текущая работающая система полностью " "загружена в оперативную память, поэтому не будет проблем с манипуляциями " "жёсткими дисками. Для выполнения этой задачи можно использовать либо " "`sysinstall`, либо man:fdisk[8] в сочетании с man:bsdlabel[8]." #. type: Plain text #: documentation/content/en/articles/remote-install/_index.adoc:228 msgid "" "At the start, mark all system disks as empty. Repeat the following command " "for each hard drive:" msgstr "" "В начале пометьте все системные диски как пустые. Повторите следующую " "команду для каждого жёсткого диска:" #. type: delimited block . 4 #: documentation/content/en/articles/remote-install/_index.adoc:232 #, no-wrap msgid "# dd if=/dev/zero of=/dev/ad0 count=2\n" msgstr "# dd if=/dev/zero of=/dev/ad0 count=2\n" #. type: Plain text #: documentation/content/en/articles/remote-install/_index.adoc:240 msgid "" "Next, create slices and label them with your preferred tool. While it is " "considered easier to use `sysinstall`, a powerful and also probably less " "buggy method will be to use standard text-based UNIX(R) tools, such as man:" "fdisk[8] and man:bsdlabel[8], which will also be covered in this section. " "The former option is well documented in the extref:{handbook}" "install[Installing FreeBSD, install-steps] chapter of the FreeBSD Handbook. " "As it was mentioned in the introduction, this article will present how to " "set up a system with RAID-1 and ZFS capabilities. Our set up will consist " "of a small man:gmirror[8] mirrored [.filename]#/# (root), [.filename]#/usr# " "and [.filename]#/var# dataset, and the rest of the disk space will be " "allocated for a man:zpool[8] mirrored ZFS file system. Please note, that " "the ZFS file system will be configured after the FreeBSD operating system is " "successfully installed and booted." msgstr "" "Далее создайте разделы и пометьте их с помощью предпочитаемого инструмента. " "Хотя использование `sysinstall` считается более простым, но мощным и, " "вероятно, менее подверженным ошибкам методом будет использование стандартных " "текстовых инструментов UNIX(R), таких как man:fdisk[8] и man:bsdlabel[8], " "которые также будут рассмотрены в этом разделе. Первый вариант хорошо " "документирован в главе extref:{handbook}install[Установка FreeBSD, install-" "steps] Руководства FreeBSD. Как упоминалось во введении, в этой статье будет " "показано, как настроить систему с возможностями RAID-1 и ZFS. Наша " "конфигурация будет состоять из небольшого зеркального раздела man:gmirror[8] " "для [.filename]#/# (корневого), [.filename]#/usr# и [.filename]#/var#, а " "остальное место на диске будет выделено для зеркальной файловой системы ZFS " "man:zpool[8]. Обратите внимание, что файловая система ZFS будет настроена " "после успешной установки и загрузки операционной системы FreeBSD." #. type: Plain text #: documentation/content/en/articles/remote-install/_index.adoc:242 msgid "" "The following example will describe how to create slices and labels, " "initialize man:gmirror[8] on each partition and how to create a UFS2 file " "system in each mirrored partition:" msgstr "" "Следующий пример описывает, как создать слайсы и метки, инициализировать man:" "gmirror[8] на каждом разделе и как создать файловую систему UFS2 в каждом " "зеркальном разделе:" #. type: delimited block . 4 #: documentation/content/en/articles/remote-install/_index.adoc:258 #, no-wrap msgid "" "# fdisk -BI /dev/ad0 <.>\n" "# fdisk -BI /dev/ad1\n" "# bsdlabel -wB /dev/ad0s1 <.>\n" "# bsdlabel -wB /dev/ad1s1\n" "# bsdlabel -e /dev/ad0s1 <.>\n" "# bsdlabel /dev/ad0s1 > /tmp/bsdlabel.txt && bsdlabel -R /dev/ad1s1 /tmp/bsdlabel.txt <.>\n" "# gmirror label root /dev/ad[01]s1a <.>\n" "# gmirror label var /dev/ad[01]s1d\n" "# gmirror label usr /dev/ad[01]s1e\n" "# gmirror label -F swap /dev/ad[01]s1b <.>\n" "# newfs /dev/mirror/root <.>\n" "# newfs /dev/mirror/var\n" "# newfs /dev/mirror/usr\n" msgstr "" "# fdisk -BI /dev/ad0 <.>\n" "# fdisk -BI /dev/ad1\n" "# bsdlabel -wB /dev/ad0s1 <.>\n" "# bsdlabel -wB /dev/ad1s1\n" "# bsdlabel -e /dev/ad0s1 <.>\n" "# bsdlabel /dev/ad0s1 > /tmp/bsdlabel.txt && bsdlabel -R /dev/ad1s1 /tmp/bsdlabel.txt <.>\n" "# gmirror label root /dev/ad[01]s1a <.>\n" "# gmirror label var /dev/ad[01]s1d\n" "# gmirror label usr /dev/ad[01]s1e\n" "# gmirror label -F swap /dev/ad[01]s1b <.>\n" "# newfs /dev/mirror/root <.>\n" "# newfs /dev/mirror/var\n" "# newfs /dev/mirror/usr\n" #. type: Plain text #: documentation/content/en/articles/remote-install/_index.adoc:261 msgid "" "Create a slice covering the entire disk and initialize the boot code " "contained in sector 0 of the given disk. Repeat this command for all hard " "drives in the system." msgstr "" "Создайте раздел, охватывающий весь диск, и инициализируйте загрузочный код, " "содержащийся в секторе 0 данного диска. Повторите эту команду для всех " "жёстких дисков в системе." #. type: Plain text #: documentation/content/en/articles/remote-install/_index.adoc:263 msgid "Write a standard label for each disk including the bootstrap code." msgstr "Запишите стандартную метку для каждого диска, включая загрузочный код." #. type: Plain text #: documentation/content/en/articles/remote-install/_index.adoc:265 msgid "" "Now, manually edit the label of the given disk. Refer to the man:bsdlabel[8] " "manual page to find out how to create partitions. Create partitions `a` for " "[.filename]#/# (root) file system, `b` for swap, `d` for [.filename]#/var#, " "`e` for [.filename]#/usr# and finally `f` which will later be used for ZFS." msgstr "" "Теперь вручную отредактируйте метку указанного диска. Обратитесь к странице " "руководства man:bsdlabel[8], чтобы узнать, как создавать разделы. Создайте " "раздел `a` для [.filename]#/# — корневой файловой системы, `b` для раздела " "подкачки, `d` для [.filename]#/var#, `e` для [.filename]#/usr# и, наконец, " "`f`, который позже будет использоваться для ZFS." #. type: Plain text #: documentation/content/en/articles/remote-install/_index.adoc:267 msgid "" "Import the recently created label for the second hard drive, so both hard " "drives will be labeled in the same way." msgstr "" "Импортируйте только что созданную метку для второго жёсткого диска, чтобы " "оба жёстких диска были размечены одинаковым образом." #. type: Plain text #: documentation/content/en/articles/remote-install/_index.adoc:269 msgid "Initialize man:gmirror[8] on each partition." msgstr "Инициализируйте man:gmirror[8] на каждом разделе." #. type: Plain text #: documentation/content/en/articles/remote-install/_index.adoc:271 msgid "" "Note that `-F` is used for the swap partition. This instructs man:gmirror[8] " "to assume that the device is in the consistent state after the power/system " "failure." msgstr "" "Обратите внимание, что `-F` используется для раздела подкачки. Это указывает " "man:gmirror[8] предполагать, что устройство находится в согласованном " "состоянии после сбоя питания/системы." #. type: Plain text #: documentation/content/en/articles/remote-install/_index.adoc:273 msgid "Create a UFS2 file system on each mirrored partition." msgstr "Создайте файловую систему UFS2 на каждом зеркальном разделе." #. type: Title === #: documentation/content/en/articles/remote-install/_index.adoc:274 #, no-wrap msgid "System Installation" msgstr "Установка системы" #. type: Plain text #: documentation/content/en/articles/remote-install/_index.adoc:279 msgid "" "This is the most important part. This section will describe how to actually " "install the minimal distribution of FreeBSD on the hard drives that we have " "prepared in the previous section. To accomplish this goal, all file systems " "need to be mounted so `sysinstall` may write the contents of FreeBSD to the " "hard drives:" msgstr "" "Это самая важная часть. В этом разделе будет описано, как фактически " "установить минимальный дистрибутив FreeBSD на жёсткие диски, которые мы " "подготовили в предыдущем разделе. Для достижения этой цели необходимо " "смонтировать все файловые системы, чтобы `sysinstall` мог записать " "содержимое FreeBSD на жёсткие диски:" #. type: delimited block . 4 #: documentation/content/en/articles/remote-install/_index.adoc:286 #, no-wrap msgid "" "# mount /dev/mirror/root /mnt\n" "# mkdir /mnt/var /mnt/usr\n" "# mount /dev/mirror/var /mnt/var\n" "# mount /dev/mirror/usr /mnt/usr\n" msgstr "" "# mount /dev/mirror/root /mnt\n" "# mkdir /mnt/var /mnt/usr\n" "# mount /dev/mirror/var /mnt/var\n" "# mount /dev/mirror/usr /mnt/usr\n" #. type: Plain text #: documentation/content/en/articles/remote-install/_index.adoc:293 msgid "" "When you are done, start man:sysinstall[8]. Select the [." "guimenuitem]#Custom# installation from the main menu. Select [." "guimenuitem]#Options# and press kbd:[Enter]. With the help of arrow keys, " "move the cursor on the `Install Root` item, press kbd:[Space] and change it " "to [.filename]#/mnt#. Press kbd:[Enter] to submit your changes and exit the " "[.guimenuitem]#Options# menu by pressing kbd:[q]." msgstr "" "Когда вы закончите, запустите man:sysinstall[8]. Выберите установку [." "guimenuitem]#Custom# в главном меню. Выберите [.guimenuitem]#Options# и " "нажмите kbd:[Enter]. С помощью клавиш со стрелками переместите курсор на " "пункт `Install Root`, нажмите kbd:[Space] и измените его на [.filename]#/" "mnt#. Нажмите kbd:[Enter], чтобы подтвердить изменения, и выйдите из меню [." "guimenuitem]#Options#, нажав kbd:[q]." #. type: delimited block = 4 #: documentation/content/en/articles/remote-install/_index.adoc:297 msgid "" "Note that this step is very important and if skipped, `sysinstall` will be " "unable to install FreeBSD." msgstr "" "Обратите внимание, что этот шаг очень важен, и если его пропустить, " "`sysinstall` не сможет установить FreeBSD." #. type: Plain text #: documentation/content/en/articles/remote-install/_index.adoc:302 msgid "" "Go to the [.guimenuitem]#Distributions# menu, move the cursor with the arrow " "keys to `Minimal`, and check it by pressing kbd:[Space]. This article uses " "the Minimal distribution to save network traffic, because the system itself " "will be installed over ftp. Exit this menu by choosing `Exit`." msgstr "" "Перейдите в меню [.guimenuitem]#Distributions#, с помощью клавиш со " "стрелками переместите курсор к пункту `Minimal` и отметьте его, нажав kbd:" "[Space]. В этой статье используется дистрибутив Minimal для экономии " "сетевого трафика, так как сама система будет устанавливаться через ftp. " "Выйдите из этого меню, выбрав `Exit`." #. type: delimited block = 4 #: documentation/content/en/articles/remote-install/_index.adoc:306 msgid "" "The [.guimenuitem]#Partition# and [.guimenuitem]#Label# menus will be " "skipped, as these are useless now." msgstr "" "[.guimenuitem]#Partition# и [.guimenuitem]#Label# будут пропущены, так как " "сейчас они бесполезны." #. type: Plain text #: documentation/content/en/articles/remote-install/_index.adoc:311 msgid "" "In the [.guimenuitem]#Media# menu, select `FTP`. Select the nearest mirror " "and let `sysinstall` assume that the network is already configured. You " "will be returned back to the [.guimenuitem]#Custom# menu." msgstr "" "В меню [.guimenuitem]#Media# выберите `FTP`. Выберите ближайший зеркальный " "сервер и позвольте `sysinstall` предположить, что сеть уже настроена. Вы " "вернётесь обратно в меню [.guimenuitem]#Custom#." #. type: Plain text #: documentation/content/en/articles/remote-install/_index.adoc:314 msgid "" "Finally, perform the system installation by selecting the last option, [." "guimenuitem]#Commit#. Exit `sysinstall` when it finishes the installation." msgstr "" "Наконец, выполните установку системы, выбрав последний пункт [." "guimenuitem]#Commit#. Выйдите из `sysinstall` после завершения установки." #. type: Title === #: documentation/content/en/articles/remote-install/_index.adoc:315 #, no-wrap msgid "Post Installation Steps" msgstr "Шаги после установки" #. type: Plain text #: documentation/content/en/articles/remote-install/_index.adoc:319 msgid "" "The FreeBSD operating system should be installed now; however, the process " "is not finished yet. It is necessary to perform some post installation " "steps to allow FreeBSD to boot in the future and to be able to log in to the " "system." msgstr "" "Операционная система FreeBSD теперь должна быть установлена; однако процесс " "ещё не завершен. Необходимо выполнить несколько шагов после установки, чтобы " "FreeBSD могла загружаться в будущем и чтобы можно было войти в систему." #. type: Plain text #: documentation/content/en/articles/remote-install/_index.adoc:322 msgid "" "You must now man:chroot[8] into the freshly installed system to finish the " "installation. Use the following command:" msgstr "" "Вы должны теперь выполнить man:chroot[8] в только что установленную систему, " "чтобы завершить установку. Используйте следующую команду:" #. type: delimited block . 4 #: documentation/content/en/articles/remote-install/_index.adoc:326 #, no-wrap msgid "# chroot /mnt\n" msgstr "# chroot /mnt\n" #. type: Plain text #: documentation/content/en/articles/remote-install/_index.adoc:329 msgid "To complete our goal, perform these steps:" msgstr "Для достижения нашей цели выполните следующие шаги:" #. type: Plain text #: documentation/content/en/articles/remote-install/_index.adoc:331 msgid "Copy the `GENERIC` kernel to the [.filename]#/boot/kernel# directory:" msgstr "Скопируйте ядро `GENERIC` в каталог [.filename]#/boot/kernel#:" #. type: delimited block . 4 #: documentation/content/en/articles/remote-install/_index.adoc:335 #, no-wrap msgid "# cp -Rp /boot/GENERIC/* /boot/kernel\n" msgstr "# cp -Rp /boot/GENERIC/* /boot/kernel\n" #. type: Plain text #: documentation/content/en/articles/remote-install/_index.adoc:338 msgid "" "Create the [.filename]#/etc/rc.conf#, [.filename]#/etc/resolv.conf# and [." "filename]#/etc/fstab# files. Do not forget to properly set the network " "information and to enable sshd in [.filename]#/etc/rc.conf#. The contents of " "[.filename]#/etc/fstab# will be similar to the following:" msgstr "" "Создайте файлы [.filename]#/etc/rc.conf#, [.filename]#/etc/resolv.conf# и [." "filename]#/etc/fstab#. Не забудьте правильно настроить сетевые параметры и " "включить sshd в [.filename]#/etc/rc.conf#. Содержимое [.filename]#/etc/" "fstab# будет выглядеть примерно следующим образом:" #. type: delimited block . 4 #: documentation/content/en/articles/remote-install/_index.adoc:347 #, no-wrap msgid "" "# Device Mountpoint FStype Options Dump Pass#\n" "/dev/mirror/swap none swap sw 0 0\n" "/dev/mirror/root / ufs rw 1 1\n" "/dev/mirror/usr /usr ufs rw 2 2\n" "/dev/mirror/var /var ufs rw 2 2\n" "/dev/cd0 /cdrom cd9660 ro,noauto 0 0\n" msgstr "" "# Device Mountpoint FStype Options Dump Pass#\n" "/dev/mirror/swap none swap sw 0 0\n" "/dev/mirror/root / ufs rw 1 1\n" "/dev/mirror/usr /usr ufs rw 2 2\n" "/dev/mirror/var /var ufs rw 2 2\n" "/dev/cd0 /cdrom cd9660 ro,noauto 0 0\n" #. type: Plain text #: documentation/content/en/articles/remote-install/_index.adoc:349 msgid "Create [.filename]#/boot/loader.conf# with the following contents:" msgstr "Создайте файл [.filename]#/boot/loader.conf# со следующим содержимым:" #. type: delimited block . 4 #: documentation/content/en/articles/remote-install/_index.adoc:354 #, no-wrap msgid "" "geom_mirror_load=\"YES\"\n" "zfs_load=\"YES\"\n" msgstr "" "geom_mirror_load=\"YES\"\n" "zfs_load=\"YES\"\n" #. type: Plain text #: documentation/content/en/articles/remote-install/_index.adoc:356 msgid "" "Perform the following command, which will make ZFS available on the next " "boot:" msgstr "" "Выполните следующую команду, чтобы сделать ZFS доступным при следующей " "загрузке:" #. type: delimited block . 4 #: documentation/content/en/articles/remote-install/_index.adoc:360 #, no-wrap msgid "# sysrc zfs_enable=\"YES\"\n" msgstr "# sysrc zfs_enable=\"YES\"\n" #. type: Plain text #: documentation/content/en/articles/remote-install/_index.adoc:363 msgid "" "Add additional users to the system using the man:adduser[8] tool. Do not " "forget to add a user to the `wheel` group so you may obtain root access " "after the reboot." msgstr "" "Добавьте дополнительных пользователей в систему с помощью инструмента man:" "adduser[8]. Не забудьте добавить пользователя в группу `wheel`, чтобы " "получить доступ к root после перезагрузки." #. type: Plain text #: documentation/content/en/articles/remote-install/_index.adoc:364 msgid "Double-check all your settings." msgstr "Перепроверьте все ваши настройки." #. type: Plain text #: documentation/content/en/articles/remote-install/_index.adoc:367 msgid "" "The system should now be ready for the next boot. Use the man:reboot[8] " "command to reboot your system." msgstr "" "Система теперь должна быть готова к следующей загрузке. Используйте команду " "man:reboot[8] для перезагрузки системы." #. type: Title == #: documentation/content/en/articles/remote-install/_index.adoc:369 #, no-wrap msgid "ZFS" msgstr "ZFS" #. type: Plain text #: documentation/content/en/articles/remote-install/_index.adoc:373 msgid "" "If your system survived the reboot, it should now be possible to log in. " "Welcome to the fresh FreeBSD installation, performed remotely without the " "use of a remote console!" msgstr "" "Если ваша система пережила перезагрузку, теперь должно быть возможно войти в " "систему. Добро пожаловать в новую установку FreeBSD, выполненную удалённо " "без использования удалённой консоли!" #. type: Plain text #: documentation/content/en/articles/remote-install/_index.adoc:376 msgid "" "The only remaining step is to configure man:zpool[8] and create some man:" "zfs[8] file systems. Creating and administering ZFS is very " "straightforward. First, create a mirrored pool:" msgstr "" "Остался только последний шаг — настроить man:zpool[8] и создать несколько " "файловых систем man:zfs[8]. Создание и администрирование ZFS очень просто. " "Сначала создайте зеркальный пул:" #. type: delimited block . 4 #: documentation/content/en/articles/remote-install/_index.adoc:380 #, no-wrap msgid "# zpool create tank mirror /dev/ad[01]s1f\n" msgstr "# zpool create tank mirror /dev/ad[01]s1f\n" #. type: Plain text #: documentation/content/en/articles/remote-install/_index.adoc:383 msgid "Next, create some file systems:" msgstr "Далее создайте несколько файловых систем:" #. type: delimited block . 4 #: documentation/content/en/articles/remote-install/_index.adoc:392 #, no-wrap msgid "" "# zfs create tank/ports\n" "# zfs create tank/src\n" "# zfs set compression=gzip tank/ports\n" "# zfs set compression=on tank/src\n" "# zfs set mountpoint=/usr/ports tank/ports\n" "# zfs set mountpoint=/usr/src tank/src\n" msgstr "" "# zfs create tank/ports\n" "# zfs create tank/src\n" "# zfs set compression=gzip tank/ports\n" "# zfs set compression=on tank/src\n" "# zfs set mountpoint=/usr/ports tank/ports\n" "# zfs set mountpoint=/usr/src tank/src\n" #. type: Plain text #: documentation/content/en/articles/remote-install/_index.adoc:395 msgid "" "That is all. If you are interested in more details about ZFS on FreeBSD, " "please refer to the https://wiki.freebsd.org/ZFS[ZFS] section of the FreeBSD " "Wiki." msgstr "" "Вот и все. Если вас интересуют более подробные сведения о ZFS в FreeBSD, " "обратитесь к разделу https://wiki.freebsd.org/ZFS[ZFS] на вики FreeBSD." diff --git a/documentation/content/ru/articles/serial-uart/_index.adoc b/documentation/content/ru/articles/serial-uart/_index.adoc index d172ca320e..56f3b56383 100644 --- a/documentation/content/ru/articles/serial-uart/_index.adoc +++ b/documentation/content/ru/articles/serial-uart/_index.adoc @@ -1,1034 +1,1034 @@ --- authors: - author: 'Frank Durda' email: uhclem@FreeBSD.org description: 'Подробная информация об использовании последовательных портов и UART в FreeBSD' tags: ["Serial", "hardware", "UART", "Tutorial", "FreeBSD"] title: 'Учебное руководство по последовательному интерфейсу и UART' trademarks: ["freebsd", "microsoft", "general"] --- = Учебное руководство по последовательному интерфейсу и UART :doctype: article :toc: macro :toclevels: 1 :icons: font :sectnums: :sectnumlevels: 6 :source-highlighter: rouge :experimental: :images-path: articles/serial-uart/ ifdef::env-beastie[] ifdef::backend-html5[] include::shared/authors.adoc[] include::shared/mirrors.adoc[] include::shared/releases.adoc[] include::shared/attributes/attributes-{{% lang %}}.adoc[] include::shared/{{% lang %}}/teams.adoc[] include::shared/{{% lang %}}/mailing-lists.adoc[] include::shared/{{% lang %}}/urls.adoc[] :imagesdir: ../../../images/{images-path} endif::[] ifdef::backend-pdf,backend-epub3[] include::../../../../shared/asciidoctor.adoc[] endif::[] endif::[] ifndef::env-beastie[] include::../../../../../shared/asciidoctor.adoc[] endif::[] [.abstract-title] Аннотация Эта статья рассказывает об использовании последовательного оборудования с FreeBSD. ''' toc::[] [[uart]] == UART: Что это и как работает _Copyright (R) 1996 `{uhclem}`, All Rights Reserved. 13 января 1996 год_ Универсальный асинхронный приёмопередатчик (UART) — это ключевой компонент подсистемы последовательной передачи данных компьютера. UART принимает байты данных и передаёт отдельные биты последовательно. На стороне приёмника второй UART собирает биты обратно в полные байты. Последовательная передача данных обычно используется с модемами и для не сетевого взаимодействия между компьютерами, терминалами и другими устройствами. Существует две основные формы последовательной передачи данных: синхронная и асинхронная. В зависимости от режимов, поддерживаемых оборудованием, название подсистемы связи обычно включает букву `A`, если она поддерживает асинхронную передачу, и букву `S`, если поддерживается синхронная передача. Обе формы описаны ниже. Некоторые распространённые сокращения: [.blockquote] UART Universal Asynchronous Receiver/Transmitter — Универсальный асинхронный приёмопередатчик [.blockquote] USART Universal Synchronous-Asynchronous Receiver/Transmitter — Универсальный синхронно-асинхронный приёмопередатчик === Синхронная последовательная передача Синхронная последовательная передача данных требует, чтобы отправитель и получатель имели общий тактовый сигнал, либо чтобы отправитель предоставлял строб-сигнал или другой сигнал синхронизации, чтобы получатель знал, когда "считывать" следующий бит данных. В большинстве форм синхронной последовательной связи, если в данный момент нет доступных данных для передачи, вместо них должен быть отправлен заполняющий символ, чтобы передача данных не прерывалась. Синхронная связь обычно более эффективна, так как между отправителем и получателем передаются только биты данных, однако она может быть более затратной, если требуются дополнительные провода и схемы для обмена тактовым сигналом между отправителем и получателем. Форма синхронной передачи используется с принтерами и устройствами с жёсткими дисками, где данные передаются по одному набору проводов, а тактовый сигнал или строб — по другому проводу. Принтеры и устройства с жёсткими дисками обычно не являются последовательными устройствами, так как большинство стандартов интерфейсов жёстких дисков передают целое слово данных для каждого тактового сигнала или строба, используя отдельный провод для каждого бита слова. В индустрии ПК такие устройства известны как параллельные. Стандартное оборудование для последовательной связи в ПК не поддерживает синхронные операции. Этот режим описан здесь только для сравнения. === Асинхронная последовательная передача Асинхронная передача позволяет передавать данные без необходимости отправки тактового сигнала от отправителя к получателю. Вместо этого отправитель и получатель заранее согласовывают параметры синхронизации, а к каждому слову добавляются специальные биты, которые используются для синхронизации передающего и принимающего устройств. При передаче слова через UART в асинхронном режиме к началу каждого передаваемого слова добавляется бит, называемый "стартовым битом". Стартовый бит используется для оповещения приёмника о начале передачи слова данных, а также для синхронизации тактового сигнала приёмника с тактовым сигналом передатчика. Эти два тактовых сигнала должны быть достаточно точными, чтобы их расхождение по частоте не превышало 10% во время передачи оставшихся битов слова. (Данное требование было установлено во времена механических телетайпов и легко выполняется современным электронным оборудованием.) После стартового бита передаются отдельные биты слова данных, начиная с младшего значащего бита (LSB). Каждый бит передаётся в течение точно такого же времени, как и все остальные биты, и приемник "проверяет" состояние линии примерно на середине интервала, отведенного для каждого бита, чтобы определить, является ли бит `1` или `0`. Например, если передача каждого бита занимает две секунды, приемник проверит сигнал, чтобы определить, является ли он `1` или `0`, через одну секунду, затем подождет две секунды и проверит значение следующего бита, и так далее. Отправитель не знает, когда получатель «посмотрел» значение бита. Отправитель знает только, когда по тактовому сигналу нужно начать передачу следующего бита слова. Когда все слово данных отправлено, передатчик может добавить бит чётности, который он генерирует. Бит чётности может быть использован приемником для выполнения простой проверки на ошибки. Затем передатчик отправляет как минимум один стоповый бит. Когда приемник получил все биты в слове данных, он может проверить биты чётности (как отправитель, так и приемник должны договориться о том, будет ли использоваться бит чётности), а затем приемник ищет стоповый бит. Если стоповый бит не появляется, когда должен, UART считает все слово искаженным и сообщит об ошибке кадрирования главному процессору при чтении слова данных. Обычная причина ошибки кадрирования — несовпадение скорости тактовых сигналов отправителя и приемника или прерывание сигнала. Независимо от того, были ли данные получены правильно или нет, UART автоматически отбрасывает бит чётности, стартовый и стоповый биты. Если отправитель и получатель настроены одинаково, эти биты не передаются хосту. Если готово следующее слово для передачи, стартовый бит нового слова может быть отправлен сразу после того, как будет отправлен стоповый бит предыдущего слова. Поскольку асинхронные данные являются "самосинхронизирующимися", если нет данных для передачи, линия передачи может быть неактивна. === Другие функции UART -Помимо основной задачи преобразования данных из параллельного формата в последовательный для передачи и из последовательного в параллельный при приеме, UART обычно предоставляет дополнительные схемы для сигналов, которые могут использоваться для указания состояния среды передачи и регулирования потока данных в случае, если удаленное устройство не готово принимать больше данных. Например, когда устройство, подключенное к UART, является модемом, модем может сообщать о наличии несущей на телефонной линии, в то время как компьютер может дать команду модему сбросить себя или не принимать вызовы, поднимая или опуская один или несколько из этих дополнительных сигналов. Функция каждого из этих дополнительных сигналов определена в стандарте EIA RS232-C. +Помимо основной задачи преобразования данных из параллельного формата в последовательный для передачи и из последовательного в параллельный при приеме, UART обычно предоставляет дополнительные схемы для сигналов, которые могут использоваться для указания состояния среды передачи и регулирования потока данных в случае, если удалённое устройство не готово принимать больше данных. Например, когда устройство, подключенное к UART, является модемом, модем может сообщать о наличии несущей на телефонной линии, в то время как компьютер может дать команду модему сбросить себя или не принимать вызовы, поднимая или опуская один или несколько из этих дополнительных сигналов. Функция каждого из этих дополнительных сигналов определена в стандарте EIA RS232-C. === Стандарты RS232-C и V.24 В большинстве компьютерных систем UART подключен к схеме, которая генерирует сигналы, соответствующие спецификации EIA RS232-C. Также существует стандарт CCITT под названием V.24, который отражает спецификации, включенные в RS232-C. ==== Назначения битов RS232-C (метки и пробелы) В стандарте RS232-C значение `1` называется `Маркер` (Mark), а значение `0` — `Пробел` (Space). Когда линия связи находится в состоянии покоя, говорят, что она "маркирует" (Marking), то есть передаёт непрерывные значения `1`. Стартовый бит всегда имеет значение `0` (пробел). Стоповый бит всегда имеет значение `1` (метка). Это означает, что на линии всегда будет переход от метки (1) к пробелу (0) в начале каждого слова, даже при передаче нескольких слов подряд. Это гарантирует, что отправитель и получатель могут синхронизировать свои тактовые сигналы независимо от содержимого передаваемых битов данных. Время простоя между стоповым и стартовым битами не обязательно должно быть точным кратным (включая ноль) скорости передачи данных коммуникационного канала, однако большинство UART спроектированы таким образом для простоты. В стандарте RS232-C сигнал «Marking» (логическая `1`) представлен напряжением от -2 В до -12 В, а сигнал «Spacing» (логический `0`) — напряжением от 0 В до +12 В. Передатчик должен выдавать +12 В или -12 В, а приёмник должен учитывать возможные потери напряжения в длинных кабелях. Некоторые маломощные передатчики (например, в портативных компьютерах) иногда используют только +5 В и -5 В, но эти значения всё ещё допустимы для приёмника RS232-C при условии использования коротких кабелей. ==== Сигнал Break в RS232-C RS232-C также определяет сигнал под названием `Break`, который вызывается передачей непрерывных значений Spacing (без стартовых или стоповых битов). Когда на линии данных отсутствует напряжение, считается, что линия передаёт `Break`. Сигнал `Break` должен иметь длительность больше, чем время, необходимое для передачи полного байта, включая стартовый, стоповый и биты чётности. Большинство UART способны различить ошибку кадрирования и сигнал Break, но если UART не поддерживает эту функцию, для определения Break можно использовать обнаружение ошибки кадрирования. Во времена телетайпов, когда множество принтеров по всей стране были соединены последовательно (например, в службах новостей), любое устройство могло вызвать `Break`, временно размыкая всю цепь, чтобы ток не протекал. Это использовалось для того, чтобы место с срочными новостями могло прервать устройство в другом месте, которое в данный момент передавало информацию. В современных системах существует два типа сигналов Break. Если Break длится дольше 1,6 секунд, он считается "Модемным Break", и некоторые модемы можно запрограммировать на завершение соединения и переход в режим ожидания или вход в командный режим модема при обнаружении этого сигнала. Если Break короче 1,6 секунд, это означает "Break данных", и удалённый компьютер должен решить, как реагировать на этот сигнал. Иногда такая форма Break используется как сигнал "Внимание" или "Прерывание", а иногда принимается как замена символу ASCII CONTROL-C. Метки и пробелы также эквивалентны "дыркам" и "отсутствию дырок" в системах с бумажной лентой. [NOTE] ==== Разрывы не могут быть сгенерированы с перфоленты или из любого другого байтового значения, поскольку байты всегда отправляются со стартовым и стоповым битами. UART обычно способен генерировать непрерывный сигнал Spacing в ответ на специальную команду от главного управляющего устройства (процессора передачи). ==== ==== RS232-C устройства DTE и DCE Спецификация RS232-C определяет два типа оборудования: оконечное оборудование данных (DTE — Data Terminal Equipment) и оборудование передачи данных (DCE — Data Carrier Equipment). Обычно устройство DTE — это терминал (или компьютер), а DCE — модем. На другом конце телефонной линии в разговоре принимающий модем также является устройством DCE, а компьютер, подключённый к этому модему, — устройством DTE. Устройство DCE принимает сигналы на тех контактах, на которых устройство DTE передаёт, и наоборот. Когда два устройства, оба являющиеся DTE или DCE, должны быть соединены вместе без модема или аналогичного преобразователя среды между ними, необходимо использовать NULL модем. NULL модем электрически перестраивает кабель так, что выход передатчика подключается ко входу приемника на другом устройстве, и наоборот. Аналогичные преобразования выполняются для всех управляющих сигналов, чтобы каждое устройство видело то, что оно считает сигналами DCE (или DTE) от другого устройства. Количество сигналов, генерируемых устройствами DTE и DCE, не симметрично. Устройство DTE генерирует меньше сигналов для устройства DCE, чем получает от него. ==== Назначение контактов RS232-C Спецификация EIA RS232-C (и её эквивалент ITU, V.24) предусматривает использование двадцатипятиконтактного разъёма (обычно DB25) и определяет назначение большинства контактов в этом разъёме. В IBM Personal Computer и подобных системах подмножество сигналов RS232-C предоставляется через девятиконтактные разъемы (DB9). Сигналы, которые не включены в разъем ПК, в основном связаны с синхронной работой, и этот режим передачи не поддерживается UART, выбранным IBM для использования в IBM PC. В зависимости от производителя компьютера, для связи по RS232-C могут использоваться разъемы DB25, DB9 или оба типа. (В IBM PC также используется разъем DB25 для параллельного интерфейса принтера, что иногда вызывает путаницу.) Ниже представлена таблица назначений сигналов RS232-C в разъемах DB25 и DB9. [.informaltable] [cols="1,1,1,1,1,1,1", frame="none", options="header"] |=== | Контакт в DB25 RS232-C | Контакт в DB9 IBM PC | Символ цепи по EIA | Символ цепи по CCITT | Общее имя | Источник сигнала | Описание |1 |- |AA |101 |PG/FG |- |Защитное заземление (Frame/Protective Ground) |2 |3 |BA |103 |TD |DTE |Передача Данных (Transmit Data) |3 |2 |BB |104 |RD |DCE |Прием данных (Receive Data) |4 |7 |CA |105 |RTS |DTE |Запрос на передачу (Request to Send) |5 |8 |CB |106 |CTS |DCE |Готовность к приёму (Clear to Send) |6 |6 |CC |107 |DSR |DCE |Готовность терминального оборудования (Data Set Ready) |7 |5 |AV |102 |SG/GND |- |Сигнальная земля (Signal Ground) |8 |1 |CF |109 |DCD/CD |DCE |Обнаружение несущей (Data Carrier Detect) |9 |- |- |- |- |- |Зарезервировано для Теста |10 |- |- |- |- |- |Зарезервировано для Теста |11 |- |- |- |- |- |Зарезервировано для Теста |12 |- |CI |122 |SRLSD |DCE |Детектор сигнала вторичной линии приёма |13 |- |SCB |121 |SCTS |DCE |Вторичный сигнал готовности к приёму |14 |- |SBA |118 |STD |DTE |Вторичная линия передачи данных |15 |- |DB |114 |TSET |DCE |Тактирование элементов сигнала передатчика (Trans. Sig. Element Timing) |16 |- |SBB |119 |SRD |DCE |Вторичная линия приема данных |17 |- |DD |115 |RSET |DCE |Тактирование элементов сигнала приёмника (Receiver Signal Element Timing) |18 |- |- |141 |LOOP |DTE |Локальная петля |19 |- |SCA |120 |SRS |DTE |Вторичный запрос на передачу |20 |4 |CD |108.2 |DTR |DTE |Готовность терминального оборудования (Data Terminal Ready) |21 |- |- |- |RDL |DTE |Режим удалённой цифровой петли (Remote Digital Loopback) |22 |9 |CE |125 |RI |DCE |Индикатор передачи данных (Ring Indicator) |23 |- |CH |111 |DSRS |DTE |Селектор скорости передачи данных |24 |- |DA |113 |TSET |DTE |Тактирование элементов сигнала передатчика (Trans. Sig. Element Timing) |25 |- |- |142 |- |DCE |Режим тестирования |=== === Биты, боды и символы Скорость передачи данных (Baud) — это единица измерения скорости передачи в асинхронной связи. Из-за развития технологий модемной связи этот термин часто ошибочно используют для описания скорости передачи данных в современных устройствах. Традиционно, скорость передачи (Baud Rate) представляет количество битов, фактически передаваемых по среде, а не объём данных, которые действительно перемещаются от одного устройства DTE к другому. Подсчет Baud включает служебные биты — Start, Stop и Parity, которые генерируются передающим UART и удаляются принимающим UART. Это означает, что 7-битные слова данных на самом деле занимают 10 бит для полной передачи. Следовательно, модем, способный передавать 300 бит в секунду, обычно может передавать только 30 7-битных слов, если используется Parity и присутствуют один бит Start и один бит Stop. Если используются 8-битные слова данных и биты чётности, скорость передачи данных снижается до 27,27 слов в секунду, так как теперь для передачи восьмибитных слов требуется 11 бит, а модем по-прежнему передаёт только 300 бит в секунду. Формула преобразования байтов в секунду в бодовую скорость и наоборот была простой до появления модемов с коррекцией ошибок. Эти модемы принимают последовательный поток битов от UART в компьютере (даже внутренние модемы часто работают с последовательными данными) и преобразуют биты обратно в байты. Затем эти байты объединяются в пакеты и передаются по телефонной линии с использованием синхронного метода передачи. Это означает, что стоповые, стартовые и биты чётности, добавленные UART в DTE (компьютере), удаляются модемом перед передачей отправляющим модемом. Когда эти байты принимаются удалённым модемом, он добавляет стартовые, стоповые и биты чётности к словам, преобразует их в последовательный формат и отправляет на принимающий UART в удалённом компьютере, который затем удаляет стартовые, стоповые и биты чётности. Причина, по которой выполняются все эти дополнительные преобразования, заключается в том, чтобы два модема могли осуществлять коррекцию ошибок. Это означает, что принимающий модем может запросить у передающего модема повторную отправку блока данных, который был получен с некорректной контрольной суммой. Эта проверка обрабатывается модемами, и устройства DTE обычно не осознают, что этот процесс происходит. Удаляя стартовые, стоповые и биты чётности, дополнительные биты данных, которые два модема должны обмениваться между собой для выполнения коррекции ошибок, в основном скрываются от эффективной скорости передачи, наблюдаемой отправляющим и принимающим оборудованием DTE. Например, если модем отправляет десять 7-битных слов другому модему без включения стартовых, стоповых и битов чётности, отправляющий модем сможет добавить 30 бит своей собственной информации, которую принимающий модем может использовать для коррекции ошибок, не влияя на скорость передачи реальных данных. Использование термина "Бод" дополнительно осложняется модемами, выполняющими сжатие. Одно 8-битное слово, переданное по телефонной линии, может представлять собой дюжину слов, переданных на отправляющий модем. Принимающий модем развернёт данные обратно в их исходное содержимое и передаст эти данные принимающему DTE. Современные модемы также включают буферы, которые позволяют скорости передачи битов по телефонной линии (DCE к DCE) отличаться от скорости передачи битов между DTE и DCE на обоих концах соединения. Обычно скорость между DTE и DCE выше, чем скорость между DCE и DCE, из-за использования сжатия модемами. Поскольку количество битов, необходимых для описания байта, менялось во время передачи между двумя машинами, а также из-за различающихся скоростей передачи в битах в секунду на линиях DTE-DCE и DCE-DCE, использование термина «Бод» для описания общей скорости связи вызывает проблемы и может искажать реальную скорость передачи. Таким образом, термин «Биты в секунду» (bps) является корректным для описания скорости передачи на интерфейсе DCE-DCE, а термины «Бод» или «Биты в секунду» допустимы, когда соединение устанавливается между двумя системами с проводным подключением или используется модем, не выполняющий коррекцию ошибок или сжатие. Современные высокоскоростные модемы (2400, 9600, 14,400 и 19,200 бит/с) на самом деле всё ещё работают на скорости 2400 бод или ниже, или, точнее, 2400 символов в секунду. Высокоскоростные модемы способны кодировать больше бит данных в каждый символ с использованием техники, называемой "Заполнение созвездия (Constellation Stuffing)", поэтому эффективная скорость передачи данных в битах в секунду у модема выше, но модем продолжает работать в ограниченной полосе пропускания звуковых частот, предоставляемой телефонной системой. Модемы, работающие на скоростях 28,800 и выше, имеют переменную скорость передачи символов, но техника остаётся той же. === UART в IBM PC Начиная с оригинального IBM Personal Computer, IBM выбрала UART INS8250 от National Semiconductor для использования в адаптере Parallel/Serial IBM PC. Последующие поколения совместимых компьютеров от IBM и других производителей продолжали использовать INS8250 или улучшенные версии UART из семейства National Semiconductor. ==== Генеалогическое дерево National Semiconductor UART Существует несколько версий и последующих поколений UART INS8250. Основные версии описаны ниже. [.programlisting] .... INS8250 -> INS8250B \ \ \-> INS8250A -> INS82C50A \ \ \-> NS16450 -> NS16C450 \ \ \-> NS16550 -> NS16550A -> PC16550D .... INS8250:: Эта часть использовалась в оригинальном IBM PC и IBM PC/XT. Первоначальное название этой части — INS8250 ACE (Asynchronous Communications Element), и она изготовлена по NMOS-технологии. + 8250 использует восемь портов ввода-вывода и имеет однобайтовый буфер передачи и однобайтовый буфер приема. Этот оригинальный UART имеет несколько состояний гонки и другие недостатки. Оригинальный BIOS IBM включает код для обхода этих недостатков, но это сделало BIOS зависимым от их наличия, поэтому последующие модели, такие как 8250A, 16450 или 16550, не могли быть использованы в оригинальном IBM PC или IBM PC/XT. INS8250-B:: Это более медленная скорость INS8250, созданная по NMOS-технологии. Она имеет те же проблемы, что и оригинальный INS8250. INS8250A:: Улучшенная версия INS8250 с использованием технологии XMOS, в которой исправлены различные функциональные недостатки. INS8250A изначально использовалась в клонах ПК от производителей, применявших "чистые" проекты BIOS. Из-за исправлений в микросхеме этот чип не мог использоваться с BIOS, совместимой с INS8250 или INS8250B. INS82C50A:: Это CMOS-версия (с низким энергопотреблением) INS8250A и имеет схожие функциональные характеристики. NS16450:: Так же, как NS8250A, но с улучшениями для работы с более быстрыми шинами CPU. IBM использовала этот компонент в IBM AT и обновила IBM BIOS, чтобы она больше не зависела от ошибок в INS8250. NS16C450:: Это версия NS16450 с технологией CMOS (низкое энергопотребление). NS16550:: То же, что и NS16450, с 16-байтовым буфером передачи и приема, но конструкция буфера была неудачной и не могла быть надёжно использована. NS16550A:: То же, что и NS16550, но с исправленными недостатками буфера. 16550A и его преемники стали наиболее популярными UART-устройствами в индустрии ПК, в основном благодаря их способности надёжно работать на высоких скоростях передачи данных в операционных системах с медленным временем отклика прерываний. NS16C552:: Этот компонент состоит из двух CMOS UART NS16C550A в одном корпусе. PC16550D:: Так же, как NS16550A, с исправленными незначительными недостатками. Это ревизия D семейства 16550 и последняя доступная версия от National Semiconductor. ==== NS16550AF и PC16550D — это одно и то же Компания National реорганизовала свою систему нумерации деталей несколько лет назад, и чип NS16550AFN больше не существует под этим названием. (Если у вас есть NS16550AFN, посмотрите на дату изготовления на корпусе — это четырёхзначное число, обычно начинающееся с девятки. Первые две цифры обозначают год, а последние две — неделю года, когда чип был упакован. Если у вас есть NS16550AFN, скорее всего, он уже довольно старый.) Новые номера выглядят как PC16550DV, с незначительными отличиями в суффиксных буквах в зависимости от материала корпуса и его формы. (Описание системы нумерации можно найти ниже.) Важно понимать, что в некоторых магазинах можно заплатить $15 (США) за микросхему NS16550AFN, выпущенную в 1990 году, а в соседнем ящике могут лежать новые PC16550DN с небольшими исправлениями, которые National внесла с момента выпуска AFN. PC16550DN, вероятно, произведены в последние полгода и стоят вдвое дешевле (от $5 (США) при оптовой покупке), чем NS16550AFN, поскольку они легко доступны. Поскольку поставки чипов NS16550AFN продолжают сокращаться, цена, вероятно, будет расти до тех пор, пока больше людей не узнают и не примут тот факт, что PC16550DN действительно выполняет ту же функцию, что и старый номер детали. ==== Система нумерации компонентов National Semiconductor Старые номера деталей NS``__nnnnnrqp__`` теперь имеют формат PC``__nnnnnrgp__``. `_r_` — это поле ревизии. Текущая ревизия 16550 от National Semiconductor — `D`. `_p_` — это поле типа пакета. Типы: [.informaltable] [cols="1,1,1", frame="none"] |=== |"F" |QFP |(quad flat pack - квадратный плоский корпус) с L-образными выводами |"N" |DIP |(dual inline package — корпус с двусторонним расположением выводов) для сквозного монтажа с прямыми выводами |"V" |LPCC |(lead plastic chip carrier — пластиковый корпус) с J-образными выводами |=== Поле _g_ обозначает класс изделия. Если перед буквой типа пакета стоит `I`, это указывает на «промышленный» класс детали, который имеет более высокие характеристики, чем стандартная деталь, но не такие высокие, как компонент военного назначения (Milspec). Это необязательное поле. То, что мы раньше называли NS16550AFN (DIP-корпус), теперь называется PC16550DN или PC16550DIN. === Другие производители и аналогичные UART На протяжении многих лет чипы 8250, 8250A, 16450 и 16550 лицензировались или копировались другими производителями. В случае с 8250, 8250A и 16450 точная схема ("мегаячейка") была лицензирована многими производителями, включая Western Digital и Intel. Другие производители проводили обратную разработку чипа или создавали эмуляции с аналогичным поведением. Во внутренних модемах разработчик модема часто эмулирует 8250A/16450 с помощью микропроцессора модема, и эмулированный UART часто имеет скрытый буфер размером в несколько сотен байт. Благодаря размеру буфера, эти эмуляции могут быть такими же надёжными, как 16550A, в способности обрабатывать высокоскоростные данные. Однако большинство операционных систем по-прежнему сообщают, что UART является только 8250A или 16450, и могут не эффективно использовать дополнительную буферизацию, присутствующую в эмулированном UART, если не используются специальные драйверы. Некоторые производители модемов под давлением рыночных сил отказываются от конструкции с буфером в сотни байт и вместо этого используют UART 16550A, чтобы их продукция выглядела выигрышно в рыночных сравнениях, даже если это может снизить фактическую производительность. Распространённое заблуждение заключается в том, что все микросхемы с маркировкой "16550A" одинаковы по производительности. Однако между ними существуют различия, а в некоторых клонах 16550A даже встречаются серьёзные недостатки. Когда компания National Semiconductor разработала NS16550, она получила несколько патентов на эту конструкцию и также ограничила лицензирование, что затруднило для других производителей выпуск чипов с аналогичными характеристиками. В результате патентов обратно спроектированные конструкции и эмуляции должны были избегать нарушения пунктов, охватываемых патентами. Впоследствии эти копии почти никогда не работают точно так же, как NS16550A или PC16550D, которые являются компонентами, наиболее востребованными производителями компьютеров и модемов, но иногда они не готовы платить цену, необходимую для получения оригинальных деталей. Некоторые различия в клонах микросхем 16550A несущественны, в то время как другие могут полностью препятствовать использованию устройства с определённой операционной системой или драйвером. Эти различия могут проявиться при использовании других драйверов или при возникновении определённых комбинаций событий, которые не были хорошо протестированы или учтены в драйвере Windows(R). Это происходит потому, что большинство производителей модемов и клонов 16550 используют драйверы Microsoft из Windows(R) for Workgroups 3.11 и утилиту Microsoft(R) MS-DOS(R) в качестве основных тестов на совместимость с NS16550A. Этот чрезмерно упрощенный критерий означает, что при использовании другой операционной системы могут возникнуть проблемы из-за тонких различий между клонами и оригинальными компонентами. National Semiconductor предоставила программу под названием COMTEST, которая выполняет тесты совместимости независимо от каких-либо драйверов ОС. Следует помнить, что цель такого типа программ — демонстрация недостатков в продуктах конкурентов, поэтому программа будет сообщать как о значительных, так и о крайне незначительных различиях в поведении тестируемого компонента. В серии тестов, проведенных автором этого документа в 1994 году, компоненты производства National Semiconductor, TI, StarTech и CMD, а также мегаячейки и эмуляции, встроенные во внутренние модемы, были протестированы с помощью COMTEST. Ниже приведен счетчик различий для некоторых из этих компонентов. Поскольку эти тесты проводились в 1994 году, они могут не отражать текущую производительность данного продукта от поставщика. Следует отметить, что COMTEST обычно завершает работу при обнаружении чрезмерного количества или определённых типов проблем. В рамках этого тестирования COMTEST был изменён так, чтобы он не завершал работу независимо от количества обнаруженных различий. [.informaltable] [cols="1,1,1", frame="none", options="header"] |=== | Поставщик | Номер детали | Ошибки (также известные как "различия" в отчётах) |National |(PC16550DV) |0 |National |(NS16550AFN) |0 |National |(NS16C552V) |0 |TI |(TL16550AFN) |3 |CMD |(16C550PE) |19 |StarTech |(ST16C550J) |23 |Rockwell |Стандартный модем с внутренним 16550 или его эмуляцией (RC144DPi/C3000-25) |117 |Sierra |Модем с внутренним 16550 (SC11951/SC11351) |91 |=== [NOTE] ==== На сегодняшний день автор данного документа не обнаружил ни одного не-National компонента, который бы показывал нулевые различия при использовании программы COMTEST. Также следует отметить, что у National было пять версий 16550 за эти годы, и новейшие компоненты ведут себя несколько иначе, чем классический NS16550AFN, который считается эталоном функциональности. COMTEST, по-видимому, закрывает глаза на различия внутри линейки продуктов National и не сообщает об ошибках в компонентах National (за исключением оригинальной 16550), даже когда существуют официальные errata, описывающие ошибки в ревизиях A, B и C этих компонентов, поэтому эту предвзятость COMTEST необходимо учитывать. ==== Важно понимать, что простое подсчитывание различий с COMTEST не даёт полного представления о том, какие различия существенны, а какие нет. Например, около половины различий, обнаруженных в двух вышеупомянутых модемах с внутренними UART, были вызваны тем, что клоновые UART не поддерживают режимы пяти- и шестибитных символов. Настоящие UART 16550, 16450 и 8250 поддерживают эти режимы, и COMTEST проверяет их функциональность, поэтому фиксируется более пятидесяти различий. Однако почти ни один современный модем не поддерживает пяти- или шестибитные символы, особенно те, что обладают функциями коррекции ошибок и сжатия. Это означает, что различия, связанные с режимами пяти- и шестибитных символов, можно не учитывать. Многие различия, о которых сообщает COMTEST, связаны с временными характеристиками. Во многих клонированных конструкциях, когда хост читает из одного порта, статусные биты в другом порте могут обновляться с иной скоростью (быстрее или медленнее), чем у _настоящего_ NS16550AFN, и COMTEST выявляет эти различия. Это означает, что количество различий может вводить в заблуждение: одно устройство может иметь всего одно или два различия, но они крайне критичны, тогда как другое устройство, обновляющее статусные регистры быстрее или медленнее эталонной части (что, вероятно, никогда не повлияет на работу правильно написанного драйвера), может иметь десятки зарегистрированных различий. COMTEST можно использовать в качестве инструмента проверки, чтобы предупредить администратора о наличии потенциально несовместимых компонентов, которые могут вызвать проблемы или потребуют особого подхода. Если вы запускаете COMTEST на 16550, который находится в модеме или к модему подключён последовательный порт, необходимо сначала отправить модему команду ATE0&W, чтобы модем не эхо-повторял ни один из тестовых символов. Если вы забудете это сделать, COMTEST сообщит как минимум об одном различии: [source, shell] .... Error (6)...Timeout interrupt failed: IIR = c1 LSR = 61 .... === Регистры 8250/16450/16550 UART 8250/16450/16550 занимает восемь последовательных адресов портов ввода-вывода. В IBM PC определены два расположения для этих восьми портов, которые вместе известны как [.filename]#COM1# и [.filename]#COM2#. Производители PC-клонов и дополнительных карт создали два дополнительных области, известных как [.filename]#COM3# и [.filename]#COM4#, но эти дополнительные COM-порты конфликтуют с другим оборудованием на некоторых системах. Наиболее распространённый конфликт возникает с видеоадаптерами, обеспечивающими эмуляцию IBM 8514. [.filename]#COM1# находится в диапазоне от 0x3f8 до 0x3ff и обычно использует IRQ 4. [.filename]#COM2# находится в диапазоне от 0x2f8 до 0x2ff и обычно использует IRQ 3. [.filename]#COM3# находится в диапазоне от 0x3e8 до 0x3ef и не имеет стандартного IRQ. [.filename]#COM4# находится в диапазоне от 0x2e8 до 0x2ef и не имеет стандартного IRQ. Описание портов ввода-вывода UART 8250/16450/16550 представлено ниже. [.informaltable] [cols="10%,10%,80%", frame="none", options="header"] |=== | Порт ввода/вывода | Доступ Разрешен | Описание |+0x00 |запись (DLAB==0) | Регистр передачи данных (THR). Информация, записанная в этот порт, обрабатывается как слова данных и передаётся через UART. |+0x00 |чтение (DLAB==0) | Регистр буфера приема (RBR). Любые слова данных, полученные UART из последовательного соединения, доступны для чтения хостом через этот порт. |+0x00 |запись/чтение (DLAB==1) | Младший байт защелки делителя (DLL — Divisor Latch LSB) Это значение будет поделено от основного входного тактового сигнала (в IBM PC основной тактовый сигнал равен 1,8432 МГц), и полученный тактовый сигнал будет определять скорость передачи UART. Этот регистр содержит биты с 0 по 7 делителя. |+0x01 |запись/чтение (DLAB==1) | Старший байт защелки делителя (DLH — Divisor Latch MSB) Это значение будет разделено от основного входного тактового сигнала (в IBM PC основной тактовый сигнал равен 1,8432 МГц), и полученный тактовый сигнал будет определять скорость передачи данных UART. Этот регистр содержит биты с 8 по 15 делителя. |+0x01 |запись/чтение (DLAB==0) |Регистр разрешения прерываний (IER) + UART 8250/16450/1655 классифицирует события на четыре категории. Каждая категория может быть настроена на генерацию прерывания при возникновении любого из событий. UART 8250/16450/16550 генерирует единый внешний сигнал прерывания независимо от того, сколько событий в разрешённых категориях произошло. Задача главного процессора — обработать прерывание и затем опросить разрешённые категории прерываний (обычно прерывания разрешены для всех категорий), чтобы определить истинную причину(ы) прерывания. + Бит 7 -> Зарезервирован, всегда 0. + Бит 6 -> Зарезервирован, всегда 0. + Бит 5 -> Зарезервирован, всегда 0. + Бит 4 -> Зарезервирован, всегда 0. + Бит 3 -> Разрешение прерывания по состоянию модема (EDSSI). Установка этого бита в "1" позволяет UART генерировать прерывание при изменении состояния одной или нескольких линий статуса. + Бит 2 -> Разрешение прерывания по состоянию линии приёмника (ELSI). Установка этого бита в "1" приводит к генерации прерывания UART при обнаружении ошибки (или сигнала BREAK) во входящих данных. + Бит 1 -> Разрешение прерывания по опустошению регистра передатчика (ETBEI). Установка этого бита в "1" приводит к генерации прерывания UART, когда в UART появляется место для одного или более дополнительных символов, предназначенных для передачи. + Бит 0 -> Разрешение прерывания по наличию принятых данных (ERBFI). Установка этого бита в "1" приводит к генерации прерывания UART, когда UART принял достаточное количество символов для превышения порога FIFO, или истекло время ожидания FIFO (устаревшие данные), или принят одиночный символ при отключённом FIFO. |+0x02 |запись |Регистр управления FIFO (FCR — FIFO Control Register) (Этот порт отсутствует в UART 8250 и 16450.) + Бит 7 -> Бит триггера приемника #1 + Бит 6 -> Бит триггера приемника #0 + Эти два бита определяют, при каком количестве данных приемник должен генерировать прерывание, когда FIFO активен. + 7 6 Количество слов перед генерацией прерывания + 0 0 1 + 0 1 4 + 1 0 8 + 1 1 14 + Бит 5 -> Зарезервирован, всегда 0. + Бит 4 -> Зарезервирован, всегда 0. + Бит 3 -> Выбор режима DMA. Если бит 0 установлен в "1" (FIFO включены), установка этого бита изменяет работу сигналов -RXRDY и -TXRDY с режима 0 на режим 1. + Бит 2 -> Сброс передающего FIFO. При записи "1" в этот бит содержимое FIFO очищается. Любое слово, которое передаётся в данный момент, будет отправлено полностью. Эта функция полезна для прерывания передачи. + Бит 1 -> Сброс приемного FIFO. При записи "1" в этот бит содержимое FIFO очищается. Любое слово, которое в данный момент собирается в сдвиговом регистре, будет принято полностью. + Бит 0 -> Включение FIFO 16550. При установке этого бита активируются как передающий, так и приемный FIFO. Любое содержимое в регистре хранения, сдвиговых регистрах или FIFO теряется при включении или отключении FIFO. + |+0x02 |чтение |Регистр идентификации прерываний + Бит 7 -> FIFO включены. На UART 8250/16450 этот бит равен нулю. + Бит 6 -> FIFO включены. На UART 8250/16450 этот бит равен нулю. + Бит 5 -> Зарезервирован, всегда 0. + Бит 4 -> Зарезервирован, всегда 0. + Бит 3 -> Бит идентификатора прерывания №2. На UART 8250/16450 этот бит равен нулю. + Бит 2 -> Бит идентификатора прерывания №1 + Бит 1 -> Бит идентификатора прерывания №0.Эти три бита объединяются для указания категории события, вызвавшего текущее прерывание. Эти категории имеют приоритеты, поэтому, если несколько категорий событий происходят одновременно, UART сообщит о более важных событиях первыми, и хост должен обрабатывать события в порядке их поступления. Все события, вызвавшие текущее прерывание, должны быть обработаны до генерации новых прерываний. (Это ограничение архитектуры ПК.) + 2 1 0 Приоритет Описание + 0 1 1 Первый Принятая ошибка (OE, PE, BI или FE) + 0 1 0 Второй Доступны принятые данные + 1 1 0 Второй Идентификация уровня триггера (Устаревшие данные в буфере приема) + 0 0 1 Третий Передатчик готов принять больше данных (THRE) + 0 0 0 Четвертый Изменение состояния модема (-CTS, -DSR, -RI или -DCD) + Бит 0 -> Бит ожидания прерывания. Если этот бит установлен в "0", то как минимум одно прерывание ожидает обработки. |+0x03 |запись/чтение |Регистр управления линией (LCR — Line Control Register) + Бит 7 -> Бит доступа к защелке делителя (DLAB). При установке доступ к регистру передачи/приема данных (THR/RBR) и регистру разрешения прерываний (IER) отключается. Любой доступ к этим портам перенаправляется к регистрам защелки делителя. Установка этого бита, загрузка регистров делителя и сброс DLAB должны выполняться при отключенных прерываниях. + Бит 6 -> Установка прерывания. При установке в "1" передатчик начинает передавать непрерывный интервал (Spacing), пока этот бит не будет сброшен в "0". Это переопределяет любые передаваемые биты символов. + Бит 5 -> Фиксированный бит чётности. При включенной проверке чётности установка этого бита приводит к тому, что бит чётности всегда будет "1" или "0" в зависимости от значения бита 4. Бит 4 -> Выбор чётности (EPS). При включенной проверке чётности и если бит 5 равен "0", установка этого бита приводит к использованию и ожиданию четной чётности. В противном случае используется нечетная чётность. + Бит 3 -> Разрешение проверки чётности (PEN). При установке в "1" бит чётности вставляется между последним битом данных и стоповым битом. UART также ожидает наличие бита чётности в принимаемых данных. + Бит 2 -> Количество стоповых битов (STB). Если установлен в "1" и используются 5-битные слова данных, передаётся и ожидается 1.5 стоповых бита в каждом слове данных. Для 6, 7 и 8-битных слов данных передаётся и ожидается 2 стоповых бита. Если этот бит сброшен в "0", используется один стоповый бит в каждом слове данных. + Бит 1 -> Бит выбора длины слова #1 (WLSB1) + Бит 0 -> Бит выбора длины слова #0 (WLSB0) + Вместе эти биты определяют количество битов в каждом слове данных. + 1 0 Длина слова + 0 0 5 бит данных + 0 1 6 бит данных + 1 0 7 бит данных + 1 1 8 бит данных + |+0x04 |запись/чтение |Регистр управления модемом (MCR — Modem Control Register) + Бит 7 -> Зарезервирован, всегда 0. + Бит 6 -> Зарезервирован, всегда 0. + Бит 5 -> Зарезервирован, всегда 0. + Бит 4 -> Режим петли (Loop-Back). При установке в "1" передатчик и приёмник UART соединяются внутри для диагностики. Также выходы управления модемом UART подключаются к его входам: CTS к RTS, DTR к DSR, OUT1 к RI, а OUT2 к DCD. + Бит 3 -> OUT2. Вспомогательный выход, который процессор может установить в высокий или низкий уровень. В адаптере IBM PC (и большинстве клонов) OUT2 используется для отключения сигнала прерывания от UART 8250/16450/16550. + Бит 2 -> OUT1. Вспомогательный выход, который процессор может установить в высокий или низкий уровень. На адаптере IBM PC не используется. + Бит 1 -> Запрос на передачу (RTS). При установке в "1" выход линии -RTS UART переходит в низкий уровень (активное состояние). + Бит 0 -> Готовность терминала данных (DTR). При установке в "1" выход линии -DTR UART переходит в низкий уровень (активное состояние). + |+0x05 |запись/чтение |Регистр состояния линии (LSR — Line Status Register) + Бит 7 -> Ошибка в FIFO приемника. На UART 8250/16450 этот бит равен нулю. Этот бит устанавливается в «1», когда любой из байтов в FIFO имеет одно или несколько из следующих условий ошибки: PE, FE или BI. + Бит 6 -> Передатчик пуст (TEMT). Когда установлен в «1», в FIFO передатчика или сдвиговом регистре передатчика не осталось слов. Передатчик полностью бездействует. + Бит 5 -> Регистр хранения передатчика пуст (THRE). Когда установлен в «1», в FIFO (или регистре хранения) теперь есть место для передачи как минимум одного дополнительного слова. Передатчик может все ещё передавать данные, когда этот бит установлен в «1». + Бит 4 -> Прерывание по Break (BI). Приемник обнаружил сигнал Break. + Бит 3 -> Ошибка кадрирования (FE). Обнаружен стартовый бит, но стоповый бит не появился в ожидаемое время. Принятое слово, вероятно, искажено. + Бит 2 -> Ошибка чётности (PE). Бит чётности для принятого слова был некорректен. + Бит 1 -> Ошибка переполнения (OE). Было получено новое слово, но в буфере приема не было места. Вновь поступившее слово в сдвиговом регистре отбрасывается. На UART 8250/16450 слово в регистре хранения отбрасывается, а вновь поступившее слово помещается в регистр хранения. + Бит 0 -> Данные готовы (DR). Одно или несколько слов находятся в FIFO приемника, которые хост может прочитать. Слово должно быть полностью принято и перемещено из сдвигового регистра в FIFO (или регистр хранения для 8250/16450) до того, как этот бит будет установлен. |+0x06 |запись/чтение |Регистр состояния модема (MSR — Modem Status Register) + Бит 7 -> Обнаружение несущей данных (DCD). Отражает состояние линии DCD на UART. + Бит 6 -> Индикатор вызова (RI). Отражает состояние линии RI на UART. + Бит 5 -> Готовность передатчика данных (DSR). Отражает состояние линии DSR на UART. + Бит 4 -> Готовность к приёму (CTS). Отражает состояние линии CTS на UART. + Бит 3 -> Изменение состояния обнаружения несущей данных (DDCD). Устанавливается в "1", если линия -DCD изменила состояние ещё раз с момента последнего чтения MSR хостом. + Бит 2 -> Фронт сигнала вызова (TERI). Устанавливается в "1", если линия -RI перешла из низкого уровня в высокий с момента последнего чтения MSR хостом. + Бит 1 -> Изменение состояния готовности передатчика данных (DDSR). Устанавливается в "1", если линия -DSR изменила состояние ещё раз с момента последнего чтения MSR хостом. + Бит 0 -> Изменение состояния готовности к приёму (DCTS). Устанавливается в "1", если линия -CTS изменила состояние ещё раз с момента последнего чтения MSR хостом. + |+0x07 |запись/чтение |Регистр Scratch (SCR — Scratch Register). Этот регистр не выполняет никакой функции в UART. Хост может записать любое значение в это место и позднее считать его. |=== === За пределами UART 16550A Хотя National Semiconductor не предлагала никаких компонентов, совместимых с 16550 и предоставляющих дополнительные функции, другие производители сделали это. Некоторые из этих компонентов описаны ниже. Следует понимать, что для эффективного использования этих улучшений могут потребоваться драйверы от производителя чипа, поскольку большинство популярных операционных систем не поддерживают функции, выходящие за рамки возможностей 16550. ST16650:: По умолчанию эта часть аналогична NS16550A, но дополнительно можно включить расширенный 32-байтовый буфер отправки и приёма. Производитель — StarTech. TIL16660:: По умолчанию эта часть ведёт себя аналогично NS16550A, но дополнительно может быть включён расширенный 64-байтный буфер передачи и приёма. Производится Texas Instruments. Hayes ESP:: Эта проприетарная внешняя карта содержит буфер передачи и приема размером 2048 байт и поддерживает скорость передачи данных до 230,4 Кбит/с. Произведено компанией Hayes. В дополнение к этим "простым" UART многие производители выпускают интеллектуальные платы для последовательной связи. Такой тип конструкции обычно включает микропроцессор, который взаимодействует с несколькими UART, обрабатывает и буферизует данные, а затем при необходимости уведомляет основной процессор ПК. Поскольку в такой системе связи UART не доступны напрямую процессору ПК, производителю не обязательно использовать UART, совместимые с 8250, 16450 или 16550. Это даёт разработчику свободу выбора компонентов с лучшими характеристиками производительности. [[sio]] == Настройка драйвера [.filename]#sio# Драйвер [.filename]#sio# обеспечивает поддержку интерфейсов связи EIA RS-232C (CCITT V.24) на основе NS8250, NS16450, NS16550 и NS16550A. Также поддерживаются несколько многопортовых карт. Подробную техническую документацию смотрите на man:sio[4]. === Digi International (DigiBoard) PC/8 _Предоставлено `{awebster}`. 26 августа 1995._ Вот фрагмент конфигурации с машины, на которой установлена плата Digi International PC/8 с чипом 16550. К ней подключено 8 модемов, работающих на этих 8 линиях, и они отлично функционируют. Не забудьте добавить `options COM_MULTIPORT`, иначе работа будет нестабильной! [.programlisting] .... device sio4 at isa? port 0x100 flags 0xb05 device sio5 at isa? port 0x108 flags 0xb05 device sio6 at isa? port 0x110 flags 0xb05 device sio7 at isa? port 0x118 flags 0xb05 device sio8 at isa? port 0x120 flags 0xb05 device sio9 at isa? port 0x128 flags 0xb05 device sio10 at isa? port 0x130 flags 0xb05 device sio11 at isa? port 0x138 flags 0xb05 irq 9 .... Хитрость настройки заключается в том, что старший бит флагов представляет последний порт SIO, в данном случае 11, поэтому флаги равны 0xb05. === Boca 16 _Предоставлено `{whiteside}`. 26 августа 1995._ Процедуры по настройке платы Boca с 16 портами в FreeBSD довольно просты, но вам понадобится несколько вещей для успешной работы: . Вам необходимо либо установить исходные коды ядра, чтобы перекомпилировать нужные опции, либо найти кого-то, кто сделает это за вас. Стандартное ядро версии 2.0.5 _не_ включает поддержку нескольких портов, и в любом случае вам потребуется добавить запись устройства для каждого порта. . Два, вам нужно знать прерывание и настройку ввода-вывода для вашей платы Boca, чтобы правильно установить эти параметры в ядре. Важное замечание — реальные микросхемы UART для Boca 16 находятся в соединительной коробке, а не на внутренней плате. Поэтому, если она отключена, попытки проверить эти порты завершатся неудачей. Я никогда не проверял загрузку с отключённой коробкой и последующим её подключением, и не рекомендую вам этого делать. Если у вас ещё нет настроенного файла конфигурации пользовательского ядра, обратитесь к разделу extref:{handbook}kernelconfig[Конфигурация ядра, kernelconfig] в руководстве FreeBSD для получения общих инструкций. Ниже приведены конкретные настройки для платы Boca 16, предполагается, что вы используете ядро с именем MYKERNEL и редактируете его с помощью vi. [.procedure] ==== . Добавьте строку + [.programlisting] .... options COM_MULTIPORT .... в конфигурационный файл. . Где находятся текущие строки `device sio__n__`, вам нужно добавить ещё 16 устройств. В следующем примере показана плата Boca Board с прерыванием 3 и базовым адресом ввода-вывода 100h. Адрес ввода-вывода для каждого порта увеличивается на 8 в шестнадцатеричной системе относительно предыдущего порта, поэтому адреса будут 100h, 108h, 110h... + [.programlisting] .... device sio1 at isa? port 0x100 flags 0x1005 device sio2 at isa? port 0x108 flags 0x1005 device sio3 at isa? port 0x110 flags 0x1005 device sio4 at isa? port 0x118 flags 0x1005 ... device sio15 at isa? port 0x170 flags 0x1005 device sio16 at isa? port 0x178 flags 0x1005 irq 3 .... + Запись flags _обязательно_ должна быть изменена по сравнению с этим примером, если вы не используете точно такие же назначения sio. Флаги устанавливаются в соответствии с 0x``__MYY__``, где _M_ обозначает младший номер главного порта (последний порт на Boca 16), а _YY_ указывает, включен или выключен FIFO (включен), используется ли разделение IRQ (да) и есть ли регистр управления IRQ, совместимый с AST/4 (нет). В этом примере, + [.programlisting] .... flags 0x1005 .... указывает, что основной порт - sio16. Если добавить другую плату и назначить порты с sio17 по sio28, флаги для всех 16 портов на _этой_ плате будут 0x1C05, где 1C обозначает минорный номер основного порта. Не изменяйте значение 05. . Сохраните и завершите конфигурацию ядра, перекомпилируйте, установите и перезагрузитесь. Предполагая, что вы успешно установили перекомпилированное ядро и настроили правильный адрес и IRQ, сообщение при загрузке должно указывать на успешное обнаружение портов Boca следующим образом: (очевидно, номера sio, IO и IRQ могут отличаться) + [source, shell] .... sio1 at 0x100-0x107 flags 0x1005 on isa sio1: type 16550A (multiport) sio2 at 0x108-0x10f flags 0x1005 on isa sio2: type 16550A (multiport) sio3 at 0x110-0x117 flags 0x1005 on isa sio3: type 16550A (multiport) sio4 at 0x118-0x11f flags 0x1005 on isa sio4: type 16550A (multiport) sio5 at 0x120-0x127 flags 0x1005 on isa sio5: type 16550A (multiport) sio6 at 0x128-0x12f flags 0x1005 on isa sio6: type 16550A (multiport) sio7 at 0x130-0x137 flags 0x1005 on isa sio7: type 16550A (multiport) sio8 at 0x138-0x13f flags 0x1005 on isa sio8: type 16550A (multiport) sio9 at 0x140-0x147 flags 0x1005 on isa sio9: type 16550A (multiport) sio10 at 0x148-0x14f flags 0x1005 on isa sio10: type 16550A (multiport) sio11 at 0x150-0x157 flags 0x1005 on isa sio11: type 16550A (multiport) sio12 at 0x158-0x15f flags 0x1005 on isa sio12: type 16550A (multiport) sio13 at 0x160-0x167 flags 0x1005 on isa sio13: type 16550A (multiport) sio14 at 0x168-0x16f flags 0x1005 on isa sio14: type 16550A (multiport) sio15 at 0x170-0x177 flags 0x1005 on isa sio15: type 16550A (multiport) sio16 at 0x178-0x17f irq 3 flags 0x1005 on isa sio16: type 16550A (multiport master) .... + Если сообщения проходят слишком быстро, чтобы их увидеть, + [source, shell] .... # dmesg | more .... покажет вам сообщения загрузки. . Далее необходимо создать соответствующие записи в [.filename]#/dev# для устройств с помощью скрипта [.filename]#/dev/MAKEDEV#. Этот шаг можно пропустить, если вы используете FreeBSD 5.X с ядром, в котором включена поддержка man:devfs[5]. + Если вам необходимо создать записи в [.filename]#/dev#, выполните следующую команду от имени `root`: + [source, shell] .... # cd /dev # ./MAKEDEV tty1 # ./MAKEDEV cua1 (everything in between) # ./MAKEDEV ttyg # ./MAKEDEV cuag .... + Если по какой-то причине вам не нужны или не требуются устройства исходящих соединений, вы можете обойтись без создания устройств [.filename]#cua*#. . Если вам нужен быстрый и небрежный способ убедиться, что устройства работают, вы можете просто подключить модем к каждому порту и (как root) + [source, shell] .... # echo at > ttyd* .... для каждого устройства, которое вы создали. Вы _должны_ увидеть, как мигают индикаторы RX для каждого рабочего порта. ==== === Поддержка дешёвых многоканальных UART-карт _Предоставлено Хельге Ольдахом_ mailto:hmo@sep.hamburg.com[hmo@sep.hamburg.com], сентябрь 1999 года Вы когда-нибудь задумывались о поддержке FreeBSD вашей 20-долларовой многофункциональной карты с двумя (или более) COM-портами, разделяющими IRQ? Вот как это сделать: Обычно единственный способ поддержки таких плат — использование отдельного IRQ для каждого порта. Например, если ваша материнская плата имеет встроенный порт [.filename]#COM1# (он же [.filename]#sio0# — адрес ввода-вывода 0x3F8 и IRQ 4), а у вас есть расширительная плата с двумя UART, то обычно их нужно настроить как [.filename]#COM2# (он же [.filename]#sio1# — адрес ввода-вывода 0x2F8 и IRQ 3), а третий порт (он же [.filename]#sio2#) — с адресом 0x3E8 и IRQ 5. Очевидно, это расточительное использование ресурсов IRQ, так как в принципе возможно запустить оба порта расширительной платы с одним IRQ, используя конфигурацию `COM_MULTIPORT`, описанную в предыдущих разделах. Такие недорогие платы ввода-вывода обычно имеют перемычечную матрицу 4x3 для COM-портов, подобную следующей: [.programlisting] .... o o o * Port A | o * o * Port B | o * o o IRQ 2 3 4 5 .... Показано, что порт A подключен для IRQ 5, а порт B — для IRQ 3. Столбцы IRQ на вашей конкретной плате могут отличаться — другие платы могут предоставлять перемычки для IRQ 3, 4, 5 и 7. Можно было бы сделать вывод, что подключение обоих портов к IRQ 3 с помощью самодельной перемычки, замыкающей все три точки соединения в колонке IRQ 3, решит проблему, но это не так. Невозможно дублировать IRQ 3, потому что выходные драйверы каждого UART соединены по схеме "монтажное И", и если один из UART управляет IRQ 3, выходной сигнал будет не таким как ожидается. В зависимости от реализации платы расширения или материнской платы, линия IRQ 3 будет постоянно находиться в высоком уровне или всегда оставаться низкой. Вам необходимо разделить драйверы прерываний для двух UART, чтобы линия прерывания платы поднималась только тогда (и только тогда), когда один из UART вызывает прерывание, и оставалась низкой в противном случае. Решение было предложено Йоргом Вуншем mailto:j@ida.interface-business.de[j@ida.interface-business.de]: припаять монтажную схему "монтажное ИЛИ", состоящую из двух диодов (предпочтительно германиевых или типа Шоттки) и резистора на 1 кОм. Вот схема, начиная с контактного поля 4x3 выше: [.programlisting] .... Diode +---------->|-------+ / | o * o o | 1 kOhm Port A +----|######|-------+ o * o o | | Port B `-------------------+ ==+== o * o o | Ground \ | +--------->|-------+ IRQ 2 3 4 5 Diode .... Катоды диодов соединены в общей точке вместе с подтягивающим резистором 1 кОм. Важно подключить резистор к земле, чтобы избежать плавания линии IRQ на шине. Теперь мы готовы настроить ядро. Продолжая этот пример, мы настроим: [.programlisting] .... # standard on-board COM1 port device sio0 at isa? port "IO_COM1" flags 0x10 # patched-up multi-I/O extension board options COM_MULTIPORT device sio1 at isa? port "IO_COM2" flags 0x205 device sio2 at isa? port "IO_COM3" flags 0x205 irq 3 .... Обратите внимание, что настройка `flags` для [.filename]#sio1# и [.filename]#sio2# действительно важна; подробности смотрите в man:sio[4]. (Обычно `2` в атрибуте "flags" относится к [.filename]#sio#`2`, который содержит IRQ, и вам наверняка потребуется нижний ниббл `5`.) При включённом режиме подробного вывода ядра это должно дать что-то похожее на следующее: [source, shell] .... sio0: irq maps: 0x1 0x11 0x1 0x1 sio0 at 0x3f8-0x3ff irq 4 flags 0x10 on isa sio0: type 16550A sio1: irq maps: 0x1 0x9 0x1 0x1 sio1 at 0x2f8-0x2ff flags 0x205 on isa sio1: type 16550A (multiport) sio2: irq maps: 0x1 0x9 0x1 0x1 sio2 at 0x3e8-0x3ef irq 3 flags 0x205 on isa sio2: type 16550A (multiport master) .... Хотя [.filename]#/sys/i386/isa/sio.c# выглядит несколько загадочно из-за использования массива "irq maps" выше, основная идея заключается в том, что вы наблюдаете `0x1` на первой, третьей и четвертой позициях. Это означает, что соответствующий IRQ был установлен при выводе и сброшен после, что полностью соответствует ожиданиям. Если ваше ядро не демонстрирует такое поведение, скорее всего, проблема в вашей разводке. [[cy]] == Настройка драйвера [.filename]#cy# _Предоставлено Алексом Нэшем. 6 июня 1996._ Многопортовые карты Cyclades основаны на драйвере [.filename]#cy#, а не на обычном драйвере [.filename]#sio#, используемом другими многопортовыми картами. Настройка сводится к простым действиям: [.procedure] ==== . Добавьте устройство [.filename]#cy# в конфигурацию ядра (обратите внимание, что параметры irq и iomem могут отличаться). + [.programlisting] .... device cy0 at isa? irq 10 iomem 0xd4000 iosiz 0x2000 .... . Перестройте и установите новый образ ядра. . Создайте файлы устройств, введя (следующий пример предполагает 8-портовую плату): + [source, shell] .... # cd /dev # for i in 0 1 2 3 4 5 6 7;do ./MAKEDEV cuac$i ttyc$i;done .... . Если необходимо, добавьте записи для коммутируемого доступа в [.filename]#/etc/ttys#, дублируя записи для последовательных устройств (`ttyd`) и используя `ttyc` вместо `ttyd`. Например: + [.programlisting] .... ttyc0 "/usr/libexec/getty std.38400" unknown on insecure ttyc1 "/usr/libexec/getty std.38400" unknown on insecure ttyc2 "/usr/libexec/getty std.38400" unknown on insecure ... ttyc7 "/usr/libexec/getty std.38400" unknown on insecure .... . Перезагрузитесь с новым ядром. ==== == Настройка драйвера [.filename]#si# _Предоставлено `{nsayer}`. 25 марта 1998._ Специальные мультипортные карты Specialix SI/XIO и SX используют драйвер [.filename]#si#. На одной машине может быть установлено до 4 хост-карт. Поддерживаются следующие хост-карты: * ISA SI/XIO host card (2 versions) * EISA SI/XIO host card * PCI SI/XIO host card * ISA SX host card * PCI SX host card Хотя хост-карты SX и SI/XIO выглядят заметно по-разному, их функциональность практически одинакова. Хост-карты не используют порты ввода-вывода, а вместо этого требуют 32К сегмента памяти. Заводская конфигурация для карт ISA размещает этот сегмент по адресу `0xd0000-0xd7fff`. Также им требуется IRQ. Карты PCI, разумеется, настраиваются автоматически. Вы можете подключить до 4 внешних модулей к каждой карте хоста. Внешние модули содержат либо 4, либо 8 последовательных портов. Они бывают следующих видов: * Модули SI на 4 или 8 портов. Поддерживается скорость до 57600 бит/с на каждом порту. * XIO 8-портовые модули. Поддерживается скорость до 115200 бит/с на каждом порту. Один из типов модулей XIO имеет 7 последовательных и 1 параллельный порт. * Модули SXDC с 8 портами. Поддерживается скорость до 921600 бит/с на каждом порту. Как и в случае с XIO, доступен модуль с одним параллельным портом. Для настройки карты хоста ISA добавьте следующую строку в файл конфигурации ядра, изменив числа по мере необходимости: [.programlisting] .... device si0 at isa? iomem 0xd0000 irq 11 .... Допустимые номера IRQ: 9, 10, 11, 12 и 15 для SX ISA host cards и 11, 12 и 15 для SI/XIO ISA host cards. Для настройки карты EISA или PCI используйте следующую строку: [.programlisting] .... device si0 .... После добавления записи конфигурации пересоберите и установите свое новое ядро. [NOTE] ==== Следующий шаг не обязателен, если вы используете man:devfs[5] в FreeBSD 5._X_. ==== После перезагрузки с новым ядром необходимо создать файлы устройств в [.filename]#/dev#. Скрипт [.filename]#MAKEDEV# выполнит эту задачу за вас. Подсчитайте общее количество портов и введите: [source, shell] .... # cd /dev # ./MAKEDEV ttyAnn cuaAnn .... (где _nn_ — количество портов) Если вы хотите, чтобы приглашения к входу отображались на этих портах, вам нужно добавить такие строки в [.filename]#/etc/ttys#: [.programlisting] .... ttyA01 "/usr/libexec/getty std.9600" vt100 on insecure .... Измените тип терминала по необходимости. Для модемов подойдут `dialup` или `unknown`. diff --git a/documentation/content/ru/articles/serial-uart/_index.po b/documentation/content/ru/articles/serial-uart/_index.po index a0e7e0d534..54dd8dd935 100644 --- a/documentation/content/ru/articles/serial-uart/_index.po +++ b/documentation/content/ru/articles/serial-uart/_index.po @@ -1,3904 +1,3904 @@ # SOME DESCRIPTIVE TITLE # Copyright (C) YEAR The FreeBSD Project # This file is distributed under the same license as the FreeBSD Documentation package. # Vladlen Popolitov , 2025, 2026. msgid "" msgstr "" "Project-Id-Version: FreeBSD Documentation VERSION\n" "POT-Creation-Date: 2025-11-08 16:17+0000\n" -"PO-Revision-Date: 2026-03-09 04:45+0000\n" +"PO-Revision-Date: 2026-04-05 04:45+0000\n" "Last-Translator: Vladlen Popolitov \n" "Language-Team: Russian \n" "Language: ru\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && " "n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" "X-Generator: Weblate 4.17\n" #. type: YAML Front Matter: description #: documentation/content/en/articles/serial-uart/_index.adoc:1 #, no-wrap msgid "Detailed information about the use of serial ports and UART with FreeBSD" msgstr "Подробная информация об использовании последовательных портов и UART в FreeBSD" #. type: Title = #: documentation/content/en/articles/serial-uart/_index.adoc:1 #: documentation/content/en/articles/serial-uart/_index.adoc:11 #, no-wrap msgid "Serial and UART Tutorial" msgstr "Учебное руководство по последовательному интерфейсу и UART" #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:44 msgid "Abstract" msgstr "Аннотация" #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:46 msgid "This article talks about using serial hardware with FreeBSD." msgstr "" "Эта статья рассказывает об использовании последовательного оборудования с " "FreeBSD." #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:48 msgid "'''" msgstr "'''" #. type: Title == #: documentation/content/en/articles/serial-uart/_index.adoc:52 #, no-wrap msgid "The UART: What it is and how it works" msgstr "UART: Что это и как работает" #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:55 msgid "_Copyright (R) 1996 `{uhclem}`, All Rights Reserved. 13 January 1996._" msgstr "" "_Copyright (R) 1996 `{uhclem}`, All Rights Reserved. 13 января 1996 год_" #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:59 msgid "" "The Universal Asynchronous Receiver/Transmitter (UART) controller is the key " "component of the serial communications subsystem of a computer. The UART " "takes bytes of data and transmits the individual bits in a sequential " "fashion. At the destination, a second UART re-assembles the bits into " "complete bytes." msgstr "" "Универсальный асинхронный приёмопередатчик (UART) — это ключевой компонент " "подсистемы последовательной передачи данных компьютера. UART принимает байты " "данных и передаёт отдельные биты последовательно. На стороне приёмника " "второй UART собирает биты обратно в полные байты." #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:61 msgid "" "Serial transmission is commonly used with modems and for non-networked " "communication between computers, terminals and other devices." msgstr "" "Последовательная передача данных обычно используется с модемами и для не " "сетевого взаимодействия между компьютерами, терминалами и другими " "устройствами." #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:65 msgid "" "There are two primary forms of serial transmission: Synchronous and " "Asynchronous. Depending on the modes that are supported by the hardware, " "the name of the communication sub-system will usually include a `A` if it " "supports Asynchronous communications, and a `S` if it supports Synchronous " "communications. Both forms are described below." msgstr "" "Существует две основные формы последовательной передачи данных: синхронная и " "асинхронная. В зависимости от режимов, поддерживаемых оборудованием, " "название подсистемы связи обычно включает букву `A`, если она поддерживает " "асинхронную передачу, и букву `S`, если поддерживается синхронная передача. " "Обе формы описаны ниже." #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:67 msgid "Some common acronyms are:" msgstr "Некоторые распространённые сокращения:" #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:70 msgid "UART Universal Asynchronous Receiver/Transmitter" msgstr "" "UART Universal Asynchronous Receiver/Transmitter — Универсальный асинхронный " "приёмопередатчик" #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:73 msgid "USART Universal Synchronous-Asynchronous Receiver/Transmitter" msgstr "" "USART Universal Synchronous-Asynchronous Receiver/Transmitter — " "Универсальный синхронно-асинхронный приёмопередатчик" #. type: Title === #: documentation/content/en/articles/serial-uart/_index.adoc:74 #, no-wrap msgid "Synchronous Serial Transmission" msgstr "Синхронная последовательная передача" #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:79 msgid "" "Synchronous serial transmission requires that the sender and receiver share " "a clock with one another, or that the sender provide a strobe or other " "timing signal so that the receiver knows when to \"read\" the next bit of " "the data. In most forms of serial Synchronous communication, if there is no " "data available at a given instant to transmit, a fill character must be sent " "instead so that data is always being transmitted. Synchronous communication " "is usually more efficient because only data bits are transmitted between " "sender and receiver, and synchronous communication can be more costly if " "extra wiring and circuits are required to share a clock signal between the " "sender and receiver." msgstr "" "Синхронная последовательная передача данных требует, чтобы отправитель и " "получатель имели общий тактовый сигнал, либо чтобы отправитель предоставлял " "строб-сигнал или другой сигнал синхронизации, чтобы получатель знал, когда " "\"считывать\" следующий бит данных. В большинстве форм синхронной " "последовательной связи, если в данный момент нет доступных данных для " "передачи, вместо них должен быть отправлен заполняющий символ, чтобы " "передача данных не прерывалась. Синхронная связь обычно более эффективна, " "так как между отправителем и получателем передаются только биты данных, " "однако она может быть более затратной, если требуются дополнительные провода " "и схемы для обмена тактовым сигналом между отправителем и получателем." #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:83 msgid "" "A form of Synchronous transmission is used with printers and fixed disk " "devices in that the data is sent on one set of wires while a clock or strobe " "is sent on a different wire. Printers and fixed disk devices are not " "normally serial devices because most fixed disk interface standards send an " "entire word of data for each clock or strobe signal by using a separate wire " "for each bit of the word. In the PC industry, these are known as Parallel " "devices." msgstr "" "Форма синхронной передачи используется с принтерами и устройствами с " "жёсткими дисками, где данные передаются по одному набору проводов, а " "тактовый сигнал или строб — по другому проводу. Принтеры и устройства с " "жёсткими дисками обычно не являются последовательными устройствами, так как " "большинство стандартов интерфейсов жёстких дисков передают целое слово " "данных для каждого тактового сигнала или строба, используя отдельный провод " "для каждого бита слова. В индустрии ПК такие устройства известны как " "параллельные." #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:86 msgid "" "The standard serial communications hardware in the PC does not support " "Synchronous operations. This mode is described here for comparison purposes " "only." msgstr "" "Стандартное оборудование для последовательной связи в ПК не поддерживает " "синхронные операции. Этот режим описан здесь только для сравнения." #. type: Title === #: documentation/content/en/articles/serial-uart/_index.adoc:87 #, no-wrap msgid "Asynchronous Serial Transmission" msgstr "Асинхронная последовательная передача" #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:91 msgid "" "Asynchronous transmission allows data to be transmitted without the sender " "having to send a clock signal to the receiver. Instead, the sender and " "receiver must agree on timing parameters in advance and special bits are " "added to each word which are used to synchronize the sending and receiving " "units." msgstr "" "Асинхронная передача позволяет передавать данные без необходимости отправки " "тактового сигнала от отправителя к получателю. Вместо этого отправитель и " "получатель заранее согласовывают параметры синхронизации, а к каждому слову " "добавляются специальные биты, которые используются для синхронизации " "передающего и принимающего устройств." #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:96 msgid "" "When a word is given to the UART for Asynchronous transmissions, a bit " "called the \"Start Bit\" is added to the beginning of each word that is to " "be transmitted. The Start Bit is used to alert the receiver that a word of " "data is about to be sent, and to force the clock in the receiver into " "synchronization with the clock in the transmitter. These two clocks must be " "accurate enough to not have the frequency drift by more than 10% during the " "transmission of the remaining bits in the word. (This requirement was set " "in the days of mechanical teleprinters and is easily met by modern " "electronic equipment.)" msgstr "" "При передаче слова через UART в асинхронном режиме к началу каждого " "передаваемого слова добавляется бит, называемый \"стартовым битом\". " "Стартовый бит используется для оповещения приёмника о начале передачи слова " "данных, а также для синхронизации тактового сигнала приёмника с тактовым " "сигналом передатчика. Эти два тактовых сигнала должны быть достаточно " "точными, чтобы их расхождение по частоте не превышало 10% во время передачи " "оставшихся битов слова. (Данное требование было установлено во времена " "механических телетайпов и легко выполняется современным электронным " "оборудованием.)" #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:100 msgid "" "After the Start Bit, the individual bits of the word of data are sent, with " "the Least Significant Bit (LSB) being sent first. Each bit in the " "transmission is transmitted for exactly the same amount of time as all of " "the other bits, and the receiver \"looks\" at the wire at approximately " "halfway through the period assigned to each bit to determine if the bit is a " "`1` or a `0`. For example, if it takes two seconds to send each bit, the " "receiver will examine the signal to determine if it is a `1` or a `0` after " "one second has passed, then it will wait two seconds and then examine the " "value of the next bit, and so on." msgstr "" "После стартового бита передаются отдельные биты слова данных, начиная с " "младшего значащего бита (LSB). Каждый бит передаётся в течение точно такого " "же времени, как и все остальные биты, и приемник \"проверяет\" состояние " "линии примерно на середине интервала, отведенного для каждого бита, чтобы " "определить, является ли бит `1` или `0`. Например, если передача каждого " "бита занимает две секунды, приемник проверит сигнал, чтобы определить, " "является ли он `1` или `0`, через одну секунду, затем подождет две секунды и " "проверит значение следующего бита, и так далее." #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:103 msgid "" "The sender does not know when the receiver has \"looked\" at the value of " "the bit. The sender only knows when the clock says to begin transmitting " "the next bit of the word." msgstr "" "Отправитель не знает, когда получатель «посмотрел» значение бита. " "Отправитель знает только, когда по тактовому сигналу нужно начать передачу " "следующего бита слова." #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:107 msgid "" "When the entire data word has been sent, the transmitter may add a Parity " "Bit that the transmitter generates. The Parity Bit may be used by the " "receiver to perform simple error checking. Then at least one Stop Bit is " "sent by the transmitter." msgstr "" "Когда все слово данных отправлено, передатчик может добавить бит чётности, " "который он генерирует. Бит чётности может быть использован приемником для " "выполнения простой проверки на ошибки. Затем передатчик отправляет как " "минимум один стоповый бит." #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:111 msgid "" "When the receiver has received all of the bits in the data word, it may " "check for the Parity Bits (both sender and receiver must agree on whether a " "Parity Bit is to be used), and then the receiver looks for a Stop Bit. If " "the Stop Bit does not appear when it is supposed to, the UART considers the " "entire word to be garbled and will report a Framing Error to the host " "processor when the data word is read. The usual cause of a Framing Error is " "that the sender and receiver clocks were not running at the same speed, or " "that the signal was interrupted." msgstr "" "Когда приемник получил все биты в слове данных, он может проверить биты " "чётности (как отправитель, так и приемник должны договориться о том, будет " "ли использоваться бит чётности), а затем приемник ищет стоповый бит. Если " "стоповый бит не появляется, когда должен, UART считает все слово искаженным " "и сообщит об ошибке кадрирования главному процессору при чтении слова " "данных. Обычная причина ошибки кадрирования — несовпадение скорости тактовых " "сигналов отправителя и приемника или прерывание сигнала." #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:114 msgid "" "Regardless of whether the data was received correctly or not, the UART " "automatically discards the Start, Parity and Stop bits. If the sender and " "receiver are configured identically, these bits are not passed to the host." msgstr "" "Независимо от того, были ли данные получены правильно или нет, UART " "автоматически отбрасывает бит чётности, стартовый и стоповый биты. Если " "отправитель и получатель настроены одинаково, эти биты не передаются хосту." #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:116 msgid "" "If another word is ready for transmission, the Start Bit for the new word " "can be sent as soon as the Stop Bit for the previous word has been sent." msgstr "" "Если готово следующее слово для передачи, стартовый бит нового слова может " "быть отправлен сразу после того, как будет отправлен стоповый бит " "предыдущего слова." #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:118 msgid "" "As asynchronous data is \"self synchronizing\", if there is no data to " "transmit, the transmission line can be idle." msgstr "" "Поскольку асинхронные данные являются \"самосинхронизирующимися\", если нет " "данных для передачи, линия передачи может быть неактивна." #. type: Title === #: documentation/content/en/articles/serial-uart/_index.adoc:119 #, no-wrap msgid "Other UART Functions" msgstr "Другие функции UART" #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:124 msgid "" "In addition to the basic job of converting data from parallel to serial for " "transmission and from serial to parallel on reception, a UART will usually " "provide additional circuits for signals that can be used to indicate the " "state of the transmission media, and to regulate the flow of data in the " "event that the remote device is not prepared to accept more data. For " "example, when the device connected to the UART is a modem, the modem may " "report the presence of a carrier on the phone line while the computer may be " "able to instruct the modem to reset itself or to not take calls by raising " "or lowering one more of these extra signals. The function of each of these " "additional signals is defined in the EIA RS232-C standard." msgstr "" "Помимо основной задачи преобразования данных из параллельного формата в " "последовательный для передачи и из последовательного в параллельный при " "приеме, UART обычно предоставляет дополнительные схемы для сигналов, которые " "могут использоваться для указания состояния среды передачи и регулирования " -"потока данных в случае, если удаленное устройство не готово принимать больше " +"потока данных в случае, если удалённое устройство не готово принимать больше " "данных. Например, когда устройство, подключенное к UART, является модемом, " "модем может сообщать о наличии несущей на телефонной линии, в то время как " "компьютер может дать команду модему сбросить себя или не принимать вызовы, " "поднимая или опуская один или несколько из этих дополнительных сигналов. " "Функция каждого из этих дополнительных сигналов определена в стандарте EIA " "RS232-C." #. type: Title === #: documentation/content/en/articles/serial-uart/_index.adoc:125 #, no-wrap msgid "The RS232-C and V.24 Standards" msgstr "Стандарты RS232-C и V.24" #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:129 msgid "" "In most computer systems, the UART is connected to circuitry that generates " "signals that comply with the EIA RS232-C specification. There is also a " "CCITT standard named V.24 that mirrors the specifications included in RS232-" "C." msgstr "" "В большинстве компьютерных систем UART подключен к схеме, которая генерирует " "сигналы, соответствующие спецификации EIA RS232-C. Также существует стандарт " "CCITT под названием V.24, который отражает спецификации, включенные в RS232-" "C." #. type: Title ==== #: documentation/content/en/articles/serial-uart/_index.adoc:130 #, no-wrap msgid "RS232-C Bit Assignments (Marks and Spaces)" msgstr "Назначения битов RS232-C (метки и пробелы)" #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:134 msgid "" "In RS232-C, a value of `1` is called a `Mark` and a value of `0` is called a " "`Space`. When a communication line is idle, the line is said to be \"Marking" "\", or transmitting continuous `1` values." msgstr "" "В стандарте RS232-C значение `1` называется `Маркер` (Mark), а значение `0` " "— `Пробел` (Space). Когда линия связи находится в состоянии покоя, говорят, " "что она \"маркирует\" (Marking), то есть передаёт непрерывные значения `1`." #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:139 msgid "" "The Start bit always has a value of `0` (a Space). The Stop Bit always has " "a value of `1` (a Mark). This means that there will always be a Mark (1) to " "Space (0) transition on the line at the start of every word, even when " "multiple word are transmitted back to back. This guarantees that sender and " "receiver can resynchronize their clocks regardless of the content of the " "data bits that are being transmitted." msgstr "" "Стартовый бит всегда имеет значение `0` (пробел). Стоповый бит всегда имеет " "значение `1` (метка). Это означает, что на линии всегда будет переход от " "метки (1) к пробелу (0) в начале каждого слова, даже при передаче нескольких " "слов подряд. Это гарантирует, что отправитель и получатель могут " "синхронизировать свои тактовые сигналы независимо от содержимого " "передаваемых битов данных." #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:141 msgid "" "The idle time between Stop and Start bits does not have to be an exact " "multiple (including zero) of the bit rate of the communication link, but " "most UARTs are designed this way for simplicity." msgstr "" "Время простоя между стоповым и стартовым битами не обязательно должно быть " "точным кратным (включая ноль) скорости передачи данных коммуникационного " "канала, однако большинство UART спроектированы таким образом для простоты." #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:145 msgid "" "In RS232-C, the \"Marking\" signal (a `1`) is represented by a voltage " "between -2 VDC and -12 VDC, and a \"Spacing\" signal (a `0`) is represented " "by a voltage between 0 and +12 VDC. The transmitter is supposed to send +12 " "VDC or -12 VDC, and the receiver is supposed to allow for some voltage loss " "in long cables. Some transmitters in low power devices (like portable " "computers) sometimes use only +5 VDC and -5 VDC, but these values are still " "acceptable to a RS232-C receiver, provided that the cable lengths are short." msgstr "" "В стандарте RS232-C сигнал «Marking» (логическая `1`) представлен " "напряжением от -2 В до -12 В, а сигнал «Spacing» (логический `0`) — " "напряжением от 0 В до +12 В. Передатчик должен выдавать +12 В или -12 В, а " "приёмник должен учитывать возможные потери напряжения в длинных кабелях. " "Некоторые маломощные передатчики (например, в портативных компьютерах) " "иногда используют только +5 В и -5 В, но эти значения всё ещё допустимы для " "приёмника RS232-C при условии использования коротких кабелей." #. type: Title ==== #: documentation/content/en/articles/serial-uart/_index.adoc:146 #, no-wrap msgid "RS232-C Break Signal" msgstr "Сигнал Break в RS232-C" #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:150 msgid "" "RS232-C also specifies a signal called a `Break`, which is caused by sending " "continuous Spacing values (no Start or Stop bits). When there is no " "electricity present on the data circuit, the line is considered to be " "sending `Break`." msgstr "" "RS232-C также определяет сигнал под названием `Break`, который вызывается " "передачей непрерывных значений Spacing (без стартовых или стоповых битов). " "Когда на линии данных отсутствует напряжение, считается, что линия передаёт " "`Break`." #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:153 msgid "" "The `Break` signal must be of a duration longer than the time it takes to " "send a complete byte plus Start, Stop and Parity bits. Most UARTs can " "distinguish between a Framing Error and a Break, but if the UART cannot do " "this, the Framing Error detection can be used to identify Breaks." msgstr "" "Сигнал `Break` должен иметь длительность больше, чем время, необходимое для " "передачи полного байта, включая стартовый, стоповый и биты чётности. " "Большинство UART способны различить ошибку кадрирования и сигнал Break, но " "если UART не поддерживает эту функцию, для определения Break можно " "использовать обнаружение ошибки кадрирования." #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:156 msgid "" "In the days of teleprinters, when numerous printers around the country were " "wired in series (such as news services), any unit could cause a `Break` by " "temporarily opening the entire circuit so that no current flowed. This was " "used to allow a location with urgent news to interrupt some other location " "that was currently sending information." msgstr "" "Во времена телетайпов, когда множество принтеров по всей стране были " "соединены последовательно (например, в службах новостей), любое устройство " "могло вызвать `Break`, временно размыкая всю цепь, чтобы ток не протекал. " "Это использовалось для того, чтобы место с срочными новостями могло прервать " "устройство в другом месте, которое в данный момент передавало информацию." #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:161 msgid "" "In modern systems there are two types of Break signals. If the Break is " "longer than 1.6 seconds, it is considered a \"Modem Break\", and some modems " "can be programmed to terminate the conversation and go on-hook or enter the " "modems' command mode when the modem detects this signal. If the Break is " "smaller than 1.6 seconds, it signifies a Data Break and it is up to the " "remote computer to respond to this signal. Sometimes this form of Break is " "used as an Attention or Interrupt signal and sometimes is accepted as a " "substitute for the ASCII CONTROL-C character." msgstr "" "В современных системах существует два типа сигналов Break. Если Break длится " "дольше 1,6 секунд, он считается \"Модемным Break\", и некоторые модемы можно " "запрограммировать на завершение соединения и переход в режим ожидания или " "вход в командный режим модема при обнаружении этого сигнала. Если Break " "короче 1,6 секунд, это означает \"Break данных\", и удалённый компьютер " "должен решить, как реагировать на этот сигнал. Иногда такая форма Break " "используется как сигнал \"Внимание\" или \"Прерывание\", а иногда " "принимается как замена символу ASCII CONTROL-C." #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:163 msgid "" "Marks and Spaces are also equivalent to \"Holes\" and \"No Holes\" in paper " "tape systems." msgstr "" "Метки и пробелы также эквивалентны \"дыркам\" и \"отсутствию дырок\" в " "системах с бумажной лентой." #. type: delimited block = 4 #: documentation/content/en/articles/serial-uart/_index.adoc:168 msgid "" "Breaks cannot be generated from paper tape or from any other byte value, " "since bytes are always sent with Start and Stop bit. The UART is usually " "capable of generating the continuous Spacing signal in response to a special " "command from the host processor." msgstr "" "Разрывы не могут быть сгенерированы с перфоленты или из любого другого " "байтового значения, поскольку байты всегда отправляются со стартовым и " "стоповым битами. UART обычно способен генерировать непрерывный сигнал " "Spacing в ответ на специальную команду от главного управляющего устройства " "(процессора передачи)." #. type: Title ==== #: documentation/content/en/articles/serial-uart/_index.adoc:170 #, no-wrap msgid "RS232-C DTE and DCE Devices" msgstr "RS232-C устройства DTE и DCE" #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:176 msgid "" "The RS232-C specification defines two types of equipment: the Data Terminal " "Equipment (DTE) and the Data Carrier Equipment (DCE). Usually, the DTE " "device is the terminal (or computer), and the DCE is a modem. Across the " "phone line at the other end of a conversation, the receiving modem is also a " "DCE device and the computer that is connected to that modem is a DTE " "device. The DCE device receives signals on the pins that the DTE device " "transmits on, and vice versa." msgstr "" "Спецификация RS232-C определяет два типа оборудования: оконечное " "оборудование данных (DTE — Data Terminal Equipment) и оборудование передачи " "данных (DCE — Data Carrier Equipment). Обычно устройство DTE — это терминал " "(или компьютер), а DCE — модем. На другом конце телефонной линии в разговоре " "принимающий модем также является устройством DCE, а компьютер, подключённый " "к этому модему, — устройством DTE. Устройство DCE принимает сигналы на тех " "контактах, на которых устройство DTE передаёт, и наоборот." #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:180 msgid "" "When two devices that are both DTE or both DCE must be connected together " "without a modem or a similar media translator between them, a NULL modem " "must be used. The NULL modem electrically re-arranges the cabling so that " "the transmitter output is connected to the receiver input on the other " "device, and vice versa. Similar translations are performed on all of the " "control signals so that each device will see what it thinks are DCE (or DTE) " "signals from the other device." msgstr "" "Когда два устройства, оба являющиеся DTE или DCE, должны быть соединены " "вместе без модема или аналогичного преобразователя среды между ними, " "необходимо использовать NULL модем. NULL модем электрически перестраивает " "кабель так, что выход передатчика подключается ко входу приемника на другом " "устройстве, и наоборот. Аналогичные преобразования выполняются для всех " "управляющих сигналов, чтобы каждое устройство видело то, что оно считает " "сигналами DCE (или DTE) от другого устройства." #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:183 msgid "" "The number of signals generated by the DTE and DCE devices are not " "symmetrical. The DTE device generates fewer signals for the DCE device than " "the DTE device receives from the DCE." msgstr "" "Количество сигналов, генерируемых устройствами DTE и DCE, не симметрично. " "Устройство DTE генерирует меньше сигналов для устройства DCE, чем получает " "от него." #. type: Title ==== #: documentation/content/en/articles/serial-uart/_index.adoc:184 #, no-wrap msgid "RS232-C Pin Assignments" msgstr "Назначение контактов RS232-C" #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:187 msgid "" "The EIA RS232-C specification (and the ITU equivalent, V.24) calls for a " "twenty-five pin connector (usually a DB25) and defines the purpose of most " "of the pins in that connector." msgstr "" "Спецификация EIA RS232-C (и её эквивалент ITU, V.24) предусматривает " "использование двадцатипятиконтактного разъёма (обычно DB25) и определяет " "назначение большинства контактов в этом разъёме." #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:190 msgid "" "In the IBM Personal Computer and similar systems, a subset of RS232-C " "signals are provided via nine pin connectors (DB9). The signals that are " "not included on the PC connector deal mainly with synchronous operation, and " "this transmission mode is not supported by the UART that IBM selected for " "use in the IBM PC." msgstr "" "В IBM Personal Computer и подобных системах подмножество сигналов RS232-C " "предоставляется через девятиконтактные разъемы (DB9). Сигналы, которые не " "включены в разъем ПК, в основном связаны с синхронной работой, и этот режим " "передачи не поддерживается UART, выбранным IBM для использования в IBM PC." #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:193 msgid "" "Depending on the computer manufacturer, a DB25, a DB9, or both types of " "connector may be used for RS232-C communications. (The IBM PC also uses a " "DB25 connector for the parallel printer interface which causes some " "confusion.)" msgstr "" "В зависимости от производителя компьютера, для связи по RS232-C могут " "использоваться разъемы DB25, DB9 или оба типа. (В IBM PC также используется " "разъем DB25 для параллельного интерфейса принтера, что иногда вызывает " "путаницу.)" #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:195 msgid "" "Below is a table of the RS232-C signal assignments in the DB25 and DB9 " "connectors." msgstr "" "Ниже представлена таблица назначений сигналов RS232-C в разъемах DB25 и DB9." #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:200 #, no-wrap msgid "DB25 RS232-C Pin" msgstr "Контакт в DB25 RS232-C" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:201 #, no-wrap msgid "DB9 IBM PC Pin" msgstr "Контакт в DB9 IBM PC" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:202 #, no-wrap msgid "EIA Circuit Symbol" msgstr "Символ цепи по EIA" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:203 #, no-wrap msgid "CCITT Circuit Symbol" msgstr "Символ цепи по CCITT" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:204 #, no-wrap msgid "Common Name" msgstr "Общее имя" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:205 #, no-wrap msgid "Signal Source" msgstr "Источник сигнала" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:207 #: documentation/content/en/articles/serial-uart/_index.adoc:675 #, no-wrap msgid "Description" msgstr "Описание" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:208 #: documentation/content/en/articles/serial-uart/_index.adoc:265 #, no-wrap msgid "1" msgstr "1" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:209 #: documentation/content/en/articles/serial-uart/_index.adoc:213 #: documentation/content/en/articles/serial-uart/_index.adoc:261 #: documentation/content/en/articles/serial-uart/_index.adoc:273 #: documentation/content/en/articles/serial-uart/_index.adoc:274 #: documentation/content/en/articles/serial-uart/_index.adoc:275 #: documentation/content/en/articles/serial-uart/_index.adoc:276 #: documentation/content/en/articles/serial-uart/_index.adoc:277 #: documentation/content/en/articles/serial-uart/_index.adoc:281 #: documentation/content/en/articles/serial-uart/_index.adoc:282 #: documentation/content/en/articles/serial-uart/_index.adoc:283 #: documentation/content/en/articles/serial-uart/_index.adoc:284 #: documentation/content/en/articles/serial-uart/_index.adoc:285 #: documentation/content/en/articles/serial-uart/_index.adoc:289 #: documentation/content/en/articles/serial-uart/_index.adoc:290 #: documentation/content/en/articles/serial-uart/_index.adoc:291 #: documentation/content/en/articles/serial-uart/_index.adoc:292 #: documentation/content/en/articles/serial-uart/_index.adoc:293 #: documentation/content/en/articles/serial-uart/_index.adoc:297 #: documentation/content/en/articles/serial-uart/_index.adoc:305 #: documentation/content/en/articles/serial-uart/_index.adoc:313 #: documentation/content/en/articles/serial-uart/_index.adoc:321 #: documentation/content/en/articles/serial-uart/_index.adoc:329 #: documentation/content/en/articles/serial-uart/_index.adoc:337 #: documentation/content/en/articles/serial-uart/_index.adoc:345 #: documentation/content/en/articles/serial-uart/_index.adoc:346 #: documentation/content/en/articles/serial-uart/_index.adoc:353 #: documentation/content/en/articles/serial-uart/_index.adoc:369 #: documentation/content/en/articles/serial-uart/_index.adoc:370 #: documentation/content/en/articles/serial-uart/_index.adoc:371 #: documentation/content/en/articles/serial-uart/_index.adoc:385 #: documentation/content/en/articles/serial-uart/_index.adoc:393 #: documentation/content/en/articles/serial-uart/_index.adoc:401 #: documentation/content/en/articles/serial-uart/_index.adoc:402 #: documentation/content/en/articles/serial-uart/_index.adoc:404 #, no-wrap msgid "-" msgstr "-" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:210 #, no-wrap msgid "AA" msgstr "AA" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:211 #, no-wrap msgid "101" msgstr "101" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:212 #, no-wrap msgid "PG/FG" msgstr "PG/FG" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:215 #, no-wrap msgid "Frame/Protective Ground" msgstr "Защитное заземление (Frame/Protective Ground)" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:216 #: documentation/content/en/articles/serial-uart/_index.adoc:225 #, no-wrap msgid "2" msgstr "2" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:217 #: documentation/content/en/articles/serial-uart/_index.adoc:224 #: documentation/content/en/articles/serial-uart/_index.adoc:610 #, no-wrap msgid "3" msgstr "3" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:218 #, no-wrap msgid "BA" msgstr "BA" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:219 #, no-wrap msgid "103" msgstr "103" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:220 #, no-wrap msgid "TD" msgstr "TD" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:221 #: documentation/content/en/articles/serial-uart/_index.adoc:237 #: documentation/content/en/articles/serial-uart/_index.adoc:317 #: documentation/content/en/articles/serial-uart/_index.adoc:349 #: documentation/content/en/articles/serial-uart/_index.adoc:357 #: documentation/content/en/articles/serial-uart/_index.adoc:365 #: documentation/content/en/articles/serial-uart/_index.adoc:373 #: documentation/content/en/articles/serial-uart/_index.adoc:389 #: documentation/content/en/articles/serial-uart/_index.adoc:397 #, no-wrap msgid "DTE" msgstr "DTE" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:223 #, no-wrap msgid "Transmit Data" msgstr "Передача Данных (Transmit Data)" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:226 #, no-wrap msgid "BB" msgstr "BB" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:227 #, no-wrap msgid "104" msgstr "104" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:228 #, no-wrap msgid "RD" msgstr "RD" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:229 #: documentation/content/en/articles/serial-uart/_index.adoc:245 #: documentation/content/en/articles/serial-uart/_index.adoc:253 #: documentation/content/en/articles/serial-uart/_index.adoc:269 #: documentation/content/en/articles/serial-uart/_index.adoc:301 #: documentation/content/en/articles/serial-uart/_index.adoc:309 #: documentation/content/en/articles/serial-uart/_index.adoc:325 #: documentation/content/en/articles/serial-uart/_index.adoc:333 #: documentation/content/en/articles/serial-uart/_index.adoc:341 #: documentation/content/en/articles/serial-uart/_index.adoc:381 #: documentation/content/en/articles/serial-uart/_index.adoc:405 #, no-wrap msgid "DCE" msgstr "DCE" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:231 #, no-wrap msgid "Receive Data" msgstr "Прием данных (Receive Data)" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:232 #: documentation/content/en/articles/serial-uart/_index.adoc:361 #, no-wrap msgid "4" msgstr "4" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:233 #: documentation/content/en/articles/serial-uart/_index.adoc:256 #, no-wrap msgid "7" msgstr "7" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:234 #, no-wrap msgid "CA" msgstr "CA" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:235 #, no-wrap msgid "105" msgstr "105" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:236 #, no-wrap msgid "RTS" msgstr "RTS" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:239 #, no-wrap msgid "Request to Send" msgstr "Запрос на передачу (Request to Send)" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:240 #: documentation/content/en/articles/serial-uart/_index.adoc:257 #, no-wrap msgid "5" msgstr "5" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:241 #: documentation/content/en/articles/serial-uart/_index.adoc:264 #, no-wrap msgid "8" msgstr "8" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:242 #, no-wrap msgid "CB" msgstr "CB" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:243 #, no-wrap msgid "106" msgstr "106" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:244 #, no-wrap msgid "CTS" msgstr "CTS" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:247 #, no-wrap msgid "Clear to Send" msgstr "Готовность к приёму (Clear to Send)" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:248 #: documentation/content/en/articles/serial-uart/_index.adoc:249 #, no-wrap msgid "6" msgstr "6" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:250 #, no-wrap msgid "CC" msgstr "CC" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:251 #, no-wrap msgid "107" msgstr "107" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:252 #, no-wrap msgid "DSR" msgstr "DSR" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:255 #, no-wrap msgid "Data Set Ready" msgstr "Готовность терминального оборудования (Data Set Ready)" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:258 #, no-wrap msgid "AV" msgstr "AV" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:259 #, no-wrap msgid "102" msgstr "102" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:260 #, no-wrap msgid "SG/GND" msgstr "SG/GND" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:263 #, no-wrap msgid "Signal Ground" msgstr "Сигнальная земля (Signal Ground)" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:266 #, no-wrap msgid "CF" msgstr "CF" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:267 #, no-wrap msgid "109" msgstr "109" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:268 #, no-wrap msgid "DCD/CD" msgstr "DCD/CD" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:271 #, no-wrap msgid "Data Carrier Detect" msgstr "Обнаружение несущей (Data Carrier Detect)" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:272 #: documentation/content/en/articles/serial-uart/_index.adoc:377 #, no-wrap msgid "9" msgstr "9" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:279 #: documentation/content/en/articles/serial-uart/_index.adoc:287 #: documentation/content/en/articles/serial-uart/_index.adoc:295 #, no-wrap msgid "Reserved for Test" msgstr "Зарезервировано для Теста" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:280 #, no-wrap msgid "10" msgstr "10" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:288 #, no-wrap msgid "11" msgstr "11" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:296 #, no-wrap msgid "12" msgstr "12" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:298 #, no-wrap msgid "CI" msgstr "CI" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:299 #, no-wrap msgid "122" msgstr "122" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:300 #, no-wrap msgid "SRLSD" msgstr "SRLSD" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:303 #, no-wrap msgid "Sec. Recv. Line Signal Detector" msgstr "Детектор сигнала вторичной линии приёма" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:304 #, no-wrap msgid "13" msgstr "13" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:306 #, no-wrap msgid "SCB" msgstr "SCB" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:307 #, no-wrap msgid "121" msgstr "121" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:308 #, no-wrap msgid "SCTS" msgstr "SCTS" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:311 #, no-wrap msgid "Secondary Clear to Send" msgstr "Вторичный сигнал готовности к приёму" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:312 #, no-wrap msgid "14" msgstr "14" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:314 #, no-wrap msgid "SBA" msgstr "SBA" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:315 #, no-wrap msgid "118" msgstr "118" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:316 #, no-wrap msgid "STD" msgstr "STD" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:319 #, no-wrap msgid "Secondary Transmit Data" msgstr "Вторичная линия передачи данных" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:320 #, no-wrap msgid "15" msgstr "15" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:322 #, no-wrap msgid "DB" msgstr "DB" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:323 #, no-wrap msgid "114" msgstr "114" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:324 #: documentation/content/en/articles/serial-uart/_index.adoc:396 #, no-wrap msgid "TSET" msgstr "TSET" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:327 #: documentation/content/en/articles/serial-uart/_index.adoc:399 #, no-wrap msgid "Trans. Sig. Element Timing" msgstr "Тактирование элементов сигнала передатчика (Trans. Sig. Element Timing)" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:328 #, no-wrap msgid "16" msgstr "16" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:330 #, no-wrap msgid "SBB" msgstr "SBB" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:331 #, no-wrap msgid "119" msgstr "119" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:332 #, no-wrap msgid "SRD" msgstr "SRD" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:335 #, no-wrap msgid "Secondary Received Data" msgstr "Вторичная линия приема данных" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:336 #, no-wrap msgid "17" msgstr "17" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:338 #, no-wrap msgid "DD" msgstr "DD" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:339 #, no-wrap msgid "115" msgstr "115" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:340 #, no-wrap msgid "RSET" msgstr "RSET" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:343 #, no-wrap msgid "Receiver Signal Element Timing" msgstr "Тактирование элементов сигнала приёмника (Receiver Signal Element Timing)" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:344 #, no-wrap msgid "18" msgstr "18" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:347 #, no-wrap msgid "141" msgstr "141" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:348 #, no-wrap msgid "LOOP" msgstr "LOOP" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:351 #, no-wrap msgid "Local Loopback" msgstr "Локальная петля" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:352 #: documentation/content/en/articles/serial-uart/_index.adoc:614 #, no-wrap msgid "19" msgstr "19" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:354 #, no-wrap msgid "SCA" msgstr "SCA" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:355 #, no-wrap msgid "120" msgstr "120" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:356 #, no-wrap msgid "SRS" msgstr "SRS" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:359 #, no-wrap msgid "Secondary Request to Send" msgstr "Вторичный запрос на передачу" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:360 #, no-wrap msgid "20" msgstr "20" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:362 #, no-wrap msgid "CD" msgstr "CD" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:363 #, no-wrap msgid "108.2" msgstr "108.2" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:364 #, no-wrap msgid "DTR" msgstr "DTR" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:367 #, no-wrap msgid "Data Terminal Ready" msgstr "Готовность терминального оборудования (Data Terminal Ready)" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:368 #, no-wrap msgid "21" msgstr "21" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:372 #, no-wrap msgid "RDL" msgstr "RDL" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:375 #, no-wrap msgid "Remote Digital Loopback" msgstr "Режим удалённой цифровой петли (Remote Digital Loopback)" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:376 #, no-wrap msgid "22" msgstr "22" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:378 #, no-wrap msgid "CE" msgstr "CE" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:379 #, no-wrap msgid "125" msgstr "125" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:380 #, no-wrap msgid "RI" msgstr "RI" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:383 #, no-wrap msgid "Ring Indicator" msgstr "Индикатор передачи данных (Ring Indicator)" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:384 #: documentation/content/en/articles/serial-uart/_index.adoc:618 #, no-wrap msgid "23" msgstr "23" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:386 #, no-wrap msgid "CH" msgstr "CH" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:387 #, no-wrap msgid "111" msgstr "111" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:388 #, no-wrap msgid "DSRS" msgstr "DSRS" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:391 #, no-wrap msgid "Data Signal Rate Selector" msgstr "Селектор скорости передачи данных" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:392 #, no-wrap msgid "24" msgstr "24" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:394 #, no-wrap msgid "DA" msgstr "DA" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:395 #, no-wrap msgid "113" msgstr "113" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:400 #, no-wrap msgid "25" msgstr "25" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:403 #, no-wrap msgid "142" msgstr "142" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:406 #, no-wrap msgid "Test Mode" msgstr "Режим тестирования" #. type: Title === #: documentation/content/en/articles/serial-uart/_index.adoc:408 #, no-wrap msgid "Bits, Baud and Symbols" msgstr "Биты, боды и символы" #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:412 msgid "" "Baud is a measurement of transmission speed in asynchronous communication. " "Due to advances in modem communication technology, this term is frequently " "misused when describing the data rates in newer devices." msgstr "" "Скорость передачи данных (Baud) — это единица измерения скорости передачи в " "асинхронной связи. Из-за развития технологий модемной связи этот термин " "часто ошибочно используют для описания скорости передачи данных в " "современных устройствах." #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:417 msgid "" "Traditionally, a Baud Rate represents the number of bits that are actually " "being sent over the media, not the amount of data that is actually moved " "from one DTE device to the other. The Baud count includes the overhead bits " "Start, Stop and Parity that are generated by the sending UART and removed by " "the receiving UART. This means that seven-bit words of data actually take " "10 bits to be completely transmitted. Therefore, a modem capable of moving " "300 bits per second from one place to another can normally only move 30 7-" "bit words if Parity is used and one Start and Stop bit are present." msgstr "" "Традиционно, скорость передачи (Baud Rate) представляет количество битов, " "фактически передаваемых по среде, а не объём данных, которые действительно " "перемещаются от одного устройства DTE к другому. Подсчет Baud включает " "служебные биты — Start, Stop и Parity, которые генерируются передающим UART " "и удаляются принимающим UART. Это означает, что 7-битные слова данных на " "самом деле занимают 10 бит для полной передачи. Следовательно, модем, " "способный передавать 300 бит в секунду, обычно может передавать только 30 7-" "битных слов, если используется Parity и присутствуют один бит Start и один " "бит Stop." #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:419 msgid "" "If 8-bit data words are used and Parity bits are also used, the data rate " "falls to 27.27 words per second, because it now takes 11 bits to send the " "eight-bit words, and the modem still only sends 300 bits per second." msgstr "" "Если используются 8-битные слова данных и биты чётности, скорость передачи " "данных снижается до 27,27 слов в секунду, так как теперь для передачи " "восьмибитных слов требуется 11 бит, а модем по-прежнему передаёт только 300 " "бит в секунду." #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:425 msgid "" "The formula for converting bytes per second into a baud rate and vice versa " "was simple until error-correcting modems came along. These modems receive " "the serial stream of bits from the UART in the host computer (even when " "internal modems are used the data is still frequently serialized) and " "converts the bits back into bytes. These bytes are then combined into " "packets and sent over the phone line using a Synchronous transmission " "method. This means that the Stop, Start, and Parity bits added by the UART " "in the DTE (the computer) were removed by the modem before transmission by " "the sending modem. When these bytes are received by the remote modem, the " "remote modem adds Start, Stop and Parity bits to the words, converts them to " "a serial format and then sends them to the receiving UART in the remote " "computer, who then strips the Start, Stop and Parity bits." msgstr "" "Формула преобразования байтов в секунду в бодовую скорость и наоборот была " "простой до появления модемов с коррекцией ошибок. Эти модемы принимают " "последовательный поток битов от UART в компьютере (даже внутренние модемы " "часто работают с последовательными данными) и преобразуют биты обратно в " "байты. Затем эти байты объединяются в пакеты и передаются по телефонной " "линии с использованием синхронного метода передачи. Это означает, что " "стоповые, стартовые и биты чётности, добавленные UART в DTE (компьютере), " "удаляются модемом перед передачей отправляющим модемом. Когда эти байты " "принимаются удалённым модемом, он добавляет стартовые, стоповые и биты " "чётности к словам, преобразует их в последовательный формат и отправляет на " "принимающий UART в удалённом компьютере, который затем удаляет стартовые, " "стоповые и биты чётности." #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:428 msgid "" "The reason all these extra conversions are done is so that the two modems " "can perform error correction, which means that the receiving modem is able " "to ask the sending modem to resend a block of data that was not received " "with the correct checksum. This checking is handled by the modems, and the " "DTE devices are usually unaware that the process is occurring." msgstr "" "Причина, по которой выполняются все эти дополнительные преобразования, " "заключается в том, чтобы два модема могли осуществлять коррекцию ошибок. Это " "означает, что принимающий модем может запросить у передающего модема " "повторную отправку блока данных, который был получен с некорректной " "контрольной суммой. Эта проверка обрабатывается модемами, и устройства DTE " "обычно не осознают, что этот процесс происходит." #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:431 msgid "" "By striping the Start, Stop and Parity bits, the additional bits of data " "that the two modems must share between themselves to perform error-" "correction are mostly concealed from the effective transmission rate seen by " "the sending and receiving DTE equipment. For example, if a modem sends ten " "7-bit words to another modem without including the Start, Stop and Parity " "bits, the sending modem will be able to add 30 bits of its own information " "that the receiving modem can use to do error-correction without impacting " "the transmission speed of the real data." msgstr "" "Удаляя стартовые, стоповые и биты чётности, дополнительные биты данных, " "которые два модема должны обмениваться между собой для выполнения коррекции " "ошибок, в основном скрываются от эффективной скорости передачи, наблюдаемой " "отправляющим и принимающим оборудованием DTE. Например, если модем " "отправляет десять 7-битных слов другому модему без включения стартовых, " "стоповых и битов чётности, отправляющий модем сможет добавить 30 бит своей " "собственной информации, которую принимающий модем может использовать для " "коррекции ошибок, не влияя на скорость передачи реальных данных." #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:435 msgid "" "The use of the term Baud is further confused by modems that perform " "compression. A single 8-bit word passed over the telephone line might " "represent a dozen words that were transmitted to the sending modem. The " "receiving modem will expand the data back to its original content and pass " "that data to the receiving DTE." msgstr "" "Использование термина \"Бод\" дополнительно осложняется модемами, " "выполняющими сжатие. Одно 8-битное слово, переданное по телефонной линии, " "может представлять собой дюжину слов, переданных на отправляющий модем. " "Принимающий модем развернёт данные обратно в их исходное содержимое и " "передаст эти данные принимающему DTE." #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:438 msgid "" "Modern modems also include buffers that allow the rate that bits move across " "the phone line (DCE to DCE) to be a different speed than the speed that the " "bits move between the DTE and DCE on both ends of the conversation. " "Normally the speed between the DTE and DCE is higher than the DCE to DCE " "speed because of the use of compression by the modems." msgstr "" "Современные модемы также включают буферы, которые позволяют скорости " "передачи битов по телефонной линии (DCE к DCE) отличаться от скорости " "передачи битов между DTE и DCE на обоих концах соединения. Обычно скорость " "между DTE и DCE выше, чем скорость между DCE и DCE, из-за использования " "сжатия модемами." #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:441 msgid "" "As the number of bits needed to describe a byte varied during the trip " "between the two machines plus the differing bits-per-seconds speeds that are " "used present on the DTE-DCE and DCE-DCE links, the usage of the term Baud to " "describe the overall communication speed causes problems and can " "misrepresent the true transmission speed. So Bits Per Second (bps) is the " "correct term to use to describe the transmission rate seen at the DCE to DCE " "interface and Baud or Bits Per Second are acceptable terms to use when a " "connection is made between two systems with a wired connection, or if a " "modem is in use that is not performing error-correction or compression." msgstr "" "Поскольку количество битов, необходимых для описания байта, менялось во " "время передачи между двумя машинами, а также из-за различающихся скоростей " "передачи в битах в секунду на линиях DTE-DCE и DCE-DCE, использование " "термина «Бод» для описания общей скорости связи вызывает проблемы и может " "искажать реальную скорость передачи. Таким образом, термин «Биты в " "секунду» (bps) является корректным для описания скорости передачи на " "интерфейсе DCE-DCE, а термины «Бод» или «Биты в секунду» допустимы, когда " "соединение устанавливается между двумя системами с проводным подключением " "или используется модем, не выполняющий коррекцию ошибок или сжатие." #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:445 msgid "" "Modern high speed modems (2400, 9600, 14,400, and 19,200bps) in reality " "still operate at or below 2400 baud, or more accurately, 2400 Symbols per " "second. High speed modem are able to encode more bits of data into each " "Symbol using a technique called Constellation Stuffing, which is why the " "effective bits per second rate of the modem is higher, but the modem " "continues to operate within the limited audio bandwidth that the telephone " "system provides. Modems operating at 28,800 and higher speeds have variable " "Symbol rates, but the technique is the same." msgstr "" "Современные высокоскоростные модемы (2400, 9600, 14,400 и 19,200 бит/с) на " "самом деле всё ещё работают на скорости 2400 бод или ниже, или, точнее, 2400 " "символов в секунду. Высокоскоростные модемы способны кодировать больше бит " "данных в каждый символ с использованием техники, называемой \"Заполнение " "созвездия (Constellation Stuffing)\", поэтому эффективная скорость передачи " "данных в битах в секунду у модема выше, но модем продолжает работать в " "ограниченной полосе пропускания звуковых частот, предоставляемой телефонной " "системой. Модемы, работающие на скоростях 28,800 и выше, имеют переменную " "скорость передачи символов, но техника остаётся той же." #. type: Title === #: documentation/content/en/articles/serial-uart/_index.adoc:446 #, no-wrap msgid "The IBM Personal Computer UART" msgstr "UART в IBM PC" #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:450 msgid "" "Starting with the original IBM Personal Computer, IBM selected the National " "Semiconductor INS8250 UART for use in the IBM PC Parallel/Serial Adapter. " "Subsequent generations of compatible computers from IBM and other vendors " "continued to use the INS8250 or improved versions of the National " "Semiconductor UART family." msgstr "" "Начиная с оригинального IBM Personal Computer, IBM выбрала UART INS8250 от " "National Semiconductor для использования в адаптере Parallel/Serial IBM PC. " "Последующие поколения совместимых компьютеров от IBM и других производителей " "продолжали использовать INS8250 или улучшенные версии UART из семейства " "National Semiconductor." #. type: Title ==== #: documentation/content/en/articles/serial-uart/_index.adoc:451 #, no-wrap msgid "National Semiconductor UART Family Tree" msgstr "Генеалогическое дерево National Semiconductor UART" #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:454 msgid "" "There have been several versions and subsequent generations of the INS8250 " "UART. Each major version is described below." msgstr "" "Существует несколько версий и последующих поколений UART INS8250. Основные " "версии описаны ниже." #. type: delimited block . 4 #: documentation/content/en/articles/serial-uart/_index.adoc:467 #, no-wrap msgid "" "INS8250 -> INS8250B\n" " \\\n" " \\\n" " \\-> INS8250A -> INS82C50A\n" " \\\n" " \\\n" " \\-> NS16450 -> NS16C450\n" " \\\n" " \\\n" " \\-> NS16550 -> NS16550A -> PC16550D\n" msgstr "" "INS8250 -> INS8250B\n" " \\\n" " \\\n" " \\-> INS8250A -> INS82C50A\n" " \\\n" " \\\n" " \\-> NS16450 -> NS16C450\n" " \\\n" " \\\n" " \\-> NS16550 -> NS16550A -> PC16550D\n" #. type: Labeled list #: documentation/content/en/articles/serial-uart/_index.adoc:469 #, no-wrap msgid "INS8250" msgstr "INS8250" #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:472 msgid "" "This part was used in the original IBM PC and IBM PC/XT. The original name " "for this part was the INS8250 ACE (Asynchronous Communications Element) and " "it is made from NMOS technology." msgstr "" "Эта часть использовалась в оригинальном IBM PC и IBM PC/XT. Первоначальное " "название этой части — INS8250 ACE (Asynchronous Communications Element), и " "она изготовлена по NMOS-технологии." #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:476 msgid "" "The 8250 uses eight I/O ports and has a one-byte send and a one-byte receive " "buffer. This original UART has several race conditions and other flaws. " "The original IBM BIOS includes code to work around these flaws, but this " "made the BIOS dependent on the flaws being present, so subsequent parts like " "the 8250A, 16450 or 16550 could not be used in the original IBM PC or IBM PC/" "XT." msgstr "" "8250 использует восемь портов ввода-вывода и имеет однобайтовый буфер " "передачи и однобайтовый буфер приема. Этот оригинальный UART имеет несколько " "состояний гонки и другие недостатки. Оригинальный BIOS IBM включает код для " "обхода этих недостатков, но это сделало BIOS зависимым от их наличия, " "поэтому последующие модели, такие как 8250A, 16450 или 16550, не могли быть " "использованы в оригинальном IBM PC или IBM PC/XT." #. type: Labeled list #: documentation/content/en/articles/serial-uart/_index.adoc:476 #, no-wrap msgid "INS8250-B" msgstr "INS8250-B" #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:479 msgid "" "This is the slower speed of the INS8250 made from NMOS technology. It " "contains the same problems as the original INS8250." msgstr "" "Это более медленная скорость INS8250, созданная по NMOS-технологии. Она " "имеет те же проблемы, что и оригинальный INS8250." #. type: Labeled list #: documentation/content/en/articles/serial-uart/_index.adoc:480 #, no-wrap msgid "INS8250A" msgstr "INS8250A" #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:484 msgid "" "An improved version of the INS8250 using XMOS technology with various " "functional flaws corrected. The INS8250A was used initially in PC clone " "computers by vendors who used \"clean\" BIOS designs. Due to the " "corrections in the chip, this part could not be used with a BIOS compatible " "with the INS8250 or INS8250B." msgstr "" "Улучшенная версия INS8250 с использованием технологии XMOS, в которой " "исправлены различные функциональные недостатки. INS8250A изначально " "использовалась в клонах ПК от производителей, применявших \"чистые\" проекты " "BIOS. Из-за исправлений в микросхеме этот чип не мог использоваться с BIOS, " "совместимой с INS8250 или INS8250B." #. type: Labeled list #: documentation/content/en/articles/serial-uart/_index.adoc:485 #, no-wrap msgid "INS82C50A" msgstr "INS82C50A" #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:487 msgid "" "This is a CMOS version (low power consumption) of the INS8250A and has " "similar functional characteristics." msgstr "" "Это CMOS-версия (с низким энергопотреблением) INS8250A и имеет схожие " "функциональные характеристики." #. type: Labeled list #: documentation/content/en/articles/serial-uart/_index.adoc:488 #, no-wrap msgid "NS16450" msgstr "NS16450" #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:491 msgid "" "Same as NS8250A with improvements so it can be used with faster CPU bus " "designs. IBM used this part in the IBM AT and updated the IBM BIOS to no " "longer rely on the bugs in the INS8250." msgstr "" "Так же, как NS8250A, но с улучшениями для работы с более быстрыми шинами " "CPU. IBM использовала этот компонент в IBM AT и обновила IBM BIOS, чтобы она " "больше не зависела от ошибок в INS8250." #. type: Labeled list #: documentation/content/en/articles/serial-uart/_index.adoc:492 #, no-wrap msgid "NS16C450" msgstr "NS16C450" #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:494 msgid "This is a CMOS version (low power consumption) of the NS16450." msgstr "Это версия NS16450 с технологией CMOS (низкое энергопотребление)." #. type: Labeled list #: documentation/content/en/articles/serial-uart/_index.adoc:495 #, no-wrap msgid "NS16550" msgstr "NS16550" #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:497 msgid "" "Same as NS16450 with a 16-byte send and receive buffer but the buffer design " "was flawed and could not be reliably be used." msgstr "" "То же, что и NS16450, с 16-байтовым буфером передачи и приема, но " "конструкция буфера была неудачной и не могла быть надёжно использована." #. type: Labeled list #: documentation/content/en/articles/serial-uart/_index.adoc:498 #, no-wrap msgid "NS16550A" msgstr "NS16550A" #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:501 msgid "" "Same as NS16550 with the buffer flaws corrected. The 16550A and its " "successors have become the most popular UART design in the PC industry, " "mainly due to its ability to reliably handle higher data rates on operating " "systems with sluggish interrupt response times." msgstr "" "То же, что и NS16550, но с исправленными недостатками буфера. 16550A и его " "преемники стали наиболее популярными UART-устройствами в индустрии ПК, в " "основном благодаря их способности надёжно работать на высоких скоростях " "передачи данных в операционных системах с медленным временем отклика " "прерываний." #. type: Labeled list #: documentation/content/en/articles/serial-uart/_index.adoc:502 #, no-wrap msgid "NS16C552" msgstr "NS16C552" #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:504 msgid "" "This component consists of two NS16C550A CMOS UARTs in a single package." msgstr "Этот компонент состоит из двух CMOS UART NS16C550A в одном корпусе." #. type: Labeled list #: documentation/content/en/articles/serial-uart/_index.adoc:505 #, no-wrap msgid "PC16550D" msgstr "PC16550D" #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:508 msgid "" "Same as NS16550A with subtle flaws corrected. This is revision D of the " "16550 family and is the latest design available from National Semiconductor." msgstr "" "Так же, как NS16550A, с исправленными незначительными недостатками. Это " "ревизия D семейства 16550 и последняя доступная версия от National " "Semiconductor." #. type: Title ==== #: documentation/content/en/articles/serial-uart/_index.adoc:509 #, no-wrap msgid "The NS16550AF and the PC16550D are the same thing" msgstr "NS16550AF и PC16550D — это одно и то же" #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:515 msgid "" "National reorganized their part numbering system a few years ago, and the " "NS16550AFN no longer exists by that name. (If you have a NS16550AFN, look " "at the date code on the part, which is a four digit number that usually " "starts with a nine. The first two digits of the number are the year, and " "the last two digits are the week in that year when the part was packaged. " "If you have a NS16550AFN, it is probably a few years old.)" msgstr "" "Компания National реорганизовала свою систему нумерации деталей несколько " "лет назад, и чип NS16550AFN больше не существует под этим названием. (Если у " "вас есть NS16550AFN, посмотрите на дату изготовления на корпусе — это " "четырёхзначное число, обычно начинающееся с девятки. Первые две цифры " "обозначают год, а последние две — неделю года, когда чип был упакован. Если " "у вас есть NS16550AFN, скорее всего, он уже довольно старый.)" #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:518 msgid "" "The new numbers are like PC16550DV, with minor differences in the suffix " "letters depending on the package material and its shape. (A description of " "the numbering system can be found below.)" msgstr "" "Новые номера выглядят как PC16550DV, с незначительными отличиями в " "суффиксных буквах в зависимости от материала корпуса и его формы. (Описание " "системы нумерации можно найти ниже.)" #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:520 msgid "" "It is important to understand that in some stores, you may pay $15(US) for a " "NS16550AFN made in 1990 and in the next bin are the new PC16550DN parts with " "minor fixes that National has made since the AFN part was in production, the " "PC16550DN was probably made in the past six months and it costs half (as low " "as $5(US) in volume) as much as the NS16550AFN because they are readily " "available." msgstr "" "Важно понимать, что в некоторых магазинах можно заплатить $15 (США) за " "микросхему NS16550AFN, выпущенную в 1990 году, а в соседнем ящике могут " "лежать новые PC16550DN с небольшими исправлениями, которые National внесла с " "момента выпуска AFN. PC16550DN, вероятно, произведены в последние полгода и " "стоят вдвое дешевле (от $5 (США) при оптовой покупке), чем NS16550AFN, " "поскольку они легко доступны." #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:522 msgid "" "As the supply of NS16550AFN chips continues to shrink, the price will " "probably continue to increase until more people discover and accept that the " "PC16550DN really has the same function as the old part number." msgstr "" "Поскольку поставки чипов NS16550AFN продолжают сокращаться, цена, вероятно, " "будет расти до тех пор, пока больше людей не узнают и не примут тот факт, " "что PC16550DN действительно выполняет ту же функцию, что и старый номер " "детали." #. type: Title ==== #: documentation/content/en/articles/serial-uart/_index.adoc:523 #, no-wrap msgid "National Semiconductor Part Numbering System" msgstr "Система нумерации компонентов National Semiconductor" #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:526 msgid "" "The older NS``__nnnnnrqp__`` part numbers are now of the format " "PC``__nnnnnrgp__``." msgstr "" "Старые номера деталей NS``__nnnnnrqp__`` теперь имеют формат " "PC``__nnnnnrgp__``." #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:528 msgid "" "The `_r_` is the revision field. The current revision of the 16550 from " "National Semiconductor is `D`." msgstr "" "`_r_` — это поле ревизии. Текущая ревизия 16550 от National Semiconductor — " "`D`." #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:530 msgid "The `_p_` is the package-type field. The types are:" msgstr "`_p_` — это поле типа пакета. Типы:" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:536 #, no-wrap msgid "\"F\"" msgstr "\"F\"" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:537 #, no-wrap msgid "QFP" msgstr "QFP" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:539 #, no-wrap msgid "(quad flat pack) L lead type" msgstr "(quad flat pack - квадратный плоский корпус) с L-образными выводами" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:540 #, no-wrap msgid "\"N\"" msgstr "\"N\"" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:541 #, no-wrap msgid "DIP" msgstr "DIP" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:543 #, no-wrap msgid "(dual inline package) through hole straight lead type" msgstr "(dual inline package — корпус с двусторонним расположением выводов) для сквозного монтажа с прямыми выводами" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:544 #, no-wrap msgid "\"V\"" msgstr "\"V\"" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:545 #, no-wrap msgid "LPCC" msgstr "LPCC" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:546 #, no-wrap msgid "(lead plastic chip carrier) J lead type" msgstr "(lead plastic chip carrier — пластиковый корпус) с J-образными выводами" #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:551 msgid "" "The _g_ is the product grade field. If an `I` precedes the package-type " "letter, it indicates an \"industrial\" grade part, which has higher specs " "than a standard part but not as high as Military Specification (Milspec) " "component. This is an optional field." msgstr "" "Поле _g_ обозначает класс изделия. Если перед буквой типа пакета стоит `I`, " "это указывает на «промышленный» класс детали, который имеет более высокие " "характеристики, чем стандартная деталь, но не такие высокие, как компонент " "военного назначения (Milspec). Это необязательное поле." #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:553 msgid "" "So what we used to call a NS16550AFN (DIP Package) is now called a PC16550DN " "or PC16550DIN." msgstr "" "То, что мы раньше называли NS16550AFN (DIP-корпус), теперь называется " "PC16550DN или PC16550DIN." #. type: Title === #: documentation/content/en/articles/serial-uart/_index.adoc:554 #, no-wrap msgid "Other Vendors and Similar UARTs" msgstr "Другие производители и аналогичные UART" #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:559 msgid "" "Over the years, the 8250, 8250A, 16450 and 16550 have been licensed or " "copied by other chip vendors. In the case of the 8250, 8250A and 16450, the " "exact circuit (the \"megacell\") was licensed to many vendors, including " "Western Digital and Intel. Other vendors reverse-engineered the part or " "produced emulations that had similar behavior." msgstr "" "На протяжении многих лет чипы 8250, 8250A, 16450 и 16550 лицензировались или " "копировались другими производителями. В случае с 8250, 8250A и 16450 точная " "схема (\"мегаячейка\") была лицензирована многими производителями, включая " "Western Digital и Intel. Другие производители проводили обратную разработку " "чипа или создавали эмуляции с аналогичным поведением." #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:563 msgid "" "In internal modems, the modem designer will frequently emulate the " "8250A/16450 with the modem microprocessor, and the emulated UART will " "frequently have a hidden buffer consisting of several hundred bytes. Due to " "the size of the buffer, these emulations can be as reliable as a 16550A in " "their ability to handle high speed data. However, most operating systems " "will still report that the UART is only a 8250A or 16450, and may not make " "effective use of the extra buffering present in the emulated UART unless " "special drivers are used." msgstr "" "Во внутренних модемах разработчик модема часто эмулирует 8250A/16450 с " "помощью микропроцессора модема, и эмулированный UART часто имеет скрытый " "буфер размером в несколько сотен байт. Благодаря размеру буфера, эти " "эмуляции могут быть такими же надёжными, как 16550A, в способности " "обрабатывать высокоскоростные данные. Однако большинство операционных систем " "по-прежнему сообщают, что UART является только 8250A или 16450, и могут не " "эффективно использовать дополнительную буферизацию, присутствующую в " "эмулированном UART, если не используются специальные драйверы." #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:565 msgid "" "Some modem makers are driven by market forces to abandon a design that has " "hundreds of bytes of buffer and instead use a 16550A UART so that the " "product will compare favorably in market comparisons even though the " "effective performance may be lowered by this action." msgstr "" "Некоторые производители модемов под давлением рыночных сил отказываются от " "конструкции с буфером в сотни байт и вместо этого используют UART 16550A, " "чтобы их продукция выглядела выигрышно в рыночных сравнениях, даже если это " "может снизить фактическую производительность." #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:568 msgid "" "A common misconception is that all parts with \"16550A\" written on them are " "identical in performance. There are differences, and in some cases, " "outright flaws in most of these 16550A clones." msgstr "" "Распространённое заблуждение заключается в том, что все микросхемы с " "маркировкой \"16550A\" одинаковы по производительности. Однако между ними " "существуют различия, а в некоторых клонах 16550A даже встречаются серьёзные " "недостатки." #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:572 msgid "" "When the NS16550 was developed, the National Semiconductor obtained several " "patents on the design and they also limited licensing, making it harder for " "other vendors to provide a chip with similar features. As a result of the " "patents, reverse-engineered designs and emulations had to avoid infringing " "the claims covered by the patents. Subsequently, these copies almost never " "perform exactly the same as the NS16550A or PC16550D, which are the parts " "most computer and modem makers want to buy but are sometimes unwilling to " "pay the price required to get the genuine part." msgstr "" "Когда компания National Semiconductor разработала NS16550, она получила " "несколько патентов на эту конструкцию и также ограничила лицензирование, что " "затруднило для других производителей выпуск чипов с аналогичными " "характеристиками. В результате патентов обратно спроектированные конструкции " "и эмуляции должны были избегать нарушения пунктов, охватываемых патентами. " "Впоследствии эти копии почти никогда не работают точно так же, как NS16550A " "или PC16550D, которые являются компонентами, наиболее востребованными " "производителями компьютеров и модемов, но иногда они не готовы платить цену, " "необходимую для получения оригинальных деталей." #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:577 msgid "" "Some of the differences in the clone 16550A parts are unimportant, while " "others can prevent the device from being used at all with a given operating " "system or driver. These differences may show up when using other drivers, " "or when particular combinations of events occur that were not well tested or " "considered in the Windows(R) driver. This is because most modem vendors and " "16550-clone makers use the Microsoft drivers from Windows(R) for Workgroups " "3.11 and the Microsoft(R) MS-DOS(R) utility as the primary tests for " "compatibility with the NS16550A. This over-simplistic criteria means that " "if a different operating system is used, problems could appear due to subtle " "differences between the clones and genuine components." msgstr "" "Некоторые различия в клонах микросхем 16550A несущественны, в то время как " "другие могут полностью препятствовать использованию устройства с " "определённой операционной системой или драйвером. Эти различия могут " "проявиться при использовании других драйверов или при возникновении " "определённых комбинаций событий, которые не были хорошо протестированы или " "учтены в драйвере Windows(R). Это происходит потому, что большинство " "производителей модемов и клонов 16550 используют драйверы Microsoft из " "Windows(R) for Workgroups 3.11 и утилиту Microsoft(R) MS-DOS(R) в качестве " "основных тестов на совместимость с NS16550A. Этот чрезмерно упрощенный " "критерий означает, что при использовании другой операционной системы могут " "возникнуть проблемы из-за тонких различий между клонами и оригинальными " "компонентами." #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:580 msgid "" "National Semiconductor has made available a program named COMTEST that " "performs compatibility tests independent of any OS drivers. It should be " "remembered that the purpose of this type of program is to demonstrate the " "flaws in the products of the competition, so the program will report major " "as well as extremely subtle differences in behavior in the part being tested." msgstr "" "National Semiconductor предоставила программу под названием COMTEST, которая " "выполняет тесты совместимости независимо от каких-либо драйверов ОС. Следует " "помнить, что цель такого типа программ — демонстрация недостатков в " "продуктах конкурентов, поэтому программа будет сообщать как о значительных, " "так и о крайне незначительных различиях в поведении тестируемого компонента." #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:583 msgid "" "In a series of tests performed by the author of this document in 1994, " "components made by National Semiconductor, TI, StarTech, and CMD as well as " "megacells and emulations embedded in internal modems were tested with " "COMTEST. A difference count for some of these components is listed below. " "Since these tests were performed in 1994, they may not reflect the current " "performance of the given product from a vendor." msgstr "" "В серии тестов, проведенных автором этого документа в 1994 году, компоненты " "производства National Semiconductor, TI, StarTech и CMD, а также мегаячейки " "и эмуляции, встроенные во внутренние модемы, были протестированы с помощью " "COMTEST. Ниже приведен счетчик различий для некоторых из этих компонентов. " "Поскольку эти тесты проводились в 1994 году, они могут не отражать текущую " "производительность данного продукта от поставщика." #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:586 msgid "" "It should be noted that COMTEST normally aborts when an excessive number or " "certain types of problems have been detected. As part of this testing, " "COMTEST was modified so that it would not abort no matter how many " "differences were encountered." msgstr "" "Следует отметить, что COMTEST обычно завершает работу при обнаружении " "чрезмерного количества или определённых типов проблем. В рамках этого " "тестирования COMTEST был изменён так, чтобы он не завершал работу независимо " "от количества обнаруженных различий." #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:591 #, no-wrap msgid "Vendor" msgstr "Поставщик" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:592 #, no-wrap msgid "Part Number" msgstr "Номер детали" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:594 #, no-wrap msgid "Errors (aka \"differences\" reported)" msgstr "Ошибки (также известные как \"различия\" в отчётах)" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:595 #: documentation/content/en/articles/serial-uart/_index.adoc:599 #: documentation/content/en/articles/serial-uart/_index.adoc:603 #, no-wrap msgid "National" msgstr "National" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:596 #, no-wrap msgid "(PC16550DV)" msgstr "(PC16550DV)" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:598 #: documentation/content/en/articles/serial-uart/_index.adoc:602 #: documentation/content/en/articles/serial-uart/_index.adoc:606 #, no-wrap msgid "0" msgstr "0" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:600 #, no-wrap msgid "(NS16550AFN)" msgstr "(NS16550AFN)" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:604 #, no-wrap msgid "(NS16C552V)" msgstr "(NS16C552V)" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:607 #, no-wrap msgid "TI" msgstr "TI" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:608 #, no-wrap msgid "(TL16550AFN)" msgstr "(TL16550AFN)" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:611 #, no-wrap msgid "CMD" msgstr "CMD" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:612 #, no-wrap msgid "(16C550PE)" msgstr "(16C550PE)" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:615 #, no-wrap msgid "StarTech" msgstr "StarTech" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:616 #, no-wrap msgid "(ST16C550J)" msgstr "(ST16C550J)" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:619 #, no-wrap msgid "Rockwell" msgstr "Rockwell" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:620 #, no-wrap msgid "Reference modem with internal 16550 or an emulation (RC144DPi/C3000-25)" msgstr "Стандартный модем с внутренним 16550 или его эмуляцией (RC144DPi/C3000-25)" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:622 #, no-wrap msgid "117" msgstr "117" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:623 #, no-wrap msgid "Sierra" msgstr "Sierra" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:624 #, no-wrap msgid "Modem with an internal 16550 (SC11951/SC11351)" msgstr "Модем с внутренним 16550 (SC11951/SC11351)" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:625 #, no-wrap msgid "91" msgstr "91" #. type: delimited block = 4 #: documentation/content/en/articles/serial-uart/_index.adoc:632 msgid "" "To date, the author of this document has not found any non-National parts " "that report zero differences using the COMTEST program. It should also be " "noted that National has had five versions of the 16550 over the years and " "the newest parts behave a bit differently than the classic NS16550AFN that " "is considered the benchmark for functionality. COMTEST appears to turn a " "blind eye to the differences within the National product line and reports no " "errors on the National parts (except for the original 16550) even when there " "are official erratas that describe bugs in the A, B and C revisions of the " "parts, so this bias in COMTEST must be taken into account." msgstr "" "На сегодняшний день автор данного документа не обнаружил ни одного не-" "National компонента, который бы показывал нулевые различия при использовании " "программы COMTEST. Также следует отметить, что у National было пять версий " "16550 за эти годы, и новейшие компоненты ведут себя несколько иначе, чем " "классический NS16550AFN, который считается эталоном функциональности. " "COMTEST, по-видимому, закрывает глаза на различия внутри линейки продуктов " "National и не сообщает об ошибках в компонентах National (за исключением " "оригинальной 16550), даже когда существуют официальные errata, описывающие " "ошибки в ревизиях A, B и C этих компонентов, поэтому эту предвзятость " "COMTEST необходимо учитывать." #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:639 msgid "" "It is important to understand that a simple count of differences from " "COMTEST does not reveal a lot about what differences are important and which " "are not. For example, about half of the differences reported in the two " "modems listed above that have internal UARTs were caused by the clone UARTs " "not supporting five- and six-bit character modes. The real 16550, 16450, " "and 8250 UARTs all support these modes and COMTEST checks the functionality " "of these modes so over fifty differences are reported. However, almost no " "modern modem supports five- or six-bit characters, particularly those with " "error-correction and compression capabilities. This means that the " "differences related to five- and six-bit character modes can be discounted." msgstr "" "Важно понимать, что простое подсчитывание различий с COMTEST не даёт полного " "представления о том, какие различия существенны, а какие нет. Например, " "около половины различий, обнаруженных в двух вышеупомянутых модемах с " "внутренними UART, были вызваны тем, что клоновые UART не поддерживают режимы " "пяти- и шестибитных символов. Настоящие UART 16550, 16450 и 8250 " "поддерживают эти режимы, и COMTEST проверяет их функциональность, поэтому " "фиксируется более пятидесяти различий. Однако почти ни один современный " "модем не поддерживает пяти- или шестибитные символы, особенно те, что " "обладают функциями коррекции ошибок и сжатия. Это означает, что различия, " "связанные с режимами пяти- и шестибитных символов, можно не учитывать." #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:643 msgid "" "Many of the differences COMTEST reports have to do with timing. In many of " "the clone designs, when the host reads from one port, the status bits in " "some other port may not update in the same amount of time (some faster, some " "slower) as a _real_ NS16550AFN and COMTEST looks for these differences. " "This means that the number of differences can be misleading in that one " "device may only have one or two differences but they are extremely serious, " "and some other device that updates the status registers faster or slower " "than the reference part (that would probably never affect the operation of a " "properly written driver) could have dozens of differences reported." msgstr "" "Многие различия, о которых сообщает COMTEST, связаны с временными " "характеристиками. Во многих клонированных конструкциях, когда хост читает из " "одного порта, статусные биты в другом порте могут обновляться с иной " "скоростью (быстрее или медленнее), чем у _настоящего_ NS16550AFN, и COMTEST " "выявляет эти различия. Это означает, что количество различий может вводить в " "заблуждение: одно устройство может иметь всего одно или два различия, но они " "крайне критичны, тогда как другое устройство, обновляющее статусные регистры " "быстрее или медленнее эталонной части (что, вероятно, никогда не повлияет на " "работу правильно написанного драйвера), может иметь десятки " "зарегистрированных различий." #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:645 msgid "" "COMTEST can be used as a screening tool to alert the administrator to the " "presence of potentially incompatible components that might cause problems or " "have to be handled as a special case." msgstr "" "COMTEST можно использовать в качестве инструмента проверки, чтобы " "предупредить администратора о наличии потенциально несовместимых " "компонентов, которые могут вызвать проблемы или потребуют особого подхода." #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:648 msgid "" "If you run COMTEST on a 16550 that is in a modem or a modem is attached to " "the serial port, you need to first issue a ATE0&W command to the modem so " "that the modem will not echo any of the test characters. If you forget to " "do this, COMTEST will report at least this one difference:" msgstr "" "Если вы запускаете COMTEST на 16550, который находится в модеме или к модему " "подключён последовательный порт, необходимо сначала отправить модему команду " "ATE0&W, чтобы модем не эхо-повторял ни один из тестовых символов. Если вы " "забудете это сделать, COMTEST сообщит как минимум об одном различии:" #. type: delimited block . 4 #: documentation/content/en/articles/serial-uart/_index.adoc:652 #, no-wrap msgid "Error (6)...Timeout interrupt failed: IIR = c1 LSR = 61\n" msgstr "Error (6)...Timeout interrupt failed: IIR = c1 LSR = 61\n" #. type: Title === #: documentation/content/en/articles/serial-uart/_index.adoc:654 #, no-wrap msgid "8250/16450/16550 Registers" msgstr "Регистры 8250/16450/16550" #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:660 msgid "" "The 8250/16450/16550 UART occupies eight contiguous I/O port addresses. In " "the IBM PC, there are two defined locations for these eight ports and they " "are known collectively as [.filename]#COM1# and [.filename]#COM2#. The " "makers of PC-clones and add-on cards have created two additional areas known " "as [.filename]#COM3# and [.filename]#COM4#, but these extra COM ports " "conflict with other hardware on some systems. The most common conflict is " "with video adapters that provide IBM 8514 emulation." msgstr "" "UART 8250/16450/16550 занимает восемь последовательных адресов портов ввода-" "вывода. В IBM PC определены два расположения для этих восьми портов, которые " "вместе известны как [.filename]#COM1# и [.filename]#COM2#. Производители PC-" "клонов и дополнительных карт создали два дополнительных области, известных " "как [.filename]#COM3# и [.filename]#COM4#, но эти дополнительные COM-порты " "конфликтуют с другим оборудованием на некоторых системах. Наиболее " "распространённый конфликт возникает с видеоадаптерами, обеспечивающими " "эмуляцию IBM 8514." #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:665 msgid "" "[.filename]#COM1# is located from 0x3f8 to 0x3ff and normally uses IRQ 4. [." "filename]#COM2# is located from 0x2f8 to 0x2ff and normally uses IRQ 3. [." "filename]#COM3# is located from 0x3e8 to 0x3ef and has no standardized IRQ. " "[.filename]#COM4# is located from 0x2e8 to 0x2ef and has no standardized IRQ." msgstr "" "[.filename]#COM1# находится в диапазоне от 0x3f8 до 0x3ff и обычно " "использует IRQ 4. [.filename]#COM2# находится в диапазоне от 0x2f8 до 0x2ff " "и обычно использует IRQ 3. [.filename]#COM3# находится в диапазоне от 0x3e8 " "до 0x3ef и не имеет стандартного IRQ. [.filename]#COM4# находится в " "диапазоне от 0x2e8 до 0x2ef и не имеет стандартного IRQ." #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:667 msgid "" "A description of the I/O ports of the 8250/16450/16550 UART is provided " "below." msgstr "Описание портов ввода-вывода UART 8250/16450/16550 представлено ниже." #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:672 #, no-wrap msgid "I/O Port" msgstr "Порт ввода/вывода" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:673 #, no-wrap msgid "Access Allowed" msgstr "Доступ Разрешен" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:676 #: documentation/content/en/articles/serial-uart/_index.adoc:684 #: documentation/content/en/articles/serial-uart/_index.adoc:692 #, no-wrap msgid "+0x00" msgstr "+0x00" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:677 #, no-wrap msgid "write (DLAB==0)" msgstr "запись (DLAB==0)" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:683 #, no-wrap msgid "" "Transmit Holding Register (THR).\n" "\n" "Information written to this port are treated as data words and will be transmitted by the UART." msgstr "" "Регистр передачи данных (THR).\n" "\n" "Информация, записанная в этот порт, обрабатывается как слова данных и " "передаётся через UART." #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:685 #, no-wrap msgid "read (DLAB==0)" msgstr "чтение (DLAB==0)" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:691 #, no-wrap msgid "" "Receive Buffer Register (RBR).\n" "\n" "Any data words received by the UART form the serial link are accessed by the host by reading this port." msgstr "" "Регистр буфера приема (RBR).\n" "\n" "Любые слова данных, полученные UART из последовательного соединения, доступны для чтения хостом через этот порт." #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:693 #: documentation/content/en/articles/serial-uart/_index.adoc:701 #, no-wrap msgid "write/read (DLAB==1)" msgstr "запись/чтение (DLAB==1)" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:699 #, no-wrap msgid "" "Divisor Latch LSB (DLL)\n" "\n" "This value will be divided from the master input clock (in the IBM PC, the master clock is 1.8432MHz) and the resulting clock will determine the baud rate of the UART. This register holds bits 0 thru 7 of the divisor." msgstr "" "Младший байт защелки делителя (DLL — Divisor Latch LSB)\n" "\n" "Это значение будет поделено от основного входного тактового сигнала (в IBM PC основной тактовый сигнал равен 1,8432 МГц), и полученный тактовый сигнал будет определять скорость передачи UART. Этот регистр содержит биты с 0 по 7 делителя." #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:700 #: documentation/content/en/articles/serial-uart/_index.adoc:708 #, no-wrap msgid "+0x01" msgstr "+0x01" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:707 #, no-wrap msgid "" "Divisor Latch MSB (DLH)\n" "\n" "This value will be divided from the master input clock (in the IBM PC, the master clock is 1.8432MHz) and the resulting clock will determine the baud rate of the UART. This register holds bits 8 thru 15 of the divisor." msgstr "" "Старший байт защелки делителя (DLH — Divisor Latch MSB)\n" "\n" "Это значение будет разделено от основного входного тактового сигнала (в IBM PC основной тактовый сигнал равен 1,8432 МГц), и полученный тактовый сигнал будет определять скорость передачи данных UART. Этот регистр содержит биты с 8 по 15 делителя." #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:709 #, no-wrap msgid "write/read (DLAB==0)" msgstr "запись/чтение (DLAB==0)" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:721 #, no-wrap msgid "" "Interrupt Enable Register (IER) +\n" "\n" "The 8250/16450/16550 UART classifies events into one of four categories. Each category can be configured to generate an interrupt when any of the events occurs. The 8250/16450/16550 UART generates a single external interrupt signal regardless of how many events in the enabled categories have occurred. It is up to the host processor to respond to the interrupt and then poll the enabled interrupt categories (usually all categories have interrupts enabled) to determine the true cause(s) of the interrupt. +\n" "Bit 7 -> Reserved, always 0. +\n" "Bit 6 -> Reserved, always 0. +\n" "Bit 5 -> Reserved, always 0. +\n" "Bit 4 -> Reserved, always 0. +\n" "Bit 3 -> Enable Modem Status Interrupt (EDSSI). Setting this bit to \"1\" allows the UART to generate an interrupt when a change occurs on one or more of the status lines. +\n" "Bit 2 -> Enable Receiver Line Status Interrupt (ELSI) Setting this bit to \"1\" causes the UART to generate an interrupt when the an error (or a BREAK signal) has been detected in the incoming data. +\n" "Bit 1 -> Enable Transmitter Holding Register Empty Interrupt (ETBEI) Setting this bit to \"1\" causes the UART to generate an interrupt when the UART has room for one or more additional characters that are to be transmitted. +\n" "Bit 0 -> Enable Received Data Available Interrupt (ERBFI) Setting this bit to \"1\" causes the UART to generate an interrupt when the UART has received enough characters to exceed the trigger level of the FIFO, or the FIFO timer has expired (stale data), or a single character has been received when the FIFO is disabled." msgstr "" "Регистр разрешения прерываний (IER) +\n" "\n" "UART 8250/16450/1655 классифицирует события на четыре категории. Каждая категория может быть настроена на генерацию прерывания при возникновении любого из событий. UART 8250/16450/16550 генерирует единый внешний сигнал прерывания независимо от того, сколько событий в разрешённых категориях произошло. Задача главного процессора — обработать прерывание и затем опросить разрешённые категории прерываний (обычно прерывания разрешены для всех категорий), чтобы определить истинную причину(ы) прерывания. +\n" "Бит 7 -> Зарезервирован, всегда 0. +\n" "Бит 6 -> Зарезервирован, всегда 0. +\n" "Бит 5 -> Зарезервирован, всегда 0. +\n" "Бит 4 -> Зарезервирован, всегда 0. +\n" "Бит 3 -> Разрешение прерывания по состоянию модема (EDSSI). Установка этого бита в \"1\" позволяет UART генерировать прерывание при изменении состояния одной или нескольких линий статуса. +\n" "Бит 2 -> Разрешение прерывания по состоянию линии приёмника (ELSI). Установка этого бита в \"1\" приводит к генерации прерывания UART при обнаружении ошибки (или сигнала BREAK) во входящих данных. +\n" "Бит 1 -> Разрешение прерывания по опустошению регистра передатчика (ETBEI). Установка этого бита в \"1\" приводит к генерации прерывания UART, когда в UART появляется место для одного или более дополнительных символов, предназначенных для передачи. +\n" "Бит 0 -> Разрешение прерывания по наличию принятых данных (ERBFI). Установка этого бита в \"1\" приводит к генерации прерывания UART, когда UART принял достаточное количество символов для превышения порога FIFO, или истекло время ожидания FIFO (устаревшие данные), или принят одиночный символ при отключённом FIFO." #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:722 #: documentation/content/en/articles/serial-uart/_index.adoc:741 #, no-wrap msgid "+0x02" msgstr "+0x02" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:723 #, no-wrap msgid "write" msgstr "запись" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:740 #, no-wrap msgid "" "FIFO Control Register (FCR) (This port does not exist on the 8250 and 16450 UART.) +\n" "Bit 7 -> Receiver Trigger Bit #1 +\n" "Bit 6 -> Receiver Trigger Bit #0 +\n" "\n" "These two bits control at what point the receiver is to generate an interrupt when the FIFO is active. +\n" "7 6 How many words are received before an interrupt is generated +\n" "0 0 1 +\n" "0 1 4 +\n" "1 0 8 +\n" "1 1 14 +\n" "Bit 5 -> Reserved, always 0. +\n" "Bit 4 -> Reserved, always 0. +\n" "Bit 3 -> DMA Mode Select. If Bit 0 is set to \"1\" (FIFOs enabled), setting this bit changes the operation of the -RXRDY and -TXRDY signals from Mode 0 to Mode 1. +\n" "Bit 2 -> Transmit FIFO Reset. When a \"1\" is written to this bit, the contents of the FIFO are discarded. Any word currently being transmitted will be sent intact. This function is useful in aborting transfers. +\n" "Bit 1 -> Receiver FIFO Reset. When a \"1\" is written to this bit, the contents of the FIFO are discarded. Any word currently being assembled in the shift register will be received intact. +\n" "Bit 0 -> 16550 FIFO Enable. When set, both the transmit and receive FIFOs are enabled. Any contents in the holding register, shift registers or FIFOs are lost when FIFOs are enabled or disabled. +" msgstr "" "Регистр управления FIFO (FCR — FIFO Control Register) (Этот порт отсутствует " "в UART 8250 и 16450.) +\n" "Бит 7 -> Бит триггера приемника #1 +\n" "Бит 6 -> Бит триггера приемника #0 +\n" "\n" "Эти два бита определяют, при каком количестве данных приемник должен " "генерировать прерывание, когда FIFO активен. +\n" "7 6 Количество слов перед генерацией прерывания +\n" "0 0 1 +\n" "0 1 4 +\n" "1 0 8 +\n" "1 1 14 +\n" "Бит 5 -> Зарезервирован, всегда 0. +\n" "Бит 4 -> Зарезервирован, всегда 0. +\n" "Бит 3 -> Выбор режима DMA. Если бит 0 установлен в \"1\" (FIFO включены), " "установка этого бита изменяет работу сигналов -RXRDY и -TXRDY с режима 0 на " "режим 1. +\n" "Бит 2 -> Сброс передающего FIFO. При записи \"1\" в этот бит содержимое FIFO " "очищается. Любое слово, которое передаётся в данный момент, будет отправлено " "полностью. Эта функция полезна для прерывания передачи. +\n" "Бит 1 -> Сброс приемного FIFO. При записи \"1\" в этот бит содержимое FIFO " "очищается. Любое слово, которое в данный момент собирается в сдвиговом " "регистре, будет принято полностью. +\n" "Бит 0 -> Включение FIFO 16550. При установке этого бита активируются как " "передающий, так и приемный FIFO. Любое содержимое в регистре хранения, " "сдвиговых регистрах или FIFO теряется при включении или отключении FIFO. +" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:742 #, no-wrap msgid "read" msgstr "чтение" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:758 #, no-wrap msgid "" "Interrupt Identification Register +\n" "Bit 7 -> FIFOs enabled. On the 8250/16450 UART, this bit is zero. +\n" "Bit 6 -> FIFOs enabled. On the 8250/16450 UART, this bit is zero. +\n" "Bit 5 -> Reserved, always 0. +\n" "Bit 4 -> Reserved, always 0. +\n" "Bit 3 -> Interrupt ID Bit #2. On the 8250/16450 UART, this bit is zero. +\n" "Bit 2 -> Interrupt ID Bit #1 +\n" "Bit 1 -> Interrupt ID Bit #0.These three bits combine to report the category of event that caused the interrupt that is in progress. These categories have priorities, so if multiple categories of events occur at the same time, the UART will report the more important events first and the host must resolve the events in the order they are reported. All events that caused the current interrupt must be resolved before any new interrupts will be generated. (This is a limitation of the PC architecture.) +\n" "2 1 0 Priority Description +\n" "0 1 1 First Received Error (OE, PE, BI, or FE) +\n" "0 1 0 Second Received Data Available +\n" "1 1 0 Second Trigger level identification (Stale data in receive buffer) +\n" "0 0 1 Third Transmitter has room for more words (THRE) +\n" "0 0 0 Fourth Modem Status Change (-CTS, -DSR, -RI, or -DCD) +\n" "Bit 0 -> Interrupt Pending Bit. If this bit is set to \"0\", then at least one interrupt is pending." msgstr "" "Регистр идентификации прерываний +\n" "Бит 7 -> FIFO включены. На UART 8250/16450 этот бит равен нулю. +\n" "Бит 6 -> FIFO включены. На UART 8250/16450 этот бит равен нулю. +\n" "Бит 5 -> Зарезервирован, всегда 0. +\n" "Бит 4 -> Зарезервирован, всегда 0. +\n" "Бит 3 -> Бит идентификатора прерывания №2. На UART 8250/16450 этот бит равен нулю. +\n" "Бит 2 -> Бит идентификатора прерывания №1 +\n" "Бит 1 -> Бит идентификатора прерывания №0.Эти три бита объединяются для указания категории события, вызвавшего текущее прерывание. Эти категории имеют приоритеты, поэтому, если несколько категорий событий происходят одновременно, UART сообщит о более важных событиях первыми, и хост должен обрабатывать события в порядке их поступления. Все события, вызвавшие текущее прерывание, должны быть обработаны до генерации новых прерываний. (Это ограничение архитектуры ПК.) +\n" "2 1 0 Приоритет Описание +\n" "0 1 1 Первый Принятая ошибка (OE, PE, BI или FE) +\n" "0 1 0 Второй Доступны принятые данные +\n" "1 1 0 Второй Идентификация уровня триггера (Устаревшие данные в буфере приема) +\n" "0 0 1 Третий Передатчик готов принять больше данных (THRE) +\n" "0 0 0 Четвертый Изменение состояния модема (-CTS, -DSR, -RI или -DCD) +\n" "Бит 0 -> Бит ожидания прерывания. Если этот бит установлен в \"0\", то как минимум одно прерывание ожидает обработки." #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:759 #, no-wrap msgid "+0x03" msgstr "+0x03" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:760 #: documentation/content/en/articles/serial-uart/_index.adoc:778 #: documentation/content/en/articles/serial-uart/_index.adoc:790 #: documentation/content/en/articles/serial-uart/_index.adoc:802 #: documentation/content/en/articles/serial-uart/_index.adoc:813 #, no-wrap msgid "write/read" msgstr "запись/чтение" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:776 #, no-wrap msgid "" "Line Control Register (LCR) +\n" "Bit 7 -> Divisor Latch Access Bit (DLAB). When set, access to the data transmit/receive register (THR/RBR) and the Interrupt Enable Register (IER) is disabled. Any access to these ports is now redirected to the Divisor Latch Registers. Setting this bit, loading the Divisor Registers, and clearing DLAB should be done with interrupts disabled. +\n" "Bit 6 -> Set Break. When set to \"1\", the transmitter begins to transmit continuous Spacing until this bit is set to \"0\". This overrides any bits of characters that are being transmitted. +\n" "Bit 5 -> Stick Parity. When parity is enabled, setting this bit causes parity to always be \"1\" or \"0\", based on the value of Bit 4.\n" "Bit 4 -> Even Parity Select (EPS). When parity is enabled and Bit 5 is \"0\", setting this bit causes even parity to be transmitted and expected. Otherwise, odd parity is used. +\n" "Bit 3 -> Parity Enable (PEN). When set to \"1\", a parity bit is inserted between the last bit of the data and the Stop Bit. The UART will also expect parity to be present in the received data. +\n" "Bit 2 -> Number of Stop Bits (STB). If set to \"1\" and using 5-bit data words, 1.5 Stop Bits are transmitted and expected in each data word. For 6, 7 and 8-bit data words, 2 Stop Bits are transmitted and expected. When this bit is set to \"0\", one Stop Bit is used on each data word. +\n" "Bit 1 -> Word Length Select Bit #1 (WLSB1) +\n" "Bit 0 -> Word Length Select Bit #0 (WLSB0) +\n" "Together these bits specify the number of bits in each data word. +\n" "1 0 Word Length +\n" "0 0 5 Data Bits +\n" "0 1 6 Data Bits +\n" "1 0 7 Data Bits +\n" "1 1 8 Data Bits +" msgstr "" "Регистр управления линией (LCR — Line Control Register) +\n" "Бит 7 -> Бит доступа к защелке делителя (DLAB). При установке доступ к " "регистру передачи/приема данных (THR/RBR) и регистру разрешения прерываний " "(IER) отключается. Любой доступ к этим портам перенаправляется к регистрам " "защелки делителя. Установка этого бита, загрузка регистров делителя и сброс " "DLAB должны выполняться при отключенных прерываниях. +\n" "Бит 6 -> Установка прерывания. При установке в \"1\" передатчик начинает " "передавать непрерывный интервал (Spacing), пока этот бит не будет сброшен в " "\"0\". Это переопределяет любые передаваемые биты символов. +\n" "Бит 5 -> Фиксированный бит чётности. При включенной проверке чётности " "установка этого бита приводит к тому, что бит чётности всегда будет \"1\" " "или \"0\" в зависимости от значения бита 4.\n" "Бит 4 -> Выбор чётности (EPS). При включенной проверке чётности и если бит 5 " "равен \"0\", установка этого бита приводит к использованию и ожиданию четной " "чётности. В противном случае используется нечетная чётность. +\n" "Бит 3 -> Разрешение проверки чётности (PEN). При установке в \"1\" бит " "чётности вставляется между последним битом данных и стоповым битом. UART " "также ожидает наличие бита чётности в принимаемых данных. +\n" "Бит 2 -> Количество стоповых битов (STB). Если установлен в \"1\" и " "используются 5-битные слова данных, передаётся и ожидается 1.5 стоповых бита " "в каждом слове данных. Для 6, 7 и 8-битных слов данных передаётся и " "ожидается 2 стоповых бита. Если этот бит сброшен в \"0\", используется один " "стоповый бит в каждом слове данных. +\n" "Бит 1 -> Бит выбора длины слова #1 (WLSB1) +\n" "Бит 0 -> Бит выбора длины слова #0 (WLSB0) +\n" "Вместе эти биты определяют количество битов в каждом слове данных. +\n" "1 0 Длина слова +\n" "0 0 5 бит данных +\n" "0 1 6 бит данных +\n" "1 0 7 бит данных +\n" "1 1 8 бит данных +" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:777 #, no-wrap msgid "+0x04" msgstr "+0x04" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:788 #, no-wrap msgid "" "Modem Control Register (MCR) +\n" "Bit 7 -> Reserved, always 0. +\n" "Bit 6 -> Reserved, always 0. +\n" "Bit 5 -> Reserved, always 0. +\n" "Bit 4 -> Loop-Back Enable. When set to \"1\", the UART transmitter and receiver are internally connected together to allow diagnostic operations. In addition, the UART modem control outputs are connected to the UART modem control inputs. CTS is connected to RTS, DTR is connected to DSR, OUT1 is connected to RI, and OUT 2 is connected to DCD. +\n" "Bit 3 -> OUT 2. An auxiliary output that the host processor may set high or low. In the IBM PC serial adapter (and most clones), OUT 2 is used to tri-state (disable) the interrupt signal from the 8250/16450/16550 UART. +\n" "Bit 2 -> OUT 1. An auxiliary output that the host processor may set high or low. This output is not used on the IBM PC serial adapter. +\n" "Bit 1 -> Request to Send (RTS). When set to \"1\", the output of the UART -RTS line is Low (Active). +\n" "Bit 0 -> Data Terminal Ready (DTR). When set to \"1\", the output of the UART -DTR line is Low (Active). +" msgstr "" "Регистр управления модемом (MCR — Modem Control Register) +\n" "Бит 7 -> Зарезервирован, всегда 0. +\n" "Бит 6 -> Зарезервирован, всегда 0. +\n" "Бит 5 -> Зарезервирован, всегда 0. +\n" "Бит 4 -> Режим петли (Loop-Back). При установке в \"1\" передатчик и приёмник UART соединяются внутри для диагностики. Также выходы управления модемом UART подключаются к его входам: CTS к RTS, DTR к DSR, OUT1 к RI, а OUT2 к DCD. +\n" "Бит 3 -> OUT2. Вспомогательный выход, который процессор может установить в высокий или низкий уровень. В адаптере IBM PC (и большинстве клонов) OUT2 используется для отключения сигнала прерывания от UART 8250/16450/16550. +\n" "Бит 2 -> OUT1. Вспомогательный выход, который процессор может установить в высокий или низкий уровень. На адаптере IBM PC не используется. +\n" "Бит 1 -> Запрос на передачу (RTS). При установке в \"1\" выход линии -RTS UART переходит в низкий уровень (активное состояние). +\n" "Бит 0 -> Готовность терминала данных (DTR). При установке в \"1\" выход линии -DTR UART переходит в низкий уровень (активное состояние). +" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:789 #, no-wrap msgid "+0x05" msgstr "+0x05" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:800 #, no-wrap msgid "" "Line Status Register (LSR) +\n" "Bit 7 -> Error in Receiver FIFO. On the 8250/16450 UART, this bit is zero. This bit is set to \"1\" when any of the bytes in the FIFO have one or more of the following error conditions: PE, FE, or BI. +\n" "Bit 6 -> Transmitter Empty (TEMT). When set to \"1\", there are no words remaining in the transmit FIFO or the transmit shift register. The transmitter is completely idle. +\n" "Bit 5 -> Transmitter Holding Register Empty (THRE). When set to \"1\", the FIFO (or holding register) now has room for at least one additional word to transmit. The transmitter may still be transmitting when this bit is set to \"1\". +\n" "Bit 4 -> Break Interrupt (BI). The receiver has detected a Break signal. +\n" "Bit 3 -> Framing Error (FE). A Start Bit was detected but the Stop Bit did not appear at the expected time. The received word is probably garbled. +\n" "Bit 2 -> Parity Error (PE). The parity bit was incorrect for the word received. +\n" "Bit 1 -> Overrun Error (OE). A new word was received and there was no room in the receive buffer. The newly-arrived word in the shift register is discarded. On 8250/16450 UARTs, the word in the holding register is discarded and the newly- arrived word is put in the holding register. +\n" "Bit 0 -> Data Ready (DR) One or more words are in the receive FIFO that the host may read. A word must be completely received and moved from the shift register into the FIFO (or holding register for 8250/16450 designs) before this bit is set." msgstr "" "Регистр состояния линии (LSR — Line Status Register) +\n" "Бит 7 -> Ошибка в FIFO приемника. На UART 8250/16450 этот бит равен нулю. " "Этот бит устанавливается в «1», когда любой из байтов в FIFO имеет одно или " "несколько из следующих условий ошибки: PE, FE или BI. +\n" "Бит 6 -> Передатчик пуст (TEMT). Когда установлен в «1», в FIFO передатчика " "или сдвиговом регистре передатчика не осталось слов. Передатчик полностью " "бездействует. +\n" "Бит 5 -> Регистр хранения передатчика пуст (THRE). Когда установлен в «1», в " "FIFO (или регистре хранения) теперь есть место для передачи как минимум " "одного дополнительного слова. Передатчик может все ещё передавать данные, " "когда этот бит установлен в «1». +\n" "Бит 4 -> Прерывание по Break (BI). Приемник обнаружил сигнал Break. +\n" "Бит 3 -> Ошибка кадрирования (FE). Обнаружен стартовый бит, но стоповый бит " "не появился в ожидаемое время. Принятое слово, вероятно, искажено. +\n" "Бит 2 -> Ошибка чётности (PE). Бит чётности для принятого слова был " "некорректен. +\n" "Бит 1 -> Ошибка переполнения (OE). Было получено новое слово, но в буфере " "приема не было места. Вновь поступившее слово в сдвиговом регистре " "отбрасывается. На UART 8250/16450 слово в регистре хранения отбрасывается, а " "вновь поступившее слово помещается в регистр хранения. +\n" "Бит 0 -> Данные готовы (DR). Одно или несколько слов находятся в FIFO " "приемника, которые хост может прочитать. Слово должно быть полностью принято " "и перемещено из сдвигового регистра в FIFO (или регистр хранения для 8250/" "16450) до того, как этот бит будет установлен." #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:801 #, no-wrap msgid "+0x06" msgstr "+0x06" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:811 #, no-wrap msgid "" "Modem Status Register (MSR) +\n" "Bit 7 -> Data Carrier Detect (DCD). Reflects the state of the DCD line on the UART. +\n" "Bit 6 -> Ring Indicator (RI). Reflects the state of the RI line on the UART. +\n" "Bit 5 -> Data Set Ready (DSR). Reflects the state of the DSR line on the UART. +\n" "Bit 4 -> Clear To Send (CTS). Reflects the state of the CTS line on the UART. +\n" "Bit 3 -> Delta Data Carrier Detect (DDCD). Set to \"1\" if the -DCD line has changed state one more time since the last time the MSR was read by the host. +\n" "Bit 2 -> Trailing Edge Ring Indicator (TERI). Set to \"1\" if the -RI line has had a low to high transition since the last time the MSR was read by the host. +\n" "Bit 1 -> Delta Data Set Ready (DDSR). Set to \"1\" if the -DSR line has changed state one more time since the last time the MSR was read by the host. +\n" "Bit 0 -> Delta Clear To Send (DCTS). Set to \"1\" if the -CTS line has changed state one more time since the last time the MSR was read by the host. +" msgstr "" "Регистр состояния модема (MSR — Modem Status Register) +\n" "Бит 7 -> Обнаружение несущей данных (DCD). Отражает состояние линии DCD на UART. +\n" "Бит 6 -> Индикатор вызова (RI). Отражает состояние линии RI на UART. +\n" "Бит 5 -> Готовность передатчика данных (DSR). Отражает состояние линии DSR на UART. +\n" "Бит 4 -> Готовность к приёму (CTS). Отражает состояние линии CTS на UART. +\n" "Бит 3 -> Изменение состояния обнаружения несущей данных (DDCD). Устанавливается в \"1\", если линия -DCD изменила состояние ещё раз с момента последнего чтения MSR хостом. +\n" "Бит 2 -> Фронт сигнала вызова (TERI). Устанавливается в \"1\", если линия -RI перешла из низкого уровня в высокий с момента последнего чтения MSR хостом. +\n" "Бит 1 -> Изменение состояния готовности передатчика данных (DDSR). Устанавливается в \"1\", если линия -DSR изменила состояние ещё раз с момента последнего чтения MSR хостом. +\n" "Бит 0 -> Изменение состояния готовности к приёму (DCTS). Устанавливается в \"1\", если линия -CTS изменила состояние ещё раз с момента последнего чтения MSR хостом. +" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:812 #, no-wrap msgid "+0x07" msgstr "+0x07" #. type: Table #: documentation/content/en/articles/serial-uart/_index.adoc:814 #, no-wrap msgid "Scratch Register (SCR). This register performs no function in the UART. Any value can be written by the host to this location and read by the host later on." msgstr "Регистр Scratch (SCR — Scratch Register). Этот регистр не выполняет никакой функции в UART. Хост может записать любое значение в это место и позднее считать его." #. type: Title === #: documentation/content/en/articles/serial-uart/_index.adoc:816 #, no-wrap msgid "Beyond the 16550A UART" msgstr "За пределами UART 16550A" #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:821 msgid "" "Although National Semiconductor has not offered any components compatible " "with the 16550 that provide additional features, various other vendors " "have. Some of these components are described below. It should be " "understood that to effectively utilize these improvements, drivers may have " "to be provided by the chip vendor since most of the popular operating " "systems do not support features beyond those provided by the 16550." msgstr "" "Хотя National Semiconductor не предлагала никаких компонентов, совместимых с " "16550 и предоставляющих дополнительные функции, другие производители сделали " "это. Некоторые из этих компонентов описаны ниже. Следует понимать, что для " "эффективного использования этих улучшений могут потребоваться драйверы от " "производителя чипа, поскольку большинство популярных операционных систем не " "поддерживают функции, выходящие за рамки возможностей 16550." #. type: Labeled list #: documentation/content/en/articles/serial-uart/_index.adoc:822 #, no-wrap msgid "ST16650" msgstr "ST16650" #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:825 msgid "" "By default this part is similar to the NS16550A, but an extended 32-byte " "send and receive buffer can be optionally enabled. Made by StarTech." msgstr "" "По умолчанию эта часть аналогична NS16550A, но дополнительно можно включить " "расширенный 32-байтовый буфер отправки и приёма. Производитель — StarTech." #. type: Labeled list #: documentation/content/en/articles/serial-uart/_index.adoc:826 #, no-wrap msgid "TIL16660" msgstr "TIL16660" #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:829 msgid "" "By default this part behaves similar to the NS16550A, but an extended 64-" "byte send and receive buffer can be optionally enabled. Made by Texas " "Instruments." msgstr "" "По умолчанию эта часть ведёт себя аналогично NS16550A, но дополнительно " "может быть включён расширенный 64-байтный буфер передачи и приёма. " "Производится Texas Instruments." #. type: Labeled list #: documentation/content/en/articles/serial-uart/_index.adoc:830 #, no-wrap msgid "Hayes ESP" msgstr "Hayes ESP" #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:833 msgid "" "This proprietary plug-in card contains a 2048-byte send and receive buffer, " "and supports data rates to 230.4Kbit/sec. Made by Hayes." msgstr "" "Эта проприетарная внешняя карта содержит буфер передачи и приема размером " "2048 байт и поддерживает скорость передачи данных до 230,4 Кбит/с. " "Произведено компанией Hayes." #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:838 msgid "" "In addition to these \"dumb\" UARTs, many vendors produce intelligent serial " "communication boards. This type of design usually provides a microprocessor " "that interfaces with several UARTs, processes and buffers the data, and then " "alerts the main PC processor when necessary. As the UARTs are not directly " "accessed by the PC processor in this type of communication system, it is not " "necessary for the vendor to use UARTs that are compatible with the 8250, " "16450, or the 16550 UART. This leaves the designer free to components that " "may have better performance characteristics." msgstr "" "В дополнение к этим \"простым\" UART многие производители выпускают " "интеллектуальные платы для последовательной связи. Такой тип конструкции " "обычно включает микропроцессор, который взаимодействует с несколькими UART, " "обрабатывает и буферизует данные, а затем при необходимости уведомляет " "основной процессор ПК. Поскольку в такой системе связи UART не доступны " "напрямую процессору ПК, производителю не обязательно использовать UART, " "совместимые с 8250, 16450 или 16550. Это даёт разработчику свободу выбора " "компонентов с лучшими характеристиками производительности." #. type: Title == #: documentation/content/en/articles/serial-uart/_index.adoc:840 #, no-wrap msgid "Configuring the [.filename]#sio# driver" msgstr "Настройка драйвера [.filename]#sio#" #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:845 msgid "" "The [.filename]#sio# driver provides support for NS8250-, NS16450-, NS16550 " "and NS16550A-based EIA RS-232C (CCITT V.24) communications interfaces. " "Several multiport cards are supported as well. See the man:sio[4] manual " "page for detailed technical documentation." msgstr "" "Драйвер [.filename]#sio# обеспечивает поддержку интерфейсов связи EIA " "RS-232C (CCITT V.24) на основе NS8250, NS16450, NS16550 и NS16550A. Также " "поддерживаются несколько многопортовых карт. Подробную техническую " "документацию смотрите на man:sio[4]." #. type: Title === #: documentation/content/en/articles/serial-uart/_index.adoc:846 #, no-wrap msgid "Digi International (DigiBoard) PC/8" msgstr "Digi International (DigiBoard) PC/8" #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:849 msgid "_Contributed by `{awebster}`. 26 August 1995._" msgstr "_Предоставлено `{awebster}`. 26 августа 1995._" #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:853 msgid "" "Here is a config snippet from a machine with a Digi International PC/8 with " "16550. It has 8 modems connected to these 8 lines, and they work just " "great. Do not forget to add `options COM_MULTIPORT` or it will not work " "very well!" msgstr "" "Вот фрагмент конфигурации с машины, на которой установлена плата Digi " "International PC/8 с чипом 16550. К ней подключено 8 модемов, работающих на " "этих 8 линиях, и они отлично функционируют. Не забудьте добавить `options " "COM_MULTIPORT`, иначе работа будет нестабильной!" #. type: delimited block . 4 #: documentation/content/en/articles/serial-uart/_index.adoc:864 #, no-wrap msgid "" "device sio4 at isa? port 0x100 flags 0xb05\n" "device sio5 at isa? port 0x108 flags 0xb05\n" "device sio6 at isa? port 0x110 flags 0xb05\n" "device sio7 at isa? port 0x118 flags 0xb05\n" "device sio8 at isa? port 0x120 flags 0xb05\n" "device sio9 at isa? port 0x128 flags 0xb05\n" "device sio10 at isa? port 0x130 flags 0xb05\n" "device sio11 at isa? port 0x138 flags 0xb05 irq 9\n" msgstr "" "device sio4 at isa? port 0x100 flags 0xb05\n" "device sio5 at isa? port 0x108 flags 0xb05\n" "device sio6 at isa? port 0x110 flags 0xb05\n" "device sio7 at isa? port 0x118 flags 0xb05\n" "device sio8 at isa? port 0x120 flags 0xb05\n" "device sio9 at isa? port 0x128 flags 0xb05\n" "device sio10 at isa? port 0x130 flags 0xb05\n" "device sio11 at isa? port 0x138 flags 0xb05 irq 9\n" #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:867 msgid "" "The trick in setting this up is that the MSB of the flags represent the last " "SIO port, in this case 11 so flags are 0xb05." msgstr "" "Хитрость настройки заключается в том, что старший бит флагов представляет " "последний порт SIO, в данном случае 11, поэтому флаги равны 0xb05." #. type: Title === #: documentation/content/en/articles/serial-uart/_index.adoc:868 #, no-wrap msgid "Boca 16" msgstr "Boca 16" #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:871 msgid "_Contributed by `{whiteside}`. 26 August 1995._" msgstr "_Предоставлено `{whiteside}`. 26 августа 1995._" #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:873 msgid "" "The procedures to make a Boca 16 port board with FreeBSD are pretty " "straightforward, but you will need a couple things to make it work:" msgstr "" "Процедуры по настройке платы Boca с 16 портами в FreeBSD довольно просты, но " "вам понадобится несколько вещей для успешной работы:" #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:875 msgid "" "You either need the kernel sources installed so you can recompile the " "necessary options or you will need someone else to compile it for you. The " "2.0.5 default kernel does _not_ come with multiport support enabled and you " "will need to add a device entry for each port anyways." msgstr "" "Вам необходимо либо установить исходные коды ядра, чтобы перекомпилировать " "нужные опции, либо найти кого-то, кто сделает это за вас. Стандартное ядро " "версии 2.0.5 _не_ включает поддержку нескольких портов, и в любом случае вам " "потребуется добавить запись устройства для каждого порта." #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:876 msgid "" "Two, you will need to know the interrupt and IO setting for your Boca Board " "so you can set these options properly in the kernel." msgstr "" "Два, вам нужно знать прерывание и настройку ввода-вывода для вашей платы " "Boca, чтобы правильно установить эти параметры в ядре." #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:880 msgid "" "One important note - the actual UART chips for the Boca 16 are in the " "connector box, not on the internal board itself. So if you have it " "unplugged, probes of those ports will fail. I have never tested booting " "with the box unplugged and plugging it back in, and I suggest you do not " "either." msgstr "" "Важное замечание — реальные микросхемы UART для Boca 16 находятся в " "соединительной коробке, а не на внутренней плате. Поэтому, если она " "отключена, попытки проверить эти порты завершатся неудачей. Я никогда не " "проверял загрузку с отключённой коробкой и последующим её подключением, и не " "рекомендую вам этого делать." #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:883 msgid "" "If you do not already have a custom kernel configuration file set up, refer " "to extref:{handbook}kernelconfig[Kernel Configuration, kernelconfig] chapter " "of the FreeBSD Handbook for general procedures. The following are the " "specifics for the Boca 16 board and assume you are using the kernel name " "MYKERNEL and editing with vi." msgstr "" "Если у вас ещё нет настроенного файла конфигурации пользовательского ядра, " "обратитесь к разделу extref:{handbook}kernelconfig[Конфигурация ядра, " "kernelconfig] в руководстве FreeBSD для получения общих инструкций. Ниже " "приведены конкретные настройки для платы Boca 16, предполагается, что вы " "используете ядро с именем MYKERNEL и редактируете его с помощью vi." #. type: delimited block = 4 #: documentation/content/en/articles/serial-uart/_index.adoc:887 msgid "Add the line" msgstr "Добавьте строку" #. type: delimited block . 4 #: documentation/content/en/articles/serial-uart/_index.adoc:891 #, no-wrap msgid "options COM_MULTIPORT\n" msgstr "options COM_MULTIPORT\n" #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:893 msgid "to the config file." msgstr "в конфигурационный файл." #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:894 msgid "" "Where the current `device sio__n__` lines are, you will need to add 16 more " "devices. The following example is for a Boca Board with an interrupt of 3, " "and a base IO address 100h. The IO address for Each port is +8 hexadecimal " "from the previous port, thus the 100h, 108h, 110h... addresses." msgstr "" "Где находятся текущие строки `device sio__n__`, вам нужно добавить ещё 16 " "устройств. В следующем примере показана плата Boca Board с прерыванием 3 и " "базовым адресом ввода-вывода 100h. Адрес ввода-вывода для каждого порта " "увеличивается на 8 в шестнадцатеричной системе относительно предыдущего " "порта, поэтому адреса будут 100h, 108h, 110h..." #. type: delimited block . 4 #: documentation/content/en/articles/serial-uart/_index.adoc:904 #, no-wrap msgid "" "device sio1 at isa? port 0x100 flags 0x1005\n" "device sio2 at isa? port 0x108 flags 0x1005\n" "device sio3 at isa? port 0x110 flags 0x1005\n" "device sio4 at isa? port 0x118 flags 0x1005\n" "...\n" "device sio15 at isa? port 0x170 flags 0x1005\n" "device sio16 at isa? port 0x178 flags 0x1005 irq 3\n" msgstr "" "device sio1 at isa? port 0x100 flags 0x1005\n" "device sio2 at isa? port 0x108 flags 0x1005\n" "device sio3 at isa? port 0x110 flags 0x1005\n" "device sio4 at isa? port 0x118 flags 0x1005\n" "...\n" "device sio15 at isa? port 0x170 flags 0x1005\n" "device sio16 at isa? port 0x178 flags 0x1005 irq 3\n" #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:909 msgid "" "The flags entry _must_ be changed from this example unless you are using the " "exact same sio assignments. Flags are set according to 0x``__MYY__`` where " "_M_ indicates the minor number of the master port (the last port on a Boca " "16) and _YY_ indicates if FIFO is enabled or disabled(enabled), IRQ sharing " "is used(yes) and if there is an AST/4 compatible IRQ control register(no). " "In this example," msgstr "" "Запись flags _обязательно_ должна быть изменена по сравнению с этим " "примером, если вы не используете точно такие же назначения sio. Флаги " "устанавливаются в соответствии с 0x``__MYY__``, где _M_ обозначает младший " "номер главного порта (последний порт на Boca 16), а _YY_ указывает, включен " "или выключен FIFO (включен), используется ли разделение IRQ (да) и есть ли " "регистр управления IRQ, совместимый с AST/4 (нет). В этом примере," #. type: delimited block . 4 #: documentation/content/en/articles/serial-uart/_index.adoc:914 #, no-wrap msgid "" " flags\n" "\t 0x1005\n" msgstr "" " flags\n" "\t 0x1005\n" #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:918 msgid "" "indicates that the master port is sio16. If I added another board and " "assigned sio17 through sio28, the flags for all 16 ports on _that_ board " "would be 0x1C05, where 1C indicates the minor number of the master port. Do " "not change the 05 setting." msgstr "" "указывает, что основной порт - sio16. Если добавить другую плату и назначить " "порты с sio17 по sio28, флаги для всех 16 портов на _этой_ плате будут " "0x1C05, где 1C обозначает минорный номер основного порта. Не изменяйте " "значение 05." #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:919 msgid "" "Save and complete the kernel configuration, recompile, install and reboot. " "Presuming you have successfully installed the recompiled kernel and have it " "set to the correct address and IRQ, your boot message should indicate the " "successful probe of the Boca ports as follows: (obviously the sio numbers, " "IO and IRQ could be different)" msgstr "" "Сохраните и завершите конфигурацию ядра, перекомпилируйте, установите и " "перезагрузитесь. Предполагая, что вы успешно установили перекомпилированное " "ядро и настроили правильный адрес и IRQ, сообщение при загрузке должно " "указывать на успешное обнаружение портов Boca следующим образом: (очевидно, " "номера sio, IO и IRQ могут отличаться)" #. type: delimited block . 4 #: documentation/content/en/articles/serial-uart/_index.adoc:954 #, no-wrap msgid "" "sio1 at 0x100-0x107 flags 0x1005 on isa\n" "sio1: type 16550A (multiport)\n" "sio2 at 0x108-0x10f flags 0x1005 on isa\n" "sio2: type 16550A (multiport)\n" "sio3 at 0x110-0x117 flags 0x1005 on isa\n" "sio3: type 16550A (multiport)\n" "sio4 at 0x118-0x11f flags 0x1005 on isa\n" "sio4: type 16550A (multiport)\n" "sio5 at 0x120-0x127 flags 0x1005 on isa\n" "sio5: type 16550A (multiport)\n" "sio6 at 0x128-0x12f flags 0x1005 on isa\n" "sio6: type 16550A (multiport)\n" "sio7 at 0x130-0x137 flags 0x1005 on isa\n" "sio7: type 16550A (multiport)\n" "sio8 at 0x138-0x13f flags 0x1005 on isa\n" "sio8: type 16550A (multiport)\n" "sio9 at 0x140-0x147 flags 0x1005 on isa\n" "sio9: type 16550A (multiport)\n" "sio10 at 0x148-0x14f flags 0x1005 on isa\n" "sio10: type 16550A (multiport)\n" "sio11 at 0x150-0x157 flags 0x1005 on isa\n" "sio11: type 16550A (multiport)\n" "sio12 at 0x158-0x15f flags 0x1005 on isa\n" "sio12: type 16550A (multiport)\n" "sio13 at 0x160-0x167 flags 0x1005 on isa\n" "sio13: type 16550A (multiport)\n" "sio14 at 0x168-0x16f flags 0x1005 on isa\n" "sio14: type 16550A (multiport)\n" "sio15 at 0x170-0x177 flags 0x1005 on isa\n" "sio15: type 16550A (multiport)\n" "sio16 at 0x178-0x17f irq 3 flags 0x1005 on isa\n" "sio16: type 16550A (multiport master)\n" msgstr "" "sio1 at 0x100-0x107 flags 0x1005 on isa\n" "sio1: type 16550A (multiport)\n" "sio2 at 0x108-0x10f flags 0x1005 on isa\n" "sio2: type 16550A (multiport)\n" "sio3 at 0x110-0x117 flags 0x1005 on isa\n" "sio3: type 16550A (multiport)\n" "sio4 at 0x118-0x11f flags 0x1005 on isa\n" "sio4: type 16550A (multiport)\n" "sio5 at 0x120-0x127 flags 0x1005 on isa\n" "sio5: type 16550A (multiport)\n" "sio6 at 0x128-0x12f flags 0x1005 on isa\n" "sio6: type 16550A (multiport)\n" "sio7 at 0x130-0x137 flags 0x1005 on isa\n" "sio7: type 16550A (multiport)\n" "sio8 at 0x138-0x13f flags 0x1005 on isa\n" "sio8: type 16550A (multiport)\n" "sio9 at 0x140-0x147 flags 0x1005 on isa\n" "sio9: type 16550A (multiport)\n" "sio10 at 0x148-0x14f flags 0x1005 on isa\n" "sio10: type 16550A (multiport)\n" "sio11 at 0x150-0x157 flags 0x1005 on isa\n" "sio11: type 16550A (multiport)\n" "sio12 at 0x158-0x15f flags 0x1005 on isa\n" "sio12: type 16550A (multiport)\n" "sio13 at 0x160-0x167 flags 0x1005 on isa\n" "sio13: type 16550A (multiport)\n" "sio14 at 0x168-0x16f flags 0x1005 on isa\n" "sio14: type 16550A (multiport)\n" "sio15 at 0x170-0x177 flags 0x1005 on isa\n" "sio15: type 16550A (multiport)\n" "sio16 at 0x178-0x17f irq 3 flags 0x1005 on isa\n" "sio16: type 16550A (multiport master)\n" #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:957 msgid "If the messages go by too fast to see," msgstr "Если сообщения проходят слишком быстро, чтобы их увидеть," #. type: delimited block . 4 #: documentation/content/en/articles/serial-uart/_index.adoc:961 #, no-wrap msgid "# dmesg | more\n" msgstr "# dmesg | more\n" #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:963 msgid "will show you the boot messages." msgstr "покажет вам сообщения загрузки." #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:964 msgid "" "Next, appropriate entries in [.filename]#/dev# for the devices must be made " "using the [.filename]#/dev/MAKEDEV# script. This step can be omitted if you " "are running FreeBSD 5.X with a kernel that has man:devfs[5] support compiled " "in." msgstr "" "Далее необходимо создать соответствующие записи в [.filename]#/dev# для " "устройств с помощью скрипта [.filename]#/dev/MAKEDEV#. Этот шаг можно " "пропустить, если вы используете FreeBSD 5.X с ядром, в котором включена " "поддержка man:devfs[5]." #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:966 msgid "" "If you do need to create the [.filename]#/dev# entries, run the following as " "`root`:" msgstr "" "Если вам необходимо создать записи в [.filename]#/dev#, выполните следующую " "команду от имени `root`:" #. type: delimited block . 4 #: documentation/content/en/articles/serial-uart/_index.adoc:972 #, no-wrap msgid "" "# cd /dev\n" "# ./MAKEDEV tty1\n" "# ./MAKEDEV cua1\n" msgstr "" "# cd /dev\n" "# ./MAKEDEV tty1\n" "# ./MAKEDEV cua1\n" #. type: delimited block . 4 #: documentation/content/en/articles/serial-uart/_index.adoc:976 #, no-wrap msgid "" "(everything in between)\n" "# ./MAKEDEV ttyg\n" "# ./MAKEDEV cuag\n" msgstr "" "(everything in between)\n" "# ./MAKEDEV ttyg\n" "# ./MAKEDEV cuag\n" #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:979 msgid "" "If you do not want or need call-out devices for some reason, you can " "dispense with making the [.filename]#cua*# devices." msgstr "" "Если по какой-то причине вам не нужны или не требуются устройства исходящих " "соединений, вы можете обойтись без создания устройств [.filename]#cua*#." #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:980 msgid "" "If you want a quick and sloppy way to make sure the devices are working, you " "can simply plug a modem into each port and (as root)" msgstr "" "Если вам нужен быстрый и небрежный способ убедиться, что устройства " "работают, вы можете просто подключить модем к каждому порту и (как root)" #. type: delimited block . 4 #: documentation/content/en/articles/serial-uart/_index.adoc:984 #, no-wrap msgid "# echo at > ttyd*\n" msgstr "# echo at > ttyd*\n" #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:986 msgid "" "for each device you have made. You _should_ see the RX lights flash for each " "working port." msgstr "" "для каждого устройства, которое вы создали. Вы _должны_ увидеть, как мигают " "индикаторы RX для каждого рабочего порта." #. type: Title === #: documentation/content/en/articles/serial-uart/_index.adoc:988 #, no-wrap msgid "Support for Cheap Multi-UART Cards" msgstr "Поддержка дешёвых многоканальных UART-карт" #. type: delimited block = 4 #: documentation/content/en/articles/serial-uart/_index.adoc:991 msgid "" "_Contributed by Helge Oldach_ mailto:hmo@sep.hamburg.com[hmo@sep.hamburg." "com], September 1999" msgstr "" "_Предоставлено Хельге Ольдахом_ mailto:hmo@sep.hamburg.com[hmo@sep.hamburg." "com], сентябрь 1999 года" #. type: delimited block = 4 #: documentation/content/en/articles/serial-uart/_index.adoc:993 msgid "" "Ever wondered about FreeBSD support for your 20$ multi-I/O card with two (or " "more) COM ports, sharing IRQs? Here is how:" msgstr "" "Вы когда-нибудь задумывались о поддержке FreeBSD вашей 20-долларовой " "многофункциональной карты с двумя (или более) COM-портами, разделяющими IRQ? " "Вот как это сделать:" #. type: delimited block = 4 #: documentation/content/en/articles/serial-uart/_index.adoc:997 msgid "" "Usually the only option to support these kind of boards is to use a distinct " "IRQ for each port. For example, if your CPU board has an on-board [." "filename]#COM1# port (aka [.filename]#sio0#-I/O address 0x3F8 and IRQ 4) and " "you have an extension board with two UARTs, you will commonly need to " "configure them as [.filename]#COM2# (aka [.filename]#sio1#-I/O address 0x2F8 " "and IRQ 3), and the third port (aka [.filename]#sio2#) as I/O 0x3E8 and IRQ " "5. Obviously this is a waste of IRQ resources, as it should be basically " "possible to run both extension board ports using a single IRQ with the " "`COM_MULTIPORT` configuration described in the previous sections." msgstr "" "Обычно единственный способ поддержки таких плат — использование отдельного " "IRQ для каждого порта. Например, если ваша материнская плата имеет " "встроенный порт [.filename]#COM1# (он же [.filename]#sio0# — адрес ввода-" "вывода 0x3F8 и IRQ 4), а у вас есть расширительная плата с двумя UART, то " "обычно их нужно настроить как [.filename]#COM2# (он же [.filename]#sio1# — " "адрес ввода-вывода 0x2F8 и IRQ 3), а третий порт (он же [.filename]#sio2#) — " "с адресом 0x3E8 и IRQ 5. Очевидно, это расточительное использование ресурсов " "IRQ, так как в принципе возможно запустить оба порта расширительной платы с " "одним IRQ, используя конфигурацию `COM_MULTIPORT`, описанную в предыдущих " "разделах." #. type: delimited block = 4 #: documentation/content/en/articles/serial-uart/_index.adoc:999 msgid "" "Such cheap I/O boards commonly have a 4 by 3 jumper matrix for the COM " "ports, similar to the following:" msgstr "" "Такие недорогие платы ввода-вывода обычно имеют перемычечную матрицу 4x3 для " "COM-портов, подобную следующей:" #. type: delimited block . 4 #: documentation/content/en/articles/serial-uart/_index.adoc:1008 #, no-wrap msgid "" " o o o *\n" "Port A |\n" " o * o *\n" "Port B |\n" " o * o o\n" "IRQ 2 3 4 5\n" msgstr "" " o o o *\n" "Port A |\n" " o * o *\n" "Port B |\n" " o * o o\n" "IRQ 2 3 4 5\n" #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:1012 msgid "" "Shown here is port A wired for IRQ 5 and port B wired for IRQ 3. The IRQ " "columns on your specific board may vary-other boards may supply jumpers for " "IRQs 3, 4, 5, and 7 instead." msgstr "" "Показано, что порт A подключен для IRQ 5, а порт B — для IRQ 3. Столбцы IRQ " "на вашей конкретной плате могут отличаться — другие платы могут " "предоставлять перемычки для IRQ 3, 4, 5 и 7." #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:1016 msgid "" "One could conclude that wiring both ports for IRQ 3 using a handcrafted wire-" "made jumper covering all three connection points in the IRQ 3 column would " "solve the issue, but no. You cannot duplicate IRQ 3 because the output " "drivers of each UART are wired in a \"totem pole\" fashion, so if one of the " "UARTs drives IRQ 3, the output signal will not be what you would expect. " "Depending on the implementation of the extension board or your motherboard, " "the IRQ 3 line will continuously stay up, or always stay low." msgstr "" "Можно было бы сделать вывод, что подключение обоих портов к IRQ 3 с помощью " "самодельной перемычки, замыкающей все три точки соединения в колонке IRQ 3, " "решит проблему, но это не так. Невозможно дублировать IRQ 3, потому что " "выходные драйверы каждого UART соединены по схеме \"монтажное И\", и если " "один из UART управляет IRQ 3, выходной сигнал будет не таким как ожидается. " "В зависимости от реализации платы расширения или материнской платы, линия " "IRQ 3 будет постоянно находиться в высоком уровне или всегда оставаться " "низкой." #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:1020 msgid "" "You need to decouple the IRQ drivers for the two UARTs, so that the IRQ line " "of the board only goes up if (and only if) one of the UARTs asserts a IRQ, " "and stays low otherwise. The solution was proposed by Joerg Wunsch mailto:" "j@ida.interface-business.de[j@ida.interface-business.de]: To solder up a " "wired-or consisting of two diodes (Germanium or Schottky-types strongly " "preferred) and a 1 kOhm resistor. Here is the schematic, starting from the " "4 by 3 jumper field above:" msgstr "" "Вам необходимо разделить драйверы прерываний для двух UART, чтобы линия " "прерывания платы поднималась только тогда (и только тогда), когда один из " "UART вызывает прерывание, и оставалась низкой в противном случае. Решение " "было предложено Йоргом Вуншем mailto:j@ida.interface-business.de[j@ida." "interface-business.de]: припаять монтажную схему \"монтажное ИЛИ\", " "состоящую из двух диодов (предпочтительно германиевых или типа Шоттки) и " "резистора на 1 кОм. Вот схема, начиная с контактного поля 4x3 выше:" #. type: delimited block . 4 #: documentation/content/en/articles/serial-uart/_index.adoc:1034 #, no-wrap msgid "" " Diode\n" " +---------->|-------+\n" " / |\n" " o * o o | 1 kOhm\n" "Port A +----|######|-------+\n" " o * o o | |\n" "Port B `-------------------+ ==+==\n" " o * o o | Ground\n" " \\ |\n" " +--------->|-------+\n" "IRQ 2 3 4 5 Diode\n" msgstr "" " Diode\n" " +---------->|-------+\n" " / |\n" " o * o o | 1 kOhm\n" "Port A +----|######|-------+\n" " o * o o | |\n" "Port B `-------------------+ ==+==\n" " o * o o | Ground\n" " \\ |\n" " +--------->|-------+\n" "IRQ 2 3 4 5 Diode\n" #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:1038 msgid "" "The cathodes of the diodes are connected to a common point, together with a " "1 kOhm pull-down resistor. It is essential to connect the resistor to " "ground to avoid floating of the IRQ line on the bus." msgstr "" "Катоды диодов соединены в общей точке вместе с подтягивающим резистором 1 " "кОм. Важно подключить резистор к земле, чтобы избежать плавания линии IRQ на " "шине." #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:1041 msgid "" "Now we are ready to configure a kernel. Staying with this example, we would " "configure:" msgstr "Теперь мы готовы настроить ядро. Продолжая этот пример, мы настроим:" #. type: delimited block . 4 #: documentation/content/en/articles/serial-uart/_index.adoc:1050 #, no-wrap msgid "" "# standard on-board COM1 port\n" "device sio0 at isa? port \"IO_COM1\" flags 0x10\n" "# patched-up multi-I/O extension board\n" "options COM_MULTIPORT\n" "device sio1 at isa? port \"IO_COM2\" flags 0x205\n" "device sio2 at isa? port \"IO_COM3\" flags 0x205 irq 3\n" msgstr "" "# standard on-board COM1 port\n" "device sio0 at isa? port \"IO_COM1\" flags 0x10\n" "# patched-up multi-I/O extension board\n" "options COM_MULTIPORT\n" "device sio1 at isa? port \"IO_COM2\" flags 0x205\n" "device sio2 at isa? port \"IO_COM3\" flags 0x205 irq 3\n" #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:1055 msgid "" "Note that the `flags` setting for [.filename]#sio1# and [.filename]#sio2# is " "truly essential; refer to man:sio[4] for details. (Generally, the `2` in " "the \"flags\" attribute refers to [.filename]#sio#`2` which holds the IRQ, " "and you surely want a `5` low nibble.) With kernel verbose mode turned on " "this should yield something similar to this:" msgstr "" "Обратите внимание, что настройка `flags` для [.filename]#sio1# и [." "filename]#sio2# действительно важна; подробности смотрите в man:sio[4]. " "(Обычно `2` в атрибуте \"flags\" относится к [.filename]#sio#`2`, который " "содержит IRQ, и вам наверняка потребуется нижний ниббл `5`.) При включённом " "режиме подробного вывода ядра это должно дать что-то похожее на следующее:" #. type: delimited block . 4 #: documentation/content/en/articles/serial-uart/_index.adoc:1067 #, no-wrap msgid "" "sio0: irq maps: 0x1 0x11 0x1 0x1\n" "sio0 at 0x3f8-0x3ff irq 4 flags 0x10 on isa\n" "sio0: type 16550A\n" "sio1: irq maps: 0x1 0x9 0x1 0x1\n" "sio1 at 0x2f8-0x2ff flags 0x205 on isa\n" "sio1: type 16550A (multiport)\n" "sio2: irq maps: 0x1 0x9 0x1 0x1\n" "sio2 at 0x3e8-0x3ef irq 3 flags 0x205 on isa\n" "sio2: type 16550A (multiport master)\n" msgstr "" "sio0: irq maps: 0x1 0x11 0x1 0x1\n" "sio0 at 0x3f8-0x3ff irq 4 flags 0x10 on isa\n" "sio0: type 16550A\n" "sio1: irq maps: 0x1 0x9 0x1 0x1\n" "sio1 at 0x2f8-0x2ff flags 0x205 on isa\n" "sio1: type 16550A (multiport)\n" "sio2: irq maps: 0x1 0x9 0x1 0x1\n" "sio2 at 0x3e8-0x3ef irq 3 flags 0x205 on isa\n" "sio2: type 16550A (multiport master)\n" #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:1072 msgid "" "Though [.filename]#/sys/i386/isa/sio.c# is somewhat cryptic with its use of " "the \"irq maps\" array above, the basic idea is that you observe `0x1` in " "the first, third, and fourth place. This means that the corresponding IRQ " "was set upon output and cleared after, which is just what we would expect. " "If your kernel does not display this behavior, most likely there is " "something wrong with your wiring." msgstr "" "Хотя [.filename]#/sys/i386/isa/sio.c# выглядит несколько загадочно из-за " "использования массива \"irq maps\" выше, основная идея заключается в том, " "что вы наблюдаете `0x1` на первой, третьей и четвертой позициях. Это " "означает, что соответствующий IRQ был установлен при выводе и сброшен после, " "что полностью соответствует ожиданиям. Если ваше ядро не демонстрирует такое " "поведение, скорее всего, проблема в вашей разводке." #. type: Title == #: documentation/content/en/articles/serial-uart/_index.adoc:1074 #, no-wrap msgid "Configuring the [.filename]#cy# driver" msgstr "Настройка драйвера [.filename]#cy#" #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:1077 msgid "_Contributed by Alex Nash. 6 June 1996._" msgstr "_Предоставлено Алексом Нэшем. 6 июня 1996._" #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:1080 msgid "" "The Cyclades multiport cards are based on the [.filename]#cy# driver instead " "of the usual [.filename]#sio# driver used by other multiport cards. " "Configuration is a simple matter of:" msgstr "" "Многопортовые карты Cyclades основаны на драйвере [.filename]#cy#, а не на " "обычном драйвере [.filename]#sio#, используемом другими многопортовыми " "картами. Настройка сводится к простым действиям:" #. type: delimited block = 4 #: documentation/content/en/articles/serial-uart/_index.adoc:1084 msgid "" "Add the [.filename]#cy# device to your kernel configuration (note that your " "irq and iomem settings may differ)." msgstr "" "Добавьте устройство [.filename]#cy# в конфигурацию ядра (обратите внимание, " "что параметры irq и iomem могут отличаться)." #. type: delimited block . 4 #: documentation/content/en/articles/serial-uart/_index.adoc:1088 #, no-wrap msgid "device cy0 at isa? irq 10 iomem 0xd4000 iosiz 0x2000\n" msgstr "device cy0 at isa? irq 10 iomem 0xd4000 iosiz 0x2000\n" #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:1090 msgid "Rebuild and install the new kernel." msgstr "Перестройте и установите новый образ ядра." #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:1091 msgid "" "Make the device nodes by typing (the following example assumes an 8-port " "board):" msgstr "" "Создайте файлы устройств, введя (следующий пример предполагает 8-портовую " "плату):" #. type: delimited block . 4 #: documentation/content/en/articles/serial-uart/_index.adoc:1096 #, no-wrap msgid "" "# cd /dev\n" "# for i in 0 1 2 3 4 5 6 7;do ./MAKEDEV cuac$i ttyc$i;done\n" msgstr "" "# cd /dev\n" "# for i in 0 1 2 3 4 5 6 7;do ./MAKEDEV cuac$i ttyc$i;done\n" #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:1099 msgid "" "If appropriate, add dialup entries to [.filename]#/etc/ttys# by duplicating " "serial device (`ttyd`) entries and using `ttyc` in place of `ttyd`. For " "example:" msgstr "" "Если необходимо, добавьте записи для коммутируемого доступа в [.filename]#/" "etc/ttys#, дублируя записи для последовательных устройств (`ttyd`) и " "используя `ttyc` вместо `ttyd`. Например:" #. type: delimited block . 4 #: documentation/content/en/articles/serial-uart/_index.adoc:1107 #, no-wrap msgid "" "ttyc0 \"/usr/libexec/getty std.38400\" unknown on insecure\n" "ttyc1 \"/usr/libexec/getty std.38400\" unknown on insecure\n" "ttyc2 \"/usr/libexec/getty std.38400\" unknown on insecure\n" "...\n" "ttyc7 \"/usr/libexec/getty std.38400\" unknown on insecure\n" msgstr "" "ttyc0 \"/usr/libexec/getty std.38400\" unknown on insecure\n" "ttyc1 \"/usr/libexec/getty std.38400\" unknown on insecure\n" "ttyc2 \"/usr/libexec/getty std.38400\" unknown on insecure\n" "...\n" "ttyc7 \"/usr/libexec/getty std.38400\" unknown on insecure\n" #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:1109 msgid "Reboot with the new kernel." msgstr "Перезагрузитесь с новым ядром." #. type: Title == #: documentation/content/en/articles/serial-uart/_index.adoc:1111 #, no-wrap msgid "Configuring the [.filename]#si# driver" msgstr "Настройка драйвера [.filename]#si#" #. type: delimited block = 4 #: documentation/content/en/articles/serial-uart/_index.adoc:1114 msgid "_Contributed by `{nsayer}`. 25 March 1998._" msgstr "_Предоставлено `{nsayer}`. 25 марта 1998._" #. type: delimited block = 4 #: documentation/content/en/articles/serial-uart/_index.adoc:1118 msgid "" "The Specialix SI/XIO and SX multiport cards use the [.filename]#si# driver. " "A single machine can have up to 4 host cards. The following host cards are " "supported:" msgstr "" "Специальные мультипортные карты Specialix SI/XIO и SX используют драйвер [." "filename]#si#. На одной машине может быть установлено до 4 хост-карт. " "Поддерживаются следующие хост-карты:" #. type: delimited block = 4 #: documentation/content/en/articles/serial-uart/_index.adoc:1120 msgid "ISA SI/XIO host card (2 versions)" msgstr "ISA SI/XIO host card (2 versions)" #. type: delimited block = 4 #: documentation/content/en/articles/serial-uart/_index.adoc:1121 msgid "EISA SI/XIO host card" msgstr "EISA SI/XIO host card" #. type: delimited block = 4 #: documentation/content/en/articles/serial-uart/_index.adoc:1122 msgid "PCI SI/XIO host card" msgstr "PCI SI/XIO host card" #. type: delimited block = 4 #: documentation/content/en/articles/serial-uart/_index.adoc:1123 msgid "ISA SX host card" msgstr "ISA SX host card" #. type: delimited block = 4 #: documentation/content/en/articles/serial-uart/_index.adoc:1124 msgid "PCI SX host card" msgstr "PCI SX host card" #. type: delimited block = 4 #: documentation/content/en/articles/serial-uart/_index.adoc:1130 msgid "" "Although the SX and SI/XIO host cards look markedly different, their " "functionality are basically the same. The host cards do not use I/O " "locations, but instead require a 32K chunk of memory. The factory " "configuration for ISA cards places this at `0xd0000-0xd7fff`. They also " "require an IRQ. PCI cards will, of course, auto-configure themselves." msgstr "" "Хотя хост-карты SX и SI/XIO выглядят заметно по-разному, их функциональность " "практически одинакова. Хост-карты не используют порты ввода-вывода, а вместо " "этого требуют 32К сегмента памяти. Заводская конфигурация для карт ISA " "размещает этот сегмент по адресу `0xd0000-0xd7fff`. Также им требуется IRQ. " "Карты PCI, разумеется, настраиваются автоматически." #. type: delimited block = 4 #: documentation/content/en/articles/serial-uart/_index.adoc:1134 msgid "" "You can attach up to 4 external modules to each host card. The external " "modules contain either 4 or 8 serial ports. They come in the following " "varieties:" msgstr "" "Вы можете подключить до 4 внешних модулей к каждой карте хоста. Внешние " "модули содержат либо 4, либо 8 последовательных портов. Они бывают следующих " "видов:" #. type: delimited block = 4 #: documentation/content/en/articles/serial-uart/_index.adoc:1136 msgid "SI 4 or 8 port modules. Up to 57600 bps on each port supported." msgstr "" "Модули SI на 4 или 8 портов. Поддерживается скорость до 57600 бит/с на " "каждом порту." #. type: delimited block = 4 #: documentation/content/en/articles/serial-uart/_index.adoc:1137 msgid "" "XIO 8 port modules. Up to 115200 bps on each port supported. One type of XIO " "module has 7 serial and 1 parallel port." msgstr "" "XIO 8-портовые модули. Поддерживается скорость до 115200 бит/с на каждом " "порту. Один из типов модулей XIO имеет 7 последовательных и 1 параллельный " "порт." #. type: delimited block = 4 #: documentation/content/en/articles/serial-uart/_index.adoc:1138 msgid "" "SXDC 8 port modules. Up to 921600 bps on each port supported. Like XIO, a " "module is available with one parallel port as well." msgstr "" "Модули SXDC с 8 портами. Поддерживается скорость до 921600 бит/с на каждом " "порту. Как и в случае с XIO, доступен модуль с одним параллельным портом." #. type: delimited block = 4 #: documentation/content/en/articles/serial-uart/_index.adoc:1140 msgid "" "To configure an ISA host card, add the following line to your kernel " "configuration file, changing the numbers as appropriate:" msgstr "" "Для настройки карты хоста ISA добавьте следующую строку в файл конфигурации " "ядра, изменив числа по мере необходимости:" #. type: delimited block . 4 #: documentation/content/en/articles/serial-uart/_index.adoc:1144 #, no-wrap msgid "device si0 at isa? iomem 0xd0000 irq 11\n" msgstr "device si0 at isa? iomem 0xd0000 irq 11\n" #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:1147 msgid "" "Valid IRQ numbers are 9, 10, 11, 12 and 15 for SX ISA host cards and 11, 12 " "and 15 for SI/XIO ISA host cards." msgstr "" "Допустимые номера IRQ: 9, 10, 11, 12 и 15 для SX ISA host cards и 11, 12 и " "15 для SI/XIO ISA host cards." #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:1149 msgid "To configure an EISA or PCI host card, use this line:" msgstr "Для настройки карты EISA или PCI используйте следующую строку:" #. type: delimited block . 4 #: documentation/content/en/articles/serial-uart/_index.adoc:1153 #, no-wrap msgid "device si0\n" msgstr "device si0\n" #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:1156 msgid "" "After adding the configuration entry, rebuild and install your new kernel." msgstr "" "После добавления записи конфигурации пересоберите и установите свое новое " "ядро." #. type: delimited block = 4 #: documentation/content/en/articles/serial-uart/_index.adoc:1160 msgid "" "The following step, is not necessary if you are using man:devfs[5] in " "FreeBSD 5._X_." msgstr "" "Следующий шаг не обязателен, если вы используете man:devfs[5] в FreeBSD 5." "_X_." #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:1165 msgid "" "After rebooting with the new kernel, you need to make the device nodes in [." "filename]#/dev#. The [.filename]#MAKEDEV# script will take care of this for " "you. Count how many total ports you have and type:" msgstr "" "После перезагрузки с новым ядром необходимо создать файлы устройств в [." "filename]#/dev#. Скрипт [.filename]#MAKEDEV# выполнит эту задачу за вас. " "Подсчитайте общее количество портов и введите:" #. type: delimited block . 4 #: documentation/content/en/articles/serial-uart/_index.adoc:1170 #, no-wrap msgid "" "# cd /dev\n" "# ./MAKEDEV ttyAnn cuaAnn\n" msgstr "" "# cd /dev\n" "# ./MAKEDEV ttyAnn cuaAnn\n" #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:1173 msgid "(where _nn_ is the number of ports)" msgstr "(где _nn_ — количество портов)" #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:1175 msgid "" "If you want login prompts to appear on these ports, you will need to add " "lines like this to [.filename]#/etc/ttys#:" msgstr "" "Если вы хотите, чтобы приглашения к входу отображались на этих портах, вам " "нужно добавить такие строки в [.filename]#/etc/ttys#:" #. type: delimited block . 4 #: documentation/content/en/articles/serial-uart/_index.adoc:1179 #, no-wrap msgid "ttyA01 \"/usr/libexec/getty std.9600\" vt100 on insecure\n" msgstr "ttyA01 \"/usr/libexec/getty std.9600\" vt100 on insecure\n" #. type: Plain text #: documentation/content/en/articles/serial-uart/_index.adoc:1182 msgid "" "Change the terminal type as appropriate. For modems, `dialup` or `unknown` " "is fine." msgstr "" "Измените тип терминала по необходимости. Для модемов подойдут `dialup` или " "`unknown`." diff --git a/documentation/content/ru/articles/solid-state/_index.adoc b/documentation/content/ru/articles/solid-state/_index.adoc index 663594956a..b41c96b313 100644 --- a/documentation/content/ru/articles/solid-state/_index.adoc +++ b/documentation/content/ru/articles/solid-state/_index.adoc @@ -1,266 +1,266 @@ --- authors: - author: 'John Kozubik' email: john@kozubik.com copyright: '2001 - 2021 The FreeBSD Documentation Project' description: 'Использование твердотельных накопителей (SSD) в FreeBSD' tags: ["Solid State", "embedded", "FreeBSD"] title: 'FreeBSD и твердотельные устройства (SSD)' trademarks: ["freebsd", "general"] --- = FreeBSD и твердотельные устройства (SSD) :doctype: article :toc: macro :toclevels: 1 :icons: font :sectnums: :sectnumlevels: 6 :source-highlighter: rouge :experimental: :images-path: articles/solid-state/ ifdef::env-beastie[] ifdef::backend-html5[] include::shared/authors.adoc[] include::shared/mirrors.adoc[] include::shared/releases.adoc[] include::shared/attributes/attributes-{{% lang %}}.adoc[] include::shared/{{% lang %}}/teams.adoc[] include::shared/{{% lang %}}/mailing-lists.adoc[] include::shared/{{% lang %}}/urls.adoc[] :imagesdir: ../../../images/{images-path} endif::[] ifdef::backend-pdf,backend-epub3[] include::../../../../shared/asciidoctor.adoc[] endif::[] endif::[] ifndef::env-beastie[] include::../../../../../shared/asciidoctor.adoc[] endif::[] [.abstract-title] Аннотация В этой статье описывается использование твердотельных дисковых устройств для создания встраиваемых систем на основе FreeBSD. Встраиваемые системы имеют преимущество в повышенной надёжности по причине отсутствия в них движущихся частей (жёстких дисков). Однако, следует принять во внимание, что системе, как правило, доступно очень малое дисковое пространство и ограниченный объём запоминающего устройства. К отдельно рассматриваемым вопросам относятся типы и характеристики твердотельных носителей, подходящих для использования в качестве дисков во FreeBSD, параметры ядра, которые представляют интерес в таких условиях, механизмы [.filename]#rc.initdiskless#, автоматизирующие инициализацию таких систем и удовлетворяющие требованиям файловых систем, доступных только для чтения, а также построение файловых систем с нуля. Статья заканчивается описанием некоторых общих стратегий для случаев малых систем FreeBSD и работ в режиме только для чтения. ''' toc::[] [[intro]] == Твердотельные дисковые устройства Эта статья будет ограничиваться рассмотрением твердотельных дисковых устройств, которые делаются на основе флеш-памяти. Флеш-память является твердотельным (здесь нет движущихся частей) запоминающим устройством, которое является энергонезависимым (данные остаются в памяти даже после отключения всех источников питания). Флеш-память может быть нечувствительной к сильным физическим воздействиям и достаточно быстра (решения на основе флеш-памяти, описываемые в этой статье, гораздо медленнее, чем диски EIDE для операций записи, и гораздо быстрее их в случае выполнения операций чтения). Одним из очень важных свойств флеш-памяти, различные варианты которого будут рассмотрены далее в этой статье, является то, что каждый сектор имеет ограниченные возможности по перезаписыванию. Вы можете только записывать, стирать и снова записывать на сектор флеш-памяти определённое количество раз до того, как сектор станет полностью неработоспособным. Хотя многие продукты на основе флеш-памяти автоматически перенаправляют испорченные блоки, а некоторые даже распределяют операции записи по всему модулю, фактом является наличие ограничения на количество операций записи, которые могут выполняться с устройством. Современные модули имеют характеристики от 1,000,000 до 10,000,000 циклов записи на сектор. Эти характеристики могут зависеть от температуры рабочей среды. В частности, мы обсудим компактные модули флеш-памяти, совместимые со стандартом ATA, которые стали весьма популярными в качестве носителя данных для цифровых камер. Особый интерес представляет тот факт, что они соответствуют шине IDE по контактам и совместимы с набором команд ATA. Таким образом, при помощи очень простого и дешевого адаптера такие устройства могут подключаться непосредственно к шине IDE компьютера. Если поступить таким образом, то такие операционные системы, как FreeBSD, распознают диск как обычный винчестер (весьма маленький). Существуют и другие решения для твердотельных дисков, но их стоимость, безвестность и сравнительная сложность использования выводят их за рамки этой статьи. [[kernel]] == Параметры ядра -Для тех, кто создает встраиваемую систему FreeBSD, интерес представляют несколько параметров ядра. +Для тех, кто создаёт встраиваемую систему FreeBSD, интерес представляют несколько параметров ядра. Все встраиваемые системы FreeBSD, которые используют флеш-память в качестве системного диска, заинтересованы в использовании дисков в памяти и файловых систем в памяти. Из-за ограниченного количества циклов записи, которые можно выполнить с флеш-памятью, диск и файловые системы на нём будут, скорее всего, монтироваться в режиме доступа только для чтения. В таком случае файловые системы типа [.filename]#/tmp# и [.filename]#/var# монтируются как файловые системы в памяти для того, чтобы позволить системе создать журналы и обновить счетчики и временные файлы. Файловые системы в памяти являются критическим компонентом успешной работы FreeBSD на твердотельных устройствах. Вы должны удостовериться, что в конфигурационном файле вашего ядра присутствуют следующие строки: [.programlisting] .... options MD_ROOT # md device usable as a potential root device .... [[ro-fs]] == Подсистема `rc` и файловые системы в режиме только чтения Инициализация встраиваемой системы FreeBSD после загрузки управляется [.filename]#/etc/rc.initdiskless#. -[.filename]#/etc/rc.d/var# монтирует [.filename]#/var# как файловую систему в памяти, создает указываемый список каталогов в [.filename]#/var# при помощи команды man:mkdir[1], изменяет режимы доступа на некоторые из этих каталогов. В процессе выполнения [.filename]#/etc/rc.d/var# задействуется ещё одна переменная [.filename]#rc.conf# - `varsize`. Скрипт [.filename]#/etc/rc.d/var# создает раздел [.filename]#/var# на основе значения этой переменной из [.filename]#rc.conf#: +[.filename]#/etc/rc.d/var# монтирует [.filename]#/var# как файловую систему в памяти, создаёт указываемый список каталогов в [.filename]#/var# при помощи команды man:mkdir[1], изменяет режимы доступа на некоторые из этих каталогов. В процессе выполнения [.filename]#/etc/rc.d/var# задействуется ещё одна переменная [.filename]#rc.conf# - `varsize`. Скрипт [.filename]#/etc/rc.d/var# создаёт раздел [.filename]#/var# на основе значения этой переменной из [.filename]#rc.conf#: [.programlisting] .... varsize=8192 .... Запомните, что по умолчанию это значение указано в секторах. Факт использования файловой системы [.filename]#/var# в режиме чтения и записи является важным признаком, так как раздел [.filename]#/# (и любые другие разделы, которые могут находиться на флеш-носителе) должен монтироваться в режиме только для чтения. Вспомните, что в разделе crossref:solid-state[intro, Твердотельные дисковые устройства] мы касались ограничений флеш-памяти - особенно ограничений, касающихся возможностей записи. Важно не монтировать файловые системы на флеш-носителях в режимах чтения и записи, и важность отказа от файла подкачки не может быть переоценена. Файл подкачки на загруженной системе может пережечь кусок флеш-носителя менее чем за год. Частое журналирование и создание временных файлов приводят к тому же результату. Поэтому, кроме удаления записи `swap` из вашего файла [.filename]#/etc/fstab#, вы должны также изменить поле параметров каждой файловой системы на `ro` таким образом: [.programlisting] .... # Device Mountpoint FStype Options Dump Pass# /dev/ad0s1a / ufs ro 1 1 .... В результате этих изменений в среднестатистической системе несколько приложений немедленно перестанут работать. Например, cron не будет нормально запускаться в результате отсутствия таблиц для него в каталоге [.filename]#/var#, созданном [.filename]#/etc/rc.d/var#, а syslog и dhcp будут испытывать проблемы из-за доступа файловой системы только для чтения, а также отсутствия записей в [.filename]#/var#, который был создан скриптом [.filename]#/etc/rc.d/var#. Хотя эти проблемы являются временными и обсуждаются вместе с решением проблем с запуском распространённых программных пакетов в разделе crossref:solid-state[strategies, Стратегии работы с системой для случаев небольших и доступных только для чтения файловых систем]. Важно помнить, что файловая система, которая была смонтирована только для чтения при помощи файла [.filename]#/etc/fstab#, в любой момент может быть сделана доступной по чтению и записи выдачей команды: [source, shell] .... # /sbin/mount -uw partition .... и может быть возвращена к режиму доступа только для чтения по такой команде: [source, shell] .... # /sbin/mount -ur partition .... == Создание файловой системы с нуля Так как совместимые с ATA компактные флеш-карты распознаются во FreeBSD как обычные жёсткие диски IDE, то теоретически вы можете установить FreeBSD по сети при помощи дискет kern и mfsroot или с компакт-диска. Однако даже маленькая установка FreeBSD при помощи обычных процедур установки может привести к созданию системы размером, превышающим 200 мегабайт. Так как большинство людей используют устройства флеш-памяти меньшего размера (128 мегабайт считается весьма большим - 32 или даже 16 мегабайт используются гораздо чаще), то установка обычным образом не подходит-просто на диске нет места даже для самой минимальной установки. Самым простым способом обойти это ограничение на объём является установка FreeBSD обычным образом на обычный жёсткий диск. После окончания установки, обрежьте операционную систему до размера, который помещается на ваш флеш-носитель, а затем полностью заархивируйте файловую систему. Следующие шаги поведут вас через процесс подготовки части флеш-памяти для вашей заархивированной файловой системы. Запомните, что из-за того, что обычная установка не выполнялась, такие операции, как разбиение на разделы, разметка, создание файловой системы и так далее должны быть выполнены вручную. Кроме дискет kern и mfsroot вам также нужно воспользоваться дискетой fixit. [.procedure] ==== . Разбиение вашего флеш-носителя на разделы + После загрузки при помощи дискет kern и mfsroot, выберите пункт `custom` из меню установки. Из следующего пункта меню выберите `partition`. В меню работы с разделами вы должны удалить все существующие разделы при помощи клавиши kbd:[d]. После удаления всех имеющихся разделов создайте раздел при помощи клавиши kbd:[c] и согласитесь с предлагаемым по умолчанию размером раздела. Когда вы будете опрошены на предмет типа раздела, удостоверьтесь, что значение типа равно `165`. Теперь запишите эту таблицу разделов на диск, нажав клавишу kbd:[w] (на этом экране эта опция скрыта). Если вы используете компактную флеш-карту, совместимую с ATA, вы должны выбрать FreeBSD Boot Manager. Теперь нажмите клавишу kbd:[q] для выхода из меню работы с разделами. Должно быть выдано ещё раз меню для выбора менеджера загрузки - повторите то, что вы выбирали ранее. . Создание файловых систем на вашем устройстве флеш-памяти + Выйдите из меню установки custom, и из главного меню установки выберите пункт `fixit`. После входа в режим работы fixit, введите следующую команду: + [source, shell] .... # disklabel -e /dev/ad0c .... + В этот момент вы войдете в редактор vi из-под команды disklabel. Затем, вам нужно добавить строку `a:` в конце файла. Эта строка `a:` должна выглядеть примерно так: + [.programlisting] .... a: 123456 0 4.2BSD 0 0 .... + Здесь _123456_ является числом, в точности совпадающим с тем, что характеризует размер имеющейся записи для `c:`. В общем, вы копируете существующую строку для `c:` для строки `a:`, не забывая определить fstype как `4.2BSD`. Сохраните файл и завершите редактирование. + [source, shell] .... # disklabel -B -r /dev/ad0c # newfs /dev/ad0a .... . Размещение вашей файловой системы на флеш-носителе + Смонтируйте только что подготовленный флеш-носитель: + [source, shell] .... # mount /dev/ad0a /flash .... + Подключите эту машину к сети, чтобы можно было перенести наш tar-файл и распаковать его в файловую систему на флеш-носителе. Вот пример того, как это можно сделать: + [source, shell] .... # ifconfig xl0 192.168.0.10 netmask 255.255.255.0 # route add default 192.168.0.1 .... + Теперь, когда машина находится в сети, перепишите ваш tar-файл. Здесь вы можете столкнуться с некоторой проблемой - если объём вашей флеш-памяти равен, к примеру, 128 мегабайтам, а ваш tar-файл превышает 64 мегабайта, то вы не можете одновременно разместить tar-файл на флеш-носителе и распаковать его - вам не хватит места. Одним из решений этой проблемы, если вы используете FTP, является распаковка файла во время его передачи по FTP. Если вы передаёте файл именно так, то вы никогда не получите на диске одновременно архивный файл и его содержимое: + [source, shell] .... ftp> get tarfile.tar "| tar xvf -" .... + Если ваш файл обработан утилитой gzip, вы также можете этого добиться: + [source, shell] .... ftp> get tarfile.tar "| zcat | tar xvf -" .... + После того, как вы получили содержимое вашей заархивированной файловой системы на файловой системе флеш-памяти, вы можете размонтировать флеш-память и выполнить перезагрузку: + [source, shell] .... # cd / # umount /flash # exit .... + При условии, что вы правильно настроили файловую систему при её создании на обычном жёстком диске (с монтированием файловых систем в режиме только для чтения и с необходимыми опциями, встроенными в ядро), ваша встраиваемая система FreeBSD теперь должна успешно загружаться. ==== [[strategies]] == Стратегии работы с системой для случаев небольших и доступных только для чтения файловых систем В разделе crossref:solid-state[ro-fs, Подсистема `rc` и файловые системы в режиме только чтения] было указано, что файловая система [.filename]#/var#, создаваемая скриптом [.filename]#/etc/rc.d/var#, и наличие корневой файловой системы, доступной только для чтения, приводят к проблемам при работе многих распространённых программных пакетов, используемых во FreeBSD. В этой статье будут даны рекомендации по настройке нормальной работы cron и syslog, установке портов и веб-сервера Apache. === Cron -Во время загрузки содержимое каталогa [.filename]#/var# формируется скриптом [.filename]#/etc/rc.d/var# используя данные из [.filename]#/etc/mtree/BSD.var.dist#, поэтому в нём создается несколько стандартных каталогов, в числе которых - [.filename]#cron#, [.filename]#cron/tabs#, [.filename]#at#. +Во время загрузки содержимое каталогa [.filename]#/var# формируется скриптом [.filename]#/etc/rc.d/var# используя данные из [.filename]#/etc/mtree/BSD.var.dist#, поэтому в нём создаётся несколько стандартных каталогов, в числе которых - [.filename]#cron#, [.filename]#cron/tabs#, [.filename]#at#. Однако это не решает проблему с сохранением cron-таблиц между перезагрузками. Когда система перезагружается, то файловая система [.filename]#/var#, которая располагается в памяти, будет уничтожена, вместе со всеми cron-таблицами, которые вы могли там иметь. Поэтому одним из решений может стать создание cron-таблиц для пользователей, которым они нужны, монтирование вашей файловой системы [.filename]#/# в режиме чтения и записи, и копирование этих cron-таблиц в безопасное место, например, в [.filename]#/etc/tabs#, и последующее добавление строки в конец скрипта [.filename]#/etc/rc.initdiskless# для копирования этих cron-таблиц в каталог [.filename]#/var/cron/tabs# после его создания во время инициализации системы. Вам может также потребоваться добавить строку, которая изменяет режимы доступа и права на каталоги, которые вы создали, и на файлы, которые вы скопировали в скрипте [.filename]#/etc/rc.initdiskless#. === Syslog В файле [.filename]#syslog.conf# задано местоположение некоторых файлов протоколов, которые имеются в каталоге [.filename]#/var/log#. Эти файлы не создаются скриптом [.filename]#/etc/rc.d/var# во время инициализации системы. Поэтому где-нибудь в скрипте [.filename]#/etc/rc.d/var#, после секции, создающей каталоги в [.filename]#/var#, вам нужно добавить нечто вроде следующего: [source, shell] .... # touch /var/log/security /var/log/maillog /var/log/cron /var/log/messages # chmod 0644 /var/log/* .... === Установка портов Перед тем, как обсудить изменения, которые нужно сделать для успешного использования дерева портов, необходимо напомнить о том, что ваши файловые системы на флеш-носителях доступны только для чтения. Поэтому вам нужно временно монтировать их в режиме чтения и записи, используя параметры командной строки, как это показано в crossref:solid-state[ro-fs, Подсистема `rc` и файловые системы в режиме только чтения]. Вы всегда должны перемонтировать эти файловые системы в режим только для чтения после окончания работ - излишние записи на флеш носитель могут значительно сократить его срок эксплуатации. Чтобы можно было войти в каталог с портами и успешно выполнить команду make `install`, необходимо создать каталог для пакетов в файловой системе, не располагающейся в памяти, где будут храниться пакеты между перезагрузками. Так как для установки пакета в любом случае требуется монтирование ваших файловых систем для чтения и записи, имеет смысл выделить область флеш-носителя также и для записи информации о пакете. Прежде всего создайте каталог с базой данных о пакетах. Обычно это каталог [.filename]#/var/db/pkg#, но мы не можем разместить базу именно здесь, так как она исчезнет после перезагрузки системы. [source, shell] .... # mkdir /etc/pkg .... Теперь в скрипт [.filename]#/etc/rc.d/var# добавьте строку, которая связывает каталог [.filename]#/etc/pkg# с [.filename]#/var/db/pkg#. Например: [source, shell] .... # ln -s /etc/pkg /var/db/pkg .... Теперь каждый раз при монтировании ваших файловых систем для чтения и записи и установки пакета, команда make `install` будет работать, а информация о пакете будет успешно записана в каталог [.filename]#/etc/pkg# (так как файловая система будет в это время смонтирована для чтения и записи), который всегда будет доступным операционной системе как [.filename]#/var/db/pkg#. === Веб-сервер Apache [NOTE] ==== Шаги, описанные в этой части статьи, необходимо выполнить лишь в том случае, если Apache настроен сохранять свой pid или журнал вне каталога [.filename]#/var#. С настройками по умолчанию Apache формирует свой pid файл в [.filename]#/var/run/httpd.pid#, а файлы журналов - в [.filename]#/var/log#. ==== Далее в статье подразумевается, что Apache сохраняет свои файлы журналов в каталог [.filename]#apache_log_dir# вне каталога [.filename]#/var#. Когда этот каталог расположен на файловой системе, смонтированной в режиме только для чтения, Apache не сможет сохранять файлы журналов, что в свою очередь может вызывать проблемы в работе веб-сервера. В таком случае необходимо добавить новый каталог к списку каталогов из [.filename]#/etc/rc.d/var# для их создания в каталоге [.filename]#/var# и связать [.filename]#apache_log_dir# с [.filename]#/var/log/apache#. Нужно также задать права доступа и владельца нового каталога. Сначала добавьте каталог `log/apache` к списку каталогов, создаваемых скриптом [.filename]#/etc/rc.d/var#. Затем добавьте в скрипт [.filename]#/etc/rc.d/var# после секции создания каталогов такие команды: [source, shell] .... # chmod 0774 /var/log/apache # chown nobody:nobody /var/log/apache .... И наконец, удалите существующий каталог [.filename]#apache_install/logs# и замените его ссылкой: [source, shell] .... # rm -rf apache_log_dir # ln -s /var/log/apache apache_log_dir .... diff --git a/documentation/content/ru/articles/solid-state/_index.po b/documentation/content/ru/articles/solid-state/_index.po index afa4125ead..256d9de345 100644 --- a/documentation/content/ru/articles/solid-state/_index.po +++ b/documentation/content/ru/articles/solid-state/_index.po @@ -1,904 +1,904 @@ # SOME DESCRIPTIVE TITLE # Copyright (C) YEAR The FreeBSD Project # This file is distributed under the same license as the FreeBSD Documentation package. -# Vladlen Popolitov , 2025. +# Vladlen Popolitov , 2025, 2026. msgid "" msgstr "" "Project-Id-Version: FreeBSD Documentation VERSION\n" "POT-Creation-Date: 2024-12-29 08:30-0500\n" -"PO-Revision-Date: 2025-11-25 04:45+0000\n" +"PO-Revision-Date: 2026-04-05 04:45+0000\n" "Last-Translator: Vladlen Popolitov \n" "Language-Team: Russian \n" "Language: ru\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && " "n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" "X-Generator: Weblate 4.17\n" #. type: YAML Front Matter: description #: documentation/content/en/articles/solid-state/_index.adoc:1 #, no-wrap msgid "The use of solid state disk devices in FreeBSD" msgstr "Использование твердотельных накопителей (SSD) в FreeBSD" #. type: Title = #: documentation/content/en/articles/solid-state/_index.adoc:1 #: documentation/content/en/articles/solid-state/_index.adoc:12 #, no-wrap msgid "FreeBSD and Solid State Devices" msgstr "FreeBSD и твердотельные устройства (SSD)" #. type: Plain text #: documentation/content/en/articles/solid-state/_index.adoc:45 msgid "Abstract" msgstr "Аннотация" #. type: Plain text #: documentation/content/en/articles/solid-state/_index.adoc:47 msgid "" "This article covers the use of solid state disk devices in FreeBSD to create " "embedded systems." msgstr "" "В этой статье описывается использование твердотельных дисковых устройств для " "создания встраиваемых систем на основе FreeBSD." #. type: Plain text #: documentation/content/en/articles/solid-state/_index.adoc:50 msgid "" "Embedded systems have the advantage of increased stability due to the lack " "of integral moving parts (hard drives). Account must be taken, however, for " "the generally low disk space available in the system and the durability of " "the storage medium." msgstr "" "Встраиваемые системы имеют преимущество в повышенной надёжности по причине " "отсутствия в них движущихся частей (жёстких дисков). Однако, следует принять " "во внимание, что системе, как правило, доступно очень малое дисковое " "пространство и ограниченный объём запоминающего устройства." #. type: Plain text #: documentation/content/en/articles/solid-state/_index.adoc:53 msgid "" "Specific topics to be covered include the types and attributes of solid " "state media suitable for disk use in FreeBSD, kernel options that are of " "interest in such an environment, the [.filename]#rc.initdiskless# mechanisms " "that automate the initialization of such systems and the need for read-only " "filesystems, and building filesystems from scratch. The article will " "conclude with some general strategies for small and read-only FreeBSD " "environments." msgstr "" "К отдельно рассматриваемым вопросам относятся типы и характеристики " "твердотельных носителей, подходящих для использования в качестве дисков во " "FreeBSD, параметры ядра, которые представляют интерес в таких условиях, " "механизмы [.filename]#rc.initdiskless#, автоматизирующие инициализацию таких " "систем и удовлетворяющие требованиям файловых систем, доступных только для " "чтения, а также построение файловых систем с нуля. Статья заканчивается " "описанием некоторых общих стратегий для случаев малых систем FreeBSD и работ " "в режиме только для чтения." #. type: Plain text #: documentation/content/en/articles/solid-state/_index.adoc:55 msgid "'''" msgstr "'''" #. type: Title == #: documentation/content/en/articles/solid-state/_index.adoc:59 #, no-wrap msgid "Solid State Disk Devices" msgstr "Твердотельные дисковые устройства" #. type: Plain text #: documentation/content/en/articles/solid-state/_index.adoc:69 msgid "" "The scope of this article will be limited to solid state disk devices made " "from flash memory. Flash memory is a solid state memory (no moving parts) " "that is non-volatile (the memory maintains data even after all power sources " "have been disconnected). Flash memory can withstand tremendous physical " "shock and is reasonably fast (the flash memory solutions covered in this " "article are slightly slower than a EIDE hard disk for write operations, and " "much faster for read operations). One very important aspect of flash " "memory, the ramifications of which will be discussed later in this article, " "is that each sector has a limited rewrite capacity. You can only write, " "erase, and write again to a sector of flash memory a certain number of times " "before the sector becomes permanently unusable. Although many flash memory " "products automatically map bad blocks, and although some even distribute " "write operations evenly throughout the unit, the fact remains that there " "exists a limit to the amount of writing that can be done to the device. " "Competitive units have between 1,000,000 and 10,000,000 writes per sector in " "their specification. This figure varies due to the temperature of the " "environment." msgstr "" "Эта статья будет ограничиваться рассмотрением твердотельных дисковых " "устройств, которые делаются на основе флеш-памяти. Флеш-память является " "твердотельным (здесь нет движущихся частей) запоминающим устройством, " "которое является энергонезависимым (данные остаются в памяти даже после " "отключения всех источников питания). Флеш-память может быть нечувствительной " "к сильным физическим воздействиям и достаточно быстра (решения на основе " "флеш-памяти, описываемые в этой статье, гораздо медленнее, чем диски EIDE " "для операций записи, и гораздо быстрее их в случае выполнения операций " "чтения). Одним из очень важных свойств флеш-памяти, различные варианты " "которого будут рассмотрены далее в этой статье, является то, что каждый " "сектор имеет ограниченные возможности по перезаписыванию. Вы можете только " "записывать, стирать и снова записывать на сектор флеш-памяти определённое " "количество раз до того, как сектор станет полностью неработоспособным. Хотя " "многие продукты на основе флеш-памяти автоматически перенаправляют " "испорченные блоки, а некоторые даже распределяют операции записи по всему " "модулю, фактом является наличие ограничения на количество операций записи, " "которые могут выполняться с устройством. Современные модули имеют " "характеристики от 1,000,000 до 10,000,000 циклов записи на сектор. Эти " "характеристики могут зависеть от температуры рабочей среды." #. type: Plain text #: documentation/content/en/articles/solid-state/_index.adoc:74 msgid "" "Specifically, we will be discussing ATA compatible compact-flash units, " "which are quite popular as storage media for digital cameras. Of particular " "interest is the fact that they pin out directly to the IDE bus and are " "compatible with the ATA command set. Therefore, with a very simple and low-" "cost adaptor, these devices can be attached directly to an IDE bus in a " "computer. Once implemented in this manner, operating systems such as " "FreeBSD see the device as a normal hard disk (albeit small)." msgstr "" "В частности, мы обсудим компактные модули флеш-памяти, совместимые со " "стандартом ATA, которые стали весьма популярными в качестве носителя данных " "для цифровых камер. Особый интерес представляет тот факт, что они " "соответствуют шине IDE по контактам и совместимы с набором команд ATA. Таким " "образом, при помощи очень простого и дешевого адаптера такие устройства " "могут подключаться непосредственно к шине IDE компьютера. Если поступить " "таким образом, то такие операционные системы, как FreeBSD, распознают диск " "как обычный винчестер (весьма маленький)." #. type: Plain text #: documentation/content/en/articles/solid-state/_index.adoc:76 msgid "" "Other solid state disk solutions do exist, but their expense, obscurity, and " "relative unease of use places them beyond the scope of this article." msgstr "" "Существуют и другие решения для твердотельных дисков, но их стоимость, " "безвестность и сравнительная сложность использования выводят их за рамки " "этой статьи." #. type: Title == #: documentation/content/en/articles/solid-state/_index.adoc:78 #, no-wrap msgid "Kernel Options" msgstr "Параметры ядра" #. type: Plain text #: documentation/content/en/articles/solid-state/_index.adoc:81 msgid "" "A few kernel options are of specific interest to those creating an embedded " "FreeBSD system." msgstr "" -"Для тех, кто создает встраиваемую систему FreeBSD, интерес представляют " +"Для тех, кто создаёт встраиваемую систему FreeBSD, интерес представляют " "несколько параметров ядра." #. type: Plain text #: documentation/content/en/articles/solid-state/_index.adoc:86 msgid "" "All embedded FreeBSD systems that use flash memory as system disk will be " "interested in memory disks and memory filesystems. As a result of the " "limited number of writes that can be done to flash memory, the disk and the " "filesystems on the disk will most likely be mounted read-only. In this " "environment, filesystems such as [.filename]#/tmp# and [.filename]#/var# are " "mounted as memory filesystems to allow the system to create logs and update " "counters and temporary files. Memory filesystems are a critical component " "to a successful solid state FreeBSD implementation." msgstr "" "Все встраиваемые системы FreeBSD, которые используют флеш-память в качестве " "системного диска, заинтересованы в использовании дисков в памяти и файловых " "систем в памяти. Из-за ограниченного количества циклов записи, которые можно " "выполнить с флеш-памятью, диск и файловые системы на нём будут, скорее " "всего, монтироваться в режиме доступа только для чтения. В таком случае " "файловые системы типа [.filename]#/tmp# и [.filename]#/var# монтируются как " "файловые системы в памяти для того, чтобы позволить системе создать журналы " "и обновить счетчики и временные файлы. Файловые системы в памяти являются " "критическим компонентом успешной работы FreeBSD на твердотельных устройствах." #. type: Plain text #: documentation/content/en/articles/solid-state/_index.adoc:88 msgid "" "You should make sure the following lines exist in your kernel configuration " "file:" msgstr "" "Вы должны удостовериться, что в конфигурационном файле вашего ядра " "присутствуют следующие строки:" #. type: delimited block . 4 #: documentation/content/en/articles/solid-state/_index.adoc:92 #, no-wrap msgid "options MD_ROOT # md device usable as a potential root device\n" msgstr "" "options MD_ROOT # md device usable as a potential root " "device\n" #. type: Title == #: documentation/content/en/articles/solid-state/_index.adoc:95 #, no-wrap msgid "The `rc` Subsystem and Read-Only Filesystems" msgstr "Подсистема `rc` и файловые системы в режиме только чтения" #. type: Plain text #: documentation/content/en/articles/solid-state/_index.adoc:98 msgid "" "The post-boot initialization of an embedded FreeBSD system is controlled by " "[.filename]#/etc/rc.initdiskless#." msgstr "" "Инициализация встраиваемой системы FreeBSD после загрузки управляется [." "filename]#/etc/rc.initdiskless#." #. type: Plain text #: documentation/content/en/articles/solid-state/_index.adoc:102 msgid "" "[.filename]#/etc/rc.d/var# mounts [.filename]#/var# as a memory filesystem, " "makes a configurable list of directories in [.filename]#/var# with the man:" "mkdir[1] command, and changes modes on some of those directories. In the " "execution of [.filename]#/etc/rc.d/var#, one other [.filename]#rc.conf# " "variable comes into play - `varsize`. A [.filename]#/var# partition is " "created by [.filename]#/etc/rc.d/var# based on the value of this variable in " "[.filename]#rc.conf#:" msgstr "" "[.filename]#/etc/rc.d/var# монтирует [.filename]#/var# как файловую систему " -"в памяти, создает указываемый список каталогов в [.filename]#/var# при " +"в памяти, создаёт указываемый список каталогов в [.filename]#/var# при " "помощи команды man:mkdir[1], изменяет режимы доступа на некоторые из этих " "каталогов. В процессе выполнения [.filename]#/etc/rc.d/var# задействуется " "ещё одна переменная [.filename]#rc.conf# - `varsize`. Скрипт [.filename]#/" -"etc/rc.d/var# создает раздел [.filename]#/var# на основе значения этой " +"etc/rc.d/var# создаёт раздел [.filename]#/var# на основе значения этой " "переменной из [.filename]#rc.conf#:" #. type: delimited block . 4 #: documentation/content/en/articles/solid-state/_index.adoc:106 #, no-wrap msgid "varsize=8192\n" msgstr "varsize=8192\n" #. type: Plain text #: documentation/content/en/articles/solid-state/_index.adoc:109 msgid "Remember that this value is in sectors by default." msgstr "Запомните, что по умолчанию это значение указано в секторах." #. type: Plain text #: documentation/content/en/articles/solid-state/_index.adoc:116 msgid "" "The fact that [.filename]#/var# is a read-write filesystem is an important " "distinction, as the [.filename]#/# partition (and any other partitions you " "may have on your flash media) should be mounted read-only. Remember that in " "crossref:solid-state[intro, Solid State Disk Devices] we detailed the " "limitations of flash memory - specifically the limited write capability. " "The importance of not mounting filesystems on flash media read-write, and " "the importance of not using a swap file, cannot be overstated. A swap file " "on a busy system can burn through a piece of flash media in less than one " "year. Heavy logging or temporary file creation and destruction can do the " "same. Therefore, in addition to removing the `swap` entry from your [." "filename]#/etc/fstab#, you should also change the Options field for each " "filesystem to `ro` as follows:" msgstr "" "Факт использования файловой системы [.filename]#/var# в режиме чтения и " "записи является важным признаком, так как раздел [.filename]#/# (и любые " "другие разделы, которые могут находиться на флеш-носителе) должен " "монтироваться в режиме только для чтения. Вспомните, что в разделе crossref" ":solid-state[intro, Твердотельные дисковые устройства] мы касались " "ограничений флеш-памяти - особенно ограничений, касающихся возможностей " "записи. Важно не монтировать файловые системы на флеш-носителях в режимах " "чтения и записи, и важность отказа от файла подкачки не может быть " "переоценена. Файл подкачки на загруженной системе может пережечь кусок флеш-" "носителя менее чем за год. Частое журналирование и создание временных файлов " "приводят к тому же результату. Поэтому, кроме удаления записи `swap` из " "вашего файла [.filename]#/etc/fstab#, вы должны также изменить поле " "параметров каждой файловой системы на `ro` таким образом:" #. type: delimited block . 4 #: documentation/content/en/articles/solid-state/_index.adoc:121 #, no-wrap msgid "" "# Device Mountpoint FStype Options Dump Pass#\n" "/dev/ad0s1a / ufs ro 1 1\n" msgstr "" "# Device Mountpoint FStype Options Dump Pass#" "\n" "/dev/ad0s1a / ufs ro 1 1\n" #. type: Plain text #: documentation/content/en/articles/solid-state/_index.adoc:128 msgid "" "A few applications in the average system will immediately begin to fail as a " "result of this change. For instance, cron will not run properly as a result " "of missing cron tabs in the [.filename]#/var# created by [.filename]#/etc/rc." "d/var#, and syslog and dhcp will encounter problems as well as a result of " "the read-only filesystem and missing items in the [.filename]#/var# that [." "filename]#/etc/rc.d/var# has created. These are only temporary problems " "though, and are addressed, along with solutions to the execution of other " "common software packages in crossref:solid-state[strategies, System " "Strategies for Small and Read Only Environments]." msgstr "" "В результате этих изменений в среднестатистической системе несколько " "приложений немедленно перестанут работать. Например, cron не будет нормально " "запускаться в результате отсутствия таблиц для него в каталоге [." "filename]#/var#, созданном [.filename]#/etc/rc.d/var#, а syslog и dhcp будут " "испытывать проблемы из-за доступа файловой системы только для чтения, а " "также отсутствия записей в [.filename]#/var#, который был создан скриптом [." "filename]#/etc/rc.d/var#. Хотя эти проблемы являются временными и " "обсуждаются вместе с решением проблем с запуском распространённых " "программных пакетов в разделе crossref:solid-state[strategies, Стратегии " "работы с системой для случаев небольших и доступных только для чтения " "файловых систем]." #. type: Plain text #: documentation/content/en/articles/solid-state/_index.adoc:130 msgid "" "An important thing to remember is that a filesystem that was mounted read-" "only with [.filename]#/etc/fstab# can be made read-write at any time by " "issuing the command:" msgstr "" "Важно помнить, что файловая система, которая была смонтирована только для " "чтения при помощи файла [.filename]#/etc/fstab#, в любой момент может быть " "сделана доступной по чтению и записи выдачей команды:" #. type: delimited block . 4 #: documentation/content/en/articles/solid-state/_index.adoc:134 #, no-wrap msgid "# /sbin/mount -uw partition\n" msgstr "# /sbin/mount -uw partition\n" #. type: Plain text #: documentation/content/en/articles/solid-state/_index.adoc:137 msgid "and can be toggled back to read-only with the command:" msgstr "" "и может быть возвращена к режиму доступа только для чтения по такой команде:" #. type: delimited block . 4 #: documentation/content/en/articles/solid-state/_index.adoc:141 #, no-wrap msgid "# /sbin/mount -ur partition\n" msgstr "# /sbin/mount -ur partition\n" #. type: Title == #: documentation/content/en/articles/solid-state/_index.adoc:143 #, no-wrap msgid "Building a File System from Scratch" msgstr "Создание файловой системы с нуля" #. type: Plain text #: documentation/content/en/articles/solid-state/_index.adoc:146 msgid "" "Since ATA compatible compact-flash cards are seen by FreeBSD as normal IDE " "hard drives, you could theoretically install FreeBSD from the network using " "the kern and mfsroot floppies or from a CD." msgstr "" "Так как совместимые с ATA компактные флеш-карты распознаются во FreeBSD как " "обычные жёсткие диски IDE, то теоретически вы можете установить FreeBSD по " "сети при помощи дискет kern и mfsroot или с компакт-диска." #. type: Plain text #: documentation/content/en/articles/solid-state/_index.adoc:149 msgid "" "However, even a small installation of FreeBSD using normal installation " "procedures can produce a system in size of greater than 200 megabytes. Most " "people will be using smaller flash memory devices (128 megabytes is " "considered fairly large - 32 or even 16 megabytes is common), so an " "installation using normal mechanisms is not possible-there is simply not " "enough disk space for even the smallest of conventional installations." msgstr "" "Однако даже маленькая установка FreeBSD при помощи обычных процедур " "установки может привести к созданию системы размером, превышающим 200 " "мегабайт. Так как большинство людей используют устройства флеш-памяти " "меньшего размера (128 мегабайт считается весьма большим - 32 или даже 16 " "мегабайт используются гораздо чаще), то установка обычным образом не " "подходит-просто на диске нет места даже для самой минимальной установки." #. type: Plain text #: documentation/content/en/articles/solid-state/_index.adoc:155 msgid "" "The easiest way to overcome this space limitation is to install FreeBSD " "using conventional means to a normal hard disk. After the installation is " "complete, pare down the operating system to a size that will fit onto your " "flash media, then tar the entire filesystem. The following steps will guide " "you through the process of preparing a piece of flash memory for your tarred " "filesystem. Remember, because a normal installation is not being performed, " "operations such as partitioning, labeling, file-system creation, etc. need " "to be performed by hand. In addition to the kern and mfsroot floppy disks, " "you will also need to use the fixit floppy." msgstr "" "Самым простым способом обойти это ограничение на объём является установка " "FreeBSD обычным образом на обычный жёсткий диск. После окончания установки, " "обрежьте операционную систему до размера, который помещается на ваш флеш-" "носитель, а затем полностью заархивируйте файловую систему. Следующие шаги " "поведут вас через процесс подготовки части флеш-памяти для вашей " "заархивированной файловой системы. Запомните, что из-за того, что обычная " "установка не выполнялась, такие операции, как разбиение на разделы, " "разметка, создание файловой системы и так далее должны быть выполнены " "вручную. Кроме дискет kern и mfsroot вам также нужно воспользоваться " "дискетой fixit." #. type: delimited block = 4 #: documentation/content/en/articles/solid-state/_index.adoc:159 msgid "Partitioning Your Flash Media Device" msgstr "Разбиение вашего флеш-носителя на разделы" #. type: delimited block = 4 #: documentation/content/en/articles/solid-state/_index.adoc:169 msgid "" "After booting with the kern and mfsroot floppies, choose `custom` from the " "installation menu. In the custom installation menu, choose `partition`. In " "the partition menu, you should delete all existing partitions using kbd:" "[d]. After deleting all existing partitions, create a partition using kbd:" "[c] and accept the default value for the size of the partition. When asked " "for the type of the partition, make sure the value is set to `165`. Now " "write this partition table to the disk by pressing kbd:[w] (this is a hidden " "option on this screen). If you are using an ATA compatible compact flash " "card, you should choose the FreeBSD Boot Manager. Now press kbd:[q] to quit " "the partition menu. You will be shown the boot manager menu once more - " "repeat the choice you made earlier." msgstr "" "После загрузки при помощи дискет kern и mfsroot, выберите пункт `custom` из " "меню установки. Из следующего пункта меню выберите `partition`. В меню " "работы с разделами вы должны удалить все существующие разделы при помощи " "клавиши kbd:[d]. После удаления всех имеющихся разделов создайте раздел при " "помощи клавиши kbd:[c] и согласитесь с предлагаемым по умолчанию размером " "раздела. Когда вы будете опрошены на предмет типа раздела, удостоверьтесь, " "что значение типа равно `165`. Теперь запишите эту таблицу разделов на диск, " "нажав клавишу kbd:[w] (на этом экране эта опция скрыта). Если вы используете " "компактную флеш-карту, совместимую с ATA, вы должны выбрать FreeBSD Boot " "Manager. Теперь нажмите клавишу kbd:[q] для выхода из меню работы с " "разделами. Должно быть выдано ещё раз меню для выбора менеджера загрузки - " "повторите то, что вы выбирали ранее." #. type: delimited block = 4 #: documentation/content/en/articles/solid-state/_index.adoc:170 msgid "Creating Filesystems on Your Flash Memory Device" msgstr "Создание файловых систем на вашем устройстве флеш-памяти" #. type: delimited block = 4 #: documentation/content/en/articles/solid-state/_index.adoc:173 msgid "" "Exit the custom installation menu, and from the main installation menu " "choose the `fixit` option. After entering the fixit environment, enter the " "following command:" msgstr "" "Выйдите из меню установки custom, и из главного меню установки выберите " "пункт `fixit`. После входа в режим работы fixit, введите следующую команду:" #. type: delimited block . 4 #: documentation/content/en/articles/solid-state/_index.adoc:177 #, no-wrap msgid "# disklabel -e /dev/ad0c\n" msgstr "# disklabel -e /dev/ad0c\n" #. type: Plain text #: documentation/content/en/articles/solid-state/_index.adoc:181 msgid "" "At this point you will have entered the vi editor under the auspices of the " "disklabel command. Next, you need to add an `a:` line at the end of the " "file. This `a:` line should look like:" msgstr "" "В этот момент вы войдете в редактор vi из-под команды disklabel. Затем, вам " "нужно добавить строку `a:` в конце файла. Эта строка `a:` должна выглядеть " "примерно так:" #. type: delimited block . 4 #: documentation/content/en/articles/solid-state/_index.adoc:185 #, no-wrap msgid "a: 123456 0 4.2BSD 0 0\n" msgstr "a: 123456 0 4.2BSD 0 0\n" #. type: Plain text #: documentation/content/en/articles/solid-state/_index.adoc:190 msgid "" "Where _123456_ is a number that is exactly the same as the number in the " "existing `c:` entry for size. Basically you are duplicating the existing `c:" "` line as an `a:` line, making sure that fstype is `4.2BSD`. Save the file " "and exit." msgstr "" "Здесь _123456_ является числом, в точности совпадающим с тем, что " "характеризует размер имеющейся записи для `c:`. В общем, вы копируете " "существующую строку для `c:` для строки `a:`, не забывая определить fstype " "как `4.2BSD`. Сохраните файл и завершите редактирование." #. type: delimited block . 4 #: documentation/content/en/articles/solid-state/_index.adoc:195 #, no-wrap msgid "" "# disklabel -B -r /dev/ad0c\n" "# newfs /dev/ad0a\n" msgstr "" "# disklabel -B -r /dev/ad0c\n" "# newfs /dev/ad0a\n" #. type: Plain text #: documentation/content/en/articles/solid-state/_index.adoc:198 msgid "Placing Your Filesystem on the Flash Media" msgstr "Размещение вашей файловой системы на флеш-носителе" #. type: Plain text #: documentation/content/en/articles/solid-state/_index.adoc:200 msgid "Mount the newly prepared flash media:" msgstr "Смонтируйте только что подготовленный флеш-носитель:" #. type: delimited block . 4 #: documentation/content/en/articles/solid-state/_index.adoc:204 #, no-wrap msgid "# mount /dev/ad0a /flash\n" msgstr "# mount /dev/ad0a /flash\n" #. type: Plain text #: documentation/content/en/articles/solid-state/_index.adoc:208 msgid "" "Bring this machine up on the network so we may transfer our tar file and " "explode it onto our flash media filesystem. One example of how to do this " "is:" msgstr "" "Подключите эту машину к сети, чтобы можно было перенести наш tar-файл и " "распаковать его в файловую систему на флеш-носителе. Вот пример того, как " "это можно сделать:" #. type: delimited block . 4 #: documentation/content/en/articles/solid-state/_index.adoc:213 #, no-wrap msgid "" "# ifconfig xl0 192.168.0.10 netmask 255.255.255.0\n" "# route add default 192.168.0.1\n" msgstr "" "# ifconfig xl0 192.168.0.10 netmask 255.255.255.0\n" "# route add default 192.168.0.1\n" #. type: Plain text #: documentation/content/en/articles/solid-state/_index.adoc:219 msgid "" "Now that the machine is on the network, transfer your tar file. You may be " "faced with a bit of a dilemma at this point - if your flash memory part is " "128 megabytes, for instance, and your tar file is larger than 64 megabytes, " "you cannot have your tar file on the flash media at the same time as you " "explode it - you will run out of space. One solution to this problem, if " "you are using FTP, is to untar the file while it is transferred over FTP. " "If you perform your transfer in this manner, you will never have the tar " "file and the tar contents on your disk at the same time:" msgstr "" "Теперь, когда машина находится в сети, перепишите ваш tar-файл. Здесь вы " "можете столкнуться с некоторой проблемой - если объём вашей флеш-памяти " "равен, к примеру, 128 мегабайтам, а ваш tar-файл превышает 64 мегабайта, то " "вы не можете одновременно разместить tar-файл на флеш-носителе и распаковать " "его - вам не хватит места. Одним из решений этой проблемы, если вы " "используете FTP, является распаковка файла во время его передачи по FTP. " "Если вы передаёте файл именно так, то вы никогда не получите на диске " "одновременно архивный файл и его содержимое:" #. type: delimited block . 4 #: documentation/content/en/articles/solid-state/_index.adoc:223 #, no-wrap msgid "ftp> get tarfile.tar \"| tar xvf -\"\n" msgstr "ftp> get tarfile.tar \"| tar xvf -\"\n" #. type: Plain text #: documentation/content/en/articles/solid-state/_index.adoc:226 msgid "If your tarfile is gzipped, you can accomplish this as well:" msgstr "Если ваш файл обработан утилитой gzip, вы также можете этого добиться:" #. type: delimited block . 4 #: documentation/content/en/articles/solid-state/_index.adoc:230 #, no-wrap msgid "ftp> get tarfile.tar \"| zcat | tar xvf -\"\n" msgstr "ftp> get tarfile.tar \"| zcat | tar xvf -\"\n" #. type: Plain text #: documentation/content/en/articles/solid-state/_index.adoc:233 msgid "" "After the contents of your tarred filesystem are on your flash memory " "filesystem, you can unmount the flash memory and reboot:" msgstr "" "После того, как вы получили содержимое вашей заархивированной файловой " "системы на файловой системе флеш-памяти, вы можете размонтировать флеш-" "память и выполнить перезагрузку:" #. type: delimited block . 4 #: documentation/content/en/articles/solid-state/_index.adoc:239 #, no-wrap msgid "" "# cd /\n" "# umount /flash\n" "# exit\n" msgstr "" "# cd /\n" "# umount /flash\n" "# exit\n" #. type: Plain text #: documentation/content/en/articles/solid-state/_index.adoc:242 msgid "" "Assuming that you configured your filesystem correctly when it was built on " "the normal hard disk (with your filesystems mounted read-only, and with the " "necessary options compiled into the kernel) you should now be successfully " "booting your FreeBSD embedded system." msgstr "" "При условии, что вы правильно настроили файловую систему при её создании на " "обычном жёстком диске (с монтированием файловых систем в режиме только для " "чтения и с необходимыми опциями, встроенными в ядро), ваша встраиваемая " "система FreeBSD теперь должна успешно загружаться." #. type: Title == #: documentation/content/en/articles/solid-state/_index.adoc:245 #, no-wrap msgid "System Strategies for Small and Read Only Environments" msgstr "" "Стратегии работы с системой для случаев небольших и доступных только для " "чтения файловых систем" #. type: delimited block = 4 #: documentation/content/en/articles/solid-state/_index.adoc:249 msgid "" "In crossref:solid-state[ro-fs, The `rc` Subsystem and Read-Only " "Filesystems], it was pointed out that the [.filename]#/var# filesystem " "constructed by [.filename]#/etc/rc.d/var# and the presence of a read-only " "root filesystem causes problems with many common software packages used with " "FreeBSD. In this article, suggestions for successfully running cron, " "syslog, ports installations, and the Apache web server will be provided." msgstr "" "В разделе crossref:solid-state[ro-fs, Подсистема `rc` и файловые системы в " "режиме только чтения] было указано, что файловая система [.filename]#/var#, " "создаваемая скриптом [.filename]#/etc/rc.d/var#, и наличие корневой файловой " "системы, доступной только для чтения, приводят к проблемам при работе многих " "распространённых программных пакетов, используемых во FreeBSD. В этой статье " "будут даны рекомендации по настройке нормальной работы cron и syslog, " "установке портов и веб-сервера Apache." #. type: Title === #: documentation/content/en/articles/solid-state/_index.adoc:250 #, no-wrap msgid "Cron" msgstr "Cron" #. type: delimited block = 4 #: documentation/content/en/articles/solid-state/_index.adoc:253 msgid "" "Upon boot, [.filename]#/var# gets populated by [.filename]#/etc/rc.d/var# " "using the list from [.filename]#/etc/mtree/BSD.var.dist#, so the [." "filename]#cron#, [.filename]#cron/tabs#, [.filename]#at#, and a few other " "standard directories get created." msgstr "" "Во время загрузки содержимое каталогa [.filename]#/var# формируется скриптом " "[.filename]#/etc/rc.d/var# используя данные из [.filename]#/etc/mtree/BSD.var" -".dist#, поэтому в нём создается несколько стандартных каталогов, в числе " +".dist#, поэтому в нём создаётся несколько стандартных каталогов, в числе " "которых - [.filename]#cron#, [.filename]#cron/tabs#, [.filename]#at#." #. type: delimited block = 4 #: documentation/content/en/articles/solid-state/_index.adoc:258 msgid "" "However, this does not solve the problem of maintaining cron tabs across " "reboots. When the system reboots, the [.filename]#/var# filesystem that is " "in memory will disappear and any cron tabs you may have had in it will also " "disappear. Therefore, one solution would be to create cron tabs for the " "users that need them, mount your [.filename]#/# filesystem as read-write and " "copy those cron tabs to somewhere safe, like [.filename]#/etc/tabs#, then " "add a line to the end of [.filename]#/etc/rc.initdiskless# that copies those " "crontabs into [.filename]#/var/cron/tabs# after that directory has been " "created during system initialization. You may also need to add a line that " "changes modes and permissions on the directories you create and the files " "you copy with [.filename]#/etc/rc.initdiskless#." msgstr "" "Однако это не решает проблему с сохранением cron-таблиц между " "перезагрузками. Когда система перезагружается, то файловая система [." "filename]#/var#, которая располагается в памяти, будет уничтожена, вместе со " "всеми cron-таблицами, которые вы могли там иметь. Поэтому одним из решений " "может стать создание cron-таблиц для пользователей, которым они нужны, " "монтирование вашей файловой системы [.filename]#/# в режиме чтения и записи, " "и копирование этих cron-таблиц в безопасное место, например, в [.filename]#/" "etc/tabs#, и последующее добавление строки в конец скрипта [.filename]#/etc/" "rc.initdiskless# для копирования этих cron-таблиц в каталог [.filename]#/var/" "cron/tabs# после его создания во время инициализации системы. Вам может " "также потребоваться добавить строку, которая изменяет режимы доступа и права " "на каталоги, которые вы создали, и на файлы, которые вы скопировали в " "скрипте [.filename]#/etc/rc.initdiskless#." #. type: Title === #: documentation/content/en/articles/solid-state/_index.adoc:259 #, no-wrap msgid "Syslog" msgstr "Syslog" #. type: delimited block = 4 #: documentation/content/en/articles/solid-state/_index.adoc:264 msgid "" "[.filename]#syslog.conf# specifies the locations of certain log files that " "exist in [.filename]#/var/log#. These files are not created by [.filename]#/" "etc/rc.d/var# upon system initialization. Therefore, somewhere in [." "filename]#/etc/rc.d/var#, after the section that creates the directories in " "[.filename]#/var#, you will need to add something like this:" msgstr "" "В файле [.filename]#syslog.conf# задано местоположение некоторых файлов " "протоколов, которые имеются в каталоге [.filename]#/var/log#. Эти файлы не " "создаются скриптом [.filename]#/etc/rc.d/var# во время инициализации " "системы. Поэтому где-нибудь в скрипте [.filename]#/etc/rc.d/var#, после " "секции, создающей каталоги в [.filename]#/var#, вам нужно добавить нечто " "вроде следующего:" #. type: delimited block . 4 #: documentation/content/en/articles/solid-state/_index.adoc:269 #, no-wrap msgid "" "# touch /var/log/security /var/log/maillog /var/log/cron /var/log/messages\n" "# chmod 0644 /var/log/*\n" msgstr "" "# touch /var/log/security /var/log/maillog /var/log/cron /var/log/messages\n" "# chmod 0644 /var/log/*\n" #. type: Title === #: documentation/content/en/articles/solid-state/_index.adoc:271 #, no-wrap msgid "Ports Installation" msgstr "Установка портов" #. type: Plain text #: documentation/content/en/articles/solid-state/_index.adoc:277 msgid "" "Before discussing the changes necessary to successfully use the ports tree, " "a reminder is necessary regarding the read-only nature of your filesystems " "on the flash media. Since they are read-only, you will need to temporarily " "mount them read-write using the mount syntax shown in crossref:solid-" "state[ro-fs, The `rc` Subsystem and Read-Only Filesystems]. You should " "always remount those filesystems read-only when you are done with any " "maintenance - unnecessary writes to the flash media could considerably " "shorten its lifespan." msgstr "" "Перед тем, как обсудить изменения, которые нужно сделать для успешного " "использования дерева портов, необходимо напомнить о том, что ваши файловые " "системы на флеш-носителях доступны только для чтения. Поэтому вам нужно " "временно монтировать их в режиме чтения и записи, используя параметры " "командной строки, как это показано в crossref:solid-state[ro-fs, Подсистема " "`rc` и файловые системы в режиме только чтения]. Вы всегда должны " "перемонтировать эти файловые системы в режим только для чтения после " "окончания работ - излишние записи на флеш носитель могут значительно " "сократить его срок эксплуатации." #. type: Plain text #: documentation/content/en/articles/solid-state/_index.adoc:280 msgid "" "To make it possible to enter a ports directory and successfully run `make " "install`, we must create a packages directory on a non-memory filesystem " "that will keep track of our packages across reboots. As it is necessary to " "mount your filesystems as read-write for the installation of a package " "anyway, it is sensible to assume that an area on the flash media can also be " "used for package information to be written to." msgstr "" "Чтобы можно было войти в каталог с портами и успешно выполнить команду make " "`install`, необходимо создать каталог для пакетов в файловой системе, не " "располагающейся в памяти, где будут храниться пакеты между перезагрузками. " "Так как для установки пакета в любом случае требуется монтирование ваших " "файловых систем для чтения и записи, имеет смысл выделить область флеш-" "носителя также и для записи информации о пакете." #. type: Plain text #: documentation/content/en/articles/solid-state/_index.adoc:283 msgid "" "First, create a package database directory. This is normally in [." "filename]#/var/db/pkg#, but we cannot place it there as it will disappear " "every time the system is booted." msgstr "" "Прежде всего создайте каталог с базой данных о пакетах. Обычно это каталог [." "filename]#/var/db/pkg#, но мы не можем разместить базу именно здесь, так как " "она исчезнет после перезагрузки системы." #. type: delimited block . 4 #: documentation/content/en/articles/solid-state/_index.adoc:287 #, no-wrap msgid "# mkdir /etc/pkg\n" msgstr "# mkdir /etc/pkg\n" #. type: Plain text #: documentation/content/en/articles/solid-state/_index.adoc:290 msgid "" "Now, add a line to [.filename]#/etc/rc.d/var# that links the [.filename]#/" "etc/pkg# directory to [.filename]#/var/db/pkg#. An example:" msgstr "" "Теперь в скрипт [.filename]#/etc/rc.d/var# добавьте строку, которая " "связывает каталог [.filename]#/etc/pkg# с [.filename]#/var/db/pkg#. Например:" #. type: delimited block . 4 #: documentation/content/en/articles/solid-state/_index.adoc:294 #, no-wrap msgid "# ln -s /etc/pkg /var/db/pkg\n" msgstr "# ln -s /etc/pkg /var/db/pkg\n" #. type: Plain text #: documentation/content/en/articles/solid-state/_index.adoc:297 msgid "" "Now, any time that you mount your filesystems as read-write and install a " "package, the `make install` will work, and package information will be " "written successfully to [.filename]#/etc/pkg# (because the filesystem will, " "at that time, be mounted read-write) which will always be available to the " "operating system as [.filename]#/var/db/pkg#." msgstr "" "Теперь каждый раз при монтировании ваших файловых систем для чтения и записи " "и установки пакета, команда make `install` будет работать, а информация о " "пакете будет успешно записана в каталог [.filename]#/etc/pkg# (так как " "файловая система будет в это время смонтирована для чтения и записи), " "который всегда будет доступным операционной системе как [.filename]#/var/db/" "pkg#." #. type: Title === #: documentation/content/en/articles/solid-state/_index.adoc:298 #, no-wrap msgid "Apache Web Server" msgstr "Веб-сервер Apache" #. type: delimited block = 4 #: documentation/content/en/articles/solid-state/_index.adoc:304 msgid "" "The steps in this section are only necessary if Apache is set up to write " "its pid or log information outside of [.filename]#/var#. By default, Apache " "keeps its pid file in [.filename]#/var/run/httpd.pid# and its log files in [." "filename]#/var/log#." msgstr "" "Шаги, описанные в этой части статьи, необходимо выполнить лишь в том случае, " "если Apache настроен сохранять свой pid или журнал вне каталога [." "filename]#/var#. С настройками по умолчанию Apache формирует свой pid файл в " "[.filename]#/var/run/httpd.pid#, а файлы журналов - в [.filename]#/var/log#." #. type: Plain text #: documentation/content/en/articles/solid-state/_index.adoc:310 msgid "" "It is now assumed that Apache keeps its log files in a directory [." "filename]#apache_log_dir# outside of [.filename]#/var#. When this directory " "lives on a read-only filesystem, Apache will not be able to save any log " "files, and may have problems working. If so, it is necessary to add a new " "directory to the list of directories in [.filename]#/etc/rc.d/var# to create " "in [.filename]#/var#, and to link [.filename]#apache_log_dir# to [." "filename]#/var/log/apache#. It is also necessary to set permissions and " "ownership on this new directory." msgstr "" "Далее в статье подразумевается, что Apache сохраняет свои файлы журналов в " "каталог [.filename]#apache_log_dir# вне каталога [.filename]#/var#. Когда " "этот каталог расположен на файловой системе, смонтированной в режиме только " "для чтения, Apache не сможет сохранять файлы журналов, что в свою очередь " "может вызывать проблемы в работе веб-сервера. В таком случае необходимо " "добавить новый каталог к списку каталогов из [.filename]#/etc/rc.d/var# для " "их создания в каталоге [.filename]#/var# и связать [." "filename]#apache_log_dir# с [.filename]#/var/log/apache#. Нужно также задать " "права доступа и владельца нового каталога." #. type: Plain text #: documentation/content/en/articles/solid-state/_index.adoc:312 msgid "" "First, add the directory `log/apache` to the list of directories to be " "created in [.filename]#/etc/rc.d/var#." msgstr "" "Сначала добавьте каталог `log/apache` к списку каталогов, создаваемых " "скриптом [.filename]#/etc/rc.d/var#." #. type: Plain text #: documentation/content/en/articles/solid-state/_index.adoc:314 msgid "" "Second, add these commands to [.filename]#/etc/rc.d/var# after the directory " "creation section:" msgstr "" "Затем добавьте в скрипт [.filename]#/etc/rc.d/var# после секции создания " "каталогов такие команды:" #. type: delimited block . 4 #: documentation/content/en/articles/solid-state/_index.adoc:319 #, no-wrap msgid "" "# chmod 0774 /var/log/apache\n" "# chown nobody:nobody /var/log/apache\n" msgstr "" "# chmod 0774 /var/log/apache\n" "# chown nobody:nobody /var/log/apache\n" #. type: Plain text #: documentation/content/en/articles/solid-state/_index.adoc:322 msgid "" "Finally, remove the existing [.filename]#apache_log_dir# directory, and " "replace it with a link:" msgstr "" "И наконец, удалите существующий каталог [.filename]#apache_install/logs# и " "замените его ссылкой:" #. type: delimited block . 4 #: documentation/content/en/articles/solid-state/_index.adoc:327 #, no-wrap msgid "" "# rm -rf apache_log_dir\n" "# ln -s /var/log/apache apache_log_dir\n" msgstr "" "# rm -rf apache_log_dir\n" "# ln -s /var/log/apache apache_log_dir\n" diff --git a/documentation/content/ru/articles/vinum/_index.adoc b/documentation/content/ru/articles/vinum/_index.adoc index ddebec7ce0..6a6e78de9e 100644 --- a/documentation/content/ru/articles/vinum/_index.adoc +++ b/documentation/content/ru/articles/vinum/_index.adoc @@ -1,601 +1,601 @@ --- authors: - author: 'Greg Lehey' description: 'Менеджер томов vinum в FreeBSD' tags: ["vinum", "Volume Manager", "FreeBSD"] title: 'Менеджер томов vinum' --- //// The Vinum Volume Manager By Greg Lehey (grog at lemis dot com) Added to the Handbook by Hiten Pandya and Tom Rhodes For the FreeBSD Documentation Project //// = Менеджер томов vinum :doctype: article :toc: macro :toclevels: 1 :icons: font :sectnums: :sectnumlevels: 6 :source-highlighter: rouge :experimental: :images-path: articles/vinum/ ifdef::env-beastie[] ifdef::backend-html5[] include::shared/authors.adoc[] include::shared/mirrors.adoc[] include::shared/releases.adoc[] include::shared/attributes/attributes-{{% lang %}}.adoc[] include::shared/{{% lang %}}/teams.adoc[] include::shared/{{% lang %}}/mailing-lists.adoc[] include::shared/{{% lang %}}/urls.adoc[] :imagesdir: ../../../images/{images-path} endif::[] ifdef::backend-pdf,backend-epub3[] include::../../../../shared/asciidoctor.adoc[] endif::[] endif::[] ifndef::env-beastie[] include::../../../../../shared/asciidoctor.adoc[] endif::[] ''' toc::[] [[vinum-synopsis]] == Обзор Независимо от типа дисков, всегда существуют потенциальные проблемы. Диски могут быть слишком малы, слишком медленны или недостаточно надёжны для соответствия требованиям системы. Хотя диски становятся больше, требования к хранению данных также растут. Часто требуется файловая система, размер которой превышает емкость одного диска. Были предложены и реализованы различные решения этих проблем. Один из методов заключается в использовании нескольких, а иногда и избыточных дисков. Помимо поддержки различных карт и контроллеров для аппаратных систем RAID (Redundant Array of Independent Disks), базовая система FreeBSD включает менеджер томов [.filename]#vinum#, драйвер блочных устройств, который реализует виртуальные диски и решает эти три проблемы. [.filename]#vinum# обеспечивает большую гибкость, производительность и надёжность по сравнению с традиционными системами хранения данных, а также реализует модели `RAID`-0, `RAID`-1 и `RAID`-5 как по отдельности, так и в комбинации. Эта глава предоставляет обзор потенциальных проблем с традиционным дисковым хранилищем и введение в менеджер томов [.filename]#vinum#. [WARNING] ==== vinum устарел и отсутствует в FreeBSD 15.0 и более поздних версиях. Пользователям рекомендуется перейти на man:gconcat[8], man:gmirror[8], man:gstripe[8], man:graid[8] или man:zfs[8]. ==== [NOTE] ==== Начиная с FreeBSD 5, [.filename]#vinum# был переписан для интеграции в extref:{handbook}geom[архитектуру GEOM, geom-synopsis], сохраняя при этом оригинальные идеи, терминологию и метаданные на диске. Эта переработанная версия называется _gvinum_ (от _GEOM vinum_). Хотя в этой главе используется термин [.filename]#vinum#, все команды должны выполняться с помощью `gvinum`. Имя модуля ядра изменилось с оригинального [.filename]#vinum.ko# на [.filename]#geom_vinum.ko#, а все узлы устройств находятся в [.filename]#/dev/gvinum# вместо [.filename]#/dev/vinum#. Начиная с FreeBSD 6, оригинальная реализация [.filename]#vinum# больше не доступна в кодовой базе. ==== [[vinum-access-bottlenecks]] == Узкие места доступа Современные системы часто нуждаются в доступе к данным в условиях высокой параллельности. Например, крупные FTP- или HTTP-серверы могут поддерживать тысячи одновременных сеансов и иметь несколько 100 Мбит/с соединений с внешним миром, что значительно превышает устойчивую скорость передачи большинства дисков. Современные дисковые накопители могут передавать данные последовательно со скоростью до 70 МБ/с, но это значение имеет мало значения в среде, где множество независимых процессов обращаются к накопителю и могут достичь лишь доли этих значений. В таких случаях более интересно рассмотреть проблему с точки зрения дисковой подсистемы. Важным параметром является нагрузка, которую передача данных создаёт на подсистему, или время, в течение которого передача занимает задействованные накопители. При любом переносе данных на диск сначала необходимо позиционировать головки, дождаться, пока первый сектор окажется под считывающей головкой, а затем выполнить перенос. Эти действия можно считать атомарными, так как их прерывание не имеет смысла. [[vinum-latency]] Рассмотрим типичную передачу около 10 КБ: современные высокопроизводительные диски могут позиционировать головки в среднем за 3,5 мс. Самые быстрые диски вращаются со скоростью 15 000 об/мин, поэтому средняя задержка вращения (половина оборота) составляет 2 мс. При скорости 70 МБ/с сама передача занимает около 150 мкс, что почти ничто по сравнению с временем позиционирования. В таком случае эффективная скорость передачи падает до чуть более 1 МБ/с и явно сильно зависит от размера передачи. Традиционное и очевидное решение этой проблемы — «больше дисков»: вместо одного большого диска использовать несколько дисков меньшего размера с тем же общим объёмом хранилища. Каждый диск способен позиционироваться и передавать данные независимо, поэтому эффективная пропускная способность увеличивается почти пропорционально количеству используемых дисков. Фактическое увеличение пропускной способности меньше, чем количество задействованных дисков. Хотя каждый диск способен передавать данные параллельно, нет возможности гарантировать равномерное распределение запросов между дисками. Неизбежно нагрузка на один диск будет выше, чем на другой. Равномерность нагрузки на диски сильно зависит от способа распределения данных по накопителям. В дальнейшем обсуждении удобно представлять дисковое хранилище как большое количество секторов данных, адресуемых по номерам, подобно страницам в книге. Наиболее очевидный метод — разделить виртуальный диск на группы последовательных секторов размером с отдельные физические диски и хранить их таким образом, как если бы большую книгу разорвали на меньшие разделы. Этот метод называется _объединением_ (конкатенацией) и имеет преимущество в том, что диски не требуют каких-либо определённых соотношений размеров. Он хорошо работает, когда доступ к виртуальному диску равномерно распределён по его адресному пространству. Если доступ сосредоточен на меньшей области, улучшение менее заметно. crossref:vinum[vinum-concat, Организация методом объединения] иллюстрирует последовательность выделения блоков хранения в организации методом объединения. [[vinum-concat]] .Организация методом объединения image::vinum-concat.png[] Альтернативный метод распределения заключается в разделении адресного пространства на меньшие равные по размеру компоненты и их последовательном хранении на разных устройствах. Например, первые 256 секторов могут храниться на первом диске, следующие 256 секторов — на следующем диске и так далее. После заполнения последнего диска процесс повторяется, пока все диски не будут заполнены. Такой метод называется _чередованием (striping)_ или RAID-0. `RAID` предлагает различные формы отказоустойчивости, хотя RAID-0 несколько вводит в заблуждение, так как не обеспечивает избыточности. Разделение данных требует несколько больше усилий для их поиска и может создавать дополнительную нагрузку ввода-вывода, когда передача распределяется по нескольким дискам, но также может обеспечить более равномерную нагрузку на диски. crossref:vinum[vinum-striped,Организация методом чередования] иллюстрирует последовательность, в которой организуется распределение блоков хранения с чередованием. [[vinum-striped]] .Организация методом чередования image::vinum-striped.png[] [[vinum-data-integrity]] == Целостность данных Последняя проблема с дисками заключается в их ненадёжности. Хотя надёжность значительно повысилась за последние годы, дисковые накопители остаются наиболее вероятным компонентом сервера, который может выйти из строя. Когда это происходит, последствия могут быть катастрофическими, а замена вышедшего из строя диска и восстановление данных могут привести к простою сервера. Один из подходов к этой проблеме — _зеркалирование_, или `RAID-1`, при котором данные хранятся в двух экземплярах на разных физических носителях. Любая запись на том записывается на оба диска; чтение может выполняться с любого из них, поэтому при отказе одного диска данные остаются доступны на другом. Зеркалирование имеет две проблемы: * Требуется в два раза больше дискового пространства, чем для решения без избыточности. * Запись должна выполняться на оба диска, поэтому она занимает в два раза больше пропускной способности, чем в незеркалированном томе. Чтение не страдает от потери производительности и может быть даже быстрее. Альтернативным решением является _чётность_, реализованная в уровнях `RAID` 2, 3, 4 и 5. Из них `RAID-5` представляет наибольший интерес. В реализации [.filename]#vinum# это вариант организации с чередованием, где один блок каждой полосы выделяется под чётность одного из других блоков. В реализации [.filename]#vinum# плекс `RAID-5` аналогичен плексу с чередованием, за исключением того, что он реализует `RAID-5`, включая блок чётности в каждую полосу. Как требуется в `RAID-5`, расположение этого блока чётности меняется от одной полосы к другой. Числа в блоках данных обозначают относительные номера блоков. [[vinum-raid5-org]] .Организация `RAID`-5 image::vinum-raid5-org.png[] По сравнению с зеркалированием, `RAID-5` имеет преимущество в виде значительно меньшего требуемого объёма хранилища. Скорость чтения аналогична таковой при чередующейся организации, но скорость записи значительно ниже — примерно 25% от скорости чтения. Если один диск выходит из строя, массив может продолжать работу в деградировавшем режиме, при котором чтение с оставшихся доступных дисков продолжается в обычном режиме, а чтение с отказавшего диска пересчитывается из соответствующих блоков всех оставшихся дисков. [[vinum-objects]] == Объекты [.filename]#vinum# Для решения этих проблем [.filename]#vinum# реализует четырёхуровневую иерархию объектов: * Наиболее заметным объектом является виртуальный диск, называемый _томом_. Том обладает практически теми же свойствами, что и UNIX(R) дисковый накопитель, хотя есть некоторые незначительные отличия. Например, у тома нет ограничений по размеру. * Тома состоят из _плексов_, каждый из которых представляет полное адресное пространство тома. Этот уровень в иерархии обеспечивает избыточность. Можно представить плексы как отдельные диски в зеркальном массиве, каждый из которых содержит одинаковые данные. * Поскольку [.filename]#vinum# существует в рамках системы хранения данных UNIX(R), можно было бы использовать разделы UNIX(R) в качестве строительных блоков для многодисковых plexes. Однако на практике это оказывается слишком негибким, так как диски UNIX(R) могут иметь только ограниченное количество разделов. Вместо этого [.filename]#vinum# разбивает единственный раздел UNIX(R), называемый _дисковый раздел (drive)_, на непрерывные области, называемые _поддисками (subdisk)_, которые используются как строительные блоки для плексов. * Поддиски располагаются на _дисковых разделах_ [.filename]#vinum#, в настоящее время это разделы UNIX(R). Разделы [.filename]#vinum# могут содержать любое количество поддисков. За исключением небольшой области в начале раздела, которая используется для хранения конфигурации и состояния, весь раздел доступен для хранения данных. Следующие разделы статьи описывают, каким образом эти объекты обеспечивают функциональность, требуемую для [.filename]#vinum#. === Учёт размера томов Плексы могут включать несколько поддисков, распределенных по всем дискам в конфигурации [.filename]#vinum#. В результате, размер отдельного диска не ограничивает размер плекса или тома. === Избыточное хранение данных [.filename]#vinum# реализует зеркалирование путем присоединения нескольких плекс к тому. Каждый плекс представляет данные в томе. Том может содержать от одного до восьми плексов. Хотя плекс представляет полные данные тома, возможно, что некоторые части представления физически отсутствуют — либо по замыслу (если поддиск для частей плекса не определён), либо случайно (в результате выхода диска из строя). До тех пор, пока хотя бы один плекс может предоставить данные для полного адресного пространства тома, том остаётся полностью работоспособным. === Какую организацию плексов выбрать? [.filename]#vinum# реализует как объединение, так и чередование на уровне плекс: * _Плекс с объединением_ использует адресное пространство каждого поддиска по очереди. Объединённые плексы являются наиболее гибкими, так как могут содержать любое количество поддисков, а поддиски могут быть разной длины. Плекс может быть расширен путём добавления дополнительных поддисков. Они требуют меньше процессорного времени, чем чередующиеся плексы, хотя разница в нагрузке на процессор незначительна. С другой стороны, они наиболее подвержены "горячим точкам", когда один диск очень активен, а другие простаивают. * _Плекс с чередованием_ распределяет данные по каждому поддиску. Поддиски должны быть одного размера, и их должно быть как минимум два, чтобы отличить такой плекс от объединенного. Главное преимущество чередующихся плексов в том, что они уменьшают вероятность появления "горячих точек". Выбрав оптимальный размер полосы (около 256 КБ), можно равномерно распределить нагрузку на диски – компоненты системы. Расширение плекса путем добавления новых поддисков настолько сложно, что [.filename]#vinum# не реализует эту возможность. crossref:vinum[vinum-comparison, Организации плексов в [.filename]#vinum#] обобщает преимущества и недостатки каждой организации плексов. [[vinum-comparison]] .Организации плексов в [.filename]#vinum# [cols="1,1,1,1,1", frame="none", options="header"] |=== | Тип плекса | Минимальное количество поддисков | Может добавлять поддиски | Должен быть равного размера | Приложение |объединённый |1 |да |no |Крупное хранилище данных с максимальной гибкостью размещения и умеренной производительностью |чередуемый |2 |no |да |Высокая производительность в сочетании с высокопараллельным доступом |=== [[vinum-examples]] == Некоторые примеры -[.filename]#vinum# поддерживает _базу данных конфигурации_, которая описывает объекты, известные конкретной системе. Первоначально пользователь создает базу данных конфигурации из одного или нескольких конфигурационных файлов с помощью man:gvinum[8]. [.filename]#vinum# хранит копию своей базы данных конфигурации на каждом _устройстве_ диска, находящемся под его управлением. Эта база данных обновляется при каждом изменении состояния, так что перезапуск точно восстанавливает состояние каждого объекта [.filename]#vinum#. +[.filename]#vinum# поддерживает _базу данных конфигурации_, которая описывает объекты, известные конкретной системе. Первоначально пользователь создаёт базу данных конфигурации из одного или нескольких конфигурационных файлов с помощью man:gvinum[8]. [.filename]#vinum# хранит копию своей базы данных конфигурации на каждом _устройстве_ диска, находящемся под его управлением. Эта база данных обновляется при каждом изменении состояния, так что перезапуск точно восстанавливает состояние каждого объекта [.filename]#vinum#. === Файл конфигурации Файл конфигурации описывает отдельные объекты [.filename]#vinum#. Определение простого тома может выглядеть следующим образом: [.programlisting] .... drive a device /dev/da3h volume myvol plex org concat sd length 512m drive a .... Этот файл описывает четыре объекта [.filename]#vinum#: * Строка _drive_ описывает раздел диска (_drive_) и его расположение относительно оборудования, на котором он расположен. Ему присваивается символическое имя _a_. Такое разделение символических имён от имён устройств позволяет перемещать диски из одного места в другое без путаницы. * Строка _volume_ описывает том. Единственный обязательный атрибут — это имя, в данном случае _myvol_. * Строка _plex_ определяет плекс. Единственный обязательный параметр — это организация, в данном случае _concat_. Имя не требуется, так как система автоматически генерирует его из имени тома, добавляя суффикс _.px_, где _x_ — номер плекса в томе. Таким образом, этот плекс будет называться _myvol.p0_. * Строка _sd_ описывает поддиск. Минимальные требования — это имя диска для его хранения и длина поддиска. Имя не обязательно, так как система автоматически назначает имена, производные от имени плекса, добавляя суффикс _.sx_, где _x_ — номер поддиска в плексе. Таким образом, [.filename]#vinum# присваивает этому поддиску имя _myvol.p0.s0_. После обработки этого файла команда man:gvinum[8] выводит следующий результат: [.programlisting] .... # gvinum -> create config1 Configuration summary Drives: 1 (4 configured) Volumes: 1 (4 configured) Plexes: 1 (8 configured) Subdisks: 1 (16 configured) D a State: up Device /dev/da3h Avail: 2061/2573 MB (80%) V myvol State: up Plexes: 1 Size: 512 MB P myvol.p0 C State: up Subdisks: 1 Size: 512 MB S myvol.p0.s0 State: up PO: 0 B Size: 512 MB .... Этот вывод показывает краткий формат списка man:gvinum[8]. Он представлен графически в crossref:vinum[vinum-simple-vol, Простой том [.filename]#vinum#]. [[vinum-simple-vol]] .Простой том [.filename]#vinum# image::vinum-simple-vol.png[] Этот рисунок и следующие представляют том, который содержит плексы, которые, в свою очередь, содержат поддиски. В этом примере том содержит один плекс, а плекс содержит один поддиск. Этот конкретный том не имеет особых преимуществ по сравнению с обычным разделом диска. Он содержит один плекс, поэтому не является избыточным. Плекс содержит один поддиск, поэтому нет различий в распределении хранилища по сравнению с обычным разделом диска. В следующих разделах показаны различные более интересные методы конфигурации. === Увеличенная отказоустойчивость: зеркалирование Устойчивость тома может быть повышена за счёт зеркалирования. При создании зеркального тома важно убедиться, что поддиски каждого плекса находятся на разных дисках, чтобы выход из строя одного диска не затронул оба плекса. Следующая конфигурация создаёт зеркальный том: [.programlisting] .... drive b device /dev/da4h volume mirror plex org concat sd length 512m drive a plex org concat sd length 512m drive b .... В этом примере не потребовалось снова указывать определение диска _a_, поскольку [.filename]#vinum# отслеживает все объекты в своей базе данных конфигурации. После обработки этого определения конфигурация выглядит следующим образом: [.programlisting] .... Drives: 2 (4 configured) Volumes: 2 (4 configured) Plexes: 3 (8 configured) Subdisks: 3 (16 configured) D a State: up Device /dev/da3h Avail: 1549/2573 MB (60%) D b State: up Device /dev/da4h Avail: 2061/2573 MB (80%) V myvol State: up Plexes: 1 Size: 512 MB V mirror State: up Plexes: 2 Size: 512 MB P myvol.p0 C State: up Subdisks: 1 Size: 512 MB P mirror.p0 C State: up Subdisks: 1 Size: 512 MB P mirror.p1 C State: initializing Subdisks: 1 Size: 512 MB S myvol.p0.s0 State: up PO: 0 B Size: 512 MB S mirror.p0.s0 State: up PO: 0 B Size: 512 MB S mirror.p1.s0 State: empty PO: 0 B Size: 512 MB .... crossref:vinum[vinum-mirrored-vol, Зеркальный том [.filename]#vinum#] графически отображает структуру. [[vinum-mirrored-vol]] .Зеркальный том [.filename]#vinum# image::vinum-mirrored-vol.png[] В этом примере каждый плекс содержит полные 512 МБ адресного пространства. Как и в предыдущем примере, каждый плекс содержит только один поддиск. === Оптимизация производительности Зеркальный том в предыдущем примере более устойчив к сбоям, чем незеркальный том, но его производительность ниже, так как каждая запись в том требует записи на оба диска, используя большую часть общей пропускной способности дисков. Соображения производительности требуют другого подхода: вместо зеркалирования данные распределяются по полосам на максимально возможное количество дисков. Следующая конфигурация показывает том с плексом, распределённым по полосам на четырёх дисках: [.programlisting] .... drive c device /dev/da5h drive d device /dev/da6h volume stripe plex org striped 512k sd length 128m drive a sd length 128m drive b sd length 128m drive c sd length 128m drive d .... Как и ранее, не нужно определять диски, которые уже известны [.filename]#vinum#. После обработки этого определения конфигурация выглядит следующим образом: [.programlisting] .... Drives: 4 (4 configured) Volumes: 3 (4 configured) Plexes: 4 (8 configured) Subdisks: 7 (16 configured) D a State: up Device /dev/da3h Avail: 1421/2573 MB (55%) D b State: up Device /dev/da4h Avail: 1933/2573 MB (75%) D c State: up Device /dev/da5h Avail: 2445/2573 MB (95%) D d State: up Device /dev/da6h Avail: 2445/2573 MB (95%) V myvol State: up Plexes: 1 Size: 512 MB V mirror State: up Plexes: 2 Size: 512 MB V striped State: up Plexes: 1 Size: 512 MB P myvol.p0 C State: up Subdisks: 1 Size: 512 MB P mirror.p0 C State: up Subdisks: 1 Size: 512 MB P mirror.p1 C State: initializing Subdisks: 1 Size: 512 MB P striped.p1 State: up Subdisks: 1 Size: 512 MB S myvol.p0.s0 State: up PO: 0 B Size: 512 MB S mirror.p0.s0 State: up PO: 0 B Size: 512 MB S mirror.p1.s0 State: empty PO: 0 B Size: 512 MB S striped.p0.s0 State: up PO: 0 B Size: 128 MB S striped.p0.s1 State: up PO: 512 kB Size: 128 MB S striped.p0.s2 State: up PO: 1024 kB Size: 128 MB S striped.p0.s3 State: up PO: 1536 kB Size: 128 MB .... [[vinum-striped-vol]] .Том [.filename]#vinum# с чередованием image::vinum-striped-vol.png[] Этот том представлен на схеме crossref:vinum[vinum-striped-vol, Том [.filename]#vinum# с чередованием]. Темнота полос указывает на позицию в адресном пространстве плекса, где самые светлые полосы идут первыми, а самые темные — последними. === Устойчивость и производительность [[vinum-resilience]]При достаточном аппаратном обеспечении можно создать тома, которые демонстрируют как повышенную отказоустойчивость, так и увеличенную производительность по сравнению со стандартными разделами UNIX(R). Типичный конфигурационный файл может выглядеть так: [.programlisting] .... volume raid10 plex org striped 512k sd length 102480k drive a sd length 102480k drive b sd length 102480k drive c sd length 102480k drive d sd length 102480k drive e plex org striped 512k sd length 102480k drive c sd length 102480k drive d sd length 102480k drive e sd length 102480k drive a sd length 102480k drive b .... Поддиски второго плекса смещены на два диска относительно поддисков первого плекса. Это помогает гарантировать, что записи не будут направляться на одни и те же поддиски, даже если передача затронет два диска. crossref:vinum[vinum-raid10-vol, Том [.filename]#vinum# c зеркалированием и чередованием] представляет структуру этого тома. [[vinum-raid10-vol]] .Том [.filename]#vinum# c зеркалированием и чередованием image::vinum-raid10-vol.png[] [[vinum-object-naming]] == Именование объектов [.filename]#vinum# назначает стандартные имена для плексов и поддисков, хотя их можно изменить. Не рекомендуется изменять стандартные имена, так как это не даёт значительных преимуществ и может вызвать путаницу. Имена могут содержать любые непустые символы, но рекомендуется ограничиваться буквами, цифрами и символами подчёркивания. Имена томов, плексов и поддисков могут быть длиной до 64 символов, а имена дисков — до 32 символов. Объектам [.filename]#vinum# назначаются узлы устройств в иерархии [.filename]#/dev/gvinum#. Приведённая выше конфигурация приведёт к тому, что [.filename]#vinum# создаст следующие узлы устройств: * Записи устройств для каждого тома. Это основные устройства, используемые [.filename]#vinum#. Приведённая конфигурация включает устройства [.filename]#/dev/gvinum/myvol#, [.filename]#/dev/gvinum/mirror#, [.filename]#/dev/gvinum/striped#, [.filename]#/dev/gvinum/raid5# и [.filename]#/dev/gvinum/raid10#. * Все тома получают собственные записи в [.filename]#/dev/gvinum/#. * Каталоги [.filename]#/dev/gvinum/plex# и [.filename]#/dev/gvinum/sd#, которые содержат узлы устройств для каждого плекса и каждого субдиска соответственно. Например, рассмотрим следующий конфигурационный файл: [.programlisting] .... drive drive1 device /dev/sd1h drive drive2 device /dev/sd2h drive drive3 device /dev/sd3h drive drive4 device /dev/sd4h volume s64 setupstate plex org striped 64k sd length 100m drive drive1 sd length 100m drive drive2 sd length 100m drive drive3 sd length 100m drive drive4 .... -После обработки этого файла man:gvinum[8] создает следующую структуру в [.filename]#/dev/gvinum#: +После обработки этого файла man:gvinum[8] создаёт следующую структуру в [.filename]#/dev/gvinum#: [.programlisting] .... drwxr-xr-x 2 root wheel 512 Apr 13 16:46 plex crwxr-xr-- 1 root wheel 91, 2 Apr 13 16:46 s64 drwxr-xr-x 2 root wheel 512 Apr 13 16:46 sd /dev/vinum/plex: total 0 crwxr-xr-- 1 root wheel 25, 0x10000002 Apr 13 16:46 s64.p0 /dev/vinum/sd: total 0 crwxr-xr-- 1 root wheel 91, 0x20000002 Apr 13 16:46 s64.p0.s0 crwxr-xr-- 1 root wheel 91, 0x20100002 Apr 13 16:46 s64.p0.s1 crwxr-xr-- 1 root wheel 91, 0x20200002 Apr 13 16:46 s64.p0.s2 crwxr-xr-- 1 root wheel 91, 0x20300002 Apr 13 16:46 s64.p0.s3 .... Хотя рекомендуется не назначать конкретные имена плексам и поддискам, диски [.filename]#vinum# должны быть именованными. Это позволяет переместить диск в другое место и по-прежнему автоматически его распознавать. Имена дисков могут быть длиной до 32 символов. === Создание файловых систем Тома для системы выглядят идентично дискам, за одним исключением. В отличие от дисков UNIX(R), [.filename]#vinum# не разбивает тома на разделы, поэтому они не содержат таблицы разделов. Это потребовало внесения изменений в некоторые утилиты для работы с дисками, в частности, в man:newfs[8], чтобы они не пытались интерпретировать последнюю букву имени тома [.filename]#vinum# как идентификатор раздела. Например, имя диска может выглядеть как [.filename]#/dev/ad0a# или [.filename]#/dev/da2h#. Эти имена обозначают первый раздел ([.filename]#a#) на первом (0) IDE-диске ([.filename]#ad#) и восьмой раздел ([.filename]#h#) на третьем (2) SCSI-диске ([.filename]#da#), соответственно. В отличие от этого, том [.filename]#vinum# может называться [.filename]#/dev/gvinum/concat#, что не имеет отношения к имени раздела. Чтобы создать файловую систему на этом томе, используйте man:newfs[8]: [source, shell] .... # newfs /dev/gvinum/concat .... [[vinum-config]] == Настройка [.filename]#vinum# Ядро [.filename]#GENERIC# не содержит [.filename]#vinum#. Можно собрать пользовательское ядро с включённым [.filename]#vinum#, но это не рекомендуется. Стандартный способ запуска [.filename]#vinum# — в качестве модуля ядра. Команда man:kldload[8] не требуется, так как при запуске man:gvinum[8] проверяет, загружен ли модуль, и если нет, загружает его автоматически. === Запуск [.filename]#vinum# хранит конфигурационную информацию на дисковых слайсах практически в той же форме, что и в конфигурационных файлах. При чтении из базы данных конфигурации [.filename]#vinum# распознаёт ряд ключевых слов, которые не допускаются в конфигурационных файлах. Например, конфигурация диска может содержать следующий текст: [.programlisting] .... volume myvol state up volume bigraid state down plex name myvol.p0 state up org concat vol myvol plex name myvol.p1 state up org concat vol myvol plex name myvol.p2 state init org striped 512b vol myvol plex name bigraid.p0 state initializing org raid5 512b vol bigraid sd name myvol.p0.s0 drive a plex myvol.p0 state up len 1048576b driveoffset 265b plexoffset 0b sd name myvol.p0.s1 drive b plex myvol.p0 state up len 1048576b driveoffset 265b plexoffset 1048576b sd name myvol.p1.s0 drive c plex myvol.p1 state up len 1048576b driveoffset 265b plexoffset 0b sd name myvol.p1.s1 drive d plex myvol.p1 state up len 1048576b driveoffset 265b plexoffset 1048576b sd name myvol.p2.s0 drive a plex myvol.p2 state init len 524288b driveoffset 1048841b plexoffset 0b sd name myvol.p2.s1 drive b plex myvol.p2 state init len 524288b driveoffset 1048841b plexoffset 524288b sd name myvol.p2.s2 drive c plex myvol.p2 state init len 524288b driveoffset 1048841b plexoffset 1048576b sd name myvol.p2.s3 drive d plex myvol.p2 state init len 524288b driveoffset 1048841b plexoffset 1572864b sd name bigraid.p0.s0 drive a plex bigraid.p0 state initializing len 4194304b driveoff set 1573129b plexoffset 0b sd name bigraid.p0.s1 drive b plex bigraid.p0 state initializing len 4194304b driveoff set 1573129b plexoffset 4194304b sd name bigraid.p0.s2 drive c plex bigraid.p0 state initializing len 4194304b driveoff set 1573129b plexoffset 8388608b sd name bigraid.p0.s3 drive d plex bigraid.p0 state initializing len 4194304b driveoff set 1573129b plexoffset 12582912b sd name bigraid.p0.s4 drive e plex bigraid.p0 state initializing len 4194304b driveoff set 1573129b plexoffset 16777216b .... Очевидные различия здесь — наличие явной информации о местоположении и именования, что разрешено, но не рекомендуется, а также информация о состояниях. [.filename]#vinum# не хранит сведения о дисках в конфигурационной информации. Он находит диски, сканируя настроенные дисковые накопители на наличие разделов с меткой [.filename]#vinum#. Это позволяет [.filename]#vinum# корректно идентифицировать диски, даже если им были присвоены разные идентификаторы дисков UNIX(R). [[vinum-rc-startup]] ==== Автоматический запуск _Gvinum_ всегда запускается автоматически после загрузки модуля ядра через man:loader.conf[5]. Чтобы загрузить модуль _Gvinum_ при загрузке системы, добавьте `geom_vinum_load="YES"` в [.filename]#/boot/loader.conf#. Когда [.filename]#vinum# запускается командой `gvinum start`, [.filename]#vinum# читает конфигурационную базу данных с одного из дисков [.filename]#vinum#. В нормальных условиях каждый диск содержит идентичную копию конфигурационной базы данных, поэтому не имеет значения, с какого диска читать. Однако после сбоя [.filename]#vinum# должен определить, какой диск был обновлён последним, и прочитать конфигурацию с этого диска. Затем, если необходимо, он обновляет конфигурацию последовательно с более старых дисков. [[vinum-root]] == Использование [.filename]#vinum# для корневой файловой системы Для машины с полностью зеркалированными файловыми системами с использованием [.filename]#vinum#, желательно также зеркалировать корневую файловую систему. Настройка такой конфигурации менее тривиальна, чем зеркалирование произвольной файловой системы, потому что: * Корневая файловая система должна быть доступна очень рано в процессе загрузки, поэтому инфраструктура [.filename]#vinum# должна быть уже доступна на этом этапе. * Том, содержащий корневую файловую систему, также включает системный загрузчик и ядро. Они должны быть прочитаны с использованием родных утилит хостовой системы, таких как BIOS, который зачастую нельзя обучить работе с деталями [.filename]#vinum#. В следующих разделах термин "корневой том" обычно используется для описания тома [.filename]#vinum#, который содержит корневую файловую систему. === Запуск [.filename]#vinum# на раннем этапе для обеспечения доступа к корневой файловой системе Файл `[.filename]#vinum#` должен быть доступен на раннем этапе загрузки системы, так как `man:loader[8]` должен загрузить модуль ядра `vinum` перед запуском ядра. Это можно сделать, добавив следующую строку в `[.filename]#/boot/loader.conf#`: [.programlisting] .... geom_vinum_load="YES" .... === Создание корневого тома на основе [.filename]#vinum#, доступного для загрузчика Текущая загрузочная запись FreeBSD занимает всего 7,5 КБ кода и не понимает внутренние структуры [.filename]#vinum#. Это означает, что она не может разобрать конфигурационные данные [.filename]#vinum# или определить элементы загрузочного тома. Таким образом, необходимы некоторые обходные решения, чтобы предоставить загрузочному коду иллюзию стандартного раздела `a`, содержащего корневую файловую систему. Для этого должны быть выполнены следующие требования к корневому тому: * Корневой том не должен быть чередующимся или `RAID`-5. * Корневой том не должен содержать более одного объединённого поддиска на плекс. Обратите внимание, что желательно и возможно использовать несколько плексов, каждый из которых содержит одну реплику корневой файловой системы. Процесс начальной загрузки будет использовать только одну реплику для поиска загрузчика и всех загрузочных файлов, пока ядро не смонтирует корневую файловую систему. Каждый отдельный поддиск в этих плексах должен иметь свою собственную иллюзию раздела `a`, чтобы соответствующее устройство было загрузочным. Не строго необходимо, чтобы каждый из этих фальшивых разделов `a` находился на том же смещении внутри своего устройства по сравнению с другими устройствами, содержащими плекс корневого тома. Однако, вероятно, хорошей идеей будет создавать тома [.filename]#vinum# таким образом, чтобы результирующие зеркальные устройства были симметричными, чтобы избежать путаницы. Для настройки этих разделов `a` на каждом устройстве, содержащем часть корневого тома, требуется следующее: [.procedure] ==== . Местоположение, смещение от начала устройства и размер подобласти этого устройства, которая является частью корневого тома, необходимо проверить с помощью команды: + [source, shell] .... # gvinum l -rv root .... + Смещения и размеры в [.filename]#vinum# измеряются в байтах. Их необходимо разделить на 512, чтобы получить номера блоков, которые будут использоваться в `bsdlabel`. . Выполните эту команду для каждого устройства, участвующего в корневом томе: + [source, shell] .... # bsdlabel -e devname .... + `_devname_` должен быть либо именем диска, например, [.filename]#da0# для дисков без таблицы разделов, либо именем раздела, например, [.filename]#ad0s1#. + Если на устройстве уже существует раздел `a` из корневой файловой системы до [.filename]#vinum#, его следует переименовать во что-то другое, чтобы он оставался доступным (на всякий случай), но больше не использовался по умолчанию для загрузки системы. Текущий смонтированный корневой файловой системы нельзя переименовать, поэтому это должно выполняться либо при загрузке с "Fixit" носителя, либо в два этапа, когда в зеркале сначала обрабатывается диск, с которого в данный момент не загружаются. + Смещение раздела [.filename]#vinum# на этом устройстве (если есть) должно быть добавлено к смещению соответствующего поддиска корневого тома на этом устройстве. Полученное значение станет значением `offset` для нового раздела `a`. Значение `size` для этого раздела можно взять дословно из приведённых выше расчётов. Для `fstype` следует указать `4.2BSD`. Значения `fsize`, `bsize` и `cpg` должны быть выбраны в соответствии с реальной файловой системой, хотя в данном контексте они не слишком важны. + Таким образом, будет создан новый раздел `a`, который перекрывает раздел [.filename]#vinum# на этом устройстве. `bsdlabel` разрешит это перекрытие только в том случае, если раздел [.filename]#vinum# был правильно помечен с использованием типа файловой системы `vinum`. . Поддельный раздел `a` теперь существует на каждом устройстве, имеющем одну реплику корневого тома. Настоятельно рекомендуется проверить результат с помощью команды, например: + [source, shell] .... # fsck -n /dev/devnamea .... ==== Следует помнить, что все файлы, содержащие управляющую информацию, должны быть относительны к корневой файловой системе в томе [.filename]#vinum#, которая при настройке нового корневого тома [.filename]#vinum# может не совпадать с текущей активной корневой файловой системой. Поэтому, в частности, необходимо позаботиться о [.filename]#/etc/fstab# и [.filename]#/boot/loader.conf#. При следующей перезагрузке загрузчик должен определить соответствующую управляющую информацию из новой корневой файловой системы на основе [.filename]#vinum# и действовать соответствующим образом. В конце процесса инициализации ядра, после объявления всех устройств, явным признаком успешного завершения настройки будет сообщение вида: [source, shell] .... Mounting root from ufs:/dev/gvinum/root .... === Пример настройки корневой системы на основе [.filename]#vinum# После настройки корневого тома [.filename]#vinum#, вывод команды `gvinum l -rv root` может выглядеть следующим образом: [source, shell] .... ... Subdisk root.p0.s0: Size: 125829120 bytes (120 MB) State: up Plex root.p0 at offset 0 (0 B) Drive disk0 (/dev/da0h) at offset 135680 (132 kB) Subdisk root.p1.s0: Size: 125829120 bytes (120 MB) State: up Plex root.p1 at offset 0 (0 B) Drive disk1 (/dev/da1h) at offset 135680 (132 kB) .... Значения, на которые следует обратить внимание: `135680` для смещения, относительного к разделу [.filename]#/dev/da0h#. Это соответствует 265 блокам диска по 512 байт в терминах `bsdlabel`. Аналогично, размер этого корневого тома составляет 245760 блоков по 512 байт. [.filename]#/dev/da1h#, содержащий вторую реплику этого корневого тома, имеет симметричную конфигурацию. Метка bsdlabel для этих устройств может выглядеть следующим образом: [source, shell] .... ... 8 partitions: # size offset fstype [fsize bsize bps/cpg] a: 245760 281 4.2BSD 2048 16384 0 # (Cyl. 0*- 15*) c: 71771688 0 unused 0 0 # (Cyl. 0 - 4467*) h: 71771672 16 vinum # (Cyl. 0*- 4467*) .... Можно заметить, что параметр `size` для поддельного раздела `a` совпадает с указанным выше значением, в то время как параметр `offset` представляет собой сумму смещения внутри раздела [.filename]#vinum# `h` и смещения этого раздела в устройстве или слайсе. Это стандартная настройка, необходимая для избежания проблемы, описанной в crossref:vinum[vinum-root-panic, Nothing Boots, the Bootstrap Panics]. Весь раздел `a` полностью находится внутри раздела `h`, содержащего все данные [.filename]#vinum# для этого устройства. В приведённом выше примере все устройство выделено под [.filename]#vinum#, и не осталось корневого раздела, существовавшего до [.filename]#vinum#. === Устранение неполадок Следующий список содержит несколько известных подводных камней и их решения. ==== Загрузчик системы загружается, но система не запускается Если по какой-либо причине система не продолжает загрузку, процесс можно прервать, нажав kbd:[space] при появлении 10-секундного предупреждения. Переменную загрузчика `vinum.autostart` можно проверить, введя команду `show`, и изменить с помощью `set` или `unset`. Если модуль ядра [.filename]#vinum# ещё не был в списке модулей для автоматической загрузки, введите `load geom_vinum`. Когда всё готово, процесс загрузки можно продолжить, введя `boot -as`, где `-as` указывает ядру запросить корневую файловую систему для монтирования (`-a`) и остановить процесс загрузки в однопользовательском режиме (`-s`), при этом корневая файловая система монтируется в режиме только для чтения. Таким образом, даже если смонтирован только один слой многокомпонентного тома, не возникает риска несогласованности данных между слоями. На запрос о корневой файловой системе для монтирования можно ввести любое устройство, содержащее действительную корневую файловую систему. Если [.filename]#/etc/fstab# настроен правильно, по умолчанию должно быть что-то вроде `ufs:/dev/gvinum/root`. Типичным альтернативным выбором может быть что-то вроде `ufs:da0d`, что может быть гипотетическим разделом, содержащим корневую файловую систему до [.filename]#vinum#. Следует быть осторожным, если здесь вводится один из псевдонимов `a` разделов, чтобы он действительно ссылался на поддиски устройства [.filename]#vinum# root, потому что в зеркальной настройке это приведёт к монтированию только одной части зеркального корневого устройства. Если эта файловая система будет позже смонтирована в режиме чтения-записи, необходимо удалить другие плексы тома [.filename]#vinum# root, так как в противном случае эти плексы будут содержать несогласованные данные. ==== Только первичная загрузка Bootstrap Если [.filename]#/boot/loader# не загружается, но первичная загрузка всё ещё работает (это видно по одному дефису в левой части экрана сразу после начала процесса загрузки), можно попытаться прервать первичную загрузку, нажав kbd:[space]. Это остановит загрузку на extref:{handbook}boot[втором этапе, boot-boot1]. Здесь можно попытаться загрузиться с альтернативного раздела, например, с раздела, содержащего предыдущую корневую файловую систему, которая была перемещена из `a`. [[vinum-root-panic]] ==== Ничего не загружается, паника при загрузке Такая ситуация произойдет, если загрузчик был уничтожен при установке [.filename]#vinum#. К сожалению, [.filename]#vinum# случайно оставляет свободными только первые 4 КБ в начале своего раздела перед записью заголовочной информации [.filename]#vinum#. Однако, первая и вторая стадии загрузчика вместе с bsdlabel требуют 8 КБ. Поэтому, если раздел [.filename]#vinum# начинается со смещения 0 внутри слайса или диска, который должен быть загрузочным, установка [.filename]#vinum# повредит загрузчик. Аналогично, если описанная выше ситуация была исправлена загрузкой с "Fixit"-носителя, и загрузчик был переустановлен с помощью `bsdlabel -B`, как описано в extref:{handbook}boot[этапе два, boot-boot1], загрузчик повредит заголовок [.filename]#vinum#, и [.filename]#vinum# больше не сможет найти свои диски. Хотя фактические данные конфигурации [.filename]#vinum# или данные в томах [.filename]#vinum# не будут повреждены, и можно восстановить все данные, введя точно такую же конфигурацию [.filename]#vinum# снова, исправить ситуацию сложно. Необходимо переместить весь раздел [.filename]#vinum# как минимум на 4 КБ, чтобы заголовок [.filename]#vinum# и системный загрузчик больше не конфликтовали. diff --git a/documentation/content/ru/articles/vinum/_index.po b/documentation/content/ru/articles/vinum/_index.po index affce6fe8a..651eebad56 100644 --- a/documentation/content/ru/articles/vinum/_index.po +++ b/documentation/content/ru/articles/vinum/_index.po @@ -1,2260 +1,2260 @@ # SOME DESCRIPTIVE TITLE # Copyright (C) YEAR The FreeBSD Project # This file is distributed under the same license as the FreeBSD Documentation package. # Vladlen Popolitov , 2025, 2026. msgid "" msgstr "" "Project-Id-Version: FreeBSD Documentation VERSION\n" "POT-Creation-Date: 2025-11-08 16:17+0000\n" -"PO-Revision-Date: 2026-03-08 09:11+0000\n" +"PO-Revision-Date: 2026-04-05 04:45+0000\n" "Last-Translator: Vladlen Popolitov \n" "Language-Team: Russian \n" "Language: ru\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && " "n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" "X-Generator: Weblate 4.17\n" #. type: YAML Front Matter: description #: documentation/content/en/articles/vinum/_index.adoc:1 #, no-wrap msgid "The vinum Volume Manager in FreeBSD" msgstr "Менеджер томов vinum в FreeBSD" #. The Vinum Volume Manager #. By Greg Lehey (grog at lemis dot com) #. Added to the Handbook by Hiten Pandya #. and Tom Rhodes #. For the FreeBSD Documentation Project #. type: Title = #: documentation/content/en/articles/vinum/_index.adoc:1 #: documentation/content/en/articles/vinum/_index.adoc:19 #, no-wrap msgid "The vinum Volume Manager" msgstr "Менеджер томов vinum" #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:51 msgid "'''" msgstr "'''" #. type: Title == #: documentation/content/en/articles/vinum/_index.adoc:55 #, no-wrap msgid "Synopsis" msgstr "Обзор" #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:62 msgid "" "No matter the type of disks, there are always potential problems. The disks " "can be too small, too slow, or too unreliable to meet the system's " "requirements. While disks are getting bigger, so are data storage " "requirements. Often a file system is needed that is bigger than a disk's " "capacity. Various solutions to these problems have been proposed and " "implemented." msgstr "" "Независимо от типа дисков, всегда существуют потенциальные проблемы. Диски " "могут быть слишком малы, слишком медленны или недостаточно надёжны для " "соответствия требованиям системы. Хотя диски становятся больше, требования " "к хранению данных также растут. Часто требуется файловая система, размер " "которой превышает емкость одного диска. Были предложены и реализованы " "различные решения этих проблем." #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:66 msgid "" "One method is through the use of multiple, and sometimes redundant, disks. " "In addition to supporting various cards and controllers for hardware " "Redundant Array of Independent Disks RAID systems, the base FreeBSD system " "includes the [.filename]#vinum# volume manager, a block device driver that " "implements virtual disk drives and addresses these three problems. [." "filename]#vinum# provides more flexibility, performance, and reliability " "than traditional disk storage and implements `RAID`-0, `RAID`-1, and " "`RAID`-5 models, both individually and in combination." msgstr "" "Один из методов заключается в использовании нескольких, а иногда и " "избыточных дисков. Помимо поддержки различных карт и контроллеров для " "аппаратных систем RAID (Redundant Array of Independent Disks), базовая " "система FreeBSD включает менеджер томов [.filename]#vinum#, драйвер блочных " "устройств, который реализует виртуальные диски и решает эти три проблемы. [." "filename]#vinum# обеспечивает большую гибкость, производительность и " "надёжность по сравнению с традиционными системами хранения данных, а также " "реализует модели `RAID`-0, `RAID`-1 и `RAID`-5 как по отдельности, так и в " "комбинации." #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:68 msgid "" "This chapter provides an overview of potential problems with traditional " "disk storage, and an introduction to the [.filename]#vinum# volume manager." msgstr "" "Эта глава предоставляет обзор потенциальных проблем с традиционным дисковым " "хранилищем и введение в менеджер томов [.filename]#vinum#." #. type: delimited block = 4 #: documentation/content/en/articles/vinum/_index.adoc:73 msgid "" "vinum is deprecated and is not present in FreeBSD 15.0 and later. Users are " "advised to migrate to man:gconcat[8], man:gmirror[8], man:gstripe[8], man:" "graid[8], or man:zfs[8]." msgstr "" "vinum устарел и отсутствует в FreeBSD 15.0 и более поздних версиях. " "Пользователям рекомендуется перейти на man:gconcat[8], man:gmirror[8], man:" "gstripe[8], man:graid[8] или man:zfs[8]." #. type: delimited block = 4 #: documentation/content/en/articles/vinum/_index.adoc:82 msgid "" "Starting with FreeBSD 5, [.filename]#vinum# has been rewritten to fit into " "the extref:{handbook}geom[GEOM architecture, geom], while retaining the " "original ideas, terminology, and on-disk metadata. This rewrite is called " "_gvinum_ (for _GEOM vinum_). While this chapter uses the term [." "filename]#vinum#, any command invocations should be performed with " "`gvinum`. The name of the kernel module has changed from the original [." "filename]#vinum.ko# to [.filename]#geom_vinum.ko#, and all device nodes " "reside under [.filename]#/dev/gvinum# instead of [.filename]#/dev/vinum#. " "As of FreeBSD 6, the original [.filename]#vinum# implementation is no longer " "available in the code base." msgstr "" "Начиная с FreeBSD 5, [.filename]#vinum# был переписан для интеграции в " "extref:{handbook}geom[архитектуру GEOM, geom-synopsis], сохраняя при этом " "оригинальные идеи, терминологию и метаданные на диске. Эта переработанная " "версия называется _gvinum_ (от _GEOM vinum_). Хотя в этой главе используется " "термин [.filename]#vinum#, все команды должны выполняться с помощью `gvinum`" ". Имя модуля ядра изменилось с оригинального [.filename]#vinum.ko# на [." "filename]#geom_vinum.ko#, а все узлы устройств находятся в [.filename]#/dev/" "gvinum# вместо [.filename]#/dev/vinum#. Начиная с FreeBSD 6, оригинальная " "реализация [.filename]#vinum# больше не доступна в кодовой базе." #. type: Title == #: documentation/content/en/articles/vinum/_index.adoc:85 #, no-wrap msgid "Access Bottlenecks" msgstr "Узкие места доступа" #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:89 msgid "" "Modern systems frequently need to access data in a highly concurrent " "manner. For example, large FTP or HTTP servers can maintain thousands of " "concurrent sessions and have multiple 100 Mbit/s connections to the outside " "world, well beyond the sustained transfer rate of most disks." msgstr "" "Современные системы часто нуждаются в доступе к данным в условиях высокой " "параллельности. Например, крупные FTP- или HTTP-серверы могут поддерживать " "тысячи одновременных сеансов и иметь несколько 100 Мбит/с соединений с " "внешним миром, что значительно превышает устойчивую скорость передачи " "большинства дисков." #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:93 msgid "" "Current disk drives can transfer data sequentially at up to 70 MB/s, but " "this value is of little importance in an environment where many independent " "processes access a drive, and where they may achieve only a fraction of " "these values. In such cases, it is more interesting to view the problem " "from the viewpoint of the disk subsystem. The important parameter is the " "load that a transfer places on the subsystem, or the time for which a " "transfer occupies the drives involved in the transfer." msgstr "" "Современные дисковые накопители могут передавать данные последовательно со " "скоростью до 70 МБ/с, но это значение имеет мало значения в среде, где " "множество независимых процессов обращаются к накопителю и могут достичь лишь " "доли этих значений. В таких случаях более интересно рассмотреть проблему с " "точки зрения дисковой подсистемы. Важным параметром является нагрузка, " "которую передача данных создаёт на подсистему, или время, в течение которого " "передача занимает задействованные накопители." #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:96 msgid "" "In any disk transfer, the drive must first position the heads, wait for the " "first sector to pass under the read head, and then perform the transfer. " "These actions can be considered to be atomic as it does not make any sense " "to interrupt them." msgstr "" "При любом переносе данных на диск сначала необходимо позиционировать " "головки, дождаться, пока первый сектор окажется под считывающей головкой, а " "затем выполнить перенос. Эти действия можно считать атомарными, так как их " "прерывание не имеет смысла." #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:101 msgid "" "[[vinum-latency]] Consider a typical transfer of about 10 kB: the current " "generation of high-performance disks can position the heads in an average of " "3.5 ms. The fastest drives spin at 15,000 rpm, so the average rotational " "latency (half a revolution) is 2 ms. At 70 MB/s, the transfer itself takes " "about 150 μs, almost nothing compared to the positioning time. In such a " "case, the effective transfer rate drops to a little over 1 MB/s and is " "clearly highly dependent on the transfer size." msgstr "" "[[vinum-latency]] Рассмотрим типичную передачу около 10 КБ: современные " "высокопроизводительные диски могут позиционировать головки в среднем за 3,5 " "мс. Самые быстрые диски вращаются со скоростью 15 000 об/мин, поэтому " "средняя задержка вращения (половина оборота) составляет 2 мс. При скорости " "70 МБ/с сама передача занимает около 150 мкс, что почти ничто по сравнению с " "временем позиционирования. В таком случае эффективная скорость передачи " "падает до чуть более 1 МБ/с и явно сильно зависит от размера передачи." #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:104 msgid "" "The traditional and obvious solution to this bottleneck is \"more spindles" "\": rather than using one large disk, use several smaller disks with the " "same aggregate storage space. Each disk is capable of positioning and " "transferring independently, so the effective throughput increases by a " "factor close to the number of disks used." msgstr "" "Традиционное и очевидное решение этой проблемы — «больше дисков»: вместо " "одного большого диска использовать несколько дисков меньшего размера с тем " "же общим объёмом хранилища. Каждый диск способен позиционироваться и " "передавать данные независимо, поэтому эффективная пропускная способность " "увеличивается почти пропорционально количеству используемых дисков." #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:108 msgid "" "The actual throughput improvement is smaller than the number of disks " "involved. Although each drive is capable of transferring in parallel, there " "is no way to ensure that the requests are evenly distributed across the " "drives. Inevitably the load on one drive will be higher than on another." msgstr "" "Фактическое увеличение пропускной способности меньше, чем количество " "задействованных дисков. Хотя каждый диск способен передавать данные " "параллельно, нет возможности гарантировать равномерное распределение " "запросов между дисками. Неизбежно нагрузка на один диск будет выше, чем на " "другой." #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:116 msgid "" "The evenness of the load on the disks is strongly dependent on the way the " "data is shared across the drives. In the following discussion, it is " "convenient to think of the disk storage as a large number of data sectors " "which are addressable by number, rather like the pages in a book. The most " "obvious method is to divide the virtual disk into groups of consecutive " "sectors the size of the individual physical disks and store them in this " "manner, rather like taking a large book and tearing it into smaller " "sections. This method is called _concatenation_ and has the advantage that " "the disks are not required to have any specific size relationships. It " "works well when the access to the virtual disk is spread evenly about its " "address space. When access is concentrated on a smaller area, the " "improvement is less marked. crossref:vinum[vinum-concat, Concatenated " "Organization] illustrates the sequence in which storage units are allocated " "in a concatenated organization." msgstr "" "Равномерность нагрузки на диски сильно зависит от способа распределения " "данных по накопителям. В дальнейшем обсуждении удобно представлять дисковое " "хранилище как большое количество секторов данных, адресуемых по номерам, " "подобно страницам в книге. Наиболее очевидный метод — разделить виртуальный " "диск на группы последовательных секторов размером с отдельные физические " "диски и хранить их таким образом, как если бы большую книгу разорвали на " "меньшие разделы. Этот метод называется _объединением_ (конкатенацией) и " "имеет преимущество в том, что диски не требуют каких-либо определённых " "соотношений размеров. Он хорошо работает, когда доступ к виртуальному диску " "равномерно распределён по его адресному пространству. Если доступ " "сосредоточен на меньшей области, улучшение менее заметно. crossref:" "vinum[vinum-concat, Организация методом объединения] иллюстрирует " "последовательность выделения блоков хранения в организации методом " "объединения." #. type: Block title #: documentation/content/en/articles/vinum/_index.adoc:118 #, no-wrap msgid "Concatenated Organization" msgstr "Организация методом объединения" #. type: Target for macro image #: documentation/content/en/articles/vinum/_index.adoc:119 #, no-wrap msgid "vinum-concat.png" msgstr "vinum-concat.png" #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:125 msgid "" "An alternative mapping is to divide the address space into smaller, equal-" "sized components and store them sequentially on different devices. For " "example, the first 256 sectors may be stored on the first disk, the next 256 " "sectors on the next disk and so on. After filling the last disk, the " "process repeats until the disks are full. This mapping is called _striping_ " "or RAID-0." msgstr "" "Альтернативный метод распределения заключается в разделении адресного " "пространства на меньшие равные по размеру компоненты и их последовательном " "хранении на разных устройствах. Например, первые 256 секторов могут " "храниться на первом диске, следующие 256 секторов — на следующем диске и так " "далее. После заполнения последнего диска процесс повторяется, пока все диски " "не будут заполнены. Такой метод называется _чередованием (striping)_ или " "RAID-0." #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:129 msgid "" "`RAID` offers various forms of fault tolerance, though RAID-0 is somewhat " "misleading as it provides no redundancy. Striping requires somewhat more " "effort to locate the data, and it can cause additional I/O load where a " "transfer is spread over multiple disks, but it can also provide a more " "constant load across the disks. crossref:vinum[vinum-striped, Striped " "Organization] illustrates the sequence in which storage units are allocated " "in a striped organization." msgstr "" "`RAID` предлагает различные формы отказоустойчивости, хотя RAID-0 несколько " "вводит в заблуждение, так как не обеспечивает избыточности. Разделение " "данных требует несколько больше усилий для их поиска и может создавать " "дополнительную нагрузку ввода-вывода, когда передача распределяется по " "нескольким дискам, но также может обеспечить более равномерную нагрузку на " "диски. crossref:vinum[vinum-striped,Организация методом чередования] " "иллюстрирует последовательность, в которой организуется распределение блоков " "хранения с чередованием." #. type: Block title #: documentation/content/en/articles/vinum/_index.adoc:131 #, no-wrap msgid "Striped Organization" msgstr "Организация методом чередования" #. type: Target for macro image #: documentation/content/en/articles/vinum/_index.adoc:132 #, no-wrap msgid "vinum-striped.png" msgstr "vinum-striped.png" #. type: Title == #: documentation/content/en/articles/vinum/_index.adoc:135 #, no-wrap msgid "Data Integrity" msgstr "Целостность данных" #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:140 msgid "" "The final problem with disks is that they are unreliable. Although " "reliability has increased tremendously over the last few years, disk drives " "are still the most likely core component of a server to fail. When they do, " "the results can be catastrophic and replacing a failed disk drive and " "restoring data can result in server downtime." msgstr "" "Последняя проблема с дисками заключается в их ненадёжности. Хотя надёжность " "значительно повысилась за последние годы, дисковые накопители остаются " "наиболее вероятным компонентом сервера, который может выйти из строя. Когда " "это происходит, последствия могут быть катастрофическими, а замена вышедшего " "из строя диска и восстановление данных могут привести к простою сервера." #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:143 msgid "" "One approach to this problem is _mirroring_, or `RAID-1`, which keeps two " "copies of the data on different physical hardware. Any write to the volume " "writes to both disks; a read can be satisfied from either, so if one drive " "fails, the data is still available on the other drive." msgstr "" "Один из подходов к этой проблеме — _зеркалирование_, или `RAID-1`, при " "котором данные хранятся в двух экземплярах на разных физических носителях. " "Любая запись на том записывается на оба диска; чтение может выполняться с " "любого из них, поэтому при отказе одного диска данные остаются доступны на " "другом." #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:145 msgid "Mirroring has two problems:" msgstr "Зеркалирование имеет две проблемы:" #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:147 msgid "It requires twice as much disk storage as a non-redundant solution." msgstr "" "Требуется в два раза больше дискового пространства, чем для решения без " "избыточности." #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:148 msgid "" "Writes must be performed to both drives, so they take up twice the bandwidth " "of a non-mirrored volume. Reads do not suffer from a performance penalty and " "can even be faster." msgstr "" "Запись должна выполняться на оба диска, поэтому она занимает в два раза " "больше пропускной способности, чем в незеркалированном томе. Чтение не " "страдает от потери производительности и может быть даже быстрее." #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:155 msgid "" "An alternative solution is _parity_, implemented in `RAID` levels 2, 3, 4 " "and 5. Of these, `RAID-5` is the most interesting. As implemented in [." "filename]#vinum#, it is a variant on a striped organization which dedicates " "one block of each stripe to parity one of the other blocks. As implemented " "by [.filename]#vinum#, a `RAID-5` plex is similar to a striped plex, except " "that it implements `RAID-5` by including a parity block in each stripe. As " "required by `RAID-5`, the location of this parity block changes from one " "stripe to the next. The numbers in the data blocks indicate the relative " "block numbers." msgstr "" "Альтернативным решением является _чётность_, реализованная в уровнях `RAID` " "2, 3, 4 и 5. Из них `RAID-5` представляет наибольший интерес. В реализации [." "filename]#vinum# это вариант организации с чередованием, где один блок " "каждой полосы выделяется под чётность одного из других блоков. В реализации [" ".filename]#vinum# плекс `RAID-5` аналогичен плексу с чередованием, за " "исключением того, что он реализует `RAID-5`, включая блок чётности в каждую " "полосу. Как требуется в `RAID-5`, расположение этого блока чётности меняется " "от одной полосы к другой. Числа в блоках данных обозначают относительные " "номера блоков." #. type: Block title #: documentation/content/en/articles/vinum/_index.adoc:157 #, no-wrap msgid "`RAID`-5 Organization" msgstr "Организация `RAID`-5" #. type: Target for macro image #: documentation/content/en/articles/vinum/_index.adoc:158 #, no-wrap msgid "vinum-raid5-org.png" msgstr "vinum-raid5-org.png" #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:163 msgid "" "Compared to mirroring, `RAID-5` has the advantage of requiring significantly " "less storage space. Read access is similar to that of striped " "organizations, but write access is significantly slower, approximately 25% " "of the read performance. If one drive fails, the array can continue to " "operate in degraded mode where a read from one of the remaining accessible " "drives continues normally, but a read from the failed drive is recalculated " "from the corresponding block from all the remaining drives." msgstr "" "По сравнению с зеркалированием, `RAID-5` имеет преимущество в виде " "значительно меньшего требуемого объёма хранилища. Скорость чтения аналогична " "таковой при чередующейся организации, но скорость записи значительно ниже — " "примерно 25% от скорости чтения. Если один диск выходит из строя, массив " "может продолжать работу в деградировавшем режиме, при котором чтение с " "оставшихся доступных дисков продолжается в обычном режиме, а чтение с " "отказавшего диска пересчитывается из соответствующих блоков всех оставшихся " "дисков." #. type: Title == #: documentation/content/en/articles/vinum/_index.adoc:165 #, no-wrap msgid "[.filename]#vinum# Objects" msgstr "Объекты [.filename]#vinum#" #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:168 msgid "" "To address these problems, [.filename]#vinum# implements a four-level " "hierarchy of objects:" msgstr "" "Для решения этих проблем [.filename]#vinum# реализует четырёхуровневую " "иерархию объектов:" #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:170 msgid "" "The most visible object is the virtual disk, called a _volume_. Volumes have " "essentially the same properties as a UNIX(R) disk drive, though there are " "some minor differences. For one, they have no size limitations." msgstr "" "Наиболее заметным объектом является виртуальный диск, называемый _томом_. " "Том обладает практически теми же свойствами, что и UNIX(R) дисковый " "накопитель, хотя есть некоторые незначительные отличия. Например, у тома нет " "ограничений по размеру." #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:171 msgid "" "Volumes are composed of _plexes_, each of which represent the total address " "space of a volume. This level in the hierarchy provides redundancy. Think of " "plexes as individual disks in a mirrored array, each containing the same " "data." msgstr "" "Тома состоят из _плексов_, каждый из которых представляет полное адресное " "пространство тома. Этот уровень в иерархии обеспечивает избыточность. Можно " "представить плексы как отдельные диски в зеркальном массиве, каждый из " "которых содержит одинаковые данные." #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:172 msgid "" "Since [.filename]#vinum# exists within the UNIX(R) disk storage framework, " "it would be possible to use UNIX(R) partitions as the building block for " "multi-disk plexes. In fact, this turns out to be too inflexible as UNIX(R) " "disks can have only a limited number of partitions. Instead, [." "filename]#vinum# subdivides a single UNIX(R) partition, the _drive_, into " "contiguous areas called _subdisks_, which are used as building blocks for " "plexes." msgstr "" "Поскольку [.filename]#vinum# существует в рамках системы хранения данных " "UNIX(R), можно было бы использовать разделы UNIX(R) в качестве строительных " "блоков для многодисковых plexes. Однако на практике это оказывается слишком " "негибким, так как диски UNIX(R) могут иметь только ограниченное количество " "разделов. Вместо этого [.filename]#vinum# разбивает единственный раздел " "UNIX(R), называемый _дисковый раздел (drive)_, на непрерывные области, " "называемые _поддисками (subdisk)_, которые используются как строительные " "блоки для плексов." #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:173 msgid "" "Subdisks reside on [.filename]#vinum#_drives_, currently UNIX(R) partitions. " "[.filename]#vinum# drives can contain any number of subdisks. With the " "exception of a small area at the beginning of the drive, which is used for " "storing configuration and state information, the entire drive is available " "for data storage." msgstr "" "Поддиски располагаются на _дисковых разделах_ [.filename]#vinum#, в " "настоящее время это разделы UNIX(R). Разделы [.filename]#vinum# могут " "содержать любое количество поддисков. За исключением небольшой области в " "начале раздела, которая используется для хранения конфигурации и состояния, " "весь раздел доступен для хранения данных." #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:175 msgid "" "The following sections describe the way these objects provide the " "functionality required of [.filename]#vinum#." msgstr "" "Следующие разделы статьи описывают, каким образом эти объекты обеспечивают " "функциональность, требуемую для [.filename]#vinum#." #. type: Title === #: documentation/content/en/articles/vinum/_index.adoc:176 #, no-wrap msgid "Volume Size Considerations" msgstr "Учёт размера томов" #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:180 msgid "" "Plexes can include multiple subdisks spread over all drives in the [." "filename]#vinum# configuration. As a result, the size of an individual " "drive does not limit the size of a plex or a volume." msgstr "" "Плексы могут включать несколько поддисков, распределенных по всем дискам в " "конфигурации [.filename]#vinum#. В результате, размер отдельного диска не " "ограничивает размер плекса или тома." #. type: Title === #: documentation/content/en/articles/vinum/_index.adoc:181 #, no-wrap msgid "Redundant Data Storage" msgstr "Избыточное хранение данных" #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:186 msgid "" "[.filename]#vinum# implements mirroring by attaching multiple plexes to a " "volume. Each plex is a representation of the data in a volume. A volume " "may contain between one and eight plexes." msgstr "" "[.filename]#vinum# реализует зеркалирование путем присоединения нескольких " "плекс к тому. Каждый плекс представляет данные в томе. Том может содержать " "от одного до восьми плексов." #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:189 msgid "" "Although a plex represents the complete data of a volume, it is possible for " "parts of the representation to be physically missing, either by design (by " "not defining a subdisk for parts of the plex) or by accident (as a result of " "the failure of a drive). As long as at least one plex can provide the data " "for the complete address range of the volume, the volume is fully functional." msgstr "" "Хотя плекс представляет полные данные тома, возможно, что некоторые части " "представления физически отсутствуют — либо по замыслу (если поддиск для " "частей плекса не определён), либо случайно (в результате выхода диска из " "строя). До тех пор, пока хотя бы один плекс может предоставить данные для " "полного адресного пространства тома, том остаётся полностью работоспособным." #. type: Title === #: documentation/content/en/articles/vinum/_index.adoc:190 #, no-wrap msgid "Which Plex Organization?" msgstr "Какую организацию плексов выбрать?" #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:193 msgid "" "[.filename]#vinum# implements both concatenation and striping at the plex " "level:" msgstr "" "[.filename]#vinum# реализует как объединение, так и чередование на уровне " "плекс:" #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:195 msgid "" "A _concatenated plex_ uses the address space of each subdisk in turn. " "Concatenated plexes are the most flexible as they can contain any number of " "subdisks, and the subdisks may be of different length. The plex may be " "extended by adding additional subdisks. They require less CPU time than " "striped plexes, though the difference in CPU overhead is not measurable. On " "the other hand, they are most susceptible to hot spots, where one disk is " "very active and others are idle." msgstr "" "_Плекс с объединением_ использует адресное пространство каждого поддиска по " "очереди. Объединённые плексы являются наиболее гибкими, так как могут " "содержать любое количество поддисков, а поддиски могут быть разной длины. " "Плекс может быть расширен путём добавления дополнительных поддисков. Они " "требуют меньше процессорного времени, чем чередующиеся плексы, хотя разница " "в нагрузке на процессор незначительна. С другой стороны, они наиболее " "подвержены \"горячим точкам\", когда один диск очень активен, а другие " "простаивают." #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:196 msgid "" "A _striped plex_ stripes the data across each subdisk. The subdisks must all " "be the same size and there must be at least two subdisks to distinguish it " "from a concatenated plex. The greatest advantage of striped plexes is that " "they reduce hot spots. By choosing an optimum sized stripe, about 256 kB, " "the load can be evened out on the component drives. Extending a plex by " "adding new subdisks is so complicated that [.filename]#vinum# does not " "implement it." msgstr "" "_Плекс с чередованием_ распределяет данные по каждому поддиску. Поддиски " "должны быть одного размера, и их должно быть как минимум два, чтобы отличить " "такой плекс от объединенного. Главное преимущество чередующихся плексов в " "том, что они уменьшают вероятность появления \"горячих точек\". Выбрав " "оптимальный размер полосы (около 256 КБ), можно равномерно распределить " "нагрузку на диски – компоненты системы. Расширение плекса путем добавления " "новых поддисков настолько сложно, что [.filename]#vinum# не реализует эту " "возможность." #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:198 msgid "" "crossref:vinum[vinum-comparison, [.filename]#vinum# Plex Organizations] " "summarizes the advantages and disadvantages of each plex organization." msgstr "" "crossref:vinum[vinum-comparison, Организации плексов в [.filename]#vinum#] " "обобщает преимущества и недостатки каждой организации плексов." #. type: Block title #: documentation/content/en/articles/vinum/_index.adoc:200 #, no-wrap msgid "[.filename]#vinum# Plex Organizations" msgstr "Организации плексов в [.filename]#vinum#" #. type: Table #: documentation/content/en/articles/vinum/_index.adoc:204 #, no-wrap msgid "Plex type" msgstr "Тип плекса" #. type: Table #: documentation/content/en/articles/vinum/_index.adoc:205 #, no-wrap msgid "Minimum subdisks" msgstr "Минимальное количество поддисков" #. type: Table #: documentation/content/en/articles/vinum/_index.adoc:206 #, no-wrap msgid "Can add subdisks" msgstr "Может добавлять поддиски" #. type: Table #: documentation/content/en/articles/vinum/_index.adoc:207 #, no-wrap msgid "Must be equal size" msgstr "Должен быть равного размера" #. type: Table #: documentation/content/en/articles/vinum/_index.adoc:209 #, no-wrap msgid "Application" msgstr "Приложение" #. type: Table #: documentation/content/en/articles/vinum/_index.adoc:210 #, no-wrap msgid "concatenated" msgstr "объединённый" #. type: Table #: documentation/content/en/articles/vinum/_index.adoc:211 #, no-wrap msgid "1" msgstr "1" #. type: Table #: documentation/content/en/articles/vinum/_index.adoc:212 #: documentation/content/en/articles/vinum/_index.adoc:219 #, no-wrap msgid "yes" msgstr "да" #. type: Table #: documentation/content/en/articles/vinum/_index.adoc:213 #: documentation/content/en/articles/vinum/_index.adoc:218 #, no-wrap msgid "no" msgstr "no" #. type: Table #: documentation/content/en/articles/vinum/_index.adoc:215 #, no-wrap msgid "Large data storage with maximum placement flexibility and moderate performance" msgstr "Крупное хранилище данных с максимальной гибкостью размещения и умеренной производительностью" #. type: Table #: documentation/content/en/articles/vinum/_index.adoc:216 #, no-wrap msgid "striped" msgstr "чередуемый" #. type: Table #: documentation/content/en/articles/vinum/_index.adoc:217 #, no-wrap msgid "2" msgstr "2" #. type: Table #: documentation/content/en/articles/vinum/_index.adoc:220 #, no-wrap msgid "High performance in combination with highly concurrent access" msgstr "Высокая производительность в сочетании с высокопараллельным доступом" #. type: Title == #: documentation/content/en/articles/vinum/_index.adoc:223 #, no-wrap msgid "Some Examples" msgstr "Некоторые примеры" #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:229 msgid "" "[.filename]#vinum# maintains a _configuration database_ which describes the " "objects known to an individual system. Initially, the user creates the " "configuration database from one or more configuration files using man:" "gvinum[8]. [.filename]#vinum# stores a copy of its configuration database " "on each disk _device_ under its control. This database is updated on each " "state change, so that a restart accurately restores the state of each [." "filename]#vinum# object." msgstr "" "[.filename]#vinum# поддерживает _базу данных конфигурации_, которая " "описывает объекты, известные конкретной системе. Первоначально пользователь " -"создает базу данных конфигурации из одного или нескольких конфигурационных " +"создаёт базу данных конфигурации из одного или нескольких конфигурационных " "файлов с помощью man:gvinum[8]. [.filename]#vinum# хранит копию своей базы " "данных конфигурации на каждом _устройстве_ диска, находящемся под его " "управлением. Эта база данных обновляется при каждом изменении состояния, так " "что перезапуск точно восстанавливает состояние каждого объекта [." "filename]#vinum#." #. type: Title === #: documentation/content/en/articles/vinum/_index.adoc:230 #, no-wrap msgid "The Configuration File" msgstr "Файл конфигурации" #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:234 msgid "" "The configuration file describes individual [.filename]#vinum# objects. The " "definition of a simple volume might be:" msgstr "" "Файл конфигурации описывает отдельные объекты [.filename]#vinum#. " "Определение простого тома может выглядеть следующим образом:" #. type: delimited block . 4 #: documentation/content/en/articles/vinum/_index.adoc:241 #, no-wrap msgid "" " drive a device /dev/da3h\n" " volume myvol\n" " plex org concat\n" " sd length 512m drive a\n" msgstr "" " drive a device /dev/da3h\n" " volume myvol\n" " plex org concat\n" " sd length 512m drive a\n" #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:244 msgid "This file describes four [.filename]#vinum# objects:" msgstr "Этот файл описывает четыре объекта [.filename]#vinum#:" #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:246 msgid "" "The _drive_ line describes a disk partition (_drive_) and its location " "relative to the underlying hardware. It is given the symbolic name _a_. This " "separation of symbolic names from device names allows disks to be moved from " "one location to another without confusion." msgstr "" "Строка _drive_ описывает раздел диска (_drive_) и его расположение " "относительно оборудования, на котором он расположен. Ему присваивается " "символическое имя _a_. Такое разделение символических имён от имён устройств " "позволяет перемещать диски из одного места в другое без путаницы." #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:247 msgid "" "The _volume_ line describes a volume. The only required attribute is the " "name, in this case _myvol_." msgstr "" "Строка _volume_ описывает том. Единственный обязательный атрибут — это имя, " "в данном случае _myvol_." #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:248 msgid "" "The _plex_ line defines a plex. The only required parameter is the " "organization, in this case _concat_. No name is necessary as the system " "automatically generates a name from the volume name by adding the suffix _." "px_, where _x_ is the number of the plex in the volume. Thus this plex will " "be called _myvol.p0_." msgstr "" "Строка _plex_ определяет плекс. Единственный обязательный параметр — это " "организация, в данном случае _concat_. Имя не требуется, так как система " "автоматически генерирует его из имени тома, добавляя суффикс _.px_, где _x_ " "— номер плекса в томе. Таким образом, этот плекс будет называться _myvol.p0_." #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:249 msgid "" "The _sd_ line describes a subdisk. The minimum specifications are the name " "of a drive on which to store it, and the length of the subdisk. No name is " "necessary as the system automatically assigns names derived from the plex " "name by adding the suffix _.sx_, where _x_ is the number of the subdisk in " "the plex. Thus [.filename]#vinum# gives this subdisk the name _myvol.p0.s0_." msgstr "" "Строка _sd_ описывает поддиск. Минимальные требования — это имя диска для " "его хранения и длина поддиска. Имя не обязательно, так как система " "автоматически назначает имена, производные от имени плекса, добавляя суффикс " "_.sx_, где _x_ — номер поддиска в плексе. Таким образом, [.filename]#vinum# " "присваивает этому поддиску имя _myvol.p0.s0_." #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:251 msgid "" "After processing this file, man:gvinum[8] produces the following output:" msgstr "" "После обработки этого файла команда man:gvinum[8] выводит следующий " "результат:" #. type: delimited block . 4 #: documentation/content/en/articles/vinum/_index.adoc:261 #, no-wrap msgid "" "# gvinum -> create config1\n" "Configuration summary\n" "Drives: 1 (4 configured)\n" "Volumes: 1 (4 configured)\n" "Plexes: 1 (8 configured)\n" "Subdisks: 1 (16 configured)\n" msgstr "" "# gvinum -> create config1\n" "Configuration summary\n" "Drives: 1 (4 configured)\n" "Volumes: 1 (4 configured)\n" "Plexes: 1 (8 configured)\n" "Subdisks: 1 (16 configured)\n" #. type: delimited block . 4 #: documentation/content/en/articles/vinum/_index.adoc:263 #, no-wrap msgid " D a State: up Device /dev/da3h Avail: 2061/2573 MB (80%)\n" msgstr " D a State: up Device /dev/da3h Avail: 2061/2573 MB (80%)\n" #. type: delimited block . 4 #: documentation/content/en/articles/vinum/_index.adoc:265 #, no-wrap msgid " V myvol State: up Plexes: 1 Size: 512 MB\n" msgstr " V myvol State: up Plexes: 1 Size: 512 MB\n" #. type: delimited block . 4 #: documentation/content/en/articles/vinum/_index.adoc:267 #, no-wrap msgid " P myvol.p0 C State: up Subdisks: 1 Size: 512 MB\n" msgstr " P myvol.p0 C State: up Subdisks: 1 Size: 512 MB\n" #. type: delimited block . 4 #: documentation/content/en/articles/vinum/_index.adoc:269 #, no-wrap msgid " S myvol.p0.s0 State: up PO: 0 B Size: 512 MB\n" msgstr " S myvol.p0.s0 State: up PO: 0 B Size: 512 MB\n" #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:273 msgid "" "This output shows the brief listing format of man:gvinum[8]. It is " "represented graphically in crossref:vinum[vinum-simple-vol, A Simple [." "filename]#vinum# Volume]." msgstr "" "Этот вывод показывает краткий формат списка man:gvinum[8]. Он представлен " "графически в crossref:vinum[vinum-simple-vol, Простой том [." "filename]#vinum#]." #. type: Block title #: documentation/content/en/articles/vinum/_index.adoc:275 #, no-wrap msgid "A Simple [.filename]#vinum# Volume" msgstr "Простой том [.filename]#vinum#" #. type: Target for macro image #: documentation/content/en/articles/vinum/_index.adoc:276 #, no-wrap msgid "vinum-simple-vol.png" msgstr "vinum-simple-vol.png" #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:280 msgid "" "This figure, and the ones which follow, represent a volume, which contains " "the plexes, which in turn contains the subdisks. In this example, the " "volume contains one plex, and the plex contains one subdisk." msgstr "" "Этот рисунок и следующие представляют том, который содержит плексы, которые, " "в свою очередь, содержат поддиски. В этом примере том содержит один плекс, а " "плекс содержит один поддиск." #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:285 msgid "" "This particular volume has no specific advantage over a conventional disk " "partition. It contains a single plex, so it is not redundant. The plex " "contains a single subdisk, so there is no difference in storage allocation " "from a conventional disk partition. The following sections illustrate " "various more interesting configuration methods." msgstr "" "Этот конкретный том не имеет особых преимуществ по сравнению с обычным " "разделом диска. Он содержит один плекс, поэтому не является избыточным. " "Плекс содержит один поддиск, поэтому нет различий в распределении хранилища " "по сравнению с обычным разделом диска. В следующих разделах показаны " "различные более интересные методы конфигурации." #. type: Title === #: documentation/content/en/articles/vinum/_index.adoc:286 #, no-wrap msgid "Increased Resilience: Mirroring" msgstr "Увеличенная отказоустойчивость: зеркалирование" #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:291 msgid "" "The resilience of a volume can be increased by mirroring. When laying out a " "mirrored volume, it is important to ensure that the subdisks of each plex " "are on different drives, so that a drive failure will not take down both " "plexes. The following configuration mirrors a volume:" msgstr "" "Устойчивость тома может быть повышена за счёт зеркалирования. При создании " "зеркального тома важно убедиться, что поддиски каждого плекса находятся на " "разных дисках, чтобы выход из строя одного диска не затронул оба плекса. " "Следующая конфигурация создаёт зеркальный том:" #. type: delimited block . 4 #: documentation/content/en/articles/vinum/_index.adoc:300 #, no-wrap msgid "" "\tdrive b device /dev/da4h\n" "\tvolume mirror\n" " plex org concat\n" " sd length 512m drive a\n" "\t plex org concat\n" "\t sd length 512m drive b\n" msgstr "" "\tdrive b device /dev/da4h\n" "\tvolume mirror\n" " plex org concat\n" " sd length 512m drive a\n" "\t plex org concat\n" "\t sd length 512m drive b\n" #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:304 msgid "" "In this example, it was not necessary to specify a definition of drive _a_ " "again, since [.filename]#vinum# keeps track of all objects in its " "configuration database. After processing this definition, the configuration " "looks like:" msgstr "" "В этом примере не потребовалось снова указывать определение диска _a_, " "поскольку [.filename]#vinum# отслеживает все объекты в своей базе данных " "конфигурации. После обработки этого определения конфигурация выглядит " "следующим образом:" #. type: delimited block . 4 #: documentation/content/en/articles/vinum/_index.adoc:312 #, no-wrap msgid "" "\tDrives: 2 (4 configured)\n" "\tVolumes: 2 (4 configured)\n" "\tPlexes: 3 (8 configured)\n" "\tSubdisks: 3 (16 configured)\n" msgstr "" "\tDrives: 2 (4 configured)\n" "\tVolumes: 2 (4 configured)\n" "\tPlexes: 3 (8 configured)\n" "\tSubdisks: 3 (16 configured)\n" #. type: delimited block . 4 #: documentation/content/en/articles/vinum/_index.adoc:315 #, no-wrap msgid "" "\tD a State: up Device /dev/da3h Avail: 1549/2573 MB (60%)\n" "\tD b State: up Device /dev/da4h Avail: 2061/2573 MB (80%)\n" msgstr "" "\tD a State: up Device /dev/da3h Avail: 1549/2573 MB (60%)\n" "\tD b State: up Device /dev/da4h Avail: 2061/2573 MB (80%)\n" #. type: delimited block . 4 #: documentation/content/en/articles/vinum/_index.adoc:318 #, no-wrap msgid "" " V myvol State: up Plexes: 1 Size: 512 MB\n" " V mirror State: up Plexes: 2 Size: 512 MB\n" msgstr "" " V myvol State: up Plexes: 1 Size: 512 MB\n" " V mirror State: up Plexes: 2 Size: 512 MB\n" #. type: delimited block . 4 #: documentation/content/en/articles/vinum/_index.adoc:322 #, no-wrap msgid "" " P myvol.p0 C State: up Subdisks: 1 Size: 512 MB\n" " P mirror.p0 C State: up Subdisks: 1 Size: 512 MB\n" " P mirror.p1 C State: initializing Subdisks: 1 Size: 512 MB\n" msgstr "" " P myvol.p0 C State: up Subdisks: 1 Size: 512 MB\n" " P mirror.p0 C State: up Subdisks: 1 Size: 512 MB\n" " P mirror.p1 C State: initializing Subdisks: 1 Size: 512 MB\n" #. type: delimited block . 4 #: documentation/content/en/articles/vinum/_index.adoc:326 #, no-wrap msgid "" " S myvol.p0.s0 State: up PO: 0 B Size: 512 MB\n" "\tS mirror.p0.s0 State: up PO: 0 B Size: 512 MB\n" "\tS mirror.p1.s0 State: empty PO: 0 B Size: 512 MB\n" msgstr "" " S myvol.p0.s0 State: up PO: 0 B Size: 512 MB\n" "\tS mirror.p0.s0 State: up PO: 0 B Size: 512 MB\n" "\tS mirror.p1.s0 State: empty PO: 0 B Size: 512 MB\n" #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:329 msgid "" "crossref:vinum[vinum-mirrored-vol, A Mirrored [.filename]#vinum# Volume] " "shows the structure graphically." msgstr "" "crossref:vinum[vinum-mirrored-vol, Зеркальный том [.filename]#vinum#] " "графически отображает структуру." #. type: Block title #: documentation/content/en/articles/vinum/_index.adoc:331 #, no-wrap msgid "A Mirrored [.filename]#vinum# Volume" msgstr "Зеркальный том [.filename]#vinum#" #. type: Target for macro image #: documentation/content/en/articles/vinum/_index.adoc:332 #, no-wrap msgid "vinum-mirrored-vol.png" msgstr "vinum-mirrored-vol.png" #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:336 msgid "" "In this example, each plex contains the full 512 MB of address space. As in " "the previous example, each plex contains only a single subdisk." msgstr "" "В этом примере каждый плекс содержит полные 512 МБ адресного пространства. " "Как и в предыдущем примере, каждый плекс содержит только один поддиск." #. type: Title === #: documentation/content/en/articles/vinum/_index.adoc:337 #, no-wrap msgid "Optimizing Performance" msgstr "Оптимизация производительности" #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:342 msgid "" "The mirrored volume in the previous example is more resistant to failure " "than an unmirrored volume, but its performance is less as each write to the " "volume requires a write to both drives, using up a greater proportion of the " "total disk bandwidth. Performance considerations demand a different " "approach: instead of mirroring, the data is striped across as many disk " "drives as possible. The following configuration shows a volume with a plex " "striped across four disk drives:" msgstr "" "Зеркальный том в предыдущем примере более устойчив к сбоям, чем незеркальный " "том, но его производительность ниже, так как каждая запись в том требует " "записи на оба диска, используя большую часть общей пропускной способности " "дисков. Соображения производительности требуют другого подхода: вместо " "зеркалирования данные распределяются по полосам на максимально возможное " "количество дисков. Следующая конфигурация показывает том с плексом, " "распределённым по полосам на четырёх дисках:" #. type: delimited block . 4 #: documentation/content/en/articles/vinum/_index.adoc:353 #, no-wrap msgid "" " drive c device /dev/da5h\n" "\tdrive d device /dev/da6h\n" "\tvolume stripe\n" "\tplex org striped 512k\n" "\t sd length 128m drive a\n" "\t sd length 128m drive b\n" "\t sd length 128m drive c\n" "\t sd length 128m drive d\n" msgstr "" " drive c device /dev/da5h\n" "\tdrive d device /dev/da6h\n" "\tvolume stripe\n" "\tplex org striped 512k\n" "\t sd length 128m drive a\n" "\t sd length 128m drive b\n" "\t sd length 128m drive c\n" "\t sd length 128m drive d\n" #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:357 msgid "" "As before, it is not necessary to define the drives which are already known " "to [.filename]#vinum#. After processing this definition, the configuration " "looks like:" msgstr "" "Как и ранее, не нужно определять диски, которые уже известны [." "filename]#vinum#. После обработки этого определения конфигурация выглядит " "следующим образом:" #. type: delimited block . 4 #: documentation/content/en/articles/vinum/_index.adoc:365 #, no-wrap msgid "" "\tDrives: 4 (4 configured)\n" "\tVolumes: 3 (4 configured)\n" "\tPlexes: 4 (8 configured)\n" "\tSubdisks: 7 (16 configured)\n" msgstr "" "\tDrives: 4 (4 configured)\n" "\tVolumes: 3 (4 configured)\n" "\tPlexes: 4 (8 configured)\n" "\tSubdisks: 7 (16 configured)\n" #. type: delimited block . 4 #: documentation/content/en/articles/vinum/_index.adoc:370 #, no-wrap msgid "" " D a State: up Device /dev/da3h Avail: 1421/2573 MB (55%)\n" " D b State: up Device /dev/da4h Avail: 1933/2573 MB (75%)\n" " D c State: up Device /dev/da5h Avail: 2445/2573 MB (95%)\n" " D d State: up Device /dev/da6h Avail: 2445/2573 MB (95%)\n" msgstr "" " D a State: up Device /dev/da3h Avail: 1421/2573 MB (55%)\n" " D b State: up Device /dev/da4h Avail: 1933/2573 MB (75%)\n" " D c State: up Device /dev/da5h Avail: 2445/2573 MB (95%)\n" " D d State: up Device /dev/da6h Avail: 2445/2573 MB (95%)\n" #. type: delimited block . 4 #: documentation/content/en/articles/vinum/_index.adoc:374 #, no-wrap msgid "" " V myvol State: up Plexes: 1 Size: 512 MB\n" " V mirror State: up Plexes: 2 Size: 512 MB\n" " V striped State: up Plexes: 1 Size: 512 MB\n" msgstr "" " V myvol State: up Plexes: 1 Size: 512 MB\n" " V mirror State: up Plexes: 2 Size: 512 MB\n" " V striped State: up Plexes: 1 Size: 512 MB\n" #. type: delimited block . 4 #: documentation/content/en/articles/vinum/_index.adoc:379 #, no-wrap msgid "" " P myvol.p0 C State: up Subdisks: 1 Size: 512 MB\n" " P mirror.p0 C State: up Subdisks: 1 Size: 512 MB\n" " P mirror.p1 C State: initializing Subdisks: 1 Size: 512 MB\n" " P striped.p1 State: up Subdisks: 1 Size: 512 MB\n" msgstr "" " P myvol.p0 C State: up Subdisks: 1 Size: 512 MB\n" " P mirror.p0 C State: up Subdisks: 1 Size: 512 MB\n" " P mirror.p1 C State: initializing Subdisks: 1 Size: 512 MB\n" " P striped.p1 State: up Subdisks: 1 Size: 512 MB\n" #. type: delimited block . 4 #: documentation/content/en/articles/vinum/_index.adoc:387 #, no-wrap msgid "" " S myvol.p0.s0 State: up PO: 0 B Size: 512 MB\n" " S mirror.p0.s0 State: up PO: 0 B Size: 512 MB\n" " S mirror.p1.s0 State: empty PO: 0 B Size: 512 MB\n" " S striped.p0.s0 State: up PO: 0 B Size: 128 MB\n" " S striped.p0.s1 State: up PO: 512 kB Size: 128 MB\n" " S striped.p0.s2 State: up PO: 1024 kB Size: 128 MB\n" " S striped.p0.s3 State: up PO: 1536 kB Size: 128 MB\n" msgstr "" " S myvol.p0.s0 State: up PO: 0 B Size: 512 MB\n" " S mirror.p0.s0 State: up PO: 0 B Size: 512 MB\n" " S mirror.p1.s0 State: empty PO: 0 B Size: 512 MB\n" " S striped.p0.s0 State: up PO: 0 B Size: 128 MB\n" " S striped.p0.s1 State: up PO: 512 kB Size: 128 MB\n" " S striped.p0.s2 State: up PO: 1024 kB Size: 128 MB\n" " S striped.p0.s3 State: up PO: 1536 kB Size: 128 MB\n" #. type: Block title #: documentation/content/en/articles/vinum/_index.adoc:390 #, no-wrap msgid "A Striped [.filename]#vinum# Volume" msgstr "Том [.filename]#vinum# с чередованием" #. type: Target for macro image #: documentation/content/en/articles/vinum/_index.adoc:391 #, no-wrap msgid "vinum-striped-vol.png" msgstr "vinum-striped-vol.png" #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:395 msgid "" "This volume is represented in crossref:vinum[vinum-striped-vol, A Striped [." "filename]#vinum# Volume]. The darkness of the stripes indicates the " "position within the plex address space, where the lightest stripes come " "first and the darkest last." msgstr "" "Этот том представлен на схеме crossref:vinum[vinum-striped-vol, Том [." "filename]#vinum# с чередованием]. Темнота полос указывает на позицию в " "адресном пространстве плекса, где самые светлые полосы идут первыми, а самые " "темные — последними." #. type: Title === #: documentation/content/en/articles/vinum/_index.adoc:396 #, no-wrap msgid "Resilience and Performance" msgstr "Устойчивость и производительность" #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:400 msgid "" "[[vinum-resilience]]With sufficient hardware, it is possible to build " "volumes which show both increased resilience and increased performance " "compared to standard UNIX(R) partitions. A typical configuration file might " "be:" msgstr "" "[[vinum-resilience]]При достаточном аппаратном обеспечении можно создать " "тома, которые демонстрируют как повышенную отказоустойчивость, так и " "увеличенную производительность по сравнению со стандартными разделами " "UNIX(R). Типичный конфигурационный файл может выглядеть так:" #. type: delimited block . 4 #: documentation/content/en/articles/vinum/_index.adoc:416 #, no-wrap msgid "" "\tvolume raid10\n" " plex org striped 512k\n" " sd length 102480k drive a\n" " sd length 102480k drive b\n" " sd length 102480k drive c\n" " sd length 102480k drive d\n" " sd length 102480k drive e\n" " plex org striped 512k\n" " sd length 102480k drive c\n" " sd length 102480k drive d\n" " sd length 102480k drive e\n" " sd length 102480k drive a\n" " sd length 102480k drive b\n" msgstr "" "\tvolume raid10\n" " plex org striped 512k\n" " sd length 102480k drive a\n" " sd length 102480k drive b\n" " sd length 102480k drive c\n" " sd length 102480k drive d\n" " sd length 102480k drive e\n" " plex org striped 512k\n" " sd length 102480k drive c\n" " sd length 102480k drive d\n" " sd length 102480k drive e\n" " sd length 102480k drive a\n" " sd length 102480k drive b\n" #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:420 msgid "" "The subdisks of the second plex are offset by two drives from those of the " "first plex. This helps to ensure that writes do not go to the same subdisks " "even if a transfer goes over two drives." msgstr "" "Поддиски второго плекса смещены на два диска относительно поддисков первого " "плекса. Это помогает гарантировать, что записи не будут направляться на одни " "и те же поддиски, даже если передача затронет два диска." #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:422 msgid "" "crossref:vinum[vinum-raid10-vol, A Mirrored, Striped [.filename]#vinum# " "Volume] represents the structure of this volume." msgstr "" "crossref:vinum[vinum-raid10-vol, Том [.filename]#vinum# c зеркалированием и " "чередованием] представляет структуру этого тома." #. type: Block title #: documentation/content/en/articles/vinum/_index.adoc:424 #, no-wrap msgid "A Mirrored, Striped [.filename]#vinum# Volume" msgstr "Том [.filename]#vinum# c зеркалированием и чередованием" #. type: Target for macro image #: documentation/content/en/articles/vinum/_index.adoc:425 #, no-wrap msgid "vinum-raid10-vol.png" msgstr "vinum-raid10-vol.png" #. type: Title == #: documentation/content/en/articles/vinum/_index.adoc:428 #, no-wrap msgid "Object Naming" msgstr "Именование объектов" #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:432 msgid "" "[.filename]#vinum# assigns default names to plexes and subdisks, although " "they may be overridden. Overriding the default names is not recommended as " "it does not bring a significant advantage and it can cause confusion." msgstr "" "[.filename]#vinum# назначает стандартные имена для плексов и поддисков, хотя " "их можно изменить. Не рекомендуется изменять стандартные имена, так как это " "не даёт значительных преимуществ и может вызвать путаницу." #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:435 msgid "" "Names may contain any non-blank character, but it is recommended to restrict " "them to letters, digits and the underscore characters. The names of " "volumes, plexes, and subdisks may be up to 64 characters long, and the names " "of drives may be up to 32 characters long." msgstr "" "Имена могут содержать любые непустые символы, но рекомендуется " "ограничиваться буквами, цифрами и символами подчёркивания. Имена томов, " "плексов и поддисков могут быть длиной до 64 символов, а имена дисков — до 32 " "символов." #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:438 msgid "" "[.filename]#vinum# objects are assigned device nodes in the hierarchy [." "filename]#/dev/gvinum#. The configuration shown above would cause [." "filename]#vinum# to create the following device nodes:" msgstr "" "Объектам [.filename]#vinum# назначаются узлы устройств в иерархии [." "filename]#/dev/gvinum#. Приведённая выше конфигурация приведёт к тому, что [." "filename]#vinum# создаст следующие узлы устройств:" #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:440 msgid "" "Device entries for each volume. These are the main devices used by [." "filename]#vinum#. The configuration above would include the devices [." "filename]#/dev/gvinum/myvol#, [.filename]#/dev/gvinum/mirror#, [.filename]#/" "dev/gvinum/striped#, [.filename]#/dev/gvinum/raid5# and [.filename]#/dev/" "gvinum/raid10#." msgstr "" "Записи устройств для каждого тома. Это основные устройства, используемые [." "filename]#vinum#. Приведённая конфигурация включает устройства [.filename]#/" "dev/gvinum/myvol#, [.filename]#/dev/gvinum/mirror#, [.filename]#/dev/gvinum/" "striped#, [.filename]#/dev/gvinum/raid5# и [.filename]#/dev/gvinum/raid10#." #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:441 msgid "All volumes get direct entries under [.filename]#/dev/gvinum/#." msgstr "Все тома получают собственные записи в [.filename]#/dev/gvinum/#." #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:442 msgid "" "The directories [.filename]#/dev/gvinum/plex#, and [.filename]#/dev/gvinum/" "sd#, which contain device nodes for each plex and for each subdisk, " "respectively." msgstr "" "Каталоги [.filename]#/dev/gvinum/plex# и [.filename]#/dev/gvinum/sd#, " "которые содержат узлы устройств для каждого плекса и каждого субдиска " "соответственно." #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:444 msgid "For example, consider the following configuration file:" msgstr "Например, рассмотрим следующий конфигурационный файл:" #. type: delimited block . 4 #: documentation/content/en/articles/vinum/_index.adoc:457 #, no-wrap msgid "" "\tdrive drive1 device /dev/sd1h\n" "\tdrive drive2 device /dev/sd2h\n" "\tdrive drive3 device /dev/sd3h\n" "\tdrive drive4 device /dev/sd4h\n" " volume s64 setupstate\n" " plex org striped 64k\n" " sd length 100m drive drive1\n" " sd length 100m drive drive2\n" " sd length 100m drive drive3\n" " sd length 100m drive drive4\n" msgstr "" "\tdrive drive1 device /dev/sd1h\n" "\tdrive drive2 device /dev/sd2h\n" "\tdrive drive3 device /dev/sd3h\n" "\tdrive drive4 device /dev/sd4h\n" " volume s64 setupstate\n" " plex org striped 64k\n" " sd length 100m drive drive1\n" " sd length 100m drive drive2\n" " sd length 100m drive drive3\n" " sd length 100m drive drive4\n" #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:460 msgid "" "After processing this file, man:gvinum[8] creates the following structure in " "[.filename]#/dev/gvinum#:" msgstr "" -"После обработки этого файла man:gvinum[8] создает следующую структуру в [." +"После обработки этого файла man:gvinum[8] создаёт следующую структуру в [." "filename]#/dev/gvinum#:" #. type: delimited block . 4 #: documentation/content/en/articles/vinum/_index.adoc:467 #, no-wrap msgid "" "\tdrwxr-xr-x 2 root wheel 512 Apr 13\n" "16:46 plex\n" "\tcrwxr-xr-- 1 root wheel 91, 2 Apr 13 16:46 s64\n" "\tdrwxr-xr-x 2 root wheel 512 Apr 13 16:46 sd\n" msgstr "" "\tdrwxr-xr-x 2 root wheel 512 Apr 13\n" "16:46 plex\n" "\tcrwxr-xr-- 1 root wheel 91, 2 Apr 13 16:46 s64\n" "\tdrwxr-xr-x 2 root wheel 512 Apr 13 16:46 sd\n" #. type: delimited block . 4 #: documentation/content/en/articles/vinum/_index.adoc:471 #, no-wrap msgid "" " /dev/vinum/plex:\n" " total 0\n" " crwxr-xr-- 1 root wheel 25, 0x10000002 Apr 13 16:46 s64.p0\n" msgstr "" " /dev/vinum/plex:\n" " total 0\n" " crwxr-xr-- 1 root wheel 25, 0x10000002 Apr 13 16:46 s64.p0\n" #. type: delimited block . 4 #: documentation/content/en/articles/vinum/_index.adoc:478 #, no-wrap msgid "" " /dev/vinum/sd:\n" " total 0\n" " crwxr-xr-- 1 root wheel 91, 0x20000002 Apr 13 16:46 s64.p0.s0\n" " crwxr-xr-- 1 root wheel 91, 0x20100002 Apr 13 16:46 s64.p0.s1\n" " crwxr-xr-- 1 root wheel 91, 0x20200002 Apr 13 16:46 s64.p0.s2\n" " crwxr-xr-- 1 root wheel 91, 0x20300002 Apr 13 16:46 s64.p0.s3\n" msgstr "" " /dev/vinum/sd:\n" " total 0\n" " crwxr-xr-- 1 root wheel 91, 0x20000002 Apr 13 16:46 s64.p0.s0\n" " crwxr-xr-- 1 root wheel 91, 0x20100002 Apr 13 16:46 s64.p0.s1\n" " crwxr-xr-- 1 root wheel 91, 0x20200002 Apr 13 16:46 s64.p0.s2\n" " crwxr-xr-- 1 root wheel 91, 0x20300002 Apr 13 16:46 s64.p0.s3\n" #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:483 msgid "" "Although it is recommended that plexes and subdisks should not be allocated " "specific names, [.filename]#vinum# drives must be named. This makes it " "possible to move a drive to a different location and still recognize it " "automatically. Drive names may be up to 32 characters long." msgstr "" "Хотя рекомендуется не назначать конкретные имена плексам и поддискам, диски " "[.filename]#vinum# должны быть именованными. Это позволяет переместить диск " "в другое место и по-прежнему автоматически его распознавать. Имена дисков " "могут быть длиной до 32 символов." #. type: Title === #: documentation/content/en/articles/vinum/_index.adoc:484 #, no-wrap msgid "Creating File Systems" msgstr "Создание файловых систем" #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:492 msgid "" "Volumes appear to the system to be identical to disks, with one exception. " "Unlike UNIX(R) drives, [.filename]#vinum# does not partition volumes, which " "thus do not contain a partition table. This has required modification to " "some disk utilities, notably man:newfs[8], so that it does not try to " "interpret the last letter of a [.filename]#vinum# volume name as a partition " "identifier. For example, a disk drive may have a name like [.filename]#/dev/" "ad0a# or [.filename]#/dev/da2h#. These names represent the first partition " "([.filename]#a#) on the first (0) IDE disk ([.filename]#ad#) and the eighth " "partition ([.filename]#h#) on the third (2) SCSI disk ([.filename]#da#) " "respectively. By contrast, a [.filename]#vinum# volume might be called [." "filename]#/dev/gvinum/concat#, which has no relationship with a partition " "name." msgstr "" "Тома для системы выглядят идентично дискам, за одним исключением. В отличие " "от дисков UNIX(R), [.filename]#vinum# не разбивает тома на разделы, поэтому " "они не содержат таблицы разделов. Это потребовало внесения изменений в " "некоторые утилиты для работы с дисками, в частности, в man:newfs[8], чтобы " "они не пытались интерпретировать последнюю букву имени тома [." "filename]#vinum# как идентификатор раздела. Например, имя диска может " "выглядеть как [.filename]#/dev/ad0a# или [.filename]#/dev/da2h#. Эти имена " "обозначают первый раздел ([.filename]#a#) на первом (0) IDE-диске ([." "filename]#ad#) и восьмой раздел ([.filename]#h#) на третьем (2) SCSI-диске ([" ".filename]#da#), соответственно. В отличие от этого, том [.filename]#vinum# " "может называться [.filename]#/dev/gvinum/concat#, что не имеет отношения к " "имени раздела." #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:494 msgid "To create a file system on this volume, use man:newfs[8]:" msgstr "Чтобы создать файловую систему на этом томе, используйте man:newfs[8]:" #. type: delimited block . 4 #: documentation/content/en/articles/vinum/_index.adoc:498 #, no-wrap msgid "# newfs /dev/gvinum/concat\n" msgstr "# newfs /dev/gvinum/concat\n" #. type: Title == #: documentation/content/en/articles/vinum/_index.adoc:501 #, no-wrap msgid "Configuring [.filename]#vinum#" msgstr "Настройка [.filename]#vinum#" #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:507 msgid "" "The [.filename]#GENERIC# kernel does not contain [.filename]#vinum#. It is " "possible to build a custom kernel which includes [.filename]#vinum#, but " "this is not recommended. The standard way to start [.filename]#vinum# is as " "a kernel module. man:kldload[8] is not needed because when man:gvinum[8] " "starts, it checks whether the module has been loaded, and if it is not, it " "loads it automatically." msgstr "" "Ядро [.filename]#GENERIC# не содержит [.filename]#vinum#. Можно собрать " "пользовательское ядро с включённым [.filename]#vinum#, но это не " "рекомендуется. Стандартный способ запуска [.filename]#vinum# — в качестве " "модуля ядра. Команда man:kldload[8] не требуется, так как при запуске man:" "gvinum[8] проверяет, загружен ли модуль, и если нет, загружает его " "автоматически." #. type: Title === #: documentation/content/en/articles/vinum/_index.adoc:508 #, no-wrap msgid "Startup" msgstr "Запуск" #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:513 msgid "" "[.filename]#vinum# stores configuration information on the disk slices in " "essentially the same form as in the configuration files. When reading from " "the configuration database, [.filename]#vinum# recognizes a number of " "keywords which are not allowed in the configuration files. For example, a " "disk configuration might contain the following text:" msgstr "" "[.filename]#vinum# хранит конфигурационную информацию на дисковых слайсах " "практически в той же форме, что и в конфигурационных файлах. При чтении из " "базы данных конфигурации [.filename]#vinum# распознаёт ряд ключевых слов, " "которые не допускаются в конфигурационных файлах. Например, конфигурация " "диска может содержать следующий текст:" #. type: delimited block . 4 #: documentation/content/en/articles/vinum/_index.adoc:535 #, no-wrap msgid "" "volume myvol state up\n" "volume bigraid state down\n" "plex name myvol.p0 state up org concat vol myvol\n" "plex name myvol.p1 state up org concat vol myvol\n" "plex name myvol.p2 state init org striped 512b vol myvol\n" "plex name bigraid.p0 state initializing org raid5 512b vol bigraid\n" "sd name myvol.p0.s0 drive a plex myvol.p0 state up len 1048576b driveoffset 265b plexoffset 0b\n" "sd name myvol.p0.s1 drive b plex myvol.p0 state up len 1048576b driveoffset 265b plexoffset 1048576b\n" "sd name myvol.p1.s0 drive c plex myvol.p1 state up len 1048576b driveoffset 265b plexoffset 0b\n" "sd name myvol.p1.s1 drive d plex myvol.p1 state up len 1048576b driveoffset 265b plexoffset 1048576b\n" "sd name myvol.p2.s0 drive a plex myvol.p2 state init len 524288b driveoffset 1048841b plexoffset 0b\n" "sd name myvol.p2.s1 drive b plex myvol.p2 state init len 524288b driveoffset 1048841b plexoffset 524288b\n" "sd name myvol.p2.s2 drive c plex myvol.p2 state init len 524288b driveoffset 1048841b plexoffset 1048576b\n" "sd name myvol.p2.s3 drive d plex myvol.p2 state init len 524288b driveoffset 1048841b plexoffset 1572864b\n" "sd name bigraid.p0.s0 drive a plex bigraid.p0 state initializing len 4194304b driveoff set 1573129b plexoffset 0b\n" "sd name bigraid.p0.s1 drive b plex bigraid.p0 state initializing len 4194304b driveoff set 1573129b plexoffset 4194304b\n" "sd name bigraid.p0.s2 drive c plex bigraid.p0 state initializing len 4194304b driveoff set 1573129b plexoffset 8388608b\n" "sd name bigraid.p0.s3 drive d plex bigraid.p0 state initializing len 4194304b driveoff set 1573129b plexoffset 12582912b\n" "sd name bigraid.p0.s4 drive e plex bigraid.p0 state initializing len 4194304b driveoff set 1573129b plexoffset 16777216b\n" msgstr "" "volume myvol state up\n" "volume bigraid state down\n" "plex name myvol.p0 state up org concat vol myvol\n" "plex name myvol.p1 state up org concat vol myvol\n" "plex name myvol.p2 state init org striped 512b vol myvol\n" "plex name bigraid.p0 state initializing org raid5 512b vol bigraid\n" "sd name myvol.p0.s0 drive a plex myvol.p0 state up len 1048576b driveoffset 265b plexoffset 0b\n" "sd name myvol.p0.s1 drive b plex myvol.p0 state up len 1048576b driveoffset 265b plexoffset 1048576b\n" "sd name myvol.p1.s0 drive c plex myvol.p1 state up len 1048576b driveoffset 265b plexoffset 0b\n" "sd name myvol.p1.s1 drive d plex myvol.p1 state up len 1048576b driveoffset 265b plexoffset 1048576b\n" "sd name myvol.p2.s0 drive a plex myvol.p2 state init len 524288b driveoffset 1048841b plexoffset 0b\n" "sd name myvol.p2.s1 drive b plex myvol.p2 state init len 524288b driveoffset 1048841b plexoffset 524288b\n" "sd name myvol.p2.s2 drive c plex myvol.p2 state init len 524288b driveoffset 1048841b plexoffset 1048576b\n" "sd name myvol.p2.s3 drive d plex myvol.p2 state init len 524288b driveoffset 1048841b plexoffset 1572864b\n" "sd name bigraid.p0.s0 drive a plex bigraid.p0 state initializing len 4194304b driveoff set 1573129b plexoffset 0b\n" "sd name bigraid.p0.s1 drive b plex bigraid.p0 state initializing len 4194304b driveoff set 1573129b plexoffset 4194304b\n" "sd name bigraid.p0.s2 drive c plex bigraid.p0 state initializing len 4194304b driveoff set 1573129b plexoffset 8388608b\n" "sd name bigraid.p0.s3 drive d plex bigraid.p0 state initializing len 4194304b driveoff set 1573129b plexoffset 12582912b\n" "sd name bigraid.p0.s4 drive e plex bigraid.p0 state initializing len 4194304b driveoff set 1573129b plexoffset 16777216b\n" #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:541 msgid "" "The obvious differences here are the presence of explicit location " "information and naming, both of which are allowed but discouraged, and the " "information on the states. [.filename]#vinum# does not store information " "about drives in the configuration information. It finds the drives by " "scanning the configured disk drives for partitions with a [.filename]#vinum# " "label. This enables [.filename]#vinum# to identify drives correctly even if " "they have been assigned different UNIX(R) drive IDs." msgstr "" "Очевидные различия здесь — наличие явной информации о местоположении и " "именования, что разрешено, но не рекомендуется, а также информация о " "состояниях. [.filename]#vinum# не хранит сведения о дисках в " "конфигурационной информации. Он находит диски, сканируя настроенные дисковые " "накопители на наличие разделов с меткой [.filename]#vinum#. Это позволяет [." "filename]#vinum# корректно идентифицировать диски, даже если им были " "присвоены разные идентификаторы дисков UNIX(R)." #. type: Title ==== #: documentation/content/en/articles/vinum/_index.adoc:543 #, no-wrap msgid "Automatic Startup" msgstr "Автоматический запуск" #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:547 msgid "" "_Gvinum_ always features an automatic startup once the kernel module is " "loaded, via man:loader.conf[5]. To load the _Gvinum_ module at boot time, " "add `geom_vinum_load=\"YES\"` to [.filename]#/boot/loader.conf#." msgstr "" "_Gvinum_ всегда запускается автоматически после загрузки модуля ядра через " "man:loader.conf[5]. Чтобы загрузить модуль _Gvinum_ при загрузке системы, " "добавьте `geom_vinum_load=\"YES\"` в [.filename]#/boot/loader.conf#." #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:552 msgid "" "When [.filename]#vinum# is started with `gvinum start`, [.filename]#vinum# " "reads the configuration database from one of the [.filename]#vinum# drives. " "Under normal circumstances, each drive contains an identical copy of the " "configuration database, so it does not matter which drive is read. After a " "crash, however, [.filename]#vinum# must determine which drive was updated " "most recently and read the configuration from this drive. It then updates " "the configuration, if necessary, from progressively older drives." msgstr "" "Когда [.filename]#vinum# запускается командой `gvinum start`, [." "filename]#vinum# читает конфигурационную базу данных с одного из дисков [." "filename]#vinum#. В нормальных условиях каждый диск содержит идентичную " "копию конфигурационной базы данных, поэтому не имеет значения, с какого " "диска читать. Однако после сбоя [.filename]#vinum# должен определить, какой " "диск был обновлён последним, и прочитать конфигурацию с этого диска. Затем, " "если необходимо, он обновляет конфигурацию последовательно с более старых " "дисков." #. type: Title == #: documentation/content/en/articles/vinum/_index.adoc:554 #, no-wrap msgid "Using [.filename]#vinum# for the Root File System" msgstr "Использование [.filename]#vinum# для корневой файловой системы" #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:558 msgid "" "For a machine that has fully-mirrored file systems using [.filename]#vinum#, " "it is desirable to also mirror the root file system. Setting up such a " "configuration is less trivial than mirroring an arbitrary file system " "because:" msgstr "" "Для машины с полностью зеркалированными файловыми системами с использованием " "[.filename]#vinum#, желательно также зеркалировать корневую файловую " "систему. Настройка такой конфигурации менее тривиальна, чем зеркалирование " "произвольной файловой системы, потому что:" #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:560 msgid "" "The root file system must be available very early during the boot process, " "so the [.filename]#vinum# infrastructure must already be available at this " "time." msgstr "" "Корневая файловая система должна быть доступна очень рано в процессе " "загрузки, поэтому инфраструктура [.filename]#vinum# должна быть уже доступна " "на этом этапе." #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:561 msgid "" "The volume containing the root file system also contains the system " "bootstrap and the kernel. These must be read using the host system's native " "utilities, such as the BIOS, which often cannot be taught about the details " "of [.filename]#vinum#." msgstr "" "Том, содержащий корневую файловую систему, также включает системный " "загрузчик и ядро. Они должны быть прочитаны с использованием родных утилит " "хостовой системы, таких как BIOS, который зачастую нельзя обучить работе с " "деталями [.filename]#vinum#." #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:563 msgid "" "In the following sections, the term \"root volume\" is generally used to " "describe the [.filename]#vinum# volume that contains the root file system." msgstr "" "В следующих разделах термин \"корневой том\" обычно используется для " "описания тома [.filename]#vinum#, который содержит корневую файловую систему." #. type: Title === #: documentation/content/en/articles/vinum/_index.adoc:564 #, no-wrap msgid "Starting up [.filename]#vinum# Early Enough for the Root File System" msgstr "Запуск [.filename]#vinum# на раннем этапе для обеспечения доступа к корневой файловой системе" #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:568 msgid "" "[.filename]#vinum# must be available early in the system boot as man:" "loader[8] must be able to load the vinum kernel module before starting the " "kernel. This can be accomplished by putting this line in [.filename]#/boot/" "loader.conf#:" msgstr "" "Файл `[.filename]#vinum#` должен быть доступен на раннем этапе загрузки " "системы, так как `man:loader[8]` должен загрузить модуль ядра `vinum` перед " "запуском ядра. Это можно сделать, добавив следующую строку в `[.filename]#/" "boot/loader.conf#`:" #. type: delimited block . 4 #: documentation/content/en/articles/vinum/_index.adoc:572 #, no-wrap msgid "geom_vinum_load=\"YES\"\n" msgstr "geom_vinum_load=\"YES\"\n" #. type: Title === #: documentation/content/en/articles/vinum/_index.adoc:574 #, no-wrap msgid "Making a [.filename]#vinum#-based Root Volume Accessible to the Bootstrap" msgstr "Создание корневого тома на основе [.filename]#vinum#, доступного для загрузчика" #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:579 msgid "" "The current FreeBSD bootstrap is only 7.5 KB of code and does not understand " "the internal [.filename]#vinum# structures. This means that it cannot parse " "the [.filename]#vinum# configuration data or figure out the elements of a " "boot volume. Thus, some workarounds are necessary to provide the bootstrap " "code with the illusion of a standard `a` partition that contains the root " "file system." msgstr "" "Текущая загрузочная запись FreeBSD занимает всего 7,5 КБ кода и не понимает " "внутренние структуры [.filename]#vinum#. Это означает, что она не может " "разобрать конфигурационные данные [.filename]#vinum# или определить элементы " "загрузочного тома. Таким образом, необходимы некоторые обходные решения, " "чтобы предоставить загрузочному коду иллюзию стандартного раздела `a`, " "содержащего корневую файловую систему." #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:581 msgid "" "For this to be possible, the following requirements must be met for the root " "volume:" msgstr "Для этого должны быть выполнены следующие требования к корневому тому:" #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:583 msgid "The root volume must not be a stripe or `RAID`-5." msgstr "Корневой том не должен быть чередующимся или `RAID`-5." #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:584 msgid "" "The root volume must not contain more than one concatenated subdisk per plex." msgstr "" "Корневой том не должен содержать более одного объединённого поддиска на " "плекс." #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:590 msgid "" "Note that it is desirable and possible to use multiple plexes, each " "containing one replica of the root file system. The bootstrap process will " "only use one replica for finding the bootstrap and all boot files, until the " "kernel mounts the root file system. Each single subdisk within these plexes " "needs its own `a` partition illusion, for the respective device to be " "bootable. It is not strictly needed that each of these faked `a` partitions " "is located at the same offset within its device, compared with other devices " "containing plexes of the root volume. However, it is probably a good idea " "to create the [.filename]#vinum# volumes that way so the resulting mirrored " "devices are symmetric, to avoid confusion." msgstr "" "Обратите внимание, что желательно и возможно использовать несколько плексов, " "каждый из которых содержит одну реплику корневой файловой системы. Процесс " "начальной загрузки будет использовать только одну реплику для поиска " "загрузчика и всех загрузочных файлов, пока ядро не смонтирует корневую " "файловую систему. Каждый отдельный поддиск в этих плексах должен иметь свою " "собственную иллюзию раздела `a`, чтобы соответствующее устройство было " "загрузочным. Не строго необходимо, чтобы каждый из этих фальшивых разделов " "`a` находился на том же смещении внутри своего устройства по сравнению с " "другими устройствами, содержащими плекс корневого тома. Однако, вероятно, " "хорошей идеей будет создавать тома [.filename]#vinum# таким образом, чтобы " "результирующие зеркальные устройства были симметричными, чтобы избежать " "путаницы." #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:592 msgid "" "To set up these `a` partitions for each device containing part of the root " "volume, the following is required:" msgstr "" "Для настройки этих разделов `a` на каждом устройстве, содержащем часть " "корневого тома, требуется следующее:" #. type: delimited block = 4 #: documentation/content/en/articles/vinum/_index.adoc:596 msgid "" "The location, offset from the beginning of the device, and size of this " "device's subdisk that is part of the root volume needs to be examined, using " "the command:" msgstr "" "Местоположение, смещение от начала устройства и размер подобласти этого " "устройства, которая является частью корневого тома, необходимо проверить с " "помощью команды:" #. type: delimited block . 4 #: documentation/content/en/articles/vinum/_index.adoc:600 #, no-wrap msgid "# gvinum l -rv root\n" msgstr "# gvinum l -rv root\n" #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:604 msgid "" "[.filename]#vinum# offsets and sizes are measured in bytes. They must be " "divided by 512 to obtain the block numbers that are to be used by `bsdlabel`." msgstr "" "Смещения и размеры в [.filename]#vinum# измеряются в байтах. Их необходимо " "разделить на 512, чтобы получить номера блоков, которые будут использоваться " "в `bsdlabel`." #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:605 msgid "Run this command for each device that participates in the root volume:" msgstr "" "Выполните эту команду для каждого устройства, участвующего в корневом томе:" #. type: delimited block . 4 #: documentation/content/en/articles/vinum/_index.adoc:609 #, no-wrap msgid "# bsdlabel -e devname\n" msgstr "# bsdlabel -e devname\n" #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:612 msgid "" "_devname_ must be either the name of the disk, like [.filename]#da0# for " "disks without a slice table, or the name of the slice, like [." "filename]#ad0s1#." msgstr "" "`_devname_` должен быть либо именем диска, например, [.filename]#da0# для " "дисков без таблицы разделов, либо именем раздела, например, [." "filename]#ad0s1#." #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:615 msgid "" "If there is already an `a` partition on the device from a pre-[." "filename]#vinum# root file system, it should be renamed to something else so " "that it remains accessible (just in case), but will no longer be used by " "default to bootstrap the system. A currently mounted root file system " "cannot be renamed, so this must be executed either when being booted from a " "\"Fixit\" media, or in a two-step process where, in a mirror, the disk that " "is not been currently booted is manipulated first." msgstr "" "Если на устройстве уже существует раздел `a` из корневой файловой системы до " "[.filename]#vinum#, его следует переименовать во что-то другое, чтобы он " "оставался доступным (на всякий случай), но больше не использовался по " "умолчанию для загрузки системы. Текущий смонтированный корневой файловой " "системы нельзя переименовать, поэтому это должно выполняться либо при " "загрузке с \"Fixit\" носителя, либо в два этапа, когда в зеркале сначала " "обрабатывается диск, с которого в данный момент не загружаются." #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:621 msgid "" "The offset of the [.filename]#vinum# partition on this device (if any) must " "be added to the offset of the respective root volume subdisk on this " "device. The resulting value will become the `offset` value for the new `a` " "partition. The `size` value for this partition can be taken verbatim from " "the calculation above. The `fstype` should be `4.2BSD`. The `fsize`, " "`bsize`, and `cpg` values should be chosen to match the actual file system, " "though they are fairly unimportant within this context." msgstr "" "Смещение раздела [.filename]#vinum# на этом устройстве (если есть) должно " "быть добавлено к смещению соответствующего поддиска корневого тома на этом " "устройстве. Полученное значение станет значением `offset` для нового раздела " "`a`. Значение `size` для этого раздела можно взять дословно из приведённых " "выше расчётов. Для `fstype` следует указать `4.2BSD`. Значения `fsize`, " "`bsize` и `cpg` должны быть выбраны в соответствии с реальной файловой " "системой, хотя в данном контексте они не слишком важны." #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:624 msgid "" "That way, a new `a` partition will be established that overlaps the [." "filename]#vinum# partition on this device. `bsdlabel` will only allow for " "this overlap if the [.filename]#vinum# partition has properly been marked " "using the `vinum` fstype." msgstr "" "Таким образом, будет создан новый раздел `a`, который перекрывает раздел [." "filename]#vinum# на этом устройстве. `bsdlabel` разрешит это перекрытие " "только в том случае, если раздел [.filename]#vinum# был правильно помечен с " "использованием типа файловой системы `vinum`." #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:625 msgid "" "A faked `a` partition now exists on each device that has one replica of the " "root volume. It is highly recommendable to verify the result using a command " "like:" msgstr "" "Поддельный раздел `a` теперь существует на каждом устройстве, имеющем одну " "реплику корневого тома. Настоятельно рекомендуется проверить результат с " "помощью команды, например:" #. type: delimited block . 4 #: documentation/content/en/articles/vinum/_index.adoc:629 #, no-wrap msgid "# fsck -n /dev/devnamea\n" msgstr "# fsck -n /dev/devnamea\n" #. type: delimited block = 4 #: documentation/content/en/articles/vinum/_index.adoc:634 msgid "" "It should be remembered that all files containing control information must " "be relative to the root file system in the [.filename]#vinum# volume which, " "when setting up a new [.filename]#vinum# root volume, might not match the " "root file system that is currently active. So in particular, [.filename]#/" "etc/fstab# and [.filename]#/boot/loader.conf# need to be taken care of." msgstr "" "Следует помнить, что все файлы, содержащие управляющую информацию, должны " "быть относительны к корневой файловой системе в томе [.filename]#vinum#, " "которая при настройке нового корневого тома [.filename]#vinum# может не " "совпадать с текущей активной корневой файловой системой. Поэтому, в " "частности, необходимо позаботиться о [.filename]#/etc/fstab# и [.filename]#/" "boot/loader.conf#." #. type: delimited block = 4 #: documentation/content/en/articles/vinum/_index.adoc:637 msgid "" "At next reboot, the bootstrap should figure out the appropriate control " "information from the new [.filename]#vinum#-based root file system, and act " "accordingly. At the end of the kernel initialization process, after all " "devices have been announced, the prominent notice that shows the success of " "this setup is a message like:" msgstr "" "При следующей перезагрузке загрузчик должен определить соответствующую " "управляющую информацию из новой корневой файловой системы на основе [." "filename]#vinum# и действовать соответствующим образом. В конце процесса " "инициализации ядра, после объявления всех устройств, явным признаком " "успешного завершения настройки будет сообщение вида:" #. type: delimited block . 4 #: documentation/content/en/articles/vinum/_index.adoc:641 #, no-wrap msgid "Mounting root from ufs:/dev/gvinum/root\n" msgstr "Mounting root from ufs:/dev/gvinum/root\n" #. type: Title === #: documentation/content/en/articles/vinum/_index.adoc:643 #, no-wrap msgid "Example of a [.filename]#vinum#-based Root Setup" msgstr "Пример настройки корневой системы на основе [.filename]#vinum#" #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:646 msgid "" "After the [.filename]#vinum# root volume has been set up, the output of " "`gvinum l -rv root` could look like:" msgstr "" "После настройки корневого тома [.filename]#vinum#, вывод команды `gvinum l -" "rv root` может выглядеть следующим образом:" #. type: delimited block . 4 #: documentation/content/en/articles/vinum/_index.adoc:655 #, no-wrap msgid "" "...\n" "Subdisk root.p0.s0:\n" "\t\tSize: 125829120 bytes (120 MB)\n" "\t\tState: up\n" "\t\tPlex root.p0 at offset 0 (0 B)\n" "\t\tDrive disk0 (/dev/da0h) at offset 135680 (132 kB)\n" msgstr "" "...\n" "Subdisk root.p0.s0:\n" "\t\tSize: 125829120 bytes (120 MB)\n" "\t\tState: up\n" "\t\tPlex root.p0 at offset 0 (0 B)\n" "\t\tDrive disk0 (/dev/da0h) at offset 135680 (132 kB)\n" #. type: delimited block . 4 #: documentation/content/en/articles/vinum/_index.adoc:661 #, no-wrap msgid "" "Subdisk root.p1.s0:\n" "\t\tSize: 125829120 bytes (120 MB)\n" "\t\tState: up\n" "\t\tPlex root.p1 at offset 0 (0 B)\n" "\t\tDrive disk1 (/dev/da1h) at offset 135680 (132 kB)\n" msgstr "" "Subdisk root.p1.s0:\n" "\t\tSize: 125829120 bytes (120 MB)\n" "\t\tState: up\n" "\t\tPlex root.p1 at offset 0 (0 B)\n" "\t\tDrive disk1 (/dev/da1h) at offset 135680 (132 kB)\n" #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:667 msgid "" "The values to note are `135680` for the offset, relative to partition [." "filename]#/dev/da0h#. This translates to 265 512-byte disk blocks in " "`bsdlabel`'s terms. Likewise, the size of this root volume is 245760 512-" "byte blocks. [.filename]#/dev/da1h#, containing the second replica of this " "root volume, has a symmetric setup." msgstr "" "Значения, на которые следует обратить внимание: `135680` для смещения, " "относительного к разделу [.filename]#/dev/da0h#. Это соответствует 265 " "блокам диска по 512 байт в терминах `bsdlabel`. Аналогично, размер этого " "корневого тома составляет 245760 блоков по 512 байт. [.filename]#/dev/da1h#, " "содержащий вторую реплику этого корневого тома, имеет симметричную " "конфигурацию." #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:669 msgid "The bsdlabel for these devices might look like:" msgstr "Метка bsdlabel для этих устройств может выглядеть следующим образом:" #. type: delimited block . 4 #: documentation/content/en/articles/vinum/_index.adoc:678 #, no-wrap msgid "" "...\n" "8 partitions:\n" "# size offset fstype [fsize bsize bps/cpg]\n" " a: 245760 281 4.2BSD 2048 16384 0 # (Cyl. 0*- 15*)\n" " c: 71771688 0 unused 0 0 # (Cyl. 0 - 4467*)\n" " h: 71771672 16 vinum # (Cyl. 0*- 4467*)\n" msgstr "" "...\n" "8 partitions:\n" "# size offset fstype [fsize bsize bps/cpg]\n" " a: 245760 281 4.2BSD 2048 16384 0 # (Cyl. 0*- 15*)\n" " c: 71771688 0 unused 0 0 # (Cyl. 0 - 4467*)\n" " h: 71771672 16 vinum # (Cyl. 0*- 4467*)\n" #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:684 msgid "" "It can be observed that the `size` parameter for the faked `a` partition " "matches the value outlined above, while the `offset` parameter is the sum of " "the offset within the [.filename]#vinum# partition `h`, and the offset of " "this partition within the device or slice. This is a typical setup that is " "necessary to avoid the problem described in crossref:vinum[vinum-root-panic, " "Nothing Boots, the Bootstrap Panics]. The entire `a` partition is " "completely within the `h` partition containing all the [.filename]#vinum# " "data for this device." msgstr "" "Можно заметить, что параметр `size` для поддельного раздела `a` совпадает с " "указанным выше значением, в то время как параметр `offset` представляет " "собой сумму смещения внутри раздела [.filename]#vinum# `h` и смещения этого " "раздела в устройстве или слайсе. Это стандартная настройка, необходимая для " "избежания проблемы, описанной в crossref:vinum[vinum-root-panic, Nothing " "Boots, the Bootstrap Panics]. Весь раздел `a` полностью находится внутри " "раздела `h`, содержащего все данные [.filename]#vinum# для этого устройства." #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:686 msgid "" "In the above example, the entire device is dedicated to [.filename]#vinum# " "and there is no leftover pre-[.filename]#vinum# root partition." msgstr "" "В приведённом выше примере все устройство выделено под [.filename]#vinum#, и " "не осталось корневого раздела, существовавшего до [.filename]#vinum#." #. type: Title === #: documentation/content/en/articles/vinum/_index.adoc:687 #, no-wrap msgid "Troubleshooting" msgstr "Устранение неполадок" #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:690 msgid "The following list contains a few known pitfalls and solutions." msgstr "" "Следующий список содержит несколько известных подводных камней и их решения." #. type: Title ==== #: documentation/content/en/articles/vinum/_index.adoc:691 #, no-wrap msgid "System Bootstrap Loads, but System Does Not Boot" msgstr "Загрузчик системы загружается, но система не запускается" #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:695 msgid "" "If for any reason the system does not continue to boot, the bootstrap can be " "interrupted by pressing kbd:[space] at the 10-seconds warning. The loader " "variable `vinum.autostart` can be examined by typing `show` and manipulated " "using `set` or `unset`." msgstr "" "Если по какой-либо причине система не продолжает загрузку, процесс можно " "прервать, нажав kbd:[space] при появлении 10-секундного предупреждения. " "Переменную загрузчика `vinum.autostart` можно проверить, введя команду " "`show`, и изменить с помощью `set` или `unset`." #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:697 msgid "" "If the [.filename]#vinum# kernel module was not yet in the list of modules " "to load automatically, type `load geom_vinum`." msgstr "" "Если модуль ядра [.filename]#vinum# ещё не был в списке модулей для " "автоматической загрузки, введите `load geom_vinum`." #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:700 msgid "" "When ready, the boot process can be continued by typing `boot -as` which `-" "as` requests the kernel to ask for the root file system to mount (`-a`) and " "make the boot process stop in single-user mode (`-s`), where the root file " "system is mounted read-only. That way, even if only one plex of a multi-" "plex volume has been mounted, no data inconsistency between plexes is being " "risked." msgstr "" "Когда всё готово, процесс загрузки можно продолжить, введя `boot -as`, где `-" "as` указывает ядру запросить корневую файловую систему для монтирования (`-" "a`) и остановить процесс загрузки в однопользовательском режиме (`-s`), при " "этом корневая файловая система монтируется в режиме только для чтения. Таким " "образом, даже если смонтирован только один слой многокомпонентного тома, не " "возникает риска несогласованности данных между слоями." #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:706 msgid "" "At the prompt asking for a root file system to mount, any device that " "contains a valid root file system can be entered. If [.filename]#/etc/" "fstab# is set up correctly, the default should be something like `ufs:/dev/" "gvinum/root`. A typical alternate choice would be something like `ufs:da0d` " "which could be a hypothetical partition containing the pre-[." "filename]#vinum# root file system. Care should be taken if one of the alias " "`a` partitions is entered here, that it actually references the subdisks of " "the [.filename]#vinum# root device, because in a mirrored setup, this would " "only mount one piece of a mirrored root device. If this file system is to " "be mounted read-write later on, it is necessary to remove the other plex(es) " "of the [.filename]#vinum# root volume since these plexes would otherwise " "carry inconsistent data." msgstr "" "На запрос о корневой файловой системе для монтирования можно ввести любое " "устройство, содержащее действительную корневую файловую систему. Если [." "filename]#/etc/fstab# настроен правильно, по умолчанию должно быть что-то " "вроде `ufs:/dev/gvinum/root`. Типичным альтернативным выбором может быть что-" "то вроде `ufs:da0d`, что может быть гипотетическим разделом, содержащим " "корневую файловую систему до [.filename]#vinum#. Следует быть осторожным, " "если здесь вводится один из псевдонимов `a` разделов, чтобы он действительно " "ссылался на поддиски устройства [.filename]#vinum# root, потому что в " "зеркальной настройке это приведёт к монтированию только одной части " "зеркального корневого устройства. Если эта файловая система будет позже " "смонтирована в режиме чтения-записи, необходимо удалить другие плексы тома [." "filename]#vinum# root, так как в противном случае эти плексы будут содержать " "несогласованные данные." #. type: Title ==== #: documentation/content/en/articles/vinum/_index.adoc:707 #, no-wrap msgid "Only Primary Bootstrap Loads" msgstr "Только первичная загрузка Bootstrap" #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:712 msgid "" "If [.filename]#/boot/loader# fails to load, but the primary bootstrap still " "loads (visible by a single dash in the left column of the screen right after " "the boot process starts), an attempt can be made to interrupt the primary " "bootstrap by pressing kbd:[space]. This will make the bootstrap stop in " "extref:{handbook}boot[stage two, boot-boot1]. An attempt can be made here " "to boot off an alternate partition, like the partition containing the " "previous root file system that has been moved away from `a`." msgstr "" "Если [.filename]#/boot/loader# не загружается, но первичная загрузка всё ещё " "работает (это видно по одному дефису в левой части экрана сразу после начала " "процесса загрузки), можно попытаться прервать первичную загрузку, нажав " "kbd:[space]. Это остановит загрузку на extref:{handbook}boot[втором этапе, " "boot-boot1]. Здесь можно попытаться загрузиться с альтернативного раздела, " "например, с раздела, содержащего предыдущую корневую файловую систему, " "которая была перемещена из `a`." #. type: Title ==== #: documentation/content/en/articles/vinum/_index.adoc:714 #, no-wrap msgid "Nothing Boots, the Bootstrap Panics" msgstr "Ничего не загружается, паника при загрузке" #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:720 msgid "" "This situation will happen if the bootstrap had been destroyed by the [." "filename]#vinum# installation. Unfortunately, [.filename]#vinum# " "accidentally leaves only 4 KB at the beginning of its partition free before " "starting to write its [.filename]#vinum# header information. However, the " "stage one and two bootstraps plus the bsdlabel require 8 KB. So if a [." "filename]#vinum# partition was started at offset 0 within a slice or disk " "that was meant to be bootable, the [.filename]#vinum# setup will trash the " "bootstrap." msgstr "" "Такая ситуация произойдет, если загрузчик был уничтожен при установке [." "filename]#vinum#. К сожалению, [.filename]#vinum# случайно оставляет " "свободными только первые 4 КБ в начале своего раздела перед записью " "заголовочной информации [.filename]#vinum#. Однако, первая и вторая стадии " "загрузчика вместе с bsdlabel требуют 8 КБ. Поэтому, если раздел [." "filename]#vinum# начинается со смещения 0 внутри слайса или диска, который " "должен быть загрузочным, установка [.filename]#vinum# повредит загрузчик." #. type: Plain text #: documentation/content/en/articles/vinum/_index.adoc:723 msgid "" "Similarly, if the above situation has been recovered, by booting from a " "\"Fixit\" media, and the bootstrap has been re-installed using `bsdlabel -B` " "as described in extref:{handbook}boot[stage two, boot-boot1], the bootstrap " "will trash the [.filename]#vinum# header, and [.filename]#vinum# will no " "longer find its disk(s). Though no actual [.filename]#vinum# configuration " "data or data in [.filename]#vinum# volumes will be trashed, and it would be " "possible to recover all the data by entering exactly the same [." "filename]#vinum# configuration data again, the situation is hard to fix. It " "is necessary to move the entire [.filename]#vinum# partition by at least 4 " "KB, to have the [.filename]#vinum# header and the system bootstrap no longer " "collide." msgstr "" "Аналогично, если описанная выше ситуация была исправлена загрузкой с \"Fixit" "\"-носителя, и загрузчик был переустановлен с помощью `bsdlabel -B`, как " "описано в extref:{handbook}boot[этапе два, boot-boot1], загрузчик повредит " "заголовок [.filename]#vinum#, и [.filename]#vinum# больше не сможет найти " "свои диски. Хотя фактические данные конфигурации [.filename]#vinum# или " "данные в томах [.filename]#vinum# не будут повреждены, и можно восстановить " "все данные, введя точно такую же конфигурацию [.filename]#vinum# снова, " "исправить ситуацию сложно. Необходимо переместить весь раздел [." "filename]#vinum# как минимум на 4 КБ, чтобы заголовок [.filename]#vinum# и " "системный загрузчик больше не конфликтовали." diff --git a/documentation/content/ru/articles/vm-design/_index.adoc b/documentation/content/ru/articles/vm-design/_index.adoc index 804913d6df..3311334419 100644 --- a/documentation/content/ru/articles/vm-design/_index.adoc +++ b/documentation/content/ru/articles/vm-design/_index.adoc @@ -1,206 +1,206 @@ --- authors: - author: 'Matthew Dillon' email: dillon@apollo.backplane.com description: 'Простое и понятное описание архитектуры системы виртуальной памяти FreeBSD' tags: ["Design", "virtual machine", "FreeBSD"] title: 'Элементы архитектуры системы виртуальной памяти во FreeBSD' trademarks: ["freebsd", "linux", "microsoft", "opengroup", "daemon-news", "general"] --- = Элементы архитектуры системы виртуальной памяти во FreeBSD :doctype: article :toc: macro :toclevels: 1 :icons: font :sectnums: :sectnumlevels: 6 :source-highlighter: rouge :experimental: :images-path: articles/vm-design/ ifdef::env-beastie[] ifdef::backend-html5[] include::shared/authors.adoc[] include::shared/mirrors.adoc[] include::shared/releases.adoc[] include::shared/attributes/attributes-{{% lang %}}.adoc[] include::shared/{{% lang %}}/teams.adoc[] include::shared/{{% lang %}}/mailing-lists.adoc[] include::shared/{{% lang %}}/urls.adoc[] :imagesdir: ../../../images/{images-path} endif::[] ifdef::backend-pdf,backend-epub3[] include::../../../../shared/asciidoctor.adoc[] endif::[] endif::[] ifndef::env-beastie[] include::../../../../../shared/asciidoctor.adoc[] endif::[] [NOTE] ==== Этот документ устарел, и некоторые разделы больше не соответствуют текущему состоянию системы виртуальной памяти. Он сохранён в исторических целях и может быть обновлён в будущем. ==== [.abstract-title] Аннотация Matthew Dillon Это название — просто замысловатый способ сказать, что я попытаюсь описать всю систему виртуальной памяти (VM) целиком, по возможности так, чтобы это было понятно каждому.В течение последнего года я сосредоточился на нескольких основных подсистемах ядра FreeBSD. Наиболее интересными из них стали подсистемы VM и подкачки (Swap), тогда как работа с NFS оказалась, скорее, «необходимой рутиной». Я переписал лишь небольшие части кода. В области VM моей единственной крупной переработкой стала подсистема подкачки. В основном моя работа заключалась в очистке и поддержке кода, с умеренными правками и без серьёзных изменений алгоритмов в подсистеме VM. Теоретическая основа VM-подсистемы осталась неизменной, и львиная доля заслуг в её модернизации за последние годы принадлежит Джону Дайсону и Дэвиду Гринману. Я не историк, в отличие от Кирка, поэтому не стану приписывать различные функции конкретным людям — всё равно где-нибудь ошибусь. ''' toc::[] [[introduction]] == Введение -Перед тем, как перейти непосредственно к существующей архитектуре, потратим немного времени на рассмотрение вопроса о необходимости поддержки и модернизации любого длительно живущего кода. В мире программирования алгоритмы становятся более важными, чем код, и именно из-за академических корней BSD изначально большое внимание уделялось проработке алгоритмов. Внимание, уделенное архитектуре, в общем отражается на ясности и гибкости кода, который может быть достаточно легко изменен, расширен или с течением времени заменен. Хотя некоторые считают BSD "старой" операционной системой, те их нас, кто работает над ней, видят её скорее системой со "зрелым" кодом с различными компонентами, которые были заменены, расширены или изменены современным кодом. Он развивается, и FreeBSD остаётся передовой системой, вне зависимости от того, насколько старой может быть часть кода. Это важное отличие, которое, к сожалению, не всеми понимается. Самой большой ошибкой, которую может допустить программист, является игнорирование истории, и это именно та ошибка, которую сделали многие другие современные операционные системы. Самым ярким примером здесь является Windows NT(R), и последствия ужасны. Linux также в некоторой степени совершил эту ошибку — достаточно, чтобы мы, люди BSD, по крайней мере по разу отпустили по этому поводу шутку. Проблема Linux заключается просто в отсутствии опыта и истории для сравнения идей, проблема, которая легко и быстро решается сообществом Linux точно так же, как она решается в сообществе BSD-постоянной работой над кодом. Разработчики Windows NT(R), с другой стороны, постоянно совершают те же самые ошибки, что были решены в UNIX(R) десятки лет назад, а затем тратят годы на их устранение. Снова и снова. Есть несколько случаев "проработка архитектуры отсутствует" и "мы всегда правы, потому что так говорит наш отдел продаж". Я плохо переношу тех, кого не учит история. +Перед тем, как перейти непосредственно к существующей архитектуре, потратим немного времени на рассмотрение вопроса о необходимости поддержки и модернизации любого длительно живущего кода. В мире программирования алгоритмы становятся более важными, чем код, и именно из-за академических корней BSD изначально большое внимание уделялось проработке алгоритмов. Более тщательное внимание к проектированию в целом приводит к созданию чистой и гибкой кодовой базы, которую со временем можно достаточно легко модифицировать, расширять или заменять. Хотя некоторые считают BSD "старой" операционной системой, те их нас, кто работает над ней, видят её скорее системой со "зрелым" кодом с различными компонентами, которые были заменены, расширены или изменены современным кодом. Он развивается, и FreeBSD остаётся передовой системой, вне зависимости от того, насколько старой может быть часть кода. Это важное отличие, которое, к сожалению, не всеми понимается. Самой большой ошибкой, которую может допустить программист, является игнорирование истории, и это именно та ошибка, которую сделали многие другие современные операционные системы. Самым ярким примером здесь является Windows NT(R), и последствия ужасны. Linux также в некоторой степени совершил эту ошибку — достаточно, чтобы мы, люди BSD, по крайней мере по разу отпустили по этому поводу шутку. Проблема Linux заключается просто в отсутствии опыта и истории для сравнения идей, проблема, которая легко и быстро решается сообществом Linux точно так же, как она решается в сообществе BSD — постоянной работой над кодом. Разработчики Windows NT(R), с другой стороны, постоянно совершают те же самые ошибки, что были решены в UNIX(R) десятки лет назад, а затем тратят годы на их устранение. Снова и снова. У них тяжёлый случай синдрома „не нами разработано“ и „мы всегда правы, потому что так говорит наш отдел маркетинга“. Я плохо переношу тех, кого не учит история. Большинство очевидной сложности архитектуры FreeBSD, особенно в подсистеме VM/Swap, является прямым следствием того, что она решает серьезные проблемы с производительностью, которые проявляются при различных условиях. Эти проблемы вызваны не плохой проработкой алгоритмов, а возникают из окружающих факторов. В любом прямом сравнении между платформами эти проблемы проявляются, когда системные ресурсы начинают истощаться. Так как я описываю подсистему VM/Swap во FreeBSD, то читатель должен всегда иметь в виду два обстоятельства: . Самым важным аспектом при проектировании производительности является то, что называется "оптимизацией критического маршрута". Часто случается, что оптимизация производительности даёт прирост объёма кода ради того, чтобы критический маршрут работал быстрее. . Четкость общей архитектуры оказывается лучше сильно оптимизированной архитектуры с течением времени. Когда как обобщенная архитектура может быть медленнее, чем оптимизированная архитектура, при первой реализации, при обобщенной архитектуре легче подстраиваться под изменяющиеся условия и чрезмерно оптимизированная архитектура оказывается непригодной. Любой код, который должен выжить и поддаваться поддержке годы, должен поэтому быть тщательно продуман с самого начала, даже если это стоит потери производительности. Двадцать лет назад были те, кто отстаивал преимущество программирования на языке ассемблера перед программированием на языке высокого уровня, потому что первый генерировал в десять раз более быстрый код. В наши дни ошибочность этого аргумента очевидна - можно провести параллели с построением алгоритмов и обобщением кода. [[vm-objects]] == Объекты VM -Лучше всего начать описание VM-системы FreeBSD с попытки взглянуть на нее с точки зрения пользовательского процесса. Каждый пользовательский процесс имеет единое, принадлежащее только ему и неразрывное адресное пространство VM, содержащее несколько типов объектов памяти. Эти объекты имеют различные характеристики. Код программы и её данные являются единым файлом, отображаемым в память (это выполняющийся двоичный файл), однако код программы доступен только для чтения, тогда как данные программы размещаются в режиме копирования-при-записи. BSS программы представляет собой всего лишь выделенную область памяти, заполненную, если это требовалось, нулями, что называется обнулением страниц памяти по требованию. Отдельные файлы могут также отображаться в адресное пространство, именно так работают динамические библиотеки. Такие отображения требуют изменений, чтобы оставаться принадлежащими процессу, который их выполнил. Системный вызов fork переводит проблему управления VM полностью в новую плоскость, вдобавок к уже имеющимся сложностям. +Лучше всего начать описание VM-системы FreeBSD с попытки взглянуть на неё с точки зрения пользовательского процесса. Каждый пользовательский процесс имеет единое, принадлежащее только ему и неразрывное адресное пространство VM, содержащее несколько типов объектов памяти. Эти объекты имеют различные характеристики. Код программы и её данные являются единым файлом, отображаемым в память (это выполняющийся двоичный файл), однако код программы доступен только для чтения, тогда как данные программы размещаются в режиме копирования-при-записи. BSS программы представляет собой всего лишь выделенную область памяти, заполненную, если это требовалось, нулями, что называется обнулением страниц памяти по требованию. Отдельные файлы могут также отображаться в адресное пространство, именно так работают динамические библиотеки. Такие отображения требуют изменений, чтобы оставаться принадлежащими процессу, который их выполнил. Системный вызов fork переводит проблему управления VM полностью в новую плоскость, вдобавок к уже имеющимся сложностям. Иллюстрирует сложность страница данных двоичной программы (которая является страницей копируемой-при-записи). Двоичная программа содержит секцию предварительно инициализированных данных, которая первоначально отображается непосредственно из файла программы. Когда программа загружается в виртуальную память процесса, эта область сначала отображается в память и поддерживается бинарным файлом программы, позволяя VM-системе освобождать/повторно использовать страницу, а потом загружать её снова из бинарного файла. Однако в момент, когда процесс изменяет эти данные, VM-система должна сделать копию страницы, принадлежащую только этому процессу. Так как эта копия была изменена, то VM-система не может больше освобождать эту страницу, так как впоследствии её невозможно будет восстановить. -Вы тут же заметите, что то, что сначала было простым отображением файла в память, становится гораздо более сложным предметом. Данные могут модифицироваться постранично, когда как отображение файла выполняется для многих страниц за раз. Сложность ещё более увеличивается, когда процесс выполняет вызов fork. При этом порождаются два процесса-каждый с собственным адресным пространством, включающим все изменения, выполненные исходным процессом до вызова функции `fork()`. Было бы глупо для VM-системы делать полную копию данных во время вызова `fork()`, так как весьма вероятно, что один из двух процессов будет нужен только для чтения из той страницы, что позволяет использование исходной страницы. То, что было страницей, принадлежащей только процессу, сделается снова страницей, копируемой при записи, так как каждый из процессов (и родитель, и потомок) полагают, что их собственные изменения после разветвления будут принадлежать только им, и не затронут родственный процесс. +Вы тут же заметите, что то, что сначала было простым отображением файла в память, становится гораздо более сложным предметом. Данные могут модифицироваться постранично, когда как отображение файла выполняется для многих страниц за раз. Сложность ещё более увеличивается, когда процесс выполняет вызов fork. При этом порождаются два процесса, и каждый с собственным адресным пространством, включающим все изменения, выполненные исходным процессом до вызова функции `fork()`. Было бы глупо для VM-системы делать полную копию данных во время вызова `fork()`, так как весьма вероятно, что один из двух процессов будет нужен только для чтения из той страницы, что позволяет использование исходной страницы. То, что было страницей, принадлежащей только процессу, снова становится страницей, копируемой при записи, поскольку каждый из процессов (родительский и дочерний) рассчитывает на то, что его собственные изменения после вызова fork() останутся приватными и не повлияют на другой процесс. -FreeBSD управляет всем этим при помощи многоуровневой модели VM-объектов. Исходный файл с двоичной программой переносится на самый нижний уровень объектов VM. Уровень страниц, копируемых при записи, находится выше него, и хранит те страницы, которые были скопированы из исходного файла. Если программа модифицирует страницы данных, относящиеся к исходному файлу, то система VM обнаруживает это и переносит копию этой страницы на более высокий уровень. Когда процесс разветвляется, добавляются новые уровни VM-объектов. Это можно показать на простом примере. Функция `fork()` является общей операцией для всех систем *BSD, так что в этом примере будет рассматриваться программа, которая запускается, а затем разветвляется. Когда процесс запускается, VM-система создает некоторый уровень объектов, обозначим его **A**: +FreeBSD управляет всем этим при помощи многоуровневой модели VM-объектов. Исходный файл с двоичной программой переносится на самый нижний уровень объектов VM. Уровень страниц, копируемых при записи, находится выше него, и хранит те страницы, которые были скопированы из исходного файла. Если программа изменяет страницу данных, принадлежащую исходному файлу, подсистема виртуальной памяти обрабатывает страничное нарушение (page fault) и создаёт копию этой страницы на вышележащем уровне. Когда процесс разветвляется, добавляются новые уровни VM-объектов. Понять это поможет достаточно простой пример. Функция `fork()` является общей операцией для всех систем *BSD, так что в этом примере будет рассматриваться программа, которая запускается, а затем разветвляется. Когда процесс запускается, VM-система создаёт некоторый уровень объектов, обозначим его **A**: image::fig1.png["Рисунок"] -На рисунке *A* соответствует файлу — по необходимости страницы памяти могут высвобождаться и подгружаться с носителя файла. Подгрузка с диска может потребоваться программе, однако на самом деле мы не хотим, чтобы она записывалась обратно в файл. Поэтому VM-система создает второй уровень, **B**, который физически поддерживается дисковым пространством подкачки: +На рисунке *A* соответствует файлу — по необходимости страницы памяти могут высвобождаться и подгружаться с носителя файла. Подгрузка с диска может потребоваться программе, однако на самом деле мы не хотим, чтобы она записывалась обратно в файл. Поэтому VM-система создаёт второй уровень, **B**, который физически поддерживается дисковым пространством подкачки: image::fig2.png[] -При первой записи в страницу после выполнения этой операции в **B** создается новая страница, содержимое которой берётся из **A**. Все страницы в **B** могут сбрасываться и считываться из устройства подкачки. Когда программа ветвится, VM-система создает два новых уровня объектов — **C1** для порождающего процесса и **C2** для порожденного — они располагаются поверх **B**: +При первой записи в страницу после выполнения этой операции в **B** создаётся новая страница, содержимое которой берётся из **A**. Все страницы в **B** могут сбрасываться и считываться из устройства подкачки. Когда программа ветвится, VM-система создаёт два новых уровня объектов — **C1** для порождающего процесса и **C2** для порождённого — они располагаются поверх **B**: image::fig3.png[] -В этом случае, допустим, что страница в **B** была изменена начальным родительским процессом. В процессе возникнет ситуация копирования при записи, и страница скопируется в **C1**, при этом исходная страница останется в **B** нетронутой. Теперь допустим, что та же самая страница в **B** изменяется порожденным процессом. В процессе возникнет ситуация копирования при записи и страница скопируется в **C2**. Исходная страница в **B** теперь полностью скрыта, так как и **C1**, и **C2** имеют копии, а уровень **B** теоретически может быть уничтожен, если он не представляет собой "реального" файла). Однако такую оптимизацию не так уж просто осуществить, потому что это надо делать на уровне слишком мелких единиц. Во FreeBSD такая оптимизация не выполняется. Теперь положим (а это часто случается), что порожденный процесс выполняет вызов `exec()`. Его текущее адресное пространство обычно заменяется новым адресным пространством, представляющим новый файл. В этом случае уровень **C2** уничтожается: +В этом случае, допустим, что страница в **B** была изменена начальным родительским процессом. Процесс вызовет страничное нарушение копирования-при-записи и продублирует страницу в **C1**, при этом исходная страница останется в **B** нетронутой. Теперь допустим, что та же самая страница в **B** изменяется дочерним процессом. В процессе возникнет ситуация копирования при записи и страница скопируется в **C2**. Исходная страница в **B** теперь полностью скрыта, так как и **C1**, и **C2** имеют копии, а уровень **B** теоретически может быть уничтожен, если он не представляет собой "реального" файла). Однако такую оптимизацию не так уж просто осуществить, потому что это надо делать на уровне слишком мелких единиц. Во FreeBSD такая оптимизация не выполняется. Теперь положим (а это часто случается), что дочерний процесс выполняет вызов `exec()`. Его текущее адресное пространство обычно заменяется новым адресным пространством, представляющим новый файл. В этом случае уровень **C2** уничтожается: image::fig4.png[] -В этом случае количество потомков **B** становится равным одному и все обращения к **B** теперь выполняются через **C1**. Это означает, что **B** и **C1** могут быть объединены. Все страницы в **B**, которые также существуют и в **C1**, во время объединения из** B** удаляются. Таким образом, хотя оптимизация на предыдущем шаге может не делаться, мы можем восстановить мертвые страницы при окончании работы процессов или при вызове `exec()`. +В этом случае количество потомков **B** становится равным одному и все обращения к **B** теперь выполняются через **C1**. Это означает, что **B** и **C1** могут быть объединены. Все страницы в **B**, которые также существуют и в **C1**, во время объединения из** B** удаляются. Таким образом, хотя оптимизация на предыдущем шаге может не делаться, мы можем восстановить мёртвые страницы при окончании работы процессов или при вызове `exec()`. -Такая модель создает некоторое количество потенциальных проблем. Первая, с которой вы можете столкнуться, заключается в сравнительно большой последовательности уровней объектов VM, на сканирование которых тратится время и память. Большое количество уровней может возникнуть, когда процессы разветвляются, а затем разветвляются ещё раз (как порожденные, так и порождающие). Вторая проблема заключается в том, что вы можете столкнуться с мертвыми, недоступными страницами глубоко в иерархии объектов VM. В нашем последнем примере если как родитель, так и потомок изменяют одну и ту же страницу, они оба получают собственные копии страницы, а исходная страница на уровне **B** становится никому не доступной. Такая страница в **B** может быть высвобождена. +Такая модель создаёт некоторое количество потенциальных проблем. Во-первых, можно получить относительно глубокий стек наслоённых объектов виртуальной памяти, что может увеличить время сканирования и расход памяти при обработке страничного исключения. Большое количество уровней может возникнуть, когда процессы разветвляются, а затем разветвляются ещё раз (как порождённые, так и порождающие). Вторая проблема заключается в том, что вы можете столкнуться с мёртвыми, недоступными страницами глубоко в иерархии объектов VM. В нашем последнем примере, если и родитель, и потомок изменяют одну и ту же страницу, они оба получают собственные копии, а исходная страница на уровне **B** становится недоступной ни для одного из них. Такая страница в **B** может быть высвобождена. -FreeBSD решает проблему с глубиной вложенности с помощью приёма оптимизации, который называется "All Shadowed Case". Этот случай возникает, если в **C1** либо *C2* происходит столько случаев копирования страниц при записи, что они полностью перекрывают все страницы в *B*. Допустим, что такое произошло в *C1*. Уровень *C1* может теперь полностью пропускать уровень *B*, так что вместо цепочек *C1* -> *B* -> *A* и *C2* -> *B* -> *A* мы теперь имеем цепочки *C1* -> *A* и *C2* -> *B* -> *A*. Но посмотрите, что получается — теперь *B* имеет только одну ссылку (*C2*), так что мы можем объединить *B* и *C2*. В конечном итоге *B* будет полностью удалён, и мы получим цепочки *C1*-> *A* и *C2*-> *A*. Часто *B* будет содержать большое количество страниц, и ни *C1*, ни *C2* не смогут полностью его заменить. Если мы снова породим процесс и создадим набор уровней *D*, при этом, однако, более вероятно, что один из уровней *D* постепенно сможет полностью заместить гораздо меньший набор данных, представленный *C1* и *C2*. Та же самая оптимизация работает в любой точке графа и её главным результатом является то, что даже на сильно загруженной машине с множеством порождаемых процессов стеки объектов VM не часто бывают глубже четырёх уровней. Это верно как для порождающего, так и для порождённого процессов, и остаётся справедливым как в случае, когда ветвление выполняет родитель, так и в случае, когда ветвление выполняет его потомок. +FreeBSD решает проблему с глубиной вложенности с помощью приёма оптимизации, который называется "All Shadowed Case". Этот случай возникает, если в **C1** либо *C2* происходит столько случаев копирования страниц при записи, что они полностью перекрывают все страницы в *B*. Допустим, что такое произошло в *C1*. Уровень *C1* может теперь полностью пропускать уровень *B*, так что вместо цепочек *C1* -> *B* -> *A* и *C2* -> *B* -> *A* мы теперь имеем цепочки *C1* -> *A* и *C2* -> *B* -> *A*. Но посмотрите, что получается — теперь *B* имеет только одну ссылку (*C2*), так что мы можем объединить *B* и *C2*. В конечном итоге *B* будет полностью удалён, и мы получим цепочки *C1* -> *A* и *C2* -> *A*. Часто *B* будет содержать большое количество страниц, и ни *C1*, ни *C2* не смогут полностью его заменить. Если мы снова породим процесс и создадим набор уровней *D*, при этом, однако, более вероятно, что один из уровней *D* постепенно сможет полностью заместить гораздо меньший набор данных, представленный *C1* и *C2*. Та же самая оптимизация работает в любой точке графа и её главным результатом является то, что даже на сильно загруженной машине с множеством порождаемых процессов стеки объектов VM не часто бывают глубже четырёх уровней. Это верно как для порождающего, так и для порождённого процессов, и остаётся справедливым как в случае, когда ветвление выполняет родитель, так и в случае, когда ветвление выполняет его потомок. -Проблема с мертвой страницей все ещё имеет место, когда *C1* или *C2* не полностью перекрывают *B*. Из-за других применяемых нами методов оптимизации этот случай не представляет большой проблемы и мы просто позволяем таким страницам существовать. Если система испытывает нехватку оперативной памяти, она выполняет их выгрузку в область подкачки, что занимает некоторое пространство в области подкачки, но это всё. +Проблема с мёртвой страницей все ещё имеет место, когда *C1* или *C2* не полностью перекрывают *B*. Из-за других применяемых нами методов оптимизации этот случай не представляет большой проблемы, и мы просто позволяем таким страницам существовать. Если система испытывает нехватку оперативной памяти, она выполняет их выгрузку в область подкачки, что занимает некоторое пространство в области подкачки, но это всё. -Преимущество модели VM-объектов заключается в очень быстром выполнении функции `fork()`, так как при этом не выполняется реального копирования данных. Минусом этого подхода является то, что вы можете построить сравнительно сложную иерархию объектов VM, которая несколько замедляет обработку ситуаций отсутствия страниц памяти, и к тому же тратится память на управление структурами объектов VM. Приёмы оптимизации, применяемые во FreeBSD, позволяют снизить значимость этих проблем до степени, когда их можно без особых потерь игнорировать. +Преимущество модели VM-объектов заключается в очень быстром выполнении функции `fork()`, так как при этом не выполняется реального копирования данных. Минусом этого подхода является то, что вы можете построить сравнительно сложную иерархию объектов VM, которая несколько замедляет обработку страничных нарушений, и к тому же тратится память на управление структурами объектов VM. Приёмы оптимизации, применяемые во FreeBSD, позволяют снизить значимость этих проблем до степени, когда их можно без особых потерь игнорировать. [[swap-layers]] == Уровни области подкачки -Страницы с собственными данными первоначально являются страницами, копируемыми-при-записи или заполняемыми нулями. Когда выполняется изменение, и, соответственно, копирование, начальное хранилище объекта (обычно файл) не может больше использоваться для хранения копии страницы, когда VM-системе нужно использовать её повторно для других целей. В этот момент на помощь приходит область подкачки. Область подкачки выделяется для организации хранилища памяти, которая иначе не может быть доступна. FreeBSD создает структуру управления подкачкой для объекта VM, только когда это действительно нужно. Однако структура управления подкачкой исторически имела некоторые проблемы: +Страницы с собственными данными первоначально являются страницами, копируемыми-при-записи или заполняемыми нулями. Когда выполняется изменение, и, соответственно, копирование, начальное хранилище объекта (обычно файл) не может больше использоваться для хранения копии страницы, когда VM-системе нужно использовать её повторно для других целей. В этот момент на помощь приходит область подкачки. Область подкачки выделяется для организации хранилища памяти, которая иначе не может быть доступна. FreeBSD создаёт структуру управления подкачкой для объекта VM, только когда это действительно нужно. Однако структура управления подкачкой исторически имела некоторые проблемы: -* Во FreeBSD 3.X в структуре управления областью подкачки предварительно выделяется массив, который представляет целый объект, требующий хранения в области подкачки — даже если только несколько страниц этого объекта хранятся в области подкачки. Это создает проблему фрагментации памяти ядра в случае, когда в память отображаются большие объекты или когда ветвятся процессы, занимающие большой объём памяти при работе (RSS). +* В FreeBSD 3.X в структуре управления областью подкачки предварительно выделяется массив, который представляет собой целый объект, требующий хранения в области подкачки — даже если только несколько страниц этого объекта хранятся в области подкачки. Это создаёт проблему фрагментации памяти ядра в случае, когда в память отображаются большие объекты или когда ветвятся процессы, занимающие большой объём памяти при работе (RSS). * Также для отслеживания памяти подкачки в памяти ядра поддерживается "список дыр", и он также несколько фрагментирован. Так как "список дыр" является последовательным списком, то производительность при распределении и высвобождении памяти в области подкачки неоптимальна, и её сложность зависит от количества страниц как O(n). * Также в процессе высвобождения памяти из области подкачки требуется выделение памяти в ядре, и это приводит к проблемам блокировки при недостатке памяти. * Проблема ещё более обостряется из-за дыр, создаваемых по чередующемуся алгоритму. * Кроме того, список распределения блоков в области подкачки легко оказывается фрагментированным, что приводит к распределению непоследовательных областей. * Память ядра также должна выделяться на лету для дополнительных структур управления подкачкой при выгрузке страниц в область подкачки. Очевидно, что мест для усовершенствований предостаточно. Во FreeBSD 4.X подсистема управления областью подкачки была полностью переписана мною: * Структуры управления областью подкачки распределяются при помощи хэш-таблицы, а не через линейный массив, что даёт им фиксированный размер при распределении и работу с гораздо меньшими структурами. * Вместо того, чтобы использовать однонаправленный связный список для отслеживания выделения пространства в области подкачки, теперь используется побитовая карта блоков области подкачки, выполненная в основном в виде древовидной структуры с информацией о свободном пространстве, находящейся в узлах структур. Это приводит к тому, что выделение и высвобождение памяти в области подкачки становится операцией сложности O(1). * Всё дерево также распределяется заранее для того, чтобы избежать распределения памяти ядра во время операций с областью подкачки при критически малом объёме свободной памяти. В конце концов, система обращается к области подкачки при нехватке памяти, так что мы должны избежать распределения памяти ядра в такие моменты для избежания потенциальных блокировок. * Для уменьшения фрагментации дерево может распределять большой последовательный кусок за раз, пропуская меньшие фрагментированные области. Я не сделал последний шаг к заведению "указателя на распределение", который будет передвигаться по участку области подкачки при выделении памяти для обеспечения в будущем распределения последовательных участков, или по крайней мере местоположения ссылки, но я убежден, что это может быть сделано. [[freeing-pages]] == Когда освобождать страницу Так как система VM использует всю доступную память для кэширования диска, то обычно действительно незанятых страниц очень мало. Система VM зависит от того, как она точно выбирает незанятые страницы для повторного использования для новых распределений. Оптимальный выбор страниц для высвобождения, возможно, является самой важной функцией любой VM-системы, из тех, что она может выполнять, потому что при неправильном выборе система VM вынуждена будет запрашивать страницы с диска, значительно снижая производительность всей системы. -Какую дополнительную нагрузку мы может выделить в критическом пути для избежания высвобождения не той страницы? Каждый неправильный выбор будет стоить нам сотни тысяч тактов работы центрального процессора и заметное замедление работы затронутых процессов, так что мы должны смириться со значительными издержками для того, чтобы была выбрана правильная страница. Вот почему FreeBSD превосходит другие системы в производительности при нехватке ресурсов памяти. +Какую дополнительную нагрузку мы может выделить в критическом пути для избежания высвобождения неверно выбранной страницы? Каждый неправильный выбор будет стоить нам сотен тысяч тактов работы центрального процессора и заметного замедления работы затронутых процессов, так что мы должны смириться со значительными издержками ради того, чтобы была выбрана правильная страница. Вот почему FreeBSD превосходит другие системы в производительности при нехватке ресурсов памяти. Алгоритм определения свободной страницы написан на основе истории использования страниц памяти. Для получения этой истории система использует возможности бита использования памяти, которые имеются в большинстве аппаратных таблицах страниц памяти. В любом случае, бит использования страницы очищается, и в некоторый более поздний момент VM-система обращается к странице снова и обнаруживает, что этот бит установлен. Это указывает на то, что страница активно используется. Периодически проверяя этот бит, накапливается история использования (в виде счетчика) физической страницы. Когда позже VM-системе требуется высвободить некоторые страницы, проверка истории выступает указателем при определении наиболее вероятной кандидатуры для повторного использования. -Для тех платформ, что не имеют этой возможности, система эмулирует этот бит. Она снимает отображение или защищает страницу, что приводит к ошибке доступа к странице, если к странице выполняется повторное обращение. При возникновении этой ошибки система просто помечает страницу как используемую и снимает защиту со страницы, так что она может использоваться. Хотя использование такого приема только для определения использования страницы весьма накладно, это выгоднее, чем повторно использовать страницу для других целей и обнаружить, что она снова нужна процессу и подгружать её с диска. +Для тех платформ, что не имеют этой возможности, система эмулирует этот бит. Она снимает отображение или защищает страницу, что приводит к страничному нарушению, если к странице выполняется повторное обращение. При возникновении этого страничного нарушения система просто помечает страницу как используемую и снимает защиту со страницы, так что она может использоваться. Хотя использование такого приема только для определения использования страницы весьма накладно, это выгоднее, чем повторно использовать страницу для других целей и обнаружить, что она снова нужна процессу и подгружать её с диска. -FreeBSD использует несколько очередей страниц для обновления выбора страниц для повторного использования, а также для определения того, когда же грязные страницы должны быть сброшены в хранилище. Так как таблицы страниц во FreeBSD являются динамическими объектами, практически ничего не стоит вырезать страницу из адресного пространства любого использующего её процесса. После того, как подходящая страница, на основе счетчика использования, выбрана, именно это и выполняется. Система должна различать чистые страницы, которые теоретически могут быть высвобождены в любое время, и грязные страницы, которые сначала должны быть переписаны в хранилище перед тем, как их можно будет использовать повторно. После нахождения подходящей страницы она перемещается в неактивную очередь, если она является грязной, или в очередь кэша, если она чистая. Отдельный алгоритм, основывающийся на отношении количества грязных страниц к чистым, определяет, когда грязные страницы в неактивной очереди должны быть сброшены на диск. Когда это выполнится, сброшенные страницы перемещаются из неактивной очереди в очередь кэша. В этот момент страницы в очереди кэша могут быть повторно активизированы VM со сравнительно малыми накладными расходами. Однако страницы в очереди кэша предполагается "высвобождать немедленно" и повторно использовать в LRU-порядке (меньше всего используемый), когда системе потребуется выделение дополнительной памяти. +FreeBSD использует несколько очередей страниц для обновления выбора страниц для повторного использования, а также для определения того, когда же грязные страницы должны быть сброшены в хранилище. Так как таблицы страниц во FreeBSD являются динамическими объектами, практически ничего не стоит вырезать страницу из адресного пространства любого использующего её процесса. После того как подходящая страница на основе счётчика использования выбрана, именно это и выполняется. Система должна различать чистые страницы, которые теоретически могут быть высвобождены в любое время, и грязные страницы, которые сначала должны быть переписаны в хранилище перед тем, как их можно будет использовать повторно. После нахождения подходящей страницы она перемещается в неактивную очередь, если она является грязной, или в очередь кэша, если она чистая. Отдельный алгоритм, основывающийся на отношении количества грязных страниц к чистым, определяет, когда грязные страницы в неактивной очереди должны быть сброшены на диск. Когда это выполнится, сброшенные страницы перемещаются из неактивной очереди в очередь кэша. В этот момент страницы в очереди кэша могут быть повторно активизированы страничными нарушениями VM со сравнительно малыми накладными расходами. Однако страницы в очереди кэша предполагается "высвобождать немедленно" и повторно использовать в LRU-порядке (наименее давно используемый), когда системе потребуется выделение дополнительной памяти. Стоит отметить, что во FreeBSD VM-система пытается разделить чистые и грязные страницы во избежание срочной необходимости в ненужных сбросах грязных страниц (что отражается на пропускной способности ввода/вывода) и не перемещает беспричинно страницы между разными очередями, когда подсистема управления памятью не испытывает нехватку ресурсов. Вот почему вы можете видеть, что при выполнении команды `systat -vm` в некоторых системах значение счетчика очереди кэша мало, а счетчик активной очереди большой. При повышении нагрузки на VM-систему она прилагает большие усилия на поддержку различных очередей страниц в соотношениях, которые являются наиболее эффективными. Годами ходили современные легенды, что Linux выполняет работу по предотвращению выгрузки на диск лучше, чем FreeBSD, но это не так. На самом деле FreeBSD старается сбросить на диск неиспользуемые страницы для освобождения места под дисковый кэш, когда как Linux хранит неиспользуемые страницы в памяти и оставляет под кэш и страницы процессов меньше памяти. Я не знаю, остаётся ли это правдой на сегодняшний день. [[prefault-optimizations]] -== Оптимизация ошибок доступа к страницам и их обнуления +== Упреждающая оптимизация страничных нарушений и обнуления -Полагая, что ошибка доступа к странице памяти в VM не является операцией с большими накладными расходами, если страница уже находится в основной памяти и может быть просто отображена в адресное пространство процесса, может оказаться, что это станет весьма накладно, если их будет оказываться регулярно много. Хорошим примером этой ситуации является запуск таких программ, как man:ls[1] или man:ps[1], снова и снова. Если бинарный файл программы отображен в память, но не отображен в таблицу страниц, то все страницы, к которым обращалась программа, окажутся недоступными при каждом запуске программы. Это не так уж необходимо, если эти страницы уже присутствуют в кэше VM, так что FreeBSD будет пытаться восстанавливать таблицы страниц процесса из тех страниц, что уже располагаются в VM-кэше. Однако во FreeBSD пока не выполняется предварительное копирование при записи определённых страниц при выполнении вызова exec. Например, если вы запускаете программу man:ls[1] одновременно с работающей `vmstat 1`, то заметите, что она всегда выдает некоторое количество ошибок доступа к страницам, даже когда вы запускаете её снова и снова. Эти ошибки относятся к типу zero-fill и не связаны с доступом к коду программы (который уже был предварительно отображён). Предварительное копирование страниц при выполнении вызовов exec или fork находятся в области, требующей более тщательного изучения. +Полагая, что страничное нарушение в VM не является операцией с большими накладными расходами, если страница уже находится в основной памяти и может быть просто отображена в адресное пространство процесса, может оказаться, что это станет весьма накладно, если их будет оказываться регулярно много. Хорошим примером этой ситуации является запуск таких программ, как man:ls[1] или man:ps[1], снова и снова. Если бинарный файл программы отображён в память, но не отображён в таблицу страниц, то все страницы, к которым обращалась программа, окажутся недоступными при каждом запуске программы. Это не так уж необходимо, если эти страницы уже присутствуют в кэше VM, так что FreeBSD будет пытаться восстанавливать таблицы страниц процесса из тех страниц, что уже располагаются в VM-кэше. Однако во FreeBSD пока не выполняется предварительное копирование при записи определённых страниц при выполнении вызова exec. Например, если вы запускаете программу man:ls[1] одновременно с работающей `vmstat 1`, то заметите, что она всегда выдаёт некоторое количество ошибок доступа к страницам, даже когда вы запускаете её снова и снова. Эти ошибки относятся к типу zero-fill и не связаны с доступом к коду программы (который уже был предварительно отображён). Предварительное копирование страниц при выполнении вызовов exec или fork находятся в области, требующей более тщательного изучения. -Большой процент ошибок доступа к страницам, относится к ошибкам при заполнении нулями. Вы можете обычно видеть это, просматривая вывод команды `vmstat -s`. Это происходит, когда процесс обращается к страницам в своей области BSS. Область BSS предполагается изначально заполненной нулями, но VM-система не заботится о выделении памяти до тех пор, пока процесс реально к ней не обратится. При возникновении ошибки VM-система должна не только выделить новую страницу, но и заполнить её нулями. Для оптимизации операции по заполнению нулями в системе VM имеется возможность предварительно обнулять страницы и помечать их, и запрашивать уже обнуленные страницы при возникновении ошибок заполнения нулями. Предварительное заполнение нулями происходит, когда CPU простаивает, однако количество страниц, которые система заранее заполняет нулями, ограничено, для того, чтобы не переполнить кэши памяти. Это прекрасный пример добавления сложности в VM-систему ради оптимизации критического пути. +Большой процент страничных нарушений относится к страничным нарушениям при заполнении нулями. Вы можете обычно видеть это, просматривая вывод команды `vmstat -s`. Это происходит, когда процесс обращается к страницам в своей области BSS. Область BSS предполагается изначально заполненной нулями, но VM-система не заботится о выделении памяти до тех пор, пока процесс реально к ней не обратится. При страничном нарушении VM-система должна не только выделить новую страницу, но и заполнить её нулями. Для оптимизации операции по заполнению нулями в системе VM имеется возможность предварительно обнулять страницы и помечать их, и запрашивать уже обнуленные страницы при возникновении страничных нарушений заполнения нулями. Предварительное заполнение нулями происходит, когда CPU простаивает, однако количество страниц, которые система заранее заполняет нулями, ограничено, для того, чтобы не переполнить кэши памяти. Это прекрасный пример добавления сложности в VM-систему ради оптимизации критического пути. [[page-table-optimizations]] == Оптимизация таблицы страниц Оптимизация таблицы страниц составляет самую содержательную часть архитектуры VM во FreeBSD и она проявляется при появлении нагрузки при значительном использовании `mmap()`. Я думаю, что это на самом деле особенность работы большинства BSD-систем, хотя я не уверен, когда это проявилось впервые. Есть два основных подхода к оптимизации. Первый заключается в том, что аппаратные таблицы страниц не содержат постоянного состояния, а вместо этого могут быть сброшены в любой момент с малыми накладными расходами. Второй подход состоит в том, что каждая активная таблица страниц в системе имеет управляющую структуру `pv_entry`, которая связана в структуру `vm_page`. FreeBSD может просто просматривать эти отображения, которые существуют, когда как в Linux должны проверяться все таблицы страниц, которые _могут_ содержать нужное отображение, что в некоторых ситуация даёт увеличение сложности O(n^2). Из-за того, что FreeBSD стремится выбрать наиболее подходящую к повторному использованию или сбросу в область подкачки страницу, когда ощущается нехватка памяти, система даёт лучшую производительность при нагрузке. Однако во FreeBSD требуется тонкая настройка ядра для соответствия ситуациям с большим совместно используемым адресным пространством, которые могут случиться в системе, обслуживающей сервер телеконференций, потому что структуры `pv_entry` могут оказаться исчерпанными. И в Linux, и во FreeBSD требуются доработки в этой области. FreeBSD пытается максимизировать преимущества от потенциально редко применяемой модели активного отображения (к примеру, не всем процессам нужно отображать все страницы динамической библиотеки), когда как Linux пытается упростить свои алгоритмы. FreeBSD имеет здесь общее преимущество в производительности за счет использования дополнительной памяти, но FreeBSD выглядит хуже в случае, когда большой файл совместно используется сотнями процессов. Linux, с другой стороны, выглядит хуже в случае, когда много процессов частично используют одну и ту же динамическую библиотеку, а также работает неоптимально при попытке определить, может ли страница повторно использоваться, или нет. [[conclusion]] == Заключение Виртуальная память в современных операционных системах должна решать несколько различных задач эффективно и при разных условиях. Модульный и алгоритмический подход, которому исторически следует BSD, позволяет нам изучить и понять существующую реализацию, а также сравнительно легко изменить большие блоки кода. За несколько последних лет в VM-системе FreeBSD было сделано некоторое количество усовершенствований, и работа над ними продолжается. [[allen-briggs-qa]] == Дополнительный сеанс вопросов и ответов от Аллена Бриггса (Allen Briggs) === Что это за алгоритм чередования, который вы упоминали в списке недостатков подсистемы управления разделом подкачки во FreeBSD 3.X? FreeBSD использует в области подкачки механизм чередования, с индексом по умолчанию, равным четырем. Это означает, что FreeBSD резервирует пространство для четырёх областей подкачки, даже если у вас имеется всего лишь одна, две или три области. Так как в области подкачки имеется чередование, то линейное адресное пространство, представляющее "четыре области подкачки", будет фрагментироваться, если у вас нет на самом деле четырёх областей подкачки. Например, если у вас две области A и B, то представление адресного пространства для этой области подкачки во FreeBSD будет организовано с чередованием блоков из 16 страниц: .... A B C D A B C D A B C D A B C D .... FreeBSD 3.X использует "последовательный список свободных областей" для управления свободными областями в разделе подкачки. Идея состоит в том, что большие последовательные блоки свободного пространства могут быть представлены при помощи узла односвязного списка ([.filename]#kern/subr_rlist.c#). Но из-за фрагментации последовательный список сам становится фрагментированным. В примере выше полностью неиспользуемое пространство в A и B будет показано как "свободное", а C и D как "полностью занятое". Каждой последовательности A-B требуется для учёта узел списка, потому что C и D являются дырами, так что узел списка не может быть связан со следующей последовательностью A-B. Почему мы организуем чередование в области подкачки вместо того, чтобы просто объединить области подкачки в одно целое и придумать что-то более умное? Потому что гораздо легче выделять последовательные полосы адресного пространства и получать в результате автоматическое чередование между несколькими дисками, чем пытаться выдумывать сложности в другом месте. Фрагментация вызывает другие проблемы. Являясь последовательным списком в 3.X и имея такое огромную фрагментацию, выделение и освобождение в области подкачки становится алгоритмом сложности O(N), а не O(1). Вместе с другими факторами (частое обращение к области подкачки) вы получаете сложность уровней O(N^2) и O(N^3), что плохо. В системе 3.X также может потребоваться выделение KVM во время работы с областью подкачки для создания нового узла списка, что в условии нехватки памяти может привести к блокировке, если система попытается сбросить страницы в область подкачки. В 4.X мы не используем последовательный список. Вместо этого мы используем базисное дерево и битовые карты блоков области подкачки, а не ограниченный список узлов. Мы принимаем предварительное выделение всех битовых карт, требуемых для всей области подкачки, но при этом тратится меньше памяти, потому что мы используем битовые карты (один бит на блок), а не связанный список узлов. Использование базисного дерева вместо последовательного списка даёт нам производительность O(1) вне зависимости от фрагментации дерева. === Как разделение чистых и грязных (неактивных) страниц связано с ситуацией, когда вы видите маленький счетчик очереди кэша и большой счетчик активной очереди в выдаче команды systat -vm? Разве системная статистика не считает активные и грязные страницы вместе за счетчик активной очереди? Да, это запутывает. Связь заключается в "желаемом" и "действительном". Мы желаем разделить страницы, но реальность такова, что пока у нас нет проблем с памятью, нам это на самом деле не нужно. Это означает, что FreeBSD не будет очень сильно стараться над отделением грязных страниц (неактивная очередь) от чистых страниц (очередь кэша), когда система не находится под нагрузкой, и не будет деактивировать страницы (активная очередь -> неактивная очередь), когда система не нагружена, даже если они не используются. -=== В примере с man:ls(1) и `vmstat 1` выше могут ли некоторые ошибки доступа к странице быть ошибками страниц данных (COW из выполнимого файла в приватные страницы)? То есть я полагаю, что ошибки доступа к страницам являются частично ошибками при заполнении нулями, а частично данных программы. Или вы гарантируете, что FreeBSD выполняет предварительно COW для данных программы? +=== В примере с man:ls(1) и `vmstat 1` выше могут ли некоторые страничные нарушения быть страничными нарушениями данных (COW из выполнимого файла в приватные страницы)? Иными словами, я ожидаю, что часть страничных нарушений будет связана с заполнением нулями, а часть — с программными данными. Или вы гарантируете, что FreeBSD выполняет предварительно COW для данных программы? -Ошибка COW может быть ошибкой при заполнении нулями или данных программы. Механизм в любом случае один и тот же, потому что хранилище данных программы уже в кэше. Я на самом деле не рад ни тому, ни другому. FreeBSD не выполняет предварительное COW данных программы и заполнение нулями, но она _выполняет_ предварительно отображение страниц, которые имеются в её кэше. +Страничное нарушение COW может быть связано или с заполнением нулями, или с данными программы. Механизм в любом случае один и тот же, потому что хранилище данных программы уже в кэше. Я на самом деле не рад ни тому, ни другому. FreeBSD не выполняет предварительное COW данных программы и заполнение нулями, но она _выполняет_ предварительно отображение страниц, которые имеются в её кэше. === В вашем разделе об оптимизации таблицы страниц, не могли бы вы более подробно рассказать о pv_entry и vm_page (или vm_page должна быть vm_pmap-как в 4.4, cf. pp. 180-181 of McKusick, Bostic, Karel, Quarterman)? А именно какое действие/реакцию должно потребоваться для сканирования отображений? `vm_page` представляет собой пару (object,index#). `pv_entry` является записью из аппаратной таблицы страниц (pte). Если у вас имеется пять процессов, совместно использующих одну и ту же физическую страницу, и в трёх таблицах страниц этих процессов на самом деле отображается страница, то страница будет представляться одной структурой `vm_page` и тремя структурами `pv_entry`. Структуры `pv_entry` представляют страницы, отображаемые MMU (одна структура `pv_entry` соответствует одной pte). Это означает, что, когда нам нужно убрать все аппаратные ссылки на `vm_page` (для того, чтобы повторно использовать страницу для чего-то ещё, выгрузить её, очистить, пометить как грязную и так далее), мы можем просто просмотреть связный список структур `pv_entry`, связанных с этой `vm_page`, для того, чтобы удалить или изменить pte из их таблиц страниц. В Linux нет такого связного списка. Для того, чтобы удалить все отображения аппаратной таблицы страниц для `vm_page`, linux должен пройти по индексу каждого объекта VM, который _может_ отображать страницу. К примеру, если у вас имеется 50 процессов, которые все отображают ту же самую динамическую библиотеку и хотите избавиться от страницы X в этой библиотеке, то вам нужно пройтись по индексу всей таблицы страниц для каждого из этих 50 процессов, даже если только 10 из них на самом деле отображают страницу. Так что Linux использует простоту подхода за счет производительности. Многие алгоритмы VM, которые имеют сложность O(1) или (N малое) во FreeBSD, в Linux приобретают сложность O(N), O(N^2) или хуже. Так как pte, представляющий конкретную страницу в объекте, скорее всего, будет с тем же смещением во всех таблицах страниц, в которых они отображаются, то уменьшение количества обращений в таблицы страниц по тому же самому смещению часто позволяет избежать разрастания кэша L1 для этого смещения, что приводит к улучшению производительности. Во FreeBSD введены дополнительные сложности (схема с `pv_entry`) для увеличения производительности (уменьшая количество обращений _только_ к тем pte, которые нужно модифицировать). Но во FreeBSD имеется проблема масштабирования, которой нет в Linux, потому что имеется ограниченное число структур `pv_entry`, и это приводит к возникновению проблем при большом объёме совместно используемых данных. В этом случае у вас может возникнуть нехватка структур `pv_entry`, даже если свободной памяти хватает. Это может быть достаточно легко исправлено увеличением количества структур `pv_entry` при настройке, но на самом деле нам нужно найти лучший способ делать это. Что касается использования памяти под таблицу страниц против схемы с `pv_entry`: Linux использует "постоянные" таблицы страниц, которые не сбрасываются, но ему не нужны `pv_entry` для каждого потенциально отображаемого pte. FreeBSD использует "сбрасываемые" таблицы страниц, но для каждого реально отображаемого pte добавляется структура `pv_entry`. Я думаю, что использование памяти будет примерно одинакова, тем более что у FreeBSD есть алгоритмическое преимущество, заключающееся в способности сбрасывать таблицы страниц с очень малыми накладными расходами. diff --git a/documentation/content/ru/articles/vm-design/_index.po b/documentation/content/ru/articles/vm-design/_index.po index adf0052a38..87686da716 100644 --- a/documentation/content/ru/articles/vm-design/_index.po +++ b/documentation/content/ru/articles/vm-design/_index.po @@ -1,1380 +1,1382 @@ # SOME DESCRIPTIVE TITLE # Copyright (C) YEAR The FreeBSD Project # This file is distributed under the same license as the FreeBSD Documentation package. # Vladlen Popolitov , 2025, 2026. msgid "" msgstr "" "Project-Id-Version: FreeBSD Documentation VERSION\n" "POT-Creation-Date: 2025-06-29 21:20+0100\n" -"PO-Revision-Date: 2026-03-23 04:45+0000\n" +"PO-Revision-Date: 2026-04-05 04:45+0000\n" "Last-Translator: Vladlen Popolitov \n" "Language-Team: Russian \n" "Language: ru\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && " "n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" "X-Generator: Weblate 4.17\n" #. type: YAML Front Matter: description #: documentation/content/en/articles/vm-design/_index.adoc:1 #, no-wrap msgid "An easy to follow description of the design of the FreeBSD virtual memory system" msgstr "" "Простое и понятное описание архитектуры системы виртуальной памяти FreeBSD" #. type: Title = #: documentation/content/en/articles/vm-design/_index.adoc:1 #: documentation/content/en/articles/vm-design/_index.adoc:11 #, no-wrap msgid "Design elements of the FreeBSD VM system" msgstr "Элементы архитектуры системы виртуальной памяти во FreeBSD" #. type: delimited block = 4 #: documentation/content/en/articles/vm-design/_index.adoc:46 msgid "" "This document is outdated and some sections do not accurately describe the " "current state of the VM system. It is retained for historical purposes and " "may be updated over time." msgstr "" "Этот документ устарел, и некоторые разделы больше не соответствуют текущему " "состоянию системы виртуальной памяти. Он сохранён в исторических целях и " "может быть обновлён в будущем." #. type: Plain text #: documentation/content/en/articles/vm-design/_index.adoc:50 msgid "Abstract" msgstr "Аннотация" #. type: Plain text #: documentation/content/en/articles/vm-design/_index.adoc:52 msgid "Matthew Dillon " msgstr "Matthew Dillon " #. type: Plain text #: documentation/content/en/articles/vm-design/_index.adoc:59 msgid "" "The title is really just a fancy way of saying that I am going to attempt to " "describe the whole VM enchilada, hopefully in a way that everyone can " "follow. For the last year I have concentrated on a number of major kernel " "subsystems within FreeBSD, with the VM and Swap subsystems being the most " "interesting and NFS being \"a necessary chore\". I rewrote only small " "portions of the code. In the VM arena the only major rewrite I have done is " "to the swap subsystem. Most of my work was cleanup and maintenance, with " "only moderate code rewriting and no major algorithmic adjustments within the " "VM subsystem. The bulk of the VM subsystem's theoretical base remains " "unchanged and a lot of the credit for the modernization effort in the last " "few years belongs to John Dyson and David Greenman. Not being a historian " "like Kirk I will not attempt to tag all the various features with peoples " "names, since I will invariably get it wrong." msgstr "" "Это название — просто замысловатый способ сказать, что я попытаюсь описать " "всю систему виртуальной памяти (VM) целиком, по возможности так, чтобы это " "было понятно каждому.В течение последнего года я сосредоточился на " "нескольких основных подсистемах ядра FreeBSD. Наиболее интересными из них " "стали подсистемы VM и подкачки (Swap), тогда как работа с NFS оказалась, " "скорее, «необходимой рутиной». Я переписал лишь небольшие части кода. В " "области VM моей единственной крупной переработкой стала подсистема подкачки. " "В основном моя работа заключалась в очистке и поддержке кода, с умеренными " "правками и без серьёзных изменений алгоритмов в подсистеме VM. Теоретическая " "основа VM-подсистемы осталась неизменной, и львиная доля заслуг в её " "модернизации за последние годы принадлежит Джону Дайсону и Дэвиду Гринману. " "Я не историк, в отличие от Кирка, поэтому не стану приписывать различные " "функции конкретным людям — всё равно где-нибудь ошибусь." #. type: Plain text #: documentation/content/en/articles/vm-design/_index.adoc:61 msgid "'''" msgstr "'''" #. type: Title == #: documentation/content/en/articles/vm-design/_index.adoc:65 #, no-wrap msgid "Introduction" msgstr "Введение" #. type: Plain text #: documentation/content/en/articles/vm-design/_index.adoc:81 msgid "" "Before moving along to the actual design let's spend a little time on the " "necessity of maintaining and modernizing any long-living codebase. In the " "programming world, algorithms tend to be more important than code and it is " "precisely due to BSD's academic roots that a great deal of attention was " "paid to algorithm design from the beginning. More attention paid to the " "design generally leads to a clean and flexible codebase that can be fairly " "easily modified, extended, or replaced over time. While BSD is considered " "an \"old\" operating system by some people, those of us who work on it tend " "to view it more as a \"mature\" codebase which has various components " "modified, extended, or replaced with modern code. It has evolved, and " "FreeBSD is at the bleeding edge no matter how old some of the code might " "be. This is an important distinction to make and one that is unfortunately " "lost to many people. The biggest error a programmer can make is to not " "learn from history, and this is precisely the error that many other modern " "operating systems have made. Windows NT(R) is the best example of this, and " "the consequences have been dire. Linux also makes this mistake to some " "degree-enough that we BSD folk can make small jokes about it every once in a " "while, anyway. Linux's problem is simply one of a lack of experience and " "history to compare ideas against, a problem that is easily and rapidly being " "addressed by the Linux community in the same way it has been addressed in " "the BSD community-by continuous code development. The Windows NT(R) folk, " "on the other hand, repeatedly make the same mistakes solved by UNIX(R) " "decades ago and then spend years fixing them. Over and over again. They " "have a severe case of \"not designed here\" and \"we are always right " "because our marketing department says so\". I have little tolerance for " "anyone who cannot learn from history." msgstr "" "Перед тем, как перейти непосредственно к существующей архитектуре, потратим " "немного времени на рассмотрение вопроса о необходимости поддержки и " "модернизации любого длительно живущего кода. В мире программирования " "алгоритмы становятся более важными, чем код, и именно из-за академических " "корней BSD изначально большое внимание уделялось проработке алгоритмов. " -"Внимание, уделенное архитектуре, в общем отражается на ясности и гибкости " -"кода, который может быть достаточно легко изменен, расширен или с течением " -"времени заменен. Хотя некоторые считают BSD \"старой\" операционной " -"системой, те их нас, кто работает над ней, видят её скорее системой со " -"\"зрелым\" кодом с различными компонентами, которые были заменены, расширены " -"или изменены современным кодом. Он развивается, и FreeBSD остаётся передовой " -"системой, вне зависимости от того, насколько старой может быть часть кода. " -"Это важное отличие, которое, к сожалению, не всеми понимается. Самой большой " -"ошибкой, которую может допустить программист, является игнорирование " -"истории, и это именно та ошибка, которую сделали многие другие современные " -"операционные системы. Самым ярким примером здесь является Windows NT(R), и " -"последствия ужасны. Linux также в некоторой степени совершил эту ошибку — " -"достаточно, чтобы мы, люди BSD, по крайней мере по разу отпустили по этому " -"поводу шутку. Проблема Linux заключается просто в отсутствии опыта и истории " -"для сравнения идей, проблема, которая легко и быстро решается сообществом " -"Linux точно так же, как она решается в сообществе BSD-постоянной работой над " -"кодом. Разработчики Windows NT(R), с другой стороны, постоянно совершают те " -"же самые ошибки, что были решены в UNIX(R) десятки лет назад, а затем тратят " -"годы на их устранение. Снова и снова. Есть несколько случаев \"проработка " -"архитектуры отсутствует\" и \"мы всегда правы, потому что так говорит наш " -"отдел продаж\". Я плохо переношу тех, кого не учит история." +"Более тщательное внимание к проектированию в целом приводит к созданию " +"чистой и гибкой кодовой базы, которую со временем можно достаточно легко " +"модифицировать, расширять или заменять. Хотя некоторые считают BSD \"старой\"" +" операционной системой, те их нас, кто работает над ней, видят её скорее " +"системой со \"зрелым\" кодом с различными компонентами, которые были " +"заменены, расширены или изменены современным кодом. Он развивается, и " +"FreeBSD остаётся передовой системой, вне зависимости от того, насколько " +"старой может быть часть кода. Это важное отличие, которое, к сожалению, не " +"всеми понимается. Самой большой ошибкой, которую может допустить " +"программист, является игнорирование истории, и это именно та ошибка, которую " +"сделали многие другие современные операционные системы. Самым ярким примером " +"здесь является Windows NT(R), и последствия ужасны. Linux также в некоторой " +"степени совершил эту ошибку — достаточно, чтобы мы, люди BSD, по крайней " +"мере по разу отпустили по этому поводу шутку. Проблема Linux заключается " +"просто в отсутствии опыта и истории для сравнения идей, проблема, которая " +"легко и быстро решается сообществом Linux точно так же, как она решается в " +"сообществе BSD — постоянной работой над кодом. Разработчики Windows NT(R), с " +"другой стороны, постоянно совершают те же самые ошибки, что были решены в " +"UNIX(R) десятки лет назад, а затем тратят годы на их устранение. Снова и " +"снова. У них тяжёлый случай синдрома „не нами разработано“ и „мы всегда " +"правы, потому что так говорит наш отдел маркетинга“. Я плохо переношу тех, " +"кого не учит история." #. type: Plain text #: documentation/content/en/articles/vm-design/_index.adoc:86 msgid "" "Much of the apparent complexity of the FreeBSD design, especially in the VM/" "Swap subsystem, is a direct result of having to solve serious performance " "issues that occur under various conditions. These issues are not due to bad " "algorithmic design but instead rise from environmental factors. In any " "direct comparison between platforms, these issues become most apparent when " "system resources begin to get stressed. As I describe FreeBSD's VM/Swap " "subsystem the reader should always keep two points in mind:" msgstr "" "Большинство очевидной сложности архитектуры FreeBSD, особенно в подсистеме " "VM/Swap, является прямым следствием того, что она решает серьезные проблемы " "с производительностью, которые проявляются при различных условиях. Эти " "проблемы вызваны не плохой проработкой алгоритмов, а возникают из окружающих " "факторов. В любом прямом сравнении между платформами эти проблемы " "проявляются, когда системные ресурсы начинают истощаться. Так как я описываю " "подсистему VM/Swap во FreeBSD, то читатель должен всегда иметь в виду два " "обстоятельства:" #. type: Plain text #: documentation/content/en/articles/vm-design/_index.adoc:88 msgid "" "The most important aspect of performance design is what is known as " "\"Optimizing the Critical Path\". It is often the case that performance " "optimizations add a little bloat to the code to make the critical path " "perform better." msgstr "" "Самым важным аспектом при проектировании производительности является то, что " "называется \"оптимизацией критического маршрута\". Часто случается, что " "оптимизация производительности даёт прирост объёма кода ради того, чтобы " "критический маршрут работал быстрее." #. type: Plain text #: documentation/content/en/articles/vm-design/_index.adoc:89 msgid "" "A solid, generalized design outperforms a heavily-optimized design over the " "long run. While a generalized design may end up being slower than an heavily-" "optimized design when they are first implemented, the generalized design " "tends to be easier to adapt to changing conditions and the heavily-optimized " "design winds up having to be thrown away." msgstr "" "Четкость общей архитектуры оказывается лучше сильно оптимизированной " "архитектуры с течением времени. Когда как обобщенная архитектура может быть " "медленнее, чем оптимизированная архитектура, при первой реализации, при " "обобщенной архитектуре легче подстраиваться под изменяющиеся условия и " "чрезмерно оптимизированная архитектура оказывается непригодной." #. type: Plain text #: documentation/content/en/articles/vm-design/_index.adoc:93 msgid "" "Any codebase that will survive and be maintainable for years must therefore " "be designed properly from the beginning even if it costs some performance. " "Twenty years ago people were still arguing that programming in assembly was " "better than programming in a high-level language because it produced code " "that was ten times as fast. Today, the fallibility of that argument is " "obvious - as are the parallels to algorithmic design and code generalization." msgstr "" "Любой код, который должен выжить и поддаваться поддержке годы, должен " "поэтому быть тщательно продуман с самого начала, даже если это стоит потери " "производительности. Двадцать лет назад были те, кто отстаивал преимущество " "программирования на языке ассемблера перед программированием на языке " "высокого уровня, потому что первый генерировал в десять раз более быстрый " "код. В наши дни ошибочность этого аргумента очевидна - можно провести " "параллели с построением алгоритмов и обобщением кода." #. type: Title == #: documentation/content/en/articles/vm-design/_index.adoc:95 #, no-wrap msgid "VM Objects" msgstr "Объекты VM" #. type: Plain text #: documentation/content/en/articles/vm-design/_index.adoc:105 msgid "" "The best way to begin describing the FreeBSD VM system is to look at it from " "the perspective of a user-level process. Each user process sees a single, " "private, contiguous VM address space containing several types of memory " "objects. These objects have various characteristics. Program code and " "program data are effectively a single memory-mapped file (the binary file " "being run), but program code is read-only while program data is copy-on-" "write. Program BSS is just memory allocated and filled with zeros on " "demand, called demand zero page fill. Arbitrary files can be memory-mapped " "into the address space as well, which is how the shared library mechanism " "works. Such mappings can require modifications to remain private to the " "process making them. The fork system call adds an entirely new dimension to " "the VM management problem on top of the complexity already given." msgstr "" -"Лучше всего начать описание VM-системы FreeBSD с попытки взглянуть на нее с " +"Лучше всего начать описание VM-системы FreeBSD с попытки взглянуть на неё с " "точки зрения пользовательского процесса. Каждый пользовательский процесс " "имеет единое, принадлежащее только ему и неразрывное адресное пространство " "VM, содержащее несколько типов объектов памяти. Эти объекты имеют различные " "характеристики. Код программы и её данные являются единым файлом, " "отображаемым в память (это выполняющийся двоичный файл), однако код " "программы доступен только для чтения, тогда как данные программы размещаются " "в режиме копирования-при-записи. BSS программы представляет собой всего лишь " "выделенную область памяти, заполненную, если это требовалось, нулями, что " "называется обнулением страниц памяти по требованию. Отдельные файлы могут " "также отображаться в адресное пространство, именно так работают динамические " "библиотеки. Такие отображения требуют изменений, чтобы оставаться " "принадлежащими процессу, который их выполнил. Системный вызов fork переводит " "проблему управления VM полностью в новую плоскость, вдобавок к уже имеющимся " "сложностям." #. type: Plain text #: documentation/content/en/articles/vm-design/_index.adoc:111 msgid "" "A program binary data page (which is a basic copy-on-write page) illustrates " "the complexity. A program binary contains a preinitialized data section " "which is initially mapped directly from the program file. When a program is " "loaded into a process's VM space, this area is initially memory-mapped and " "backed by the program binary itself, allowing the VM system to free/reuse " "the page and later load it back in from the binary. The moment a process " "modifies this data, however, the VM system must make a private copy of the " "page for that process. Since the private copy has been modified, the VM " "system may no longer free it, because there is no longer any way to restore " "it later on." msgstr "" "Иллюстрирует сложность страница данных двоичной программы (которая является " "страницей копируемой-при-записи). Двоичная программа содержит секцию " "предварительно инициализированных данных, которая первоначально отображается " "непосредственно из файла программы. Когда программа загружается в " "виртуальную память процесса, эта область сначала отображается в память и " "поддерживается бинарным файлом программы, позволяя VM-системе освобождать/" "повторно использовать страницу, а потом загружать её снова из бинарного " "файла. Однако в момент, когда процесс изменяет эти данные, VM-система должна " "сделать копию страницы, принадлежащую только этому процессу. Так как эта " "копия была изменена, то VM-система не может больше освобождать эту страницу, " "так как впоследствии её невозможно будет восстановить." #. type: Plain text #: documentation/content/en/articles/vm-design/_index.adoc:118 msgid "" "You will notice immediately that what was originally a simple file mapping " "has become much more complex. Data may be modified on a page-by-page basis " "whereas the file mapping encompasses many pages at once. The complexity " "further increases when a process forks. When a process forks, the result is " "two processes-each with their own private address spaces, including any " "modifications made by the original process prior to the call to `fork()`. " "It would be silly for the VM system to make a complete copy of the data at " "the time of the `fork()` because it is quite possible that at least one of " "the two processes will only need to read from that page from then on, " "allowing the original page to continue to be used. What was a private page " "is made copy-on-write again, since each process (parent and child) expects " "their own personal post-fork modifications to remain private to themselves " "and not affect the other." msgstr "" "Вы тут же заметите, что то, что сначала было простым отображением файла в " "память, становится гораздо более сложным предметом. Данные могут " "модифицироваться постранично, когда как отображение файла выполняется для " "многих страниц за раз. Сложность ещё более увеличивается, когда процесс " -"выполняет вызов fork. При этом порождаются два процесса-каждый с собственным " -"адресным пространством, включающим все изменения, выполненные исходным " -"процессом до вызова функции `fork()`. Было бы глупо для VM-системы делать " -"полную копию данных во время вызова `fork()`, так как весьма вероятно, что " -"один из двух процессов будет нужен только для чтения из той страницы, что " -"позволяет использование исходной страницы. То, что было страницей, " -"принадлежащей только процессу, сделается снова страницей, копируемой при " -"записи, так как каждый из процессов (и родитель, и потомок) полагают, что их " -"собственные изменения после разветвления будут принадлежать только им, и не " -"затронут родственный процесс." +"выполняет вызов fork. При этом порождаются два процесса, и каждый с " +"собственным адресным пространством, включающим все изменения, выполненные " +"исходным процессом до вызова функции `fork()`. Было бы глупо для VM-системы " +"делать полную копию данных во время вызова `fork()`, так как весьма " +"вероятно, что один из двух процессов будет нужен только для чтения из той " +"страницы, что позволяет использование исходной страницы. То, что было " +"страницей, принадлежащей только процессу, снова становится страницей, " +"копируемой при записи, поскольку каждый из процессов (родительский и " +"дочерний) рассчитывает на то, что его собственные изменения после вызова " +"fork() останутся приватными и не повлияют на другой процесс." #. type: Plain text #: documentation/content/en/articles/vm-design/_index.adoc:127 msgid "" "FreeBSD manages all of this with a layered VM Object model. The original " "binary program file winds up being the lowest VM Object layer. A copy-on-" "write layer is pushed on top of that to hold those pages which had to be " "copied from the original file. If the program modifies a data page " "belonging to the original file the VM system takes a fault and makes a copy " "of the page in the higher layer. When a process forks, additional VM Object " "layers are pushed on. This might make a little more sense with a fairly " "basic example. A `fork()` is a common operation for any *BSD system, so " "this example will consider a program that starts up, and forks. When the " "process starts, the VM system creates an object layer, let's call this A:" msgstr "" "FreeBSD управляет всем этим при помощи многоуровневой модели VM-объектов. " "Исходный файл с двоичной программой переносится на самый нижний уровень " "объектов VM. Уровень страниц, копируемых при записи, находится выше него, и " "хранит те страницы, которые были скопированы из исходного файла. Если " -"программа модифицирует страницы данных, относящиеся к исходному файлу, то " -"система VM обнаруживает это и переносит копию этой страницы на более высокий " -"уровень. Когда процесс разветвляется, добавляются новые уровни VM-объектов. " -"Это можно показать на простом примере. Функция `fork()` является общей " -"операцией для всех систем *BSD, так что в этом примере будет рассматриваться " -"программа, которая запускается, а затем разветвляется. Когда процесс " -"запускается, VM-система создает некоторый уровень объектов, обозначим его " -"**A**:" +"программа изменяет страницу данных, принадлежащую исходному файлу, " +"подсистема виртуальной памяти обрабатывает страничное нарушение (page fault) " +"и создаёт копию этой страницы на вышележащем уровне. Когда процесс " +"разветвляется, добавляются новые уровни VM-объектов. Понять это поможет " +"достаточно простой пример. Функция `fork()` является общей операцией для " +"всех систем *BSD, так что в этом примере будет рассматриваться программа, " +"которая запускается, а затем разветвляется. Когда процесс запускается, VM-" +"система создаёт некоторый уровень объектов, обозначим его **A**:" #. type: Positional ($1) AttributeList argument for macro 'image' #: documentation/content/en/articles/vm-design/_index.adoc:128 #, no-wrap msgid "A picture" msgstr "Рисунок" #. type: Target for macro image #: documentation/content/en/articles/vm-design/_index.adoc:128 #, no-wrap msgid "fig1.png" msgstr "fig1.png" #. type: Plain text #: documentation/content/en/articles/vm-design/_index.adoc:133 msgid "" "A represents the file-pages may be paged in and out of the file's physical " "media as necessary. Paging in from the disk is reasonable for a program, " "but we really do not want to page back out and overwrite the executable. " "The VM system therefore creates a second layer, B, that will be physically " "backed by swap space:" msgstr "" "На рисунке *A* соответствует файлу — по необходимости страницы памяти могут " "высвобождаться и подгружаться с носителя файла. Подгрузка с диска может " "потребоваться программе, однако на самом деле мы не хотим, чтобы она " -"записывалась обратно в файл. Поэтому VM-система создает второй уровень, **B**" +"записывалась обратно в файл. Поэтому VM-система создаёт второй уровень, **B**" ", который физически поддерживается дисковым пространством подкачки:" #. type: Target for macro image #: documentation/content/en/articles/vm-design/_index.adoc:134 #, no-wrap msgid "fig2.png" msgstr "fig2.png" #. type: Plain text #: documentation/content/en/articles/vm-design/_index.adoc:139 msgid "" "On the first write to a page after this, a new page is created in B, and its " "contents are initialized from A. All pages in B can be paged in or out to a " "swap device. When the program forks, the VM system creates two new object " "layers-C1 for the parent, and C2 for the child-that rest on top of B:" msgstr "" "При первой записи в страницу после выполнения этой операции в **B** " -"создается новая страница, содержимое которой берётся из **A**. Все страницы " +"создаётся новая страница, содержимое которой берётся из **A**. Все страницы " "в **B** могут сбрасываться и считываться из устройства подкачки. Когда " -"программа ветвится, VM-система создает два новых уровня объектов — **C1** " -"для порождающего процесса и **C2** для порожденного — они располагаются " +"программа ветвится, VM-система создаёт два новых уровня объектов — **C1** " +"для порождающего процесса и **C2** для порождённого — они располагаются " "поверх **B**:" #. type: Target for macro image #: documentation/content/en/articles/vm-design/_index.adoc:140 #, no-wrap msgid "fig3.png" msgstr "fig3.png" #. type: Plain text #: documentation/content/en/articles/vm-design/_index.adoc:151 msgid "" "In this case, let's say a page in B is modified by the original parent " "process. The process will take a copy-on-write fault and duplicate the page " "in C1, leaving the original page in B untouched. Now, let's say the same " "page in B is modified by the child process. The process will take a copy-on-" "write fault and duplicate the page in C2. The original page in B is now " "completely hidden since both C1 and C2 have a copy and B could theoretically " "be destroyed if it does not represent a \"real\" file; however, this sort of " "optimization is not trivial to make because it is so fine-grained. FreeBSD " "does not make this optimization. Now, suppose (as is often the case) that " "the child process does an `exec()`. Its current address space is usually " "replaced by a new address space representing a new file. In this case, the " "C2 layer is destroyed:" msgstr "" "В этом случае, допустим, что страница в **B** была изменена начальным " -"родительским процессом. В процессе возникнет ситуация копирования при " -"записи, и страница скопируется в **C1**, при этом исходная страница " +"родительским процессом. Процесс вызовет страничное нарушение копирования-при-" +"записи и продублирует страницу в **C1**, при этом исходная страница " "останется в **B** нетронутой. Теперь допустим, что та же самая страница в " -"**B** изменяется порожденным процессом. В процессе возникнет ситуация " +"**B** изменяется дочерним процессом. В процессе возникнет ситуация " "копирования при записи и страница скопируется в **C2**. Исходная страница в " "**B** теперь полностью скрыта, так как и **C1**, и **C2** имеют копии, а " "уровень **B** теоретически может быть уничтожен, если он не представляет " "собой \"реального\" файла). Однако такую оптимизацию не так уж просто " "осуществить, потому что это надо делать на уровне слишком мелких единиц. Во " "FreeBSD такая оптимизация не выполняется. Теперь положим (а это часто " -"случается), что порожденный процесс выполняет вызов `exec()`. Его текущее " +"случается), что дочерний процесс выполняет вызов `exec()`. Его текущее " "адресное пространство обычно заменяется новым адресным пространством, " "представляющим новый файл. В этом случае уровень **C2** уничтожается:" #. type: Target for macro image #: documentation/content/en/articles/vm-design/_index.adoc:152 #, no-wrap msgid "fig4.png" msgstr "fig4.png" #. type: Plain text #: documentation/content/en/articles/vm-design/_index.adoc:158 msgid "" "In this case, the number of children of B drops to one, and all accesses to " "B now go through C1. This means that B and C1 can be collapsed together. " "Any pages in B that also exist in C1 are deleted from B during the " "collapse. Thus, even though the optimization in the previous step could not " "be made, we can recover the dead pages when either of the processes exit or " "`exec()`." msgstr "" "В этом случае количество потомков **B** становится равным одному и все " "обращения к **B** теперь выполняются через **C1**. Это означает, что **B** и " "**C1** могут быть объединены. Все страницы в **B**, которые также существуют " "и в **C1**, во время объединения из** B** удаляются. Таким образом, хотя " "оптимизация на предыдущем шаге может не делаться, мы можем восстановить " -"мертвые страницы при окончании работы процессов или при вызове `exec()`." +"мёртвые страницы при окончании работы процессов или при вызове `exec()`." #. type: Plain text #: documentation/content/en/articles/vm-design/_index.adoc:165 msgid "" "This model creates a number of potential problems. The first is that you " "can wind up with a relatively deep stack of layered VM Objects which can " "cost scanning time and memory when you take a fault. Deep layering can " "occur when processes fork and then fork again (either parent or child). The " "second problem is that you can wind up with dead, inaccessible pages deep in " "the stack of VM Objects. In our last example if both the parent and child " "processes modify the same page, they both get their own private copies of " "the page and the original page in B is no longer accessible by anyone. That " "page in B can be freed." msgstr "" -"Такая модель создает некоторое количество потенциальных проблем. Первая, с " -"которой вы можете столкнуться, заключается в сравнительно большой " -"последовательности уровней объектов VM, на сканирование которых тратится " -"время и память. Большое количество уровней может возникнуть, когда процессы " -"разветвляются, а затем разветвляются ещё раз (как порожденные, так и " -"порождающие). Вторая проблема заключается в том, что вы можете столкнуться с " -"мертвыми, недоступными страницами глубоко в иерархии объектов VM. В нашем " -"последнем примере если как родитель, так и потомок изменяют одну и ту же " -"страницу, они оба получают собственные копии страницы, а исходная страница " -"на уровне **B** становится никому не доступной. Такая страница в **B** может " -"быть высвобождена." +"Такая модель создаёт некоторое количество потенциальных проблем. Во-первых, " +"можно получить относительно глубокий стек наслоённых объектов виртуальной " +"памяти, что может увеличить время сканирования и расход памяти при обработке " +"страничного исключения. Большое количество уровней может возникнуть, когда " +"процессы разветвляются, а затем разветвляются ещё раз (как порождённые, так " +"и порождающие). Вторая проблема заключается в том, что вы можете столкнуться " +"с мёртвыми, недоступными страницами глубоко в иерархии объектов VM. В нашем " +"последнем примере, если и родитель, и потомок изменяют одну и ту же " +"страницу, они оба получают собственные копии, а исходная страница на уровне " +"**B** становится недоступной ни для одного из них. Такая страница в **B** " +"может быть высвобождена." #. type: Plain text #: documentation/content/en/articles/vm-design/_index.adoc:176 msgid "" "FreeBSD solves the deep layering problem with a special optimization called " "the \"All Shadowed Case\". This case occurs if either C1 or C2 take " "sufficient COW faults to completely shadow all pages in B. Lets say that C1 " "achieves this. C1 can now bypass B entirely, so rather then have C1->B->A " "and C2->B->A we now have C1->A and C2->B->A. But look what also happened-" "now B has only one reference (C2), so we can collapse B and C2 together. " "The end result is that B is deleted entirely and we have C1->A and C2->A. " "It is often the case that B will contain a large number of pages and neither " "C1 nor C2 will be able to completely overshadow it. If we fork again and " "create a set of D layers, however, it is much more likely that one of the D " "layers will eventually be able to completely overshadow the much smaller " "dataset represented by C1 or C2. The same optimization will work at any " "point in the graph and the grand result of this is that even on a heavily " "forked machine VM Object stacks tend to not get much deeper then 4. This is " "true of both the parent and the children and true whether the parent is " "doing the forking or whether the children cascade forks." msgstr "" "FreeBSD решает проблему с глубиной вложенности с помощью приёма оптимизации, " "который называется \"All Shadowed Case\". Этот случай возникает, если в " "**C1** либо *C2* происходит столько случаев копирования страниц при записи, " "что они полностью перекрывают все страницы в *B*. Допустим, что такое " "произошло в *C1*. Уровень *C1* может теперь полностью пропускать уровень *B*" -", так что вместо цепочек *C1* -> *B* -> *A* и *C2* -> *B* -> *A* мы теперь имеем " -"цепочки *C1* -> *A* и *C2* -> *B* -> *A*. Но посмотрите, что получается — теперь " -"*B* имеет только одну ссылку (*C2*), так что мы можем объединить *B* и *C2*. " -"В конечном итоге *B* будет полностью удалён, и мы получим цепочки *C1* -> *A* и " -"*C2* -> *A*. Часто *B* будет содержать большое количество страниц, и ни *C1*, ни " -"*C2* не смогут полностью его заменить. Если мы снова породим процесс и " -"создадим набор уровней *D*, при этом, однако, более вероятно, что один из " -"уровней *D* постепенно сможет полностью заместить гораздо меньший набор " -"данных, представленный *C1* и *C2*. Та же самая оптимизация работает в любой " -"точке графа и её главным результатом является то, что даже на сильно " -"загруженной машине с множеством порождаемых процессов стеки объектов VM не " -"часто бывают глубже четырёх уровней. Это верно как для порождающего, так и " -"для порождённого процессов, и остаётся справедливым как в случае, когда " -"ветвление выполняет родитель, так и в случае, когда ветвление выполняет его " -"потомок." +", так что вместо цепочек *C1* -> *B* -> *A* и *C2* -> *B* -> *A* мы теперь " +"имеем цепочки *C1* -> *A* и *C2* -> *B* -> *A*. Но посмотрите, что " +"получается — теперь *B* имеет только одну ссылку (*C2*), так что мы можем " +"объединить *B* и *C2*. В конечном итоге *B* будет полностью удалён, и мы " +"получим цепочки *C1* -> *A* и *C2* -> *A*. Часто *B* будет содержать большое " +"количество страниц, и ни *C1*, ни *C2* не смогут полностью его заменить. " +"Если мы снова породим процесс и создадим набор уровней *D*, при этом, " +"однако, более вероятно, что один из уровней *D* постепенно сможет полностью " +"заместить гораздо меньший набор данных, представленный *C1* и *C2*. Та же " +"самая оптимизация работает в любой точке графа и её главным результатом " +"является то, что даже на сильно загруженной машине с множеством порождаемых " +"процессов стеки объектов VM не часто бывают глубже четырёх уровней. Это " +"верно как для порождающего, так и для порождённого процессов, и остаётся " +"справедливым как в случае, когда ветвление выполняет родитель, так и в " +"случае, когда ветвление выполняет его потомок." #. type: Plain text #: documentation/content/en/articles/vm-design/_index.adoc:180 msgid "" "The dead page problem still exists in the case where C1 or C2 do not " "completely overshadow B. Due to our other optimizations this case does not " "represent much of a problem and we simply allow the pages to be dead. If " "the system runs low on memory it will swap them out, eating a little swap, " "but that is it." msgstr "" -"Проблема с мертвой страницей все ещё имеет место, когда *C1* или *C2* не " +"Проблема с мёртвой страницей все ещё имеет место, когда *C1* или *C2* не " "полностью перекрывают *B*. Из-за других применяемых нами методов оптимизации " -"этот случай не представляет большой проблемы и мы просто позволяем таким " +"этот случай не представляет большой проблемы, и мы просто позволяем таким " "страницам существовать. Если система испытывает нехватку оперативной памяти, " "она выполняет их выгрузку в область подкачки, что занимает некоторое " "пространство в области подкачки, но это всё." #. type: Plain text #: documentation/content/en/articles/vm-design/_index.adoc:184 msgid "" "The advantage to the VM Object model is that `fork()` is extremely fast, " "since no real data copying need take place. The disadvantage is that you " "can build a relatively complex VM Object layering that slows page fault " "handling down a little, and you spend memory managing the VM Object " "structures. The optimizations FreeBSD makes proves to reduce the problems " "enough that they can be ignored, leaving no real disadvantage." msgstr "" "Преимущество модели VM-объектов заключается в очень быстром выполнении " "функции `fork()`, так как при этом не выполняется реального копирования " "данных. Минусом этого подхода является то, что вы можете построить " "сравнительно сложную иерархию объектов VM, которая несколько замедляет " -"обработку ситуаций отсутствия страниц памяти, и к тому же тратится память на " -"управление структурами объектов VM. Приёмы оптимизации, применяемые во " -"FreeBSD, позволяют снизить значимость этих проблем до степени, когда их " -"можно без особых потерь игнорировать." +"обработку страничных нарушений, и к тому же тратится память на управление " +"структурами объектов VM. Приёмы оптимизации, применяемые во FreeBSD, " +"позволяют снизить значимость этих проблем до степени, когда их можно без " +"особых потерь игнорировать." #. type: Title == #: documentation/content/en/articles/vm-design/_index.adoc:186 #, no-wrap msgid "SWAP Layers" msgstr "Уровни области подкачки" #. type: Plain text #: documentation/content/en/articles/vm-design/_index.adoc:194 msgid "" "Private data pages are initially either copy-on-write or zero-fill pages. " "When a change, and therefore a copy, is made, the original backing object " "(usually a file) can no longer be used to save a copy of the page when the " "VM system needs to reuse it for other purposes. This is where SWAP comes " "in. SWAP is allocated to create backing store for memory that does not " "otherwise have it. FreeBSD allocates the swap management structure for a VM " "Object only when it is actually needed. However, the swap management " "structure has had problems historically:" msgstr "" "Страницы с собственными данными первоначально являются страницами, " "копируемыми-при-записи или заполняемыми нулями. Когда выполняется изменение, " "и, соответственно, копирование, начальное хранилище объекта (обычно файл) не " "может больше использоваться для хранения копии страницы, когда VM-системе " "нужно использовать её повторно для других целей. В этот момент на помощь " "приходит область подкачки. Область подкачки выделяется для организации " -"хранилища памяти, которая иначе не может быть доступна. FreeBSD создает " +"хранилища памяти, которая иначе не может быть доступна. FreeBSD создаёт " "структуру управления подкачкой для объекта VM, только когда это " "действительно нужно. Однако структура управления подкачкой исторически имела " "некоторые проблемы:" #. type: Plain text #: documentation/content/en/articles/vm-design/_index.adoc:196 msgid "" "Under FreeBSD 3.X the swap management structure preallocates an array that " "encompasses the entire object requiring swap backing store-even if only a " "few pages of that object are swap-backed. This creates a kernel memory " "fragmentation problem when large objects are mapped, or processes with large " "runsizes (RSS) fork." msgstr "" -"Во FreeBSD 3.X в структуре управления областью подкачки предварительно " -"выделяется массив, который представляет целый объект, требующий хранения в " -"области подкачки — даже если только несколько страниц этого объекта хранятся " -"в области подкачки. Это создает проблему фрагментации памяти ядра в случае, " -"когда в память отображаются большие объекты или когда ветвятся процессы, " -"занимающие большой объём памяти при работе (RSS)." +"В FreeBSD 3.X в структуре управления областью подкачки предварительно " +"выделяется массив, который представляет собой целый объект, требующий " +"хранения в области подкачки — даже если только несколько страниц этого " +"объекта хранятся в области подкачки. Это создаёт проблему фрагментации " +"памяти ядра в случае, когда в память отображаются большие объекты или когда " +"ветвятся процессы, занимающие большой объём памяти при работе (RSS)." #. type: Plain text #: documentation/content/en/articles/vm-design/_index.adoc:197 msgid "" "Also, to keep track of swap space, a \"list of holes\" is kept in kernel " "memory, and this tends to get severely fragmented as well. Since the \"list " "of holes\" is a linear list, the swap allocation and freeing performance is " "a non-optimal O(n)-per-page." msgstr "" "Также для отслеживания памяти подкачки в памяти ядра поддерживается \"список " "дыр\", и он также несколько фрагментирован. Так как \"список дыр\" является " "последовательным списком, то производительность при распределении и " "высвобождении памяти в области подкачки неоптимальна, и её сложность зависит " "от количества страниц как O(n)." #. type: Plain text #: documentation/content/en/articles/vm-design/_index.adoc:198 msgid "" "It requires kernel memory allocations to take place during the swap freeing " "process, and that creates low memory deadlock problems." msgstr "" "Также в процессе высвобождения памяти из области подкачки требуется " "выделение памяти в ядре, и это приводит к проблемам блокировки при " "недостатке памяти." #. type: Plain text #: documentation/content/en/articles/vm-design/_index.adoc:199 msgid "" "The problem is further exacerbated by holes created due to the interleaving " "algorithm." msgstr "" "Проблема ещё более обостряется из-за дыр, создаваемых по чередующемуся " "алгоритму." #. type: Plain text #: documentation/content/en/articles/vm-design/_index.adoc:200 msgid "" "Also, the swap block map can become fragmented fairly easily resulting in " "non-contiguous allocations." msgstr "" "Кроме того, список распределения блоков в области подкачки легко оказывается " "фрагментированным, что приводит к распределению непоследовательных областей." #. type: Plain text #: documentation/content/en/articles/vm-design/_index.adoc:201 msgid "" "Kernel memory must also be allocated on the fly for additional swap " "management structures when a swapout occurs." msgstr "" "Память ядра также должна выделяться на лету для дополнительных структур " "управления подкачкой при выгрузке страниц в область подкачки." #. type: Plain text #: documentation/content/en/articles/vm-design/_index.adoc:204 msgid "" "It is evident from that list that there was plenty of room for improvement. " "For FreeBSD 4.X, I completely rewrote the swap subsystem:" msgstr "" "Очевидно, что мест для усовершенствований предостаточно. Во FreeBSD 4.X " "подсистема управления областью подкачки была полностью переписана мною:" #. type: Plain text #: documentation/content/en/articles/vm-design/_index.adoc:206 msgid "" "Swap management structures are allocated through a hash table rather than a " "linear array giving them a fixed allocation size and much finer granularity." msgstr "" "Структуры управления областью подкачки распределяются при помощи хэш-" "таблицы, а не через линейный массив, что даёт им фиксированный размер при " "распределении и работу с гораздо меньшими структурами." #. type: Plain text #: documentation/content/en/articles/vm-design/_index.adoc:207 msgid "" "Rather then using a linearly linked list to keep track of swap space " "reservations, it now uses a bitmap of swap blocks arranged in a radix tree " "structure with free-space hinting in the radix node structures. This " "effectively makes swap allocation and freeing an O(1) operation." msgstr "" "Вместо того, чтобы использовать однонаправленный связный список для " "отслеживания выделения пространства в области подкачки, теперь используется " "побитовая карта блоков области подкачки, выполненная в основном в виде " "древовидной структуры с информацией о свободном пространстве, находящейся в " "узлах структур. Это приводит к тому, что выделение и высвобождение памяти в " "области подкачки становится операцией сложности O(1)." #. type: Plain text #: documentation/content/en/articles/vm-design/_index.adoc:208 msgid "" "The entire radix tree bitmap is also preallocated to avoid having to " "allocate kernel memory during critical low memory swapping operations. After " "all, the system tends to swap when it is low on memory so we should avoid " "allocating kernel memory at such times to avoid potential deadlocks." msgstr "" "Всё дерево также распределяется заранее для того, чтобы избежать " "распределения памяти ядра во время операций с областью подкачки при " "критически малом объёме свободной памяти. В конце концов, система обращается " "к области подкачки при нехватке памяти, так что мы должны избежать " "распределения памяти ядра в такие моменты для избежания потенциальных " "блокировок." #. type: Plain text #: documentation/content/en/articles/vm-design/_index.adoc:209 msgid "" "To reduce fragmentation the radix tree is capable of allocating large " "contiguous chunks at once, skipping over smaller fragmented chunks." msgstr "" "Для уменьшения фрагментации дерево может распределять большой " "последовательный кусок за раз, пропуская меньшие фрагментированные области." #. type: Plain text #: documentation/content/en/articles/vm-design/_index.adoc:211 msgid "" "I did not take the final step of having an \"allocating hint pointer\" that " "would trundle through a portion of swap as allocations were made to further " "guarantee contiguous allocations or at least locality of reference, but I " "ensured that such an addition could be made." msgstr "" "Я не сделал последний шаг к заведению \"указателя на распределение\", " "который будет передвигаться по участку области подкачки при выделении памяти " "для обеспечения в будущем распределения последовательных участков, или по " "крайней мере местоположения ссылки, но я убежден, что это может быть сделано." #. type: Title == #: documentation/content/en/articles/vm-design/_index.adoc:213 #, no-wrap msgid "When to free a page" msgstr "Когда освобождать страницу" #. type: Plain text #: documentation/content/en/articles/vm-design/_index.adoc:218 msgid "" "Since the VM system uses all available memory for disk caching, there are " "usually very few truly-free pages. The VM system depends on being able to " "properly choose pages which are not in use to reuse for new allocations. " "Selecting the optimal pages to free is possibly the single-most important " "function any VM system can perform because if it makes a poor selection, the " "VM system may be forced to unnecessarily retrieve pages from disk, seriously " "degrading system performance." msgstr "" "Так как система VM использует всю доступную память для кэширования диска, то " "обычно действительно незанятых страниц очень мало. Система VM зависит от " "того, как она точно выбирает незанятые страницы для повторного использования " "для новых распределений. Оптимальный выбор страниц для высвобождения, " "возможно, является самой важной функцией любой VM-системы, из тех, что она " "может выполнять, потому что при неправильном выборе система VM вынуждена " "будет запрашивать страницы с диска, значительно снижая производительность " "всей системы." #. type: Plain text #: documentation/content/en/articles/vm-design/_index.adoc:221 msgid "" "How much overhead are we willing to suffer in the critical path to avoid " "freeing the wrong page? Each wrong choice we make will cost us hundreds of " "thousands of CPU cycles and a noticeable stall of the affected processes, so " "we are willing to endure a significant amount of overhead to be sure that " "the right page is chosen. This is why FreeBSD tends to outperform other " "systems when memory resources become stressed." msgstr "" "Какую дополнительную нагрузку мы может выделить в критическом пути для " -"избежания высвобождения не той страницы? Каждый неправильный выбор будет " -"стоить нам сотни тысяч тактов работы центрального процессора и заметное " -"замедление работы затронутых процессов, так что мы должны смириться со " -"значительными издержками для того, чтобы была выбрана правильная страница. " -"Вот почему FreeBSD превосходит другие системы в производительности при " -"нехватке ресурсов памяти." +"избежания высвобождения неверно выбранной страницы? Каждый неправильный " +"выбор будет стоить нам сотен тысяч тактов работы центрального процессора и " +"заметного замедления работы затронутых процессов, так что мы должны " +"смириться со значительными издержками ради того, чтобы была выбрана " +"правильная страница. Вот почему FreeBSD превосходит другие системы в " +"производительности при нехватке ресурсов памяти." #. type: Plain text #: documentation/content/en/articles/vm-design/_index.adoc:224 msgid "" "The free page determination algorithm is built upon a history of the use of " "memory pages. To acquire this history, the system takes advantage of a page-" "used bit feature that most hardware page tables have." msgstr "" "Алгоритм определения свободной страницы написан на основе истории " "использования страниц памяти. Для получения этой истории система использует " "возможности бита использования памяти, которые имеются в большинстве " "аппаратных таблицах страниц памяти." #. type: Plain text #: documentation/content/en/articles/vm-design/_index.adoc:230 msgid "" "In any case, the page-used bit is cleared and at some later point the VM " "system comes across the page again and sees that the page-used bit has been " "set. This indicates that the page is still being actively used. If the bit " "is still clear it is an indication that the page is not being actively " "used. By testing this bit periodically, a use history (in the form of a " "counter) for the physical page is developed. When the VM system later needs " "to free up some pages, checking this history becomes the cornerstone of " "determining the best candidate page to reuse." msgstr "" "В любом случае, бит использования страницы очищается, и в некоторый более " "поздний момент VM-система обращается к странице снова и обнаруживает, что " "этот бит установлен. Это указывает на то, что страница активно используется. " "Периодически проверяя этот бит, накапливается история использования (в виде " "счетчика) физической страницы. Когда позже VM-системе требуется высвободить " "некоторые страницы, проверка истории выступает указателем при определении " "наиболее вероятной кандидатуры для повторного использования." #. type: Plain text #: documentation/content/en/articles/vm-design/_index.adoc:235 msgid "" "For those platforms that do not have this feature, the system actually " "emulates a page-used bit. It unmaps or protects a page, forcing a page " "fault if the page is accessed again. When the page fault is taken, the " "system simply marks the page as having been used and unprotects the page so " "that it may be used. While taking such page faults just to determine if a " "page is being used appears to be an expensive proposition, it is much less " "expensive than reusing the page for some other purpose only to find that a " "process needs it back and then have to go to disk." msgstr "" "Для тех платформ, что не имеют этой возможности, система эмулирует этот бит. " -"Она снимает отображение или защищает страницу, что приводит к ошибке доступа " -"к странице, если к странице выполняется повторное обращение. При " -"возникновении этой ошибки система просто помечает страницу как используемую " -"и снимает защиту со страницы, так что она может использоваться. Хотя " -"использование такого приема только для определения использования страницы " -"весьма накладно, это выгоднее, чем повторно использовать страницу для других " -"целей и обнаружить, что она снова нужна процессу и подгружать её с диска." +"Она снимает отображение или защищает страницу, что приводит к страничному " +"нарушению, если к странице выполняется повторное обращение. При " +"возникновении этого страничного нарушения система просто помечает страницу " +"как используемую и снимает защиту со страницы, так что она может " +"использоваться. Хотя использование такого приема только для определения " +"использования страницы весьма накладно, это выгоднее, чем повторно " +"использовать страницу для других целей и обнаружить, что она снова нужна " +"процессу и подгружать её с диска." #. type: Plain text #: documentation/content/en/articles/vm-design/_index.adoc:245 msgid "" "FreeBSD makes use of several page queues to further refine the selection of " "pages to reuse as well as to determine when dirty pages must be flushed to " "their backing store. Since page tables are dynamic entities under FreeBSD, " "it costs virtually nothing to unmap a page from the address space of any " "processes using it. When a page candidate has been chosen based on the page-" "use counter, this is precisely what is done. The system must make a " "distinction between clean pages which can theoretically be freed up at any " "time, and dirty pages which must first be written to their backing store " "before being reusable. When a page candidate has been found it is moved to " "the inactive queue if it is dirty, or the cache queue if it is clean. A " "separate algorithm based on the dirty-to-clean page ratio determines when " "dirty pages in the inactive queue must be flushed to disk. Once this is " "accomplished, the flushed pages are moved from the inactive queue to the " "cache queue. At this point, pages in the cache queue can still be " "reactivated by a VM fault at relatively low cost. However, pages in the " "cache queue are considered to be \"immediately freeable\" and will be reused " "in an LRU (least-recently used) fashion when the system needs to allocate " "new memory." msgstr "" "FreeBSD использует несколько очередей страниц для обновления выбора страниц " "для повторного использования, а также для определения того, когда же грязные " "страницы должны быть сброшены в хранилище. Так как таблицы страниц во " "FreeBSD являются динамическими объектами, практически ничего не стоит " "вырезать страницу из адресного пространства любого использующего её " -"процесса. После того, как подходящая страница, на основе счетчика " -"использования, выбрана, именно это и выполняется. Система должна различать " +"процесса. После того как подходящая страница на основе счётчика " +"использования выбрана, именно это и выполняется. Система должна различать " "чистые страницы, которые теоретически могут быть высвобождены в любое время, " "и грязные страницы, которые сначала должны быть переписаны в хранилище перед " "тем, как их можно будет использовать повторно. После нахождения подходящей " "страницы она перемещается в неактивную очередь, если она является грязной, " "или в очередь кэша, если она чистая. Отдельный алгоритм, основывающийся на " "отношении количества грязных страниц к чистым, определяет, когда грязные " "страницы в неактивной очереди должны быть сброшены на диск. Когда это " "выполнится, сброшенные страницы перемещаются из неактивной очереди в очередь " "кэша. В этот момент страницы в очереди кэша могут быть повторно " -"активизированы VM со сравнительно малыми накладными расходами. Однако " -"страницы в очереди кэша предполагается \"высвобождать немедленно\" и " -"повторно использовать в LRU-порядке (меньше всего используемый), когда " -"системе потребуется выделение дополнительной памяти." +"активизированы страничными нарушениями VM со сравнительно малыми накладными " +"расходами. Однако страницы в очереди кэша предполагается \"высвобождать " +"немедленно\" и повторно использовать в LRU-порядке (наименее давно " +"используемый), когда системе потребуется выделение дополнительной памяти." #. type: Plain text #: documentation/content/en/articles/vm-design/_index.adoc:249 msgid "" "It is important to note that the FreeBSD VM system attempts to separate " "clean and dirty pages for the express reason of avoiding unnecessary flushes " "of dirty pages (which eats I/O bandwidth), nor does it move pages between " "the various page queues gratuitously when the memory subsystem is not being " "stressed. This is why you will see some systems with very low cache queue " "counts and high active queue counts when doing a `systat -vm` command. As " "the VM system becomes more stressed, it makes a greater effort to maintain " "the various page queues at the levels determined to be the most effective." msgstr "" "Стоит отметить, что во FreeBSD VM-система пытается разделить чистые и " "грязные страницы во избежание срочной необходимости в ненужных сбросах " "грязных страниц (что отражается на пропускной способности ввода/вывода) и не " "перемещает беспричинно страницы между разными очередями, когда подсистема " "управления памятью не испытывает нехватку ресурсов. Вот почему вы можете " "видеть, что при выполнении команды `systat -vm` в некоторых системах " "значение счетчика очереди кэша мало, а счетчик активной очереди большой. При " "повышении нагрузки на VM-систему она прилагает большие усилия на поддержку " "различных очередей страниц в соотношениях, которые являются наиболее " "эффективными." #. type: Plain text #: documentation/content/en/articles/vm-design/_index.adoc:253 msgid "" "An urban myth has circulated for years that Linux did a better job avoiding " "swapouts than FreeBSD, but this in fact is not true. What was actually " "occurring was that FreeBSD was proactively paging out unused pages to make " "room for more disk cache while Linux was keeping unused pages in core and " "leaving less memory available for cache and process pages. I do not know " "whether this is still true today." msgstr "" "Годами ходили современные легенды, что Linux выполняет работу по " "предотвращению выгрузки на диск лучше, чем FreeBSD, но это не так. На самом " "деле FreeBSD старается сбросить на диск неиспользуемые страницы для " "освобождения места под дисковый кэш, когда как Linux хранит неиспользуемые " "страницы в памяти и оставляет под кэш и страницы процессов меньше памяти. Я " "не знаю, остаётся ли это правдой на сегодняшний день." #. type: Title == #: documentation/content/en/articles/vm-design/_index.adoc:255 #, no-wrap msgid "Pre-Faulting and Zeroing Optimizations" -msgstr "Оптимизация ошибок доступа к страницам и их обнуления" +msgstr "Упреждающая оптимизация страничных нарушений и обнуления" #. type: Plain text #: documentation/content/en/articles/vm-design/_index.adoc:265 msgid "" "Taking a VM fault is not expensive if the underlying page is already in core " "and can simply be mapped into the process, but it can become expensive if " "you take a whole lot of them on a regular basis. A good example of this is " "running a program such as man:ls[1] or man:ps[1] over and over again. If " "the program binary is mapped into memory but not mapped into the page table, " "then all the pages that will be accessed by the program will have to be " "faulted in every time the program is run. This is unnecessary when the " "pages in question are already in the VM Cache, so FreeBSD will attempt to " "pre-populate a process's page tables with those pages that are already in " "the VM Cache. One thing that FreeBSD does not yet do is pre-copy-on-write " "certain pages on exec. For example, if you run the man:ls[1] program while " "running `vmstat 1` you will notice that it always takes a certain number of " "page faults, even when you run it over and over again. These are zero-fill " "faults, not program code faults (which were pre-faulted in already). Pre-" "copying pages on exec or fork is an area that could use more study." msgstr "" -"Полагая, что ошибка доступа к странице памяти в VM не является операцией с " -"большими накладными расходами, если страница уже находится в основной памяти " -"и может быть просто отображена в адресное пространство процесса, может " -"оказаться, что это станет весьма накладно, если их будет оказываться " -"регулярно много. Хорошим примером этой ситуации является запуск таких " -"программ, как man:ls[1] или man:ps[1], снова и снова. Если бинарный файл " -"программы отображен в память, но не отображен в таблицу страниц, то все " -"страницы, к которым обращалась программа, окажутся недоступными при каждом " -"запуске программы. Это не так уж необходимо, если эти страницы уже " -"присутствуют в кэше VM, так что FreeBSD будет пытаться восстанавливать " -"таблицы страниц процесса из тех страниц, что уже располагаются в VM-кэше. " -"Однако во FreeBSD пока не выполняется предварительное копирование при записи " -"определённых страниц при выполнении вызова exec. Например, если вы " -"запускаете программу man:ls[1] одновременно с работающей `vmstat 1`, то " -"заметите, что она всегда выдает некоторое количество ошибок доступа к " -"страницам, даже когда вы запускаете её снова и снова. Эти ошибки относятся к " -"типу zero-fill и не связаны с доступом к коду программы (который уже был " -"предварительно отображён). Предварительное копирование страниц при " -"выполнении вызовов exec или fork находятся в области, требующей более " -"тщательного изучения." +"Полагая, что страничное нарушение в VM не является операцией с большими " +"накладными расходами, если страница уже находится в основной памяти и может " +"быть просто отображена в адресное пространство процесса, может оказаться, " +"что это станет весьма накладно, если их будет оказываться регулярно много. " +"Хорошим примером этой ситуации является запуск таких программ, как man:ls[1] " +"или man:ps[1], снова и снова. Если бинарный файл программы отображён в " +"память, но не отображён в таблицу страниц, то все страницы, к которым " +"обращалась программа, окажутся недоступными при каждом запуске программы. " +"Это не так уж необходимо, если эти страницы уже присутствуют в кэше VM, так " +"что FreeBSD будет пытаться восстанавливать таблицы страниц процесса из тех " +"страниц, что уже располагаются в VM-кэше. Однако во FreeBSD пока не " +"выполняется предварительное копирование при записи определённых страниц при " +"выполнении вызова exec. Например, если вы запускаете программу man:ls[1] " +"одновременно с работающей `vmstat 1`, то заметите, что она всегда выдаёт " +"некоторое количество ошибок доступа к страницам, даже когда вы запускаете её " +"снова и снова. Эти ошибки относятся к типу zero-fill и не связаны с доступом " +"к коду программы (который уже был предварительно отображён). Предварительное " +"копирование страниц при выполнении вызовов exec или fork находятся в " +"области, требующей более тщательного изучения." #. type: Plain text #: documentation/content/en/articles/vm-design/_index.adoc:274 msgid "" "A large percentage of page faults that occur are zero-fill faults. You can " "usually see this by observing the `vmstat -s` output. These occur when a " "process accesses pages in its BSS area. The BSS area is expected to be " "initially zero but the VM system does not bother to allocate any memory at " "all until the process actually accesses it. When a fault occurs the VM " "system must not only allocate a new page, it must zero it as well. To " "optimize the zeroing operation the VM system has the ability to pre-zero " "pages and mark them as such, and to request pre-zeroed pages when zero-fill " "faults occur. The pre-zeroing occurs whenever the CPU is idle but the " "number of pages the system pre-zeros is limited to avoid blowing away the " "memory caches. This is an excellent example of adding complexity to the VM " "system to optimize the critical path." msgstr "" -"Большой процент ошибок доступа к страницам, относится к ошибкам при " +"Большой процент страничных нарушений относится к страничным нарушениям при " "заполнении нулями. Вы можете обычно видеть это, просматривая вывод команды `" "vmstat -s`. Это происходит, когда процесс обращается к страницам в своей " "области BSS. Область BSS предполагается изначально заполненной нулями, но VM-" "система не заботится о выделении памяти до тех пор, пока процесс реально к " -"ней не обратится. При возникновении ошибки VM-система должна не только " +"ней не обратится. При страничном нарушении VM-система должна не только " "выделить новую страницу, но и заполнить её нулями. Для оптимизации операции " "по заполнению нулями в системе VM имеется возможность предварительно " "обнулять страницы и помечать их, и запрашивать уже обнуленные страницы при " -"возникновении ошибок заполнения нулями. Предварительное заполнение нулями " -"происходит, когда CPU простаивает, однако количество страниц, которые " -"система заранее заполняет нулями, ограничено, для того, чтобы не переполнить " -"кэши памяти. Это прекрасный пример добавления сложности в VM-систему ради " -"оптимизации критического пути." +"возникновении страничных нарушений заполнения нулями. Предварительное " +"заполнение нулями происходит, когда CPU простаивает, однако количество " +"страниц, которые система заранее заполняет нулями, ограничено, для того, " +"чтобы не переполнить кэши памяти. Это прекрасный пример добавления сложности " +"в VM-систему ради оптимизации критического пути." #. type: Title == #: documentation/content/en/articles/vm-design/_index.adoc:276 #, no-wrap msgid "Page Table Optimizations" msgstr "Оптимизация таблицы страниц" #. type: Plain text #: documentation/content/en/articles/vm-design/_index.adoc:286 msgid "" "The page table optimizations make up the most contentious part of the " "FreeBSD VM design and they have shown some strain with the advent of serious " "use of `mmap()`. I think this is actually a feature of most BSDs though I " "am not sure when it was first introduced. There are two major " "optimizations. The first is that hardware page tables do not contain " "persistent state but instead can be thrown away at any time with only a " "minor amount of management overhead. The second is that every active page " "table entry in the system has a governing `pv_entry` structure which is tied " "into the `vm_page` structure. FreeBSD can simply iterate through those " "mappings that are known to exist while Linux must check all page tables that " "_might_ contain a specific mapping to see if it does, which can achieve " "O(n^2) overhead in certain situations. It is because of this that FreeBSD " "tends to make better choices on which pages to reuse or swap when memory is " "stressed, giving it better performance under load. However, FreeBSD " "requires kernel tuning to accommodate large-shared-address-space situations " "such as those that can occur in a news system because it may run out of " "`pv_entry` structures." msgstr "" "Оптимизация таблицы страниц составляет самую содержательную часть " "архитектуры VM во FreeBSD и она проявляется при появлении нагрузки при " "значительном использовании `mmap()`. Я думаю, что это на самом деле " "особенность работы большинства BSD-систем, хотя я не уверен, когда это " "проявилось впервые. Есть два основных подхода к оптимизации. Первый " "заключается в том, что аппаратные таблицы страниц не содержат постоянного " "состояния, а вместо этого могут быть сброшены в любой момент с малыми " "накладными расходами. Второй подход состоит в том, что каждая активная " "таблица страниц в системе имеет управляющую структуру `pv_entry`, которая " "связана в структуру `vm_page`. FreeBSD может просто просматривать эти " "отображения, которые существуют, когда как в Linux должны проверяться все " "таблицы страниц, которые _могут_ содержать нужное отображение, что в " "некоторых ситуация даёт увеличение сложности O(n^2). Из-за того, что FreeBSD " "стремится выбрать наиболее подходящую к повторному использованию или сбросу " "в область подкачки страницу, когда ощущается нехватка памяти, система даёт " "лучшую производительность при нагрузке. Однако во FreeBSD требуется тонкая " "настройка ядра для соответствия ситуациям с большим совместно используемым " "адресным пространством, которые могут случиться в системе, обслуживающей " "сервер телеконференций, потому что структуры `pv_entry` могут оказаться " "исчерпанными." #. type: Plain text #: documentation/content/en/articles/vm-design/_index.adoc:291 msgid "" "Both Linux and FreeBSD need work in this area. FreeBSD is trying to " "maximize the advantage of a potentially sparse active-mapping model (not all " "processes need to map all pages of a shared library, for example), whereas " "Linux is trying to simplify its algorithms. FreeBSD generally has the " "performance advantage here at the cost of wasting a little extra memory, but " "FreeBSD breaks down in the case where a large file is massively shared " "across hundreds of processes. Linux, on the other hand, breaks down in the " "case where many processes are sparsely-mapping the same shared library and " "also runs non-optimally when trying to determine whether a page can be " "reused or not." msgstr "" "И в Linux, и во FreeBSD требуются доработки в этой области. FreeBSD пытается " "максимизировать преимущества от потенциально редко применяемой модели " "активного отображения (к примеру, не всем процессам нужно отображать все " "страницы динамической библиотеки), когда как Linux пытается упростить свои " "алгоритмы. FreeBSD имеет здесь общее преимущество в производительности за " "счет использования дополнительной памяти, но FreeBSD выглядит хуже в случае, " "когда большой файл совместно используется сотнями процессов. Linux, с другой " "стороны, выглядит хуже в случае, когда много процессов частично используют " "одну и ту же динамическую библиотеку, а также работает неоптимально при " "попытке определить, может ли страница повторно использоваться, или нет." #. type: Title == #: documentation/content/en/articles/vm-design/_index.adoc:293 #, no-wrap msgid "Conclusion" msgstr "Заключение" #. type: Plain text #: documentation/content/en/articles/vm-design/_index.adoc:298 msgid "" "Virtual memory in modern operating systems must address a number of " "different issues efficiently and for many different usage patterns. The " "modular and algorithmic approach that BSD has historically taken allows us " "to study and understand the current implementation as well as relatively " "cleanly replace large sections of the code. There have been a number of " "improvements to the FreeBSD VM system in the last several years, and work is " "ongoing." msgstr "" "Виртуальная память в современных операционных системах должна решать " "несколько различных задач эффективно и при разных условиях. Модульный и " "алгоритмический подход, которому исторически следует BSD, позволяет нам " "изучить и понять существующую реализацию, а также сравнительно легко " "изменить большие блоки кода. За несколько последних лет в VM-системе FreeBSD " "было сделано некоторое количество усовершенствований, и работа над ними " "продолжается." #. type: Title == #: documentation/content/en/articles/vm-design/_index.adoc:300 #, no-wrap msgid "Bonus QA session by Allen Briggs" msgstr "" "Дополнительный сеанс вопросов и ответов от Аллена Бриггса (Allen Briggs)" #. type: Title === #: documentation/content/en/articles/vm-design/_index.adoc:302 #, no-wrap msgid "What is the interleaving algorithm that you refer to in your listing of the ills of the FreeBSD 3.X swap arrangements?" msgstr "" "Что это за алгоритм чередования, который вы упоминали в списке недостатков " "подсистемы управления разделом подкачки во FreeBSD 3.X?" #. type: Plain text #: documentation/content/en/articles/vm-design/_index.adoc:308 msgid "" "FreeBSD uses a fixed swap interleave which defaults to 4. This means that " "FreeBSD reserves space for four swap areas even if you only have one, two, " "or three. Since swap is interleaved the linear address space representing " "the \"four swap areas\" will be fragmented if you do not actually have four " "swap areas. For example, if you have two swap areas A and B FreeBSD's " "address space representation for that swap area will be interleaved in " "blocks of 16 pages:" msgstr "" "FreeBSD использует в области подкачки механизм чередования, с индексом по " "умолчанию, равным четырем. Это означает, что FreeBSD резервирует " "пространство для четырёх областей подкачки, даже если у вас имеется всего " "лишь одна, две или три области. Так как в области подкачки имеется " "чередование, то линейное адресное пространство, представляющее \"четыре " "области подкачки\", будет фрагментироваться, если у вас нет на самом деле " "четырёх областей подкачки. Например, если у вас две области A и B, то " "представление адресного пространства для этой области подкачки во FreeBSD " "будет организовано с чередованием блоков из 16 страниц:" #. type: delimited block . 4 #: documentation/content/en/articles/vm-design/_index.adoc:311 #, no-wrap msgid "A B C D A B C D A B C D A B C D\n" msgstr "A B C D A B C D A B C D A B C D\n" #. type: Plain text #: documentation/content/en/articles/vm-design/_index.adoc:318 msgid "" "FreeBSD 3.X uses a \"sequential list of free regions\" approach to " "accounting for the free swap areas. The idea is that large blocks of free " "linear space can be represented with a single list node ([.filename]#kern/" "subr_rlist.c#). But due to the fragmentation the sequential list winds up " "being insanely fragmented. In the above example, completely unused swap " "will have A and B shown as \"free\" and C and D shown as \"all allocated\". " "Each A-B sequence requires a list node to account for because C and D are " "holes, so the list node cannot be combined with the next A-B sequence." msgstr "" "FreeBSD 3.X использует \"последовательный список свободных областей\" для " "управления свободными областями в разделе подкачки. Идея состоит в том, что " "большие последовательные блоки свободного пространства могут быть " "представлены при помощи узла односвязного списка ([.filename]#kern/subr_rlist" ".c#). Но из-за фрагментации последовательный список сам становится " "фрагментированным. В примере выше полностью неиспользуемое пространство в A " "и B будет показано как \"свободное\", а C и D как \"полностью занятое\". " "Каждой последовательности A-B требуется для учёта узел списка, потому что C " "и D являются дырами, так что узел списка не может быть связан со следующей " "последовательностью A-B." #. type: Plain text #: documentation/content/en/articles/vm-design/_index.adoc:320 msgid "" "Why do we interleave our swap space instead of just tack swap areas onto the " "end and do something fancier? It is a whole lot easier to allocate linear " "swaths of an address space and have the result automatically be interleaved " "across multiple disks than it is to try to put that sophistication elsewhere." msgstr "" "Почему мы организуем чередование в области подкачки вместо того, чтобы " "просто объединить области подкачки в одно целое и придумать что-то более " "умное? Потому что гораздо легче выделять последовательные полосы адресного " "пространства и получать в результате автоматическое чередование между " "несколькими дисками, чем пытаться выдумывать сложности в другом месте." #. type: Plain text #: documentation/content/en/articles/vm-design/_index.adoc:325 msgid "" "The fragmentation causes other problems. Being a linear list under 3.X, and " "having such a huge amount of inherent fragmentation, allocating and freeing " "swap winds up being an O(N) algorithm instead of an O(1) algorithm. " "Combined with other factors (heavy swapping) and you start getting into " "O(N^2) and O(N^3) levels of overhead, which is bad. The 3.X system may also " "need to allocate KVM during a swap operation to create a new list node which " "can lead to a deadlock if the system is trying to pageout pages in a low-" "memory situation." msgstr "" "Фрагментация вызывает другие проблемы. Являясь последовательным списком в " "3.X и имея такое огромную фрагментацию, выделение и освобождение в области " "подкачки становится алгоритмом сложности O(N), а не O(1). Вместе с другими " "факторами (частое обращение к области подкачки) вы получаете сложность " "уровней O(N^2) и O(N^3), что плохо. В системе 3.X также может потребоваться " "выделение KVM во время работы с областью подкачки для создания нового узла " "списка, что в условии нехватки памяти может привести к блокировке, если " "система попытается сбросить страницы в область подкачки." #. type: Plain text #: documentation/content/en/articles/vm-design/_index.adoc:330 msgid "" "Under 4.X we do not use a sequential list. Instead we use a radix tree and " "bitmaps of swap blocks rather than ranged list nodes. We take the hit of " "preallocating all the bitmaps required for the entire swap area up front but " "it winds up wasting less memory due to the use of a bitmap (one bit per " "block) instead of a linked list of nodes. The use of a radix tree instead " "of a sequential list gives us nearly O(1) performance no matter how " "fragmented the tree becomes." msgstr "" "В 4.X мы не используем последовательный список. Вместо этого мы используем " "базисное дерево и битовые карты блоков области подкачки, а не ограниченный " "список узлов. Мы принимаем предварительное выделение всех битовых карт, " "требуемых для всей области подкачки, но при этом тратится меньше памяти, " "потому что мы используем битовые карты (один бит на блок), а не связанный " "список узлов. Использование базисного дерева вместо последовательного списка " "даёт нам производительность O(1) вне зависимости от фрагментации дерева." #. type: Title === #: documentation/content/en/articles/vm-design/_index.adoc:331 #, no-wrap msgid "How is the separation of clean and dirty (inactive) pages related to the situation where you see low cache queue counts and high active queue counts in systat -vm? Do the systat stats roll the active and dirty pages together for the active queue count?" msgstr "" "Как разделение чистых и грязных (неактивных) страниц связано с ситуацией, " "когда вы видите маленький счетчик очереди кэша и большой счетчик активной " "очереди в выдаче команды systat -vm? Разве системная статистика не считает " "активные и грязные страницы вместе за счетчик активной очереди?" #. type: Plain text #: documentation/content/en/articles/vm-design/_index.adoc:336 msgid "" "Yes, that is confusing. The relationship is \"goal\" verses \"reality\". " "Our goal is to separate the pages but the reality is that if we are not in a " "memory crunch, we do not really have to." msgstr "" "Да, это запутывает. Связь заключается в \"желаемом\" и \"действительном\". " "Мы желаем разделить страницы, но реальность такова, что пока у нас нет " "проблем с памятью, нам это на самом деле не нужно." #. type: Plain text #: documentation/content/en/articles/vm-design/_index.adoc:338 msgid "" "What this means is that FreeBSD will not try very hard to separate out dirty " "pages (inactive queue) from clean pages (cache queue) when the system is not " "being stressed, nor will it try to deactivate pages (active queue -> " "inactive queue) when the system is not being stressed, even if they are not " "being used." msgstr "" "Это означает, что FreeBSD не будет очень сильно стараться над отделением " "грязных страниц (неактивная очередь) от чистых страниц (очередь кэша), когда " "система не находится под нагрузкой, и не будет деактивировать страницы (" "активная очередь -> неактивная очередь), когда система не нагружена, даже " "если они не используются." #. type: Title === #: documentation/content/en/articles/vm-design/_index.adoc:339 #, no-wrap msgid "In man:ls[1] the / vmstat 1 example, would not some of the page faults be data page faults (COW from executable file to private page)? I.e., I would expect the page faults to be some zero-fill and some program data. Or are you implying that FreeBSD does do pre-COW for the program data?" msgstr "" -"В примере с man:ls(1) и `vmstat 1` выше могут ли некоторые ошибки доступа к " -"странице быть ошибками страниц данных (COW из выполнимого файла в приватные " -"страницы)? То есть я полагаю, что ошибки доступа к страницам являются " -"частично ошибками при заполнении нулями, а частично данных программы. Или вы " +"В примере с man:ls(1) и `vmstat 1` выше могут ли некоторые страничные " +"нарушения быть страничными нарушениями данных (COW из выполнимого файла в " +"приватные страницы)? Иными словами, я ожидаю, что часть страничных нарушений " +"будет связана с заполнением нулями, а часть — с программными данными. Или вы " "гарантируете, что FreeBSD выполняет предварительно COW для данных программы?" #. type: Plain text #: documentation/content/en/articles/vm-design/_index.adoc:345 msgid "" "A COW fault can be either zero-fill or program-data. The mechanism is the " "same either way because the backing program-data is almost certainly already " "in the cache. I am indeed lumping the two together. FreeBSD does not pre-" "COW program data or zero-fill, but it _does_ pre-map pages that exist in its " "cache." msgstr "" -"Ошибка COW может быть ошибкой при заполнении нулями или данных программы. " -"Механизм в любом случае один и тот же, потому что хранилище данных программы " -"уже в кэше. Я на самом деле не рад ни тому, ни другому. FreeBSD не выполняет " -"предварительное COW данных программы и заполнение нулями, но она _выполняет_ " -"предварительно отображение страниц, которые имеются в её кэше." +"Страничное нарушение COW может быть связано или с заполнением нулями, или с " +"данными программы. Механизм в любом случае один и тот же, потому что " +"хранилище данных программы уже в кэше. Я на самом деле не рад ни тому, ни " +"другому. FreeBSD не выполняет предварительное COW данных программы и " +"заполнение нулями, но она _выполняет_ предварительно отображение страниц, " +"которые имеются в её кэше." #. type: Title === #: documentation/content/en/articles/vm-design/_index.adoc:346 #, no-wrap msgid "In your section on page table optimizations, can you give a little more detail about pv_entry and vm_page (or should vm_page be vm_pmap-as in 4.4, cf. pp. 180-181 of McKusick, Bostic, Karel, Quarterman)? Specifically, what kind of operation/reaction would require scanning the mappings?" msgstr "" "В вашем разделе об оптимизации таблицы страниц, не могли бы вы более " "подробно рассказать о pv_entry и vm_page (или vm_page должна быть vm_pmap-" "как в 4.4, cf. pp. 180-181 of McKusick, Bostic, Karel, Quarterman)? А именно " "какое действие/реакцию должно потребоваться для сканирования отображений?" #. type: Plain text #: documentation/content/en/articles/vm-design/_index.adoc:350 msgid "" "A `vm_page` represents an (object,index#) tuple. A `pv_entry` represents a " "hardware page table entry (pte). If you have five processes sharing the " "same physical page, and three of those processes's page tables actually map " "the page, that page will be represented by a single `vm_page` structure and " "three `pv_entry` structures." msgstr "" "`vm_page` представляет собой пару (object,index#). `pv_entry` является " "записью из аппаратной таблицы страниц (pte). Если у вас имеется пять " "процессов, совместно использующих одну и ту же физическую страницу, и в трёх " "таблицах страниц этих процессов на самом деле отображается страница, то " "страница будет представляться одной структурой `vm_page` и тремя структурами " "`pv_entry`." #. type: Plain text #: documentation/content/en/articles/vm-design/_index.adoc:353 msgid "" "`pv_entry` structures only represent pages mapped by the MMU (one `pv_entry` " "represents one pte). This means that when we need to remove all hardware " "references to a `vm_page` (to reuse the page for something else, page it " "out, clear it, dirty it, and so forth) we can simply scan the linked list of " "pv_entry's associated with that vm_page to remove or modify the pte's from " "their page tables." msgstr "" "Структуры `pv_entry` представляют страницы, отображаемые MMU (одна структура " "`pv_entry` соответствует одной pte). Это означает, что, когда нам нужно " "убрать все аппаратные ссылки на `vm_page` (для того, чтобы повторно " "использовать страницу для чего-то ещё, выгрузить её, очистить, пометить как " "грязную и так далее), мы можем просто просмотреть связный список структур " "`pv_entry`, связанных с этой `vm_page`, для того, чтобы удалить или изменить " "pte из их таблиц страниц." #. type: Plain text #: documentation/content/en/articles/vm-design/_index.adoc:360 msgid "" "Under Linux there is no such linked list. To remove all the hardware page " "table mappings for a `vm_page` linux must index into every VM object that " "_might_ have mapped the page. For example, if you have 50 processes all " "mapping the same shared library and want to get rid of page X in that " "library, you need to index into the page table for each of those 50 " "processes even if only 10 of them have actually mapped the page. So Linux " "is trading off the simplicity of its design against performance. Many VM " "algorithms which are O(1) or (small N) under FreeBSD wind up being O(N), " "O(N^2), or worse under Linux. Since the pte's representing a particular " "page in an object tend to be at the same offset in all the page tables they " "are mapped in, reducing the number of accesses into the page tables at the " "same pte offset will often avoid blowing away the L1 cache line for that " "offset, which can lead to better performance." msgstr "" "В Linux нет такого связного списка. Для того, чтобы удалить все отображения " "аппаратной таблицы страниц для `vm_page`, linux должен пройти по индексу " "каждого объекта VM, который _может_ отображать страницу. К примеру, если у " "вас имеется 50 процессов, которые все отображают ту же самую динамическую " "библиотеку и хотите избавиться от страницы X в этой библиотеке, то вам нужно " "пройтись по индексу всей таблицы страниц для каждого из этих 50 процессов, " "даже если только 10 из них на самом деле отображают страницу. Так что Linux " "использует простоту подхода за счет производительности. Многие алгоритмы VM, " "которые имеют сложность O(1) или (N малое) во FreeBSD, в Linux приобретают " "сложность O(N), O(N^2) или хуже. Так как pte, представляющий конкретную " "страницу в объекте, скорее всего, будет с тем же смещением во всех таблицах " "страниц, в которых они отображаются, то уменьшение количества обращений в " "таблицы страниц по тому же самому смещению часто позволяет избежать " "разрастания кэша L1 для этого смещения, что приводит к улучшению " "производительности." #. type: Plain text #: documentation/content/en/articles/vm-design/_index.adoc:362 msgid "" "FreeBSD has added complexity (the `pv_entry` scheme) to increase performance " "(to limit page table accesses to _only_ those pte's that need to be " "modified)." msgstr "" "Во FreeBSD введены дополнительные сложности (схема с `pv_entry`) для " "увеличения производительности (уменьшая количество обращений _только_ к тем " "pte, которые нужно модифицировать)." #. type: Plain text #: documentation/content/en/articles/vm-design/_index.adoc:366 msgid "" "But FreeBSD has a scaling problem that Linux does not in that there are a " "limited number of `pv_entry` structures and this causes problems when you " "have massive sharing of data. In this case you may run out of `pv_entry` " "structures even though there is plenty of free memory available. This can " "be fixed easily enough by bumping up the number of `pv_entry` structures in " "the kernel config, but we really need to find a better way to do it." msgstr "" "Но во FreeBSD имеется проблема масштабирования, которой нет в Linux, потому " "что имеется ограниченное число структур `pv_entry`, и это приводит к " "возникновению проблем при большом объёме совместно используемых данных. В " "этом случае у вас может возникнуть нехватка структур `pv_entry`, даже если " "свободной памяти хватает. Это может быть достаточно легко исправлено " "увеличением количества структур `pv_entry` при настройке, но на самом деле " "нам нужно найти лучший способ делать это." #. type: Plain text #: documentation/content/en/articles/vm-design/_index.adoc:369 msgid "" "In regards to the memory overhead of a page table verses the `pv_entry` " "scheme: Linux uses \"permanent\" page tables that are not throw away, but " "does not need a `pv_entry` for each potentially mapped pte. FreeBSD uses " "\"throw away\" page tables but adds in a `pv_entry` structure for each " "actually-mapped pte. I think memory utilization winds up being about the " "same, giving FreeBSD an algorithmic advantage with its ability to throw away " "page tables at will with very low overhead." msgstr "" "Что касается использования памяти под таблицу страниц против схемы с " "`pv_entry`: Linux использует \"постоянные\" таблицы страниц, которые не " "сбрасываются, но ему не нужны `pv_entry` для каждого потенциально " "отображаемого pte. FreeBSD использует \"сбрасываемые\" таблицы страниц, но " "для каждого реально отображаемого pte добавляется структура `pv_entry`. Я " "думаю, что использование памяти будет примерно одинакова, тем более что у " "FreeBSD есть алгоритмическое преимущество, заключающееся в способности " "сбрасывать таблицы страниц с очень малыми накладными расходами."