Перейти к основному содержанию
Рецепты Linux

Main navigation

  • Основы
  • Система
  • Команды
  • Программы
  • Дистро
  • Интерфейсы
  • Устройства
  • Доки
User account menu
  • Войти

Строка навигации

  1. Главная
  2. Linux: Введение
  3. Конфигурационные файлы

Проектирование свойств системы

Операционная система, позволяющая задействовать все возможности компьютера, резко отличается от специализированного программного обеспечения огромным числом т. н. «вариантов использования» (use cases) и обширнейшими возможностями тонкой настройки для решения задач конкретного пользователя наилучшим способом. Достаточно сравнить какую-нибудь игровую приставку (например, PlayStation2) под управлением собственной операционной системы и её же под управлением Linux. Вычислительная и мультимедийная мощность такого копьютера весьма высока (известно, что именно компьютерные игры определяют сейчас ресурсопотребление персонального компьютера). Однако способы управления одной и другой системами настолько различны, что неподготовленный человек просто теряется при виде возможностей Linux: где? на какие кнопки нажимать? А кнопок-то и нет...

Можно попытаться описать операционную систему как большой и сложный универсальный инструмент решения любых задач. Предполагается, что пользователь, прочтя документацию, в которой описывается как работает система и как применять её в различных ситуациях, сможет решать и свои задачи. Правда, для этого ему придётся прочесть большую часть документации по системе (в том числе и технической) и перепрограммировать некоторые части системы сообразно своим нуждам. На такой подвиг способны немногие, времени это займёт немало, да и вероятность ошибки (которая тем выше, чем сложнее средства управления системой) при таком подходе недопустимо велика. Сами утилиты или службы Linux, каждую из которых можно «окинуть взором» и понять, что и как она умеет, и чего в ней не хватает, разрабатываются именно теми из пользователей, у которых хватает времени, знаний и навыков на такое полное освоение (см. лекцию Политика свободного лицензирования. История Linux: от ядра к дистрибутивам). Вывод: пользователь — не разработчик, ему всё-таки важнее быстро и качественно решить задачу, чем долго и качественно улучшать инструмент решения.

Можно пойти обратным путём: попытаться предусмотреть все основные способы использования операционной системы на всех основных пользовательских задачах, и на каждый такой способ создать (запрограммировать) отдельную часть, управляемую «кнопкой» или утилитой. Эту часть обычно называют «решением» (solution), и в документации обычно пишут, что должно быть «на входе» системы, и что получается «на выходе» после применения решения. Если пользователь не умеет сам поставить задачу, или делает это в неопределённой форме («хочу, чтобы был текст», «хочу, чтобы играла музыка»), этот способ работает на ура: та же игровая приставка — это отличное решение крайне неопределённой задачи «хочу без толку потратить время». Однако, стоит пользователю захотеть чего-то конкретного, начинаются трудности. Трудности могут быстро стать непреодолимыми, как только для этого «конкретного» не окажется готового решения: внутренняя структура систем, ориентированных на «решения», столь сложна и столь плохо документирована, что сделать что-либо вручную, скорее всего, не удастся. Вывод: пользователь, понимающий суть собственных задач, — не «клиент», он должен иметь возможность быстро и качественно решать задачи самостоятельно, а не выбирать то из готовых «решений», которое нанесёт меньше вреда.

Что же нужно идеальному — достаточно подготовленному, чтобы действовать самостоятельно, и достаточно занятому, чтобы не переделывать системы — пользователю? По-видимому, механизм, с помощью которого можно сформулировать и придать операционной системе все требуемые свойства, имея возможность описывать решение задачи по крайней мере на том же уровне конкретности, на котором было поставлено её условие. Большая часть других, не нужных для решения собственных задач пользователя, свойств должны быть «стандартными» и не требовать его вмешательства.

Профиль системы

Так возникает идея разделить систему на два подмножества: профиль и реализацию. Всё, что не потребует вмешательства пользователя, необходимо запрограммировать и использовать в готовом виде в качестве составных частей реализации. В Linux этому соответствуют программы и подпрограммы: ядро, модули, демоны, утилиты; используемые ими библиотеки и прочие разделяемые файлы и т. п. Реализация — это монолитная, неизменяемая часть системы, устроенная по типу «решений» основных задач, только задачи эти, как правило, не совпадают с задачами пользователей, а только помогают решать их, являясь как бы строительным материалом, деталями и инструментами сборки «больших» решений.

Всё, чего может коснуться рука человека, из реализации переносится в профиль системы. Профиль задаёт поведение реализации на данных пользователя, и должен быть устроен так, чтобы пользователь мог его беспрепятственно изменять, если понадобится. С одной стороны, это может быть вариант «высокоуровневого программирования», когда пользователь описывает алгоритм решения и структуру используемых данных на некотором высокоуровневом языке (специализированном или общем, например, на shell). С другой стороны задание свойств может превращаться в указание модификаторов поведения, когда пользователь просто перечисляет необходимые параметры работы программы, которые изменяют её заранее известную, но достаточно общую функциональность.

Таким образом система полностью описывается в виде набора необходимых компонентов реализации, активизированных (запущенных) с определёнными профилями, вкупе с текущим состоянием каждого компонента. Поскольку компонент реализации не может изменяться, а его текущее состояние, наоборот, меняется постоянно и не управляется пользователем, можно считать, что систему задаёт её профиль. Это означает, что для того, чтобы продублировать работу ситемы на другом компьютере, достаточно установить там стандартную реализацию и перенестипрофиль (обычно занимающий несравненно меньше места) и пользовательское наполнение. Наполнение (файлы пользователей, содерживое www-страниц и т. п.) может занимать много места, но оно входит в понятие «задача прользователя», поэтому забывать о нём нельзя.

профиль
Изменяемая часть системы, задающая её поведение во время работы.

Как проще всего создать профиль, если не всей системы, то хотя бы её компонента (программы)? Один из вариантов такой: снабдить программу функцией «сохранить настройки», тогда можно будет эту программу запустить, любым способом добиться её работоспособности, а после зафиксировать достигнутое состояние с помощью этой функции. При этом по началу совершенно неважно, как выглядят эти настройки: программа-то заработала, значит, цель достигнута (проницательный Мефодий немедленно заметил, что название функции «сохранить настройки» как-то подозрительно похоже на название кнопки).

Зачастую для того, чтобы собрать более или менее отвечающий требованиям пользователя профиль, задействуется больше ресурсов, чем для работы самой программы. Утилита автоматической настройки выглядит эдаким шаманом, или кудесником, который, задав всего несколько вопросов человеку, невесть как приводит систему в работоспособное состояние. Такая подсистема и называется-то «wizard», причём в русском переводе её отчего-то стесняются называть «шаманом», а величают уважительно «мастером». Вот пример поведения обычного шамана-настройщика (пакет wvdial, заведующий модемным подключением к Internet):

[root@localhost root]# wvdialconf 
 Usage: wvdialconf <configfile-name>
        (create/update a wvdial.conf file automatically)
[root@localhost root]# wvdialconf .wvdialrc
 Scanning your serial ports for a modem.
 Port Scan<*1>: Scanning ttyS4 first, /dev/modem is a link to it.
  . . .
 ttyS4<*1>: Modem Identifier: ATI -- Xircom CardBus 10/100+Modem 56 (Revision 2.40)
  . . .
 ttyS4<*1>: ATQ0 V1 E1 S0=0 &C1 &D2 +FCLASS=0 -- OK
 ircomm0<*1>: ATQ0 V1 E1 -- failed at 9600 and 19200 baud.
  . . .
 ircomm9<*1>: ATQ0 V1 E1 -- failed at 9600 and 19200 baud.
 Port Scan<*1>: LT0  
  . . .
 ttyS0<*1>: ATQ0 V1 E1 -- and failed too at 115200, giving up.
  . . .
 ttyS1<*1>: ATQ0 V1 E1 -- and failed too at 115200, giving up.
 Port Scan<*1>: S2   S3   S5   S6   S7   S8   S10  
  . . .
 Port Scan<*1>: USB11 USB12 USB13 USB14 USB15 
 Found a modem on /dev/ttyS4, using link /dev/modem in config.
 Modem configuration written to .wvdialrc.
 ttyS4<Info>: Speed 115200; init "ATQ0 V1 E1 S0=0 &C1 &D2 +FCLASS=0"

Пример 1. Кудесник wvdialconf

Даже ни о каких наводящих вопросах речи не зашло! Программа проверила более полусотни устройств, не модемы ли они, но нашла всего одно — /dev/ttyS4. Его настройки определились автоматически (и хорошо, потому что Мефодий не знает, что такое «ATQ0 V1 E1 S0=0 &C1 &D2 +FCLASS=0»). Профиль (а wvdialrc создаёт именно профиль) лежит теперь в файле .wvdialrc, так что программа wvdial начнёт работать с модемом, нуждаясь только в пользовательских настройках (входное имя, пароль и т. п.).

Яркий пример того, как элементы реализации связываются профилем в единую подсистему для решения определённой задачи — командная строка и сецнарии командного интерпретатора. Здесь утилиты играют роль элементов реализации, их параметры — роль «настроечной» части профиля, а способ их объединения в сценарий — «программируемой» части профиля. Скажем, команда find /etc -type f 2> /dev/null | xargs -n1 file | cut -d: -f2 | sort | uniq -c задействует шесть утилит системы: командную оболочку, find, xargs, cut, sort и uniq, причём четыре из них запускаются с изменённым профилем.

Эта команда определяет, файлы какого типа и в каком количестве содержатся в каталоге /etc.

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

Конфигурационный файл

Задание профиля с помощью командной строки — метод далеко не всегда удобный. Даже при работе с самой командной строкой используется окружение для сохранения настроек, чтобы не задавать их всякий раз и для всякой команды. Что уж говорить о сложных системных службах, свойства которых должны сохраняться не от сеанса к сеансу, а постоянно (в том числе при перезагрузке системы). Вывод прост: профиль необходимо держать в файле, вроде того, что создаётся по команде «сохранить настройки».

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

конфигурационный файл
Текстовый файл, содержащий настройки какой-нибудь части системы (утилиты, демона и т. п.). Как правило, считывается ею при запуске. Типичный для Linux способ организации профиля.

Одним словом, если есть конфигурационный файл, то должны быть и средства редактирования этого файла. Учитывая то, что в Linux есть высокоразвитая система хранения и переработки (как ручной, так и автоматической) данных в текстовом виде, изобретать какой-то новый формат не лучше, чем изобретать новый велосипед. Тем более, что именно текст, разделённый на строки и слова, лучше всего подходит тогда, когда есть чёткое деление профиля на объекты управления и их свойства (например, настройки какого-нибудь демона и значения этих настроек). Вдобавок именно со структурированными текстами отменно управляются текстовые редакторы Linux: Vi, Emacs и др.

methody@localhost:~ $ cat .vimrc
 so $VIMRUNTIME/vimrc_example.vim
 " Some mappings
 map <F2> :wall!^M
 map! <F2> ^O:wall!^M
 " Tune up
 set shiftwidth=2 tabstop=8 history=200 viminfo='50
 set showmode showmatch showcmd ruler modeline
 set autoindent ignorecase smartcase
 set nohlsearch noincsearch
 set dir=/var/tmp
 set wildmode=list:longest,full
 set wildmenu
 " Colouring
 syntax on
 colorscheme desert

Пример 2. Настройки редактора vim

Вот как выглядит конфигурационный файл для Vi, написанный Мефодием на основе взятого у Гуревича. Легко заметить, что файл состоит из команд режима командной строки Vi с комментариями (в отличие от большинства утилит Linux, в Vi комментарии начинаются на «"»). Символы «^O» и «^M» — это именно соответствующие управляющие символы (вставленные в текстовый файл с помощью «^V», см. лекцию Текстовые редакторы). Такой конфигурационный файл легко понимать и изменять.

Как уже было замечено, набор переменных окружения составляет особенный профиль, к которому чувствительны все запускаемые программы — в этом его достоинство. Задаются переменные окружения обычно в командном сценарии, который тоже можно рассматривать как конфигурационный файл). Например, во многих дистрибутивах используется конфигурационный файл .i18n для настройки языковых особенностей клавиатуры, языка вывода сообщений и т. п.:

methody@localhost:~ $ cat .i18n 
 LANG=ru_RU.KOI8-R
 LANGUAGE=ru_RU.KOI8-R
 SYSFONTACM=koi8-r
 SYSFONT=UniCyr_8x16
 DICTIONARY=russian
 MPAGE="-CKOI8-R"
 export DICTIONARY MPAGE

Пример 3. Файл настройки языковых особенностей

Однако хранить настройки специфической программы (не нужные всем остальным) в окружении — не самое удачное решение: синтаксис, задающий переменную окружения, слишком прост (имя_переменной = значение), а самих переменных становится слишком много, поэтому при просмотре трудно выделить, какая из них к какой группе настроек относится. Если пытаться упаковать все настройки в значение одной переменной, это значение окажется трудночитаемым, и всё преимущество текстового формата сойдёт на нет. Например, стандартный конфигурационный файл утилиты ls (точнее, только её цветовых предпочтений) — /etc/DIR_COLORS (его можно подменить личным файлом ~/.dir_colors) занимает около ста строк вместе с комментариями. Команда ls использует не этот файл, а создаваемую утилитой dircolors переменную LS_COLORS, значене которой — 600-символьная строка безо всяких комментариев.

Если профиль слишком велик, держать его в одном конфигурационном файле — значит, доставлять пользователю сомнительное удовольствие разбирать этот файл целиком даже при необходимости внести минимальное изменение. Методов борьбы с неудобочитаемостью несколько. Во-первых, уже известный по лекции Этапы загрузки системы механизм «. d»: файл разделяется на несколько независимых друг от друга так, что редактировать приходится только один из файлов, а программа во время самонастройки считывает все.

Другой способ опирается на то, что изменения, которые пользователь вносит в профиль, как правило существенно меньше объёма всего профиля. Поэтому может быть выгодно хранить все настройки по умолчанию в каком-нибудь файле, менять который вообще не надо, а файл пользовательских настроек использовать как бы «поверх», изменяя профиль в соотвтетствии с ними после того, как выставлен профиль по умолчанию. Дополнительная выгода такого способа — в том, что пользователь всегда может подглядеть в «большой» файл, чтобы узнать как оформляется та или иная настройка. Например, утилита updfstab, которая изменяет содержимое /etc/fstab при появлении или удалении съёмного дискового носителя (например, лазерного диска), считывает данные из конфигурационного файла /etc/updfstab.conf. Сам этот файл состоит из единственной строки: include /etc/updfstab.conf.default, что приводит к чтению файла с настройками по умолчанию, где задан способ работы со многими съёмными устройствами системы. Если администратору нужно как-то изменить поведение updfstab в отношении определённого устройства, он копирует соответствующую группу настроек из updfstab.conf.default в updfstab.conf после строчки include... и исправляет их. То, что эти группы настроек читаются дважды, не играет особой роли: чтение коротких файлов выполняется быстро.

Наконец, третий способ сделать конфигурационный файл удобочитаемым — это секционирование профиля, когда все настройки разбиваются на группы, каждой группе даётся собственное имя, и синтаксис конфигурационного файла проектируется так, чтобы границы групп хорошо различались при просмотре. В сущности, этот способ — предок схемы «. d», где группе соответствует отдельный файл, однако нередки ситуации, когда разбиение на файлы неудобно (например, если группы не полностью независимы, поэтому может понадобиться редактировать их сразу и несколько). Конфигурационный файл утилиты дозвона wvdial, например, секционируется по адресату (провайдеру) плюс отдельная секция «по умолчанию». Сами секции отделяются друг от друга заголовками, заключёнными в квадратные скобки:

root@localhost:~> cat .wvdialrc 
 [Dialer Defaults]
 Modem = /dev/modem
 Baud = 115200
 Init1 = ATZ
 Init2 = ATQ0 L0 M4 V1 E1 S0=0 &C1 &D2 +FCLASS=0
 Auto DNS = on
 Modem Type = Analog Modem

 [Dialer hotspace]
 Phone = 0123456
 Username = fireman
 Password = Fire!Fire!
 TOnline = true

 [Dialer warlock]
 Phone = 0246813
 Username = cop-120
 Password = gimmethegun
 Force Address=10.0.0.120

Пример 4. Секционированный конфигурационный файл

Утилита wvdial обладает высокоразвитым искусственным интеллектом: она самостоятельно догадывается, какой именно тип идентификации используется на сервере. Например, «с той стороны» может оказаться терминал Linux, которому требуется сначала ввести обыкновенное входное имя и пароль, затем надо получить командную строку, затем запустить на сервере сетевой демон pppd, и только затем запустить pppd на собственной машине. Другой вариант: pppd на сервере уже запущен, а настройки «Username» и «Password» означают идентификационную информацию протокола CHAP, используемого pppd. Обо всём этом и о многом другом wvdial умеет догадываться, как wvdialconf умел определять, какое же из устройств — модем.

Однако на любой искуственный интеллект найдется непостижимая ему жизненная ситуация. На одном из серверов (секция «Dialer hotspace») тоже стоит программа с зачатками искуственного интеллекта, которая тоже пытается определить, каким способом хочет идентифицироваться позвонивший. Оттого эти два кудесника, созвонившись, всё ждут, пока кто-нибудь не проявит себя... Помогает настройка TOnline, которая заставляет wvdial немедленно использовать протокол ppp, на что сервер, подумавши «ах, ppp!», с облегчением запускает pppd. Остаётся вопросом: почему эта полезная настройка никак не отражена в документации (её нашёл в исходных текстах программы Гуревич)? Не потому ли, что пара wvdialconf-wvdial не по Linux-овски стремится всё делать за пользователя, а стало быть, пользовательская документация для разработчиков этой программы — не главное?..

Идею чтения настроек по умолчанию можно развить чуть дальше. Оказывается, бывает удобно, когда описание настройки помещено не в руководство, а непосредственно в конфигурационный файл в виде комментариев. Тогда при изменении этой настройки пользователь сразу видит, что она из себя представляет, при этом отпадает необходимость сначала находить строчку в файле, а потом искать её же в руководстве. Такой способ оформления называется самодокументированием профиля и часто используется. Например, файл /etc/man.conf, управляющий работой команды man, оформлен в самодокументированном стиле: 

methody@localhost:~ $ cat /etc/man.conf
  . . .
 # NOCACHE keeps man from creating cache pages ("cat pages")
 # (generally one enables/disable cat page creation by creating/deleting
 # the directory they would live in - man never does mkdir)
 #
 # NOCACHE
 # The command "man -a xyzzy" will show all man pages for xyzzy.
 # When CMP is defined man will try to avoid showing the same
 # text twice. (But compressed pages compare unequal.)
 #
 CMP             /usr/bin/cmp -s
  . . .

Пример 5. Самодокументированный конфигурационный файл

Мефодий, может быть, и не понял бы сразу, зачем команде man использовать утилиту cmp, однако в поясняющем комментарии написано: когда нужно показать несколько руководств разом, предварительно они сравниваются, и показываются только несовпадающие.

Если пойти ещё дальше, то можно создать несколько различных файлов с примерами настроек, чтобы пользователь мог взять один из них и довести до нужного ему состояния. Именно такую — демонстрационную — настройку Мефодий и включил в качестве настройки по умолчанию в свой .vimrc (в первой строке). Кстати, на самом деле профиль Vi весьма сложен, но большинство его настроек по умолчанию находятся в различных файлах дерева каталогов /usr/share/vim — эдакая «схема. d/. d», где файлы профиля, соответствующие подгруппам настроек, лежат в подкаталогах, соответствующих группам. Включение определённого настроечного файла может происходить неявно: например, строчка colorscheme desert из .vimrc приводит к чтению /usr/share/vim/colors/desert.vim.

Конфигурационные файлы могут иметь довольно замысловатый синтаксис, если соответствуют сложным структурам данных (таковы, например, настройка irc-клиента irssi) или содержать в себе дополнительные средства самодокументиования (например, файл настройки текстового www-броузера lynx не просто хорошо документирован, но и размечен теми же средствами, какие используются в самом броузере для представления HTML).

Изменение конфигурационных файлов

Как правило, конфигурационный файл считывается программой при запуске, отражая, таким образом, её состояние на момент старта. Изменения настроек работающей программы в конфигурационном файле, как правило, не отражаются. Тому есть несколько причин: не стоит превращать файл, изредка редактируемый пользователем, в файл, изменение которого происходит постоянно; не стоит держать конфигурационный файл всегда открытым; тяжело, изменяя файл автоматически, не испортить структуру комментариев (интерпретируемых не машиной, а пользователем) и т. д. Впрочем, многие утилиты, особенно использующие графическую среду, могут записывать настройки в файл по окончании работы. Большинство конфигурационных файлов весьма удобно редактировать вручную, с помощью Vi или Emacs (для файлов более или менее похожих используется общая подсветка синтаксиса, а для наиболее популярных есть и собственные варианты подсветки).

В /etc хранятся настройки системных служб, в том числе настройки по умолчанию, настройки по умолчанию пользовательских утилит, профили командных интерпретаторов, а также настройки, используемые в процессе загрузки системы (например, modules.conf). Там же располагаются и стартовые сценарии, о которых рассказано в лекции Этапы загрузки системы. Чего не стоит искать в /etc, так это разнообразных примеров настройки той или иной службы. Считается, что пример — это часть документации, и их стоит помещать, например, в /usr/share/doc/название_службы/examples.

Файлы, имеющие отношение к процессу досистемной загрузки, обычно лежат не там, а в /boot, это стоит иметь в виду, так как /boot/grub/menu.lst — тоже часть профиля системы, хотя и довольно специфическая. В профиль системы входит содержимое каталогов etc из т. н. «песочниц», расположенных обычно в /var/lib.

Смысл термина «песочница» вот в чём. В Linux есть замечательный системный вызов chroot() и использующая его утилита chroot, формат командной строки которой chroot каталог команда. Эта утилита запускает команду, изменив окружение таким образом, что та считает каталог — корневым. Соответственно, все подкаталоги каталога кажутся команде каталогами первого уровня вложенности, и т. д. Если необходимо во что бы то ни стало ограничить область действия некоторой утилиты (например, по причине её небезопасности), можно запускать её с помощью chroot. Тогда, даже имея права суперпользователя, эта утилита получит доступ только к каталогу и его подкаталогам, а /etc и прочие важные части системы окажутся в неприкосновенности. Сам каталог как раз и играет роль «песочницы», в которую утилиту «пустили поиграть», позволяя вытворять что угодно. Часто бывает, что в песочнице есть и свой каталог etc, содержащий необходимые для запуска утилиты (или системной службы) настройки. Вот этот-то etc из «песочницы» также входит в список каталогов, хранящих профиль системы.

В /etc могут находиться не только файлы, но и подкаталоги (особенно в стиле «. d») и целые поддеревья каталогов. Например, в некоторых дистрибутивах Linux используется подкаталог /etc/sysconfig. Этот каталог создаётся и заполняется файлами при установке системы или при запуске специального «конфигуратора» — программы-кудесника, задающей наводящие вопросы. Некоторые стартовые сценарии, использующие полученные настройки, также лежат в этом каталоге или его подкаталогах. Если в системе есть каталог /etc/sysconfig, там должны оказаться настройки, относящиеся не к самим службам или утилитам, а к способу их запуска при загрузке, а также языковые и сетевые настройки, тип мыши и т. д.

Перекрёстные ссылки книги для Проектирование свойств системы

  • Конфигурационные файлы
  • Вверх
  • Системные конфигурационные файлы

Book navigation

  • Предисловие
  • Сеанс работы в Linux
  • Терминал и командная строка
  • Структура файловой системы
  • Работа с файловой системой
  • Доступ процессов к файлам и каталогам
  • Права доступа
  • Работа с текстовыми данными
  • Возможности командной оболочки
  • Текстовые редакторы
  • Этапы загрузки системы
  • Работа с внешними устройствами
  • Конфигурационные файлы
    • Проектирование свойств системы
    • Системные конфигурационные файлы
    • Конфигурационные файлы в домашнем каталоге
  • Управление пакетами
  • Сеть TCP/IP в Linux
  • Сетевые и серверные возможности
  • Графический интерфейс (X11)
  • Прикладные программы
  • Политика свободного лицензирования

Последние материалы

  • Файловый менеджер Thunar
    11 hours ago
  • Эмулятор терминала Terminator
    5 days 12 hours ago
  • Приложение scanimage
    1 week 4 days ago
  • Утилита sensors
    2 weeks 1 day ago
  • Сканер Rkhunter
    3 weeks 2 days ago
RSS feed

Secondary menu

  • О проекте

© 2008–2025 Олег Меньшенин mensh@yandex.ru