LINUX.ORG.RU

Как заставить Debian работать из RAM

 , , , ,


2

2

Итак, я продолжаю «искать свой святой Грааль» - метод загрузки полноценной custom-системы Debian целиком в RAM. Сперва пытался сделать это путем помещения всей системы в initramfs - все заработало, да только большая система (с GUI и кучей приложений) не грузится (после загрузки ядра начинает грузить initramfs и выдает Invalid argument - при этом такой же Дебиан но без GUI и программ весом до 1 ГБ грузит в RAM в составе initramfs без проблем: по всей видимости, где то ограничение на размер initramfs зашито в ядре, туда лезть у меня не хватит, боюсь, знаний).

Тогда я решил поместить в RAM систему другим путем, который в общих чертах описан здесь: https://habr.com/ru/post/253759/

Чтобы не заставлять Вас бродить по ссылкам, приведу основные точки способа:

1. Меняем конфигурацию initramfs, отключая проверку кФС (здесь и далее - обозначение корневой ФС) и стандартное монтирование кФС:

# checkfs ${ROOT} root
# mount ${roflag} -t ${FSTYPE} ${ROOTFLAGS} ${ROOT} ${rootmnt}
а затем создаем временную точку монтирования (еще работая в пределах initramfs!) для нашего CD:
mkdir /ramboottmp
монтируем нашу кФС с CD во временную точку монтирования:
mount ${roflag} -t ${FSTYPE} ${ROOTFLAGS} ${ROOT} /ramboottmp
Создаем ФС в RAM:
mount -t tmpfs -o size=100% none ${rootmnt}
Ну и распаковываем нашу кФС (файл ram.tar.gz) в эту tmpfs:
cd ${rootmnt}
tar -zxf /ramboottmp/ram.tar.gz
umount /ramboottmp

2. Геним новый initramfs:

/sbin/mkinitramfs -o /initrd-ram.img

3. В кФС (автор поста предлагал заходить туда из-под Live-CD, я предпочел напрямую вытащить кФС из виртуального диска .vdi - но это дело вкуса) отключаем прописанное там в /etc/fstab монтирование кФС и пишем свое:

none / tmpfs defaults 0 0

4. А затем архивируем всё из корня:

busybox tar -czf /путь-к-архиву/ram.tar.gz *

5. Создаем директорию, туда кидаем isolinux (в директории isolinux, разумеется), в эту же директорию isolinux кидаю ядро и initrd-ram.img, а ram.tar.gz кидаю в основную директорию. В isolinux.cfg прописываю:

DEFAULT MyLive
LABEL MyLive
linux /isolinux/ЯДРО
APPEND initrd=/isolinux/initrd-ram.img root=/dev/sr0 rw

6. Ну и генерирую .iso:

genisoimage -o disk.iso -b isolinux/isolinux.bin -c isolinux/boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table -J -R /полный-путь-к-директории-из-пункта-5

Указанный .iso шикарно грузится, лишь немного затупливая при заливке 1.6 ГБ в RAM - но! Сам Линукс не загружается, выдавая в конце ошибку:

No init found. Try passing init= bootarg

При этом в директории root лежит моя кФС, то есть все, что я прописывал в initramfs РАБОТАЕТ! Но система то не запускается...

Что я пробовал:

1. По рекомендации самой системы выполнить run-init, указав в качестве NEW_ROOT точку монтирования моей кФС (/root), а в качестве NEW_INIT - Init моей кФС (/root/sbin/init):

run-init /root /root/sbin/init
Не происходит ровным счетом НИЧЕГО. Просто заново выдает консоль initramfs'а.

2. Просто запустить init initramfs'а:

/sbin/init
Выдает:
Not activating Mandatory Access Control as /sbin/tomoyo-init does not exist. Init must be run as PID 1

3. Кончилась фантазия и обращаюсь к Форуму...

@Spoofing, вот он тот единственный человек, которому интересны твои радикальные взгляды. Ты уж оттянись, чтоб нам с тобой следующую пару лет проще было.

t184256 ★★★★★ ()

Я не понял цели всего вот этого - это для повседневного использования планируется?

Если да, то проще ssd купить хороший и не парится…

ololoid ★★★★ ()
Ответ на: комментарий от t184256

Да как Вам сказать… Радикальность - понятие контекстное. Если речь о СПОСОБЕ построения Live-системы - то я ищу самы ПРОСТОЙ. Но использование скриптов для построения таких систем, принципы работы которых я не понимаю - тупиковый путь, ибо уже сталкивался неоднократно, что они далеко не всегда работают корректно. А разбираться с тем же live-build ДЕТАЛЬНО, скрипт за скриптом - так это, согласитесь, вовсе не легче, чем пытаться запихнуть тупо все в RAM или даже сразу в initramfs.

Ну а если радикализмом считать саму работу в RAM - то тут есть нюансы. И, поверьте, есть ряд задач, где работа в RAM - единственный способ спать спокойно.

dima9kin ()
Ответ на: комментарий от ololoid

Повторюсь - принципиальна работа в RAM как таковая, а вовсе не быстродействие или экономия ресурса копеечного SSD. Причины есть, я не хотел бы их озвучивать - тем более в рамках данного Форума они совершенно не принципиальны.

dima9kin ()
Ответ на: комментарий от dima9kin

Радикализм в том, что спуфи считает это единственно верным способом запуска, для всех задач, всегда. Никакого попсового erase my darlings, никаких полумер, все в tmpfs, только хардкор.

К вашему сообщению претензий нет, если разве что не считать отсутствия пояснений, чем стандартные способы изготовки Debian Live не подошли.

t184256 ★★★★★ ()
Последнее исправление: t184256 (всего исправлений: 1)
Ответ на: комментарий от dima9kin

А разбираться с тем же live-build ДЕТАЛЬНО, скрипт за скриптом - так это, согласитесь, вовсе не легче, чем пытаться запихнуть тупо все в RAM или даже сразу в initramfs

Не соглашусь. Он заработает сразу, а магии под капотом в линуксе и так полно. От того, что вместо ваших костыликов будет поддерживаемая другими заведомо рабочая схема вам не убудет.

Вот если конкретные ограничения всплывут, тогда другой разговор.

t184256 ★★★★★ ()
Ответ на: комментарий от dima9kin

Причины есть, я не хотел бы их озвучивать

Вот это вдвойне странно звучит.

ololoid ★★★★ ()
Ответ на: комментарий от t184256

А я пояснил - использовать скрипты a la live-build как «черный ящик» - мне не подходит, это путь в никуда. А разобрать эти скрипты подробно - это колоссальный труд, который намного сложнее тех путей, что я выбрал.

dima9kin ()

Кончилась фантазия…

А пока, банально раcпакуй инитрд и посмотри хотя-бы, что у него внутри. Хотя-бы скрипт init. И прочие скрипты, связанные с загрузкой. Например, параметр «toram». Другие параметры, касаемые «живой системы». Зачем тебе вообще возня с исо-образом вообще и с isolinux в частности.

andytux ★★★★ ()

No init found. Try passing init= bootarg

Вы уже пробовали найти это сообщение в исходниках live-initramfs или initramfs-tools и проследить, какие проверки происходят, прежде чем его выдать, после чего исправить те части Вашего кода, чтобы эти проверки проходили?

Если нет, почему?

run-init /root /root/sbin/init

/sbin/init

Всё это сработает только в том случае, если

  1. Ваш шелл имеет PID 1
  2. Вы используете exec, чтобы запускаемый процесс init тоже был PID 1.

Причём на это есть только одна попытка, потому что ядро уйдёт в панику после того, как PID 1 упадёт с ошибкой. После этого придётся перезагружаться и начинать с нуля.

А разбираться с тем же live-build ДЕТАЛЬНО, скрипт за скриптом - так это, согласитесь, вовсе не легче, чем пытаться запихнуть тупо все в RAM или даже сразу в initramfs.

Вам всё равно уже сейчас приходится детально разбираться в скриптах, потому что Вы ими же и пользуетесь для запуска своего live CD. Либо крестик снимите (и соберите ядро и initramfs руками, полностью, с нуля, не полагаясь на скрипты из live-initramfs), либо трусы наденьте (и используйте документированные способы собирать носители, которые работают на live-initramfs, т.е. live-build).

anonymous ()
Ответ на: комментарий от dima9kin

мне не подходит, это путь в никуда

Сходи прочитай исходники для начала своей системы инициализации, потом ядра. Как разупорешься — возвращайся, авось и аргумент какой придумаешь вместо вот этого вот.

t184256 ★★★★★ ()
Ответ на: комментарий от t184256

Ну, возможно, я просто дважды обжигался - сперва с respin, потом с Linux Live Kit - они тупо не делали Debian 11 (при том, что 9-ый и 8-ой они резали на ура). Это достаточно обидно - сперва целый день делать в виртуалке систему, вылизывать ее, все кнопочки и прочее настраивать - а потом тупо все это не суметь закатать в Live-CD. Возможно, live-build это крутой продукт без подобных косяков - но проверять я уже, простите, не хочу… Отбило охоту. Хочется понимания почему что то работает, а почему нет. Я не думаю, что это преступление.

dima9kin ()
Ответ на: комментарий от dima9kin

Нет, конечно, это опенсорс и ты волен делать вообще что угодно!

Но дело в том, что от этого несколько меняются правила задавания вопросов: если ты задался целью сознательно переизобрести колесо не используя инструментов, кроме кисточки «белочка», то «а че это оно не едет» внезапно уже не котируется. Придётся очень много разбираться самому и задавать только очень узко очерченные и точные вопросы. Такие дела =(

t184256 ★★★★★ ()
Ответ на: комментарий от anonymous

Вот, наконец, совет и ПО ДЕЛУ появился. Сейчас пойду смотреть, спасибо!

dima9kin ()
Ответ на: комментарий от t184256

Так я, вроде, и не просил разжевать мне и дать подробную инструкцию вида «нажми сюда и введи то то и то то». Напротив, я от таких инструкций бегу сознательно. Я лишь попросил дать какую то наводку, мысль - в какую сторону посмотреть.

Странно, что это все здесь восприняли как преступление. Ну, разве что кроме одного anonymous’a :)

dima9kin ()
Ответ на: комментарий от t184256

erase my darlings

Ты бы хоть ссылку дал. А то ведь никто, кроме 2,5 регистрантов, не поймёт, о чём речь.

sudopacman ★★★★★ ()
Ответ на: комментарий от dima9kin

Исо нужен, только если действительно нужно нарезать его на болванку. В остальных случаях от исо только лишние сложности, ограничения.

обидно - сперва целый день делать в виртуалке систему, вылизывать ее, все кнопочки и прочее настраивать - а потом тупо все это не суметь закатать в Live-CD…

Все проще…

andytux ★★★★ ()
Ответ на: комментарий от andytux

Так его и нужно нарезать на болванку. Работа ведется ИСКЛЮЧИТЕЛЬНО с носителем, неизменность которого может быть гарантирована ФИЗИЧЕСКИ.

За ссылку очень благодарен, изучаю.

dima9kin ()
Ответ на: комментарий от dima9kin

Работа ведется ИСКЛЮЧИТЕЛЬНО с носителем, неизменность которого может быть гарантирована ФИЗИЧЕСКИ.

А обязательно рассыпающегося от солнечного света или можно SD-карту с задвинутой задвижкой?

t184256 ★★★★★ ()
Ответ на: комментарий от t184256

Вся проблема в том, что физически задвижка SD-карты далеко не всегда защищает ее от записи - я так встрял один раз. А потом не раз замечал. Раньше был уверен, что там физически ножка, ответственная за запись размыкается этой задвижкой - пока не убедился, что это, увы, отнюдь не так. Поэтому я других защищенных носителей кроме CD/DVD/BR не знаю. Ну, хотя если именно в RAM систему помещать - то можно и на SD и даже на простой флешке: там загрузился и (в отличии от классической Live-системы!) можно носитель извлечь еще до того, как подцепится сеть и, как следствие, возникнет вектор для атаки на систему. Но для этого, опять таки, нужно сперва поместить систему в RAM - а от этого все меня прям дюже активно отговаривают :)

dima9kin ()
Ответ на: комментарий от anonymous

Невероятно благодарен тебе, Anonymous! Ковыряясь там, куда ты мне указал - я обнаружил ошибку (она была наитупейшая: отсутствовал Init основной системы) и все заработало. Теперь система весом 1,6 ГБ c GUI, Офисом, кучей приложений шикарно грузится в RAM. Приложения, кстати, действительно, стартуют настолько быстро, словно они просто свернуты в трее. Всем, кто давал советы по делу - также огромное спасибо. В планах теперь все таки разобрать initramfs (на досуге) и попытаться понять как собирать его ПРОСТЕЙШИЙ РАБОЧИЙ вариант самостоятельно, без привлечения скриптов mkinitramfs.

dima9kin ()
Ответ на: комментарий от dima9kin

Если речь о СПОСОБЕ построения Live-системы - то я ищу самы ПРОСТОЙ.

@dima9kin, самый простой состоит из четырёх компонентов:

  1. ядро linux
  2. initrd, отличается от обычного тем что там перед mount делают cat rootfs.img>/dev/zram0
  3. раздел с известным UUID
  4. rootfs.img на этом разделе.

Человек ты вроде образованный, что и как делать вроде как должен понять.

torvn77 ★★★★★ ()

И, кстати, напоследок для скептиков технологии «система-в-RAM» отмечу, что только она позволяет (теоретически пока) запилить «стерильную» систему на телефонах Android: загрузил кФС с SD-карты в RAM, вытащил ее и - вуа ля - все данные крутятся в RAM, перезагрузка дает нам абсолютно стерильный девайс.

Да, там много нюансов, но не вижу ничего принципиально невозможного. По сути, разобраться с загрузчиком который там вместо isolinux/grub, изучить структуру initramfs/initrd, ну и посмотреть есть ли там встроенная поддержка tmpfs в ядре.

dima9kin ()
Ответ на: комментарий от torvn77

Класс! Этот способ мне кажется еще быстрее чем тот, что у меня заработал...

to 3: Причем, поскольку всегда грузимся исключительно с единственного CD-ROM - можно даже не морочиться с UUID, а просто передавать ядру root=/dev/sr0

А вот по пункту 2 есть пара вопросов (если Вас не затруднит):

а) «перед mount делают» - Вы имеете в виду указанную команду помещают в init-файл самого initrd (не init кФС, а именно в init самой initramfs), правильно я понимаю? б) команда

cat rootfs.img > /dev/zram0
как я понимаю, копирует образ кФС на блочное псевдоустройство, представляющее собой область ОЗУ. Я так понимаю, затем этот /dev/zram0 нужно подмонтировать как кФС, то есть его и нужно передавать ядру как параметр вида root=/dev/zram0? Или у меня каша в голове? в) если пункт «б» я понимаю правильно, то, выходит, файл init самого initrd упрощается до нельзя: в нем нужно только выполнить
cat rootfs.img > /dev/zram0
а потом выполнить стандартные pivot_root и chroot, так?

P.S. Sorry за вагон вопросов, просто Ваш метод действительно проще и позволяет уйти от «черного ящика» - скриптов утилиты mkinitramfs

dima9kin ()
Ответ на: комментарий от dima9kin

команду помещают в init-файл самого initrd (не init кФС, а именно в init самой initramfs), правильно я понимаю?

Да.

то есть его и нужно передавать ядру как параметр вида root=/dev/zram0?

Нет, ему передаёшь UUID раздела на котором лежит rootfs.img

То есть:
1. mount UUUID="" /mnt
2. cat /mnt/rootfs.img > /dev/zram0
3. mount /dev/zram0 /newroot
4. pivot_root бла бла /new_root

файл init самого initrd упрощается до нельзя: в нем нужно только выполнить

cat rootfs.img > /dev/zram0
а потом выполнить стандартные pivot_root и chroot

Не совсем, перед этим тебе надо загрузить нужные модули ядра и запустить команду которая вытащит в систему метки и uuid файловых систем.

torvn77 ★★★★★ ()
Последнее исправление: torvn77 (всего исправлений: 2)
Ответ на: комментарий от torvn77
  1. А, точно, блин - мы ж сперва должны сам диск подмонтировать на котором кФС лежит - а уж только потом сможем его залить в zram! Тупанул.
dima9kin ()
Ответ на: комментарий от torvn77

А если в ядре нет модулей, если все нужное попытаться включить в ядро изначально - то можно, соответственно, не загружать модули отдельно, так?

Ну и по поводу меток и UUID файловых систем не очень понял - у меня же есть только корневая ФС, ее мы благополучно подмонтировали и сделали корневой ранее, разве нет? Зачем нам еще какие то другие ФСки?

dima9kin ()
Ответ на: комментарий от dima9kin

Можно, но зачем?
Покидал в initrd нужные модули для райдконтролёров и ФС и всё.
Ну можно ещё модуль видеокарты закинуть чтобы консоль сразу была хорошей.

torvn77 ★★★★★ ()
Ответ на: комментарий от torvn77

Просто страшно звучит: загрузить модули ядра :)

Я пока ядро трогать побаиваюсь, не мой уровень, боюсь :)

Хотя, по здравому размышлению - пересобирать его со всеми модулями это тоже «трогать» - так что, выходит, Ваш вариант более правильный, почитаю как их загружать. Не боги горшки обжигают.

dima9kin ()

в инете есть пример скрипта, где скрипт передаётся как init= в качестве параметра ядра. там монтируется tmpfs, копируется туда содержимое корня, с исключениями (/proc/*, /sys/*, ...), делается туда pivot_root, перемонтируется /proc/ и /sys/, и chroot со стартом настоящего инита, с предварительным отмонтированием старого корня. там строк 10, все команды понятны. я так гружусь постоянно уже 7 лет. посмотри у меня по поиску "pivot_root"

teod0r ★★★★★ ()
Последнее исправление: teod0r (всего исправлений: 2)
Ответ на: комментарий от dima9kin

грузимся исключительно с единственного CD-ROM

А почему CDROM а не флешка?
Если у тебя криптопораноя то отмонтируй раздел посленакатывания rootfs.img и вынимай флешку из компьютера.

torvn77 ★★★★★ ()
Ответ на: комментарий от torvn77

Разумеется, с учетом того, что все сперва заливается в RAM - конечно можно так и сделать. Раньше то пользовался (и сейчас еще пока с него пишу) именно Live-системой, там доверия нет - любую опцию ro можно перемонтировать, так что там только оптические носители… Ну а по поводу криптопаранойи… Лично сталкивался с ситуацией, когда RAM очень много в моменте бонусов дал коллегам :)

dima9kin ()
Ответ на: комментарий от dima9kin

Если тебе надо то делай.
Просто ты можешь в initrc сразу после cat rootfs.img> отмонтировать флешку и запустить цикл ожидания её извлечения из компьютера.

torvn77 ★★★★★ ()
Последнее исправление: torvn77 (всего исправлений: 2)
Ответ на: комментарий от teod0r

Нашёл тот пост Ваш, сейчас внимательно его изучаю. Пока один вопрос - уже яндекс сломал искать - что за загадочный такой у Вас в этом скрипте каталог (и точка монтирования) = (знак «равно»)?

dima9kin ()
Ответ на: комментарий от Chord

Сложнее значительно, на мой взгляд, получается - а видимых преимуществ я не нашёл… Возможно, я ошибаюсь и Вы мне на них укажете

dima9kin ()
Ответ на: комментарий от dima9kin

а видимых преимуществ я не нашёл…

Возможность при необходимости сохранять изменения, сделанные в процессе сессии, налету (пересобирать образ).

Chord ★★ ()
Ответ на: комментарий от Chord

Образы, с которыми мы работаем весьма консервативны - мы, например, сейчас работаем с образом, собранным аж 2 года назад! Как правило, ПО с которым работаем не меняется годами: Офис, браузер, XMPP-клиент, некоторое специфическое ПО.

Ну а изменению подлежат ИСКЛЮЧИТЕЛЬНО документы - а работа с ними ведется удаленно, тут вообще не нужны носители с возможностью RW.

dima9kin ()
Ответ на: комментарий от t184256

Для всего есть, прежде всего, своя МОДЕЛЬ УГРОЗ. И именно с нее нужно начинать всегда разговоры о страхе и бесстрашии.

dima9kin ()
Ответ на: комментарий от dima9kin

Да, бесспорно. Но если у тебя пользователи переходят по левым ссылкам вне интранета, используя браузер двухлетней давности, ты все равно уже бесстрашен.

t184256 ★★★★★ ()
Ответ на: комментарий от dima9kin

просто = просто директорию так назвал. там типо должна быть директория /new_rooеt, а я просто у себя решил назвать /= просто на самом деле там ещё должна быть директория /old_root, у меня там не всё правильно в том скрипте в той теме. ищи оригинальный how-to с изначальной версией скрипта

teod0r ★★★★★ ()
Ответ на: комментарий от teod0r

С ходу не смог найти оригинальный how-to по поиску «pivot_root» среди Ваших сообщений. Но! Решил пойти от самого низа и для начала распаковал initramfs (точнее сразу 2 - от своей текущей системы и от стандартного Debial-Live) чтобы глянуть что там в принципе написано в init-файле (именно в init'е самого initramfs'а, а не в init'е кФС), а так же что там вообще напихано внутри. Напихано там дофига всякой мутоты, что усложняет до безобразия восприятие initramfs'a как такового. Однако, параллельно я наткнулся на неплохую статейку (https://www.opennet.ru/base/sys/initrd_intro.txt.html), и в совокупности всего этого пришел вот к каким (пока абстрактным) выводам:

Собственно, чтобы создать свой простенький initramfs необходимо и достаточно создать ФС и создать там директории /bin, /lib, /etc, /dev, /proc, /sys. А также ссылку /sbin на /bin и файл init.

В /bin нужно либо поместить основные утилиты (какой их перечень минимально необходим??), либо busybox (тогда нужно будет создавать ссылки на его функции в /bin - и, опять же, встает вопрос - какой минимум функций необходим??), в /lib - необходимые библиотеки (для busybox вывод apt-rdepends говорит о том, что нужны libc6, libgcc1 и gcc-6-base).

В /dev нужно поместить ряд устройств, которые почему то не создаются динамически (почему - для меня загадка пока) - console, ramdisk, ram0, null, zero, random, tty1, tty2. Очередной вопрос: достаточен ли этот перечень?

Все это добро можно скопипастить с текущей системы. Минимальный же init, насколько я понял, может иметь вид:

#!/bin/ash
mount -t proc /proc /proc
mount -t sysfs none /sys
mount -t devtmpfs udev /dev
/bin/ash --login
Разумеется, этот init тупо даст нам консоль и возможность выполнять команды busybox'а.

Поэтому как раз дальше должны идти команды, которые заливают кФС в tmpfs - а тут есть ДВА принципиально отличных пути: либо копирование (или распаковка из tar.gz) кФС в созданную в tmpfs директорию - тот путь, который Вы и реализуете в Вашем скрипте, либо вывод ОБРАЗА кФС на блочное псевдоустройство в RAM (/dev/zram0) - способ, любезно предложенный пользователем torvn77. И вот каким путем пойти - сейчас главный для меня вопрос, потому что остальные моменты сейчас кажутся уже делом техники и многочисленных экспериментов. Поэтому приветствую любые аргументы за и против каждого из двух способов.

Ну, а завершается простейший init перемонтированием виртуальных ФС в нашу кФС:

mount -n -o move /sys /путь-к-смонтированной-кФС/sys
mount -n -o move /proc /путь-к-смонтированной-кФС/proc
mount -n -o move /dev /путь-к-смонтированной-кФС/dev
И завершаем все выполнением pivot_root+chroot (кстати, кто может популярно объяснить зачем делать chroot после pivot_root - опять же буду весьма признателен; ключевое слово - популярно, потому как непопулярных объяснений вагон, я не могу их понять в силу ограниченности, видимо). Здесь код приводить не буду - я пока разбираюсь еще как это правильно делать, не хочу на смех общественности выносить заведомо сырые строки))

Итак, буду благодарен за пинок в нужном направлении по следующим вопросам:

1. Какие утилиты обязательно должны присутствовать в initramfs для возможности успешного подмонтирования кФС?

2. Какие псевдоустройства (кроме приведенных мной выше) нужно еще изначально (то есть на этапе создания initramfs) включать в директорию /dev?

3. Какой из двух методов заливки (через tmpfs или через /dev/zram0, подробности в тексте) на Ваш взгляд лучше и почему?

4. Вопрос про необходимость chroot после pivot_root - популярное объяснение этой необходимости.

Заранее благодарен всем неравнодушным к проблеме run-from-RAM в целом и к моим вопросам в частности. Всем шикарного вечера!

dima9kin ()
Ответ на: комментарий от dima9kin

встает вопрос - какой минимум функций необходим??

Ровно тот который задействован в твоём initrc плюс опционально команды которые ты будешь применять если ты решишь запустить из initrc командную оболочку.

torvn77 ★★★★★ ()
Для того чтобы оставить комментарий войдите или зарегистрируйтесь.