Блог:Виталий Филиппов

Материал из YourcmcWiki
Версия от 20:46, 2 января 2011; VitaliyFilippov (обсуждение | вклад)

Это снимок страницы. Он включает старые, но не удалённые версии шаблонов и изображений.
Перейти к: навигация, поиск

Технические вопросы и вменяемые заметки от меня, Виталика.

У меня, конечно, уже есть блог Ljuser.gifsimply_a_man.

2015-03-15 Мне не нравится HTML5

Не нравится мне HTML5. Ну не то что весь, а та его часть, где именно про HTML, то есть про теги.

Вот нафига нужно столько новых тегов? article aside bdi details dialog figcaption figure footer header main mark menuitem nav rp rt ruby section summary time wbr.

По мне, правильнее было бы число тегов и атрибутов наоборот уменьшить! И пересадить всё на CSS-свойства. Например, сделать, чтобы colspan и rowspan можно было задавать в CSS…

2015-03-01 Удалённое изнасилование: миграция сервера с 32 на 64 бита

О, я крут. Вчера удалённо сменил систему (Debian Wheezy) на сервачке с 32-х на 64-х битную.

Применил для этого свою «аварийную систему», состоящую из dropbear и busybox в initramfs (очень рекомендую, удобная штука).

Общая схема действий у меня была такая — почистить систему от устаревших пакетов, перейти на 64-битное ядро, создать 64-битную копию системы из тех же пакетов и потом через аварийную систему (dropbear) заменить содержимое / и /usr на 64-битное, оставив старые /etc и /var.

В целом, за исключением некоторых нюансов, после такой операции система стартует без особых проблем. Какие конкретно есть нюансы:

  • Чтобы поставить все те же пакеты в 64-битном виде, сначала нужно почистить систему от устаревших пакетов. Для этого удобно использовать Aptitude — оно умеет показывать «локальные/устаревшие» пакеты — то есть установленные, но которых при этом нет в репозиториях. Все такие пакеты надо прибить или на что-то заменить — собственно, это вообще полезно, система чище будет.
  • Модули perl/python/ruby/php, установленные через cpan/pip/gem/pear, естественно, в 64-битной системе нужно установить заново.
  • Данные MySQL (InnoDB) трогать не надо — они отлично переносятся, формат хранения архитектурно-независим.
  • Базы данных dpkg и debconf (/var/lib/dpkg и /var/cache/debconf) нужно обязательно скопировать из chroot’а от новой 64-битной системы в свой /var, в целом остающийся от старой системы без изменений).
  • Некоторые alternatives — конкретно, java’шные — могут поломаться, их нужно починить (update-alternatives --all).
  • /etc/ld.so.conf.d/* нужно тоже взять от 64-битной системы.
  • Базы данных rrdtool архитектурно-зависимы! Их нужно сделать dump/restore. Актуально для систем мониторинга — nagios, munin и подобные, как правило, именно RRD и используют.

UPD: А ведь действительно, о потреблении памяти-то я и не подумал. Оно в 64-битной версии возросло очень прилично — после echo 3 > /proc/sys/vm/drop_caches в 32-битной системе занято 1.85 гб, а в 64-битной — 2.9 гб при идентичном наборе запущенных сервисов. Налицо рост на 56 %… Ну ладно. Технология удалённого изнасилования уже отработана — вернул 32-битную систему взад ))

2015-03-02 Аварийная система для Debian - краткая инструкция

Уже давно сделал себе из dropbear и busybox в initramfs «аварийную систему», позволяющую войти на сервер, даже если в процессе загрузки что-то сдохло.

Очень рекомендую — при наличии такой штуки практически полностью отпадает необходимость иметь KVM или физический доступ к серверу. Вот краткая инструкция по конфигурированию её в Debian:

  • Установить пакеты initramfs-tools (ну вдруг не установлен? :D), dropbear, busybox.
  • В /etc/initramfs-tools/initramfs.conf прописать BUSYBOX=y, DROPBEAR=y, IP=<адрес>::<шлюз>:<маска_подсети>:<имя_хоста>::static (либо просто IP=dhcp, если у вас на сервере DHCP).
  • Прописать свой SSH-ключ в /etc/initramfs-tools/root/.ssh/authorized_keys, не забыть сделать его chmod 600.
  • Модифицировать несколько скриптов в /usr/share/initramfs-tools.conf вот таким патчиком, командой cd / && patch -p0 < patch-rescue_dropbear_udev_initramfs-tools.diff (патчик делает так, чтобы содержимое initramfs, а также /sys, /proc, /dev и /dev/pts не убирались из «старого» корня и чтобы dropbear запускался на 1022 порту и не останавливался при продолжении загрузки).
  • Сделать hold пакетов initramfs-tools, udev, dropbear, чтобы не перезаписались случайно наши модифированные скрипты.
  • Запустить update-initramfs -u -k all, перезагрузиться.

Вроде ничего не забыл… после этих операций у вас должна появиться «аварийная система», работающая целиком из initramfs и не требующая подмонтированных дисков, в которую вы сможете всегда (даже после старта основной системы) зайти через ssh с ключом на 1022-й порт. И если что-то сломается в процессе загрузки — вы сможете зайти и попытаться это исправить, хотя консоль, конечно, не увидите… (кстати, может способ увидеть её есть и надо просто его найти?)

И последняя фишка — как намеренно перезагрузиться в «аварийную систему» так, чтобы основная не стартовала? Оказывается, очень просто — нужно только прописать в параметры загрузки ядра опцию break=mount. Это штатная фича Debian’овской initramfs — она приостановит выполнение init’а как раз перед моментом монтирования «нормальной» корневой ФС.

2014-11-25 Ортокератология

Сделал себе недавно ортокератологическую («ночную») контактную линзу. Одну, потому что левый глаз всё равно не исправляется — амблиопия с детства (в чём причина оной, хз — никто не диагностировал никогда, хотя лет до 5 можно было и вообще исправить, по идее).

Ночная линза — это такая штука, которую каждую ночь надеваешь, каждое утро снимаешь, а день потом видишь хорошо, потому что она за ночь искривляет (точнее, распрямляет) роговицу, чтобы она стала менее выпуклой. Исправляется таким образом близорукость от −1 до −7, лично у меня где-то −2.5, из которых −0.8 — это минимальный астигматизм (горизонтальные линии двоятся, вертикальные чёткие). Ещё есть некие неподтверждённые данные о том, что эта фигня тормозит прогрессирование близорукости. В моём случае до 16 лет я видел идеально, так что прогрессирование составляло где-то 0.25 в год — посмотрим, затормозится ли.

Почему это круто? В моём случае это круто потому, что недеструктивно — достаточно перестать носить и через несколько дней (максимум через неделю) зрение вернётся к своему естественному состоянию. А глаз-то у меня фактически один (левый видит плохо и не исправляется), так что если допустим при операции что-то не то отрежут (выпарят) лазером — восстановить уже куда сложнее.

Ну ещё, понятное дело, круто, что её носить днём не надо, ничего в глазу не торчит, не сохнет (как мягкие линзы), не боится дыма (как жёсткие дневные), и не мешает дыханию и слезообмену глаза (а следовательно, меньше приводит к побочным эффектам).

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

Ещё степень воздействия зависит от того, сколько спать — мне вот сделали линзу максимального диаметра (11 мм), с ней если спать меньше 8 часов — явно заметно, что двоится в темноте сильнее. Лучше всего спать часов 9, тогда почти не двоится.

Короче, прикольная штука. Делал в Доктор Линз.

2014-10-08 Обновил статью про Perl-платформы

2014-09-20 Я HTML джедай)))

Ну я джедай)) для адаптивной вёрстки сделал на чистом HTML+CSS табличку размером 1x4 (1 строка, 4 столбца), которая при необходимости опять-таки посредством чистого CSS превращается в таблицу 2x2, при этом она остаётся именно таблицей, а не набором плавающих слоёв, и во второй строчке оказываются не 3 и 4 ячейки, как в решении с плавающими слоями, а 2 и 4, и решение легко меняется для выбора другой комбинации.

Хак основан на применении rowspan и скрытии ячеек через display: none, поэтому хорошо работает во всех браузерах. Идея:

2x2: все ячейки видны, но пустые незаметны, ибо схлопываются до нулевой ширины.

Ячейка 1, rowspan=2 пустая ячейка Ячейка 3, rowspan=2 пустая ячейка
пустая ячейка (строка 2) пустая ячейка (строка 2)
Ячейка 2 пустая ячейка Ячейка 4 пустая ячейка

1x4: путём display: none целиком скрывается 2-я строка (<tr>), состоящая из двух пустых ячеек, а также пустые ячейки (<td>) в 3-ей строке. Скрытие второй строки заставляет rowspan захватить третью, ячейки 2 и 4 позиционируются на свои места, а пустые схлопываются до нулевой высоты (они ж пустые!) и становятся не видны. Выглядит это как таблица 1x4.

Ячейка 1, rowspan=2 пустая ячейка Ячейка 3, rowspan=2 пустая ячейка
Ячейка 2 Ячейка 4

Вуаля — вёрстка осталась неизменной, путём чистого CSS таблица превращена из 2x2 в 1x4! Стилевое преобразование легко вешается на Media Query и становится частичкой адаптивной вёрстки (responsive layout).

А я джедай :-P

2014-09-18 Blender, Radeon, Mesa, OpenCL

Пытался тут на новом ноуте заюзать OpenCL в блендере — потерпел неудачу… ещё конечно подебажить попробую… но хз, получится ли.

Теоретически там радеон 8770M, а это значит, что в Mesa есть OpenCL, реализованный посредством LLVM.

Практически:

Сначала блендер просто не видел OpenCL в системе… это решилось просто — он хотел библиотеку libOpenCL.so, а это симлинк на libOpenCL.so.1.0.0, который почему-то оказался не в том пакете (оказался в -dev).

Потом что blender, что clinfo не могли заюзать радеон из-за permission denied по какому-то ioctl — это я не решил, но обошёл тупо путём запуска из-под рута.

Потом оказалось, что blender’у нужно передать переменную окружения CYCLES_OPENCL_TEST, передал… С этого момента OpenCL он у меня увидел.

Следующая проблема была в том, что ядро (OpenCL kernel, программа, которую на GPU грузят) не компилилось мезой. Я было подумал что всё, пиши пропало — например, пишут, что вроде на закрытом AMD’шном драйвере там вообще всё совсем печально, типа не компилится потому что тупо ядро большое, и их компилятор давится.

Но тут-то вроде LLVM, не должно такого быть! И таки да — я нашёл просто ошибку в этом самом ядре. Она мелкая, там они просто . вместо -> в одном месте юзали (код по сути C-шный). Правда, чтобы это найти, я сначала нашёл ещё одну переменную окружения — CYCLES_OPENCL_DEBUG, чтобы готовый исходник ядра, собранный из кучи файлов, увидеть.

Итак, после исправления этой очипятки ядро собралось… но после этого, увы, блендер просто стал падать с segmentation fault’ом где-то в недрах LLVM уже при попытке трансляции видимо IR’а в radeon’овый шейдерный код. И тут я пока хз, получится ли это поправить. Есть ещё маленькая вероятность, что это баг oibaf’ской сборки, так как mesa у меня именно оттуда… В общем, буду искать баг дальше. Очень уж хочется Cycles на GPU запустить.

UPD: Залез в недра LLVM, попробовал поискать баг; обнаружил, что в SIAnnotateControlFlow.cpp в handleLoopCondition() в какой-то момент попадает PHINode, у которого первый аргумент равен ему самому. Теперь вся интрига в том, как это всё-таки происходит?

UPD2: Видимо, в LLVM PHINode, содержащий себя — это вполне нормальный продукт оптимизатора. Причём мало того, что он может содержать себя напрямую, в качестве одного из IncomingValue, так оказывается, что может и через другой PHINode (то есть phi->getIncomingValue(0)->getIncomingValue(0) == phi)… Поэтому просто пропускать значения, равные самому PHINode, не помогает, нужно проверять во всю глубину… И главное, не очень понятно, ЧТО вообще по логике означают такие PHINode. Написал по этому поводу в список рассылки LLVMdev — пока в ответ тишина…

2014-07-30 Пришла она

Сегодня к нам пришла она,
Бессовестная информационная война
Готовы блогеры к труду и к обороне -
В жж, в сети иль в стандалоне!
Всегда мобилизованы в России
войска диванной рефлексии...

2014-07-29 Wine

Докладываю: сегодня впервые у меня игра не заработала под виндой, но отлично завелась под Wine :) глядишь, скоро линукс будет большая винда, чем сама винда, и как следствие, винда вообще совсем не нужна станет… А уж если многопоточную трансляцию DirectX в OpenGL в состав wine примут… или нативную реализацию оного поверх Mesa/Gallium3D… :) а ещё наконец запилят тесселяцию в Mesa… Хе-хе :) круто, короче.

2014-07-06 Ремонт сифона SodaStream

Есть у меня доставшийся на халяву SodaStream’овский сифон для газирования воды, вот такой «Pure»:

SodaStream Pure.jpg

Не то чтобы из него газировка лучше или дешевле… Ничего подобного. Концентраты у них двух видов, обычные и «Goodness» — первые с бензоатом натрия, стоят по 320р и баночки хватает на 12л, вторые типа получше, но баночка стоит уже 400р, и хватает её только на 6л. Перезаправка баллона с CO2 стоит 800р, хватает его примерно литров на 60. То есть, цена 1 литра получается либо 40р, либо 80р с дорогим сиропом. Бывают ещё всякие левые сиропы, но стоят всё равно примерно так же.

Зато прикольно — налил воды, нагазировал и пьёшь себе =) ну и сиропы довольно вкусные и разнообразные, аналогов многих видов в магазине нет.

Ну и если сравнивать с обычными баллончиковыми сифонами, то SodaStream круче в стопицот раз, так как удобный:

  • Вода газируется не в самом сифоне, а в прикручиваемой к нему отдельной бутылке
  • Баллон CO2 используется большой (425 грамм), а не эти мелочи по 5г… Соответственно давление в нём выше и газируется вода гораздо лучше.
  • Конструкция довольно грамотная и вода из всех дыр в процессе не хлещет.

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

В процессе ремонта сфотал и решил запостить устройство сифона. Оно простое, разборка тоже простая — сначала снимается крышка, потом железки с боков, потом откручивается кажется 6 винтов и перед нами весь механизм:

Sodastream int comment.jpg

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

В общем, у меня оказалось всё просто — клапан 1 клинил и не закрывался, видимо я как-то раз пытался газировать воду прямо с концентратом, эта сладость туда попала и залепила клапан. Снял клапан, разобрал (там две трубки, одна вкручена в другую и потом вторая уже вкручена в корпус), помыл, закрутил обратно с лентой ФУМ и вуаля, сифон опять работает :)

2014-04-02 Опупенно Йота проблемы фиксит!

Опупенно Йота проблемы фиксит!

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

Как, по-вашему, они это пофиксили?

УБРАЛИ СОТУ ОБРАТНО)))))

Просто гениально. Хотя в общем да, я теперь обратно дальнюю ловлю, и там, как и было раньше, скорость и пинги вполне приличные, несмотря на довольно слабый сигнал.))

2014-03-26 OpenSCAD

OpenSCAD-logo.png
Нашёл клёвую штуку — OpenSCAD.

Типа «CAD для программиста». Пишешь скриптик, тебе генерится какая-нибудь шестерёночка =) а потом ты её, скажем, экспортируешь в STL и печатаешь на 3D-принтере. Язык простой, состоит из примитивов и операций над ними, в основном булевых (объединение/пересечение/разность).

Правда, есть пара нюансов:

(1) Нежелательно оперировать объектами с совпадающими или очень близкими плоскостями/вершинами, то есть склеивать/резать детали «заподлицо». Из-за того, что все операции с плавающей точкой, иногда получается, что детали «недоклеиваются» и где-нибудь «проступают» лишние вырожденные грани (то есть грани с очень маленькой площадью)… Их обычно мало, но тем не менее, софт 3D принтера они могут расстраивать, и объект на печати может получаться не совсем качественный. Причём это может проявляться даже хитрее — например, при объединении шестерёнки и цилиндра нужно следить, чтобы края зубьев шестерёнки не совпадали к краями граней цилиндра. То есть, для цилиндра нужно ставить число граней = 2 * числу зубьев шестерёнки.

(2) Дефолтный OpenSCAD использует какой-то совершенно дебильный метод триангуляции — пытается тянуть треугольники из одной точки во все точки, в которые может дотянуть. Что, собственно, часто ведёт к тем же вырожденным граням — причём на совершенно нормальных деталях. И говорят, даже без вырожденных граней из-за длинных и узких треугольников при печати получается хреновое качество поверхности. Однако это не беда, есть простой фикс (я его в свой форк влил — https://github.com/vitalif/openscad), заставляющий OpenSCAD юзать триангуляцию Делоне, которая, естественно, вполне себе приличная. Сравнение на примере шестерёнки выглядит вот так:

Triangulation-bad.png Triangulation-delaunay.png

Проверять модели на предмет подобных проблем, кстати, можно с помощью FreeCAD — там есть инструмент «Оценить и ремонтировать сетку».

А в остальном — очень удобная штука =) чем пытаться чего-то чертить, пишешь себе программку и наслаждаешься шестерёночками…

Кроме того, есть и готовые куски кода, в том числе — эвольвентный профиль зубьев шестерёнки — в библиотеке MCAD, входящей в комплект поставки. Ну, и ещё OpenSCAD скрипты можно брать (и выкладывать!!!) на http://thingiverse.com/.

2014-03-19 Глобальный программист

Откопал ржачное резюме 16-летнего «глобального программиста», которое нам в сентябре 2012 скидывали HR’ы. Орфография и пунктуация сохранены.

Жалко, что он не пришёл, когда мы его позвали )))))

Профессиональный web программист. Более 200 сайтов в портфолио. Дипломы и награды от компании microsoft. Я получил 2 сертификата microsoft pro 2010 и 2011. Для меня сайт должен быть сильный и мощный, чтобы выдерживал всю нагрузку как на сервера так и на работоспособность, я считаю что это и есть обязанность программиста сделать то, что сделать сложно. Мои функции заключаются в профессиональной работоспособности как и программ так и сайтов. Легко владею php, javascript, html, css, c++, c# и многими другими языками. Так же работаю в сфере CMS 1c:Битрикс, создаю сначала сайт, проверяю его, а после заношу на CMS, если оно требует.

Прошу учесть что мне 16 лет, если вас волнует возраст, то в этом случае я без силен, но если вас интересует и нужны глобальные программисты с резюме microsoft, то мой номер 89857890201. Мой e-mail: Daniltrane95@gmail.com

Блестяще владею в плане дизайнера. У меня 2 социальных сети написанные на java, можно сказать что и javascript мне подвластны.

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

  • http://javagala.ru/ - социальная сеть в которой более 18 мл. человек.
  • http://69.tehnosila.ru/ - техносила в нижнем тагиле
  • http://tagilnext.ru/ - сайт торгового центра в нижнем тагиле
  • http://rostov-na-donu.wikihelps.ru/ - мини портал ростова-на-дону
  • http://www.krd.ru/ - мэрия города Краснодара. шаблон и дизайн сделал я. так же поставил туда админ. доступ, чтобы весь текс и все остальное они сами смогли добавлять и редактировать.

Рекомендации

  • microsoft
  • Deciy, программист

2014-02-19 Новые ограничения в Говнодроиде

О, ну как я и ожидал, гугл (говногугл) продолжает добавление геморроя пользователям Андроида (говнодроида блин):

http://www.opennet.ru/opennews/art.shtml?num=39112

Начиная с андроида 4.4 приложениям (даже имеющим разрешение WRITE_EXTERNAL_STORAGE) запрещается писать на внешнюю карточку памяти. Каждому приложению разрешается писать только в его личную папку на внешней карточке, причём эта папка будет УДАЛЕНА при удалении приложения. Для полного доступа к флешке вводится отдельное разрешение, но оно не выдаётся НИЧЕМУ, кроме гугловских системных приложений. Короче, гудбай файлменеджеры.

Особенный дебилизм в том, что на внутреннюю флешку писать всё равно можно, соответственно, предположение о том, что мера призвана побороться с разведением срача на карточке памяти, оказывается неверным — срач приложения разводят как раз на внутренней карточке.

Какого хера сраный гугл решает, что я должен делать и что не должен? Что за б**дский подход? Прямо как у эппла и мелкософта, гугл в таких же говнюков превращается. Уже давно превращается, как минимум с момента выпиливания USB Mass Storage.

Слава богу есть рут, но если бы его не было — это вообще можно было бы сразу виндоус фон покупать, бггг.

Короче, когда гугл будут патентами троллить — я предлагаю всем приговаривать «так вам, козлы, и надо». ПРОПРИЕТАРЩИКИ ДОЛЖНЫ СТРАДАТЬ.

UPD: Кстати, ещё одно соображение — о том, как это надо было реализовать правильно. Очень просто: по дефолту приложение должно иметь полный доступ, но только к собственной папочке на карте памяти, плюс по одному пермишну на чтение и на запись в любое место карты памяти. Естественно, НЕ разделяя в этом смысле внутреннюю и внешнюю SD. Но что об этом говорить, когда модель безопасности в ведроиде всё равно изначально кривая и не рассчитана на то, чтобы пользователь что-то вообще решал…

2014-02-15 Гениальная идея по конвертации ФС

Оказывается, под Linux существуют утилитки для конвертирования (без копирования в свободное пространство) ЛЮБЫХ файловых систем в ЛЮБЫЕ, основанные на совершенно гениальной идее!

Я говорю о convertfs (постарее) и fstransform (поновее). Конвертируют друг в друга любые файловые системы, драйвер которых поддерживает запись и разреженные файлы.

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

То есть понятно, что скорость конвертации не лучшая — данные всё-таки копируются. Но зато процесс почти абсолютно универсальный! Плюс заодно происходит дефрагментация.

Но главное, что с помощью такого подхода можно мутить и более интересные вещи — например, можно слить два рядом находящихся раздела (причём, в принципе, ещё и с разными ФС) в один, достаточно добавить в процесс цель linear линуксового Device Mapper’а. Идея та же — создаём внутри второго раздела «дополнительный» кусок раздела, который будет присоединяться к первому, потом с помощью linear создаём девайс, объединённый из первого раздела и разреженного файла во втором разделе, ресайзим исходную ФС, а дальше всё то же самое — перемещаем туда все файлы со второго раздела и перезаписываем второй раздел этим куском. После чего спокойно меняем размер первого раздела — и всё, объединение закончено.

Ещё есть утилитка anyconvertfs, которая конвертирует разделы с помощью более традиционного подхода, без копирования данных, что быстрее и не требует от исходной файловой системы ни поддержки записи, ни поддержки разреженных файлов (то есть исходной ФС может быть, например, FAT32), но зато в качестве результирующих ФС поддерживает только ext2, ext3 и XFS. Fix: на самом деле требуется поддержка ioctl’я FIEMAP. Без него конвертация либо вообще не произойдёт (если также не поддерживается BMAP), либо если через BMAP — будет очень медленной и займёт 100500 лет. ntfs-3g, например, FIEMAP не поддерживает.

2014-02-14 debian & systemd

Хе, забавно. Недавно техкомитет дебиана, поругавшись, выбрал systemd, а вот и Шаттл-в-рот уже написал (http://www.markshuttleworth.com/archives/1316), что убунта тоже на него перейдёт. Ну в общем логично, нафига им делать лишнюю работу по написанию инитскриптов, если за них всё дебиановцы сделают =)

В принципе, ожидаемо — когда всякие говнодистры уровня mageia на него только-только начинали переходить, я даже вроде в комментах писал, что если добавят в дебиан, то, наверное, только когда уже станет юзабельным. Ну, говорят, уже юзабелен… Хотя опасность того, что какую-нибудь очередную Новую Супермодную Революционную приблуду будут жрать ВООБЩЕ ВСЕ, с переходом дебиана и убунты на эту опухоль только усилится.

Но раз уж ЭТО светит, придётся хотя бы попробовать что-то сделать с journal’ом… Он, говорят, уже отключается почти полностью — можно сказать, чтобы он свои ссаные логи в бинарном формате вообще не хранил, а только в сислог отправлял. Но это всё равно не то — надо либо (а) чтобы он вообще был отключён, даже запущен не был, либо (б) чтобы сам хранил логи в тексте + отдельный индекс для быстрого поиска. Вот что-нибудь из этого и надо будет попробовать запилить…

2014-01-24 Зигзаг МакКряк

Зигзаг МакКряк (Launchpad McQuack)

Launchpad McQuack.jpg

Ебанутый на всю голову пилот с пеликаньим клювом. Водить может всё, вот только впитанное с молоком матери «тормоза придумали трусы» приводит к тому, что добраться ему получается максимум до места назначения ввиду полной убитости техники (хотя фирменный самолет ЧП сажал вполне нормально). С другой стороны, это имеет и некоторую пользу ввиду нажитой способности за вменяемое время привести в состояние движения любой хлам. Раньше работал на миллиардера Скруджа МакДака, теперь является помощником Чёрного Плаща. Мозга не имеет, отчего иногда не может посадить самолёт даже на [много]километровой ВПП. Но годы, проведенные у Скруджа, всё-таки принесли определенную пользу, ибо если у Скруджа после посадки самолёт восстановлению подлежал крайне редко, то у ЧП требовал всего лишь капитального ремонта. Прототипом оного послужил пиндосский сенатор Джон Маккейн, который, будучи пилотом палубной авиации, потерпел в общей сложности 18 катастроф, причем в одной из них угробил не только свою леталку, но и еще 26 штук вкупе с авианосцем базирования. Примечателен тем, что не только не получил за это люлей (ибо папа и дедушка адмиралы ВМФ), но еще и остался цел и невредим.

via http://lurkmore.to/Чёрный_плащ


2014-01-13 Изменение числа инодов на живой ext2-3-4

О! Я написал софтинку, чтобы менять число инодов на живой ФС ext2/ext3/ext4.

Идея в чём — в этих ФС (самых распространённых под Linux, и самых шустрых, кстати) есть такая особенность: иноды хранятся в заранее предопределённых местах — в таблицах инодов, место под которые выделяется один раз при форматировании и после этого (через tune2fs, например) уже не меняется. То есть, если таблицы инодов внезапно заполнятся — может получиться так, что место на диске ещё есть, а файл создать уже нельзя! Видимо, из-за этого по умолчанию mkfs по умолчанию выделяет место под иноды «с запасом» — по 1 иноду на каждые 4 блока (блок обычно = 4 кб). То есть из расчёта среднего размера файла 16 Кб.

Размер инода в ext4 256 байт, откуда путём нехитрых вычислений мы получаем, что по дефолту 1/64 (!!!) дискового пространства выделяется под иноды. На терабайтном разделе это уже ни хрена себе оверхед — 15 гигов под иноды! А на 3 ТБ — уже 45 гигов. Которые на таком разделе, очевидно, никто никогда в таком количестве не заюзает :-)) 3 ТБ раздел забить файлами по 16 кб — это надо постараться, то есть инодов, конечно, надо сразу выделять поменьше. Но если ты уже создал ФС — давай, до свидания, 45 гигов уже никто тебе не вернёт.

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

То есть это всё, конечно, не значит, что я гарантирую, что там всё хорошо работает :-) на тестовых образах вроде всё отлично, в разных комбинациях и даже с bigalloc’ом; на реальных ФС я пока не решался запускать :-)

В общем, если кому интересно — можно тестить, исходники тут: http://svn.yourcmc.ru/viewvc.py/vitalif/trunk/ext4-realloc-inodes/. Для сборки нужна библиотека libext2fs (из состава e2fsprogs). Юзать так: ./realloc-inodes --patch <файл_патча> <файловая_система> <новое_число_инодов>. Потом ./e2patch backup <файловая_система> <файл_патча> <файл_бэкапного_патча> и ./e2patch apply <файловая_система> <файл_патча>.

Надо видимо это куда-то в район списка рассылки linux-ext4 отправить :-)

2013-12-23 О! Лента продолжает умирать

Ух ты, как прикольно! Лента продолжает умирать.

Уже для вчерашних (ВЧЕРАШНИХ) новостей вместо комментариев теперь показывается:

«Комментарии к материалу закрыты в связи с истечением срока его актуальности.»

Круто, чо.

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

Ну и хрен с ним. Го на мейл.ру, посоны.))

2013-12-18 Итак, как же изнасиловать корневой раздел без перезагрузки

Итак, задача — не перезагружаясь, перейти в такой режим, в котором ваш Linux не будет использовать диски совсем. Чтобы, например, иметь возможность с ними что-то поделать.

Главная загвоздка — это init, первый (PID=1) и неубиваемый процесс в системе, запущенный с корневого раздела. Разделы, кроме корневого, отмонтировать обычно довольно легко — достаточно убить все процессы в системе. Однако init убить нельзя, большую часть сигналов, в том числе SIGKILL, он игнорирует (PID’у 1 можно игнорировать SIGKILL), а если у вас и получится его убить — ядро запаникует и остановит работу системы.

Так что init нужно, не выключая, «вытащить» в другой корневой раздел. Способ это сделать, по сути, один — подменить запущенный образ exec()ом другого, который сделает chroot и снова exec. Однако как заставить init сделать exec() того, чего нам надо? А вот как — все init’ы (даже несчастный systemd) умеют перезапускать себя. И хотя это сделано вовсе для другой цели, а именно — для применения обновлений в самом init или системных библиотеках (libc?) без перезапуска системы — это вполне можно заюзать в наших целях… достаточно поверх /sbin/init смонтировать свой файл --bind’ом. После чего команда «init U» перезапустит вместо init’а наш файл. Только сам инит надо куда-то скопировать, типа cp /sbin/init /sbin/init1, мы ж его только что перемонтировали.

А дальше нужно переключать корень. Мне изначально хотелось его переключать обратно в initramfs (то есть rootfs), чтобы «аварийная система» находилась именно там — типа, так надёжнее — загрузился сразу dropbear и всё, никуда уже не уходит и на машину можно зайти по ssh. Если не заморачиваться именно выходом в initramfs, переключить корень ещё проще — достаточно сделать pivot_root. pivot_root — это такой хитрый системный вызов, который подменяет / другой точкой монтирования, а текущий / помещает в подпапку нового, причём (!) насколько я понял, это единственный системный вызов, нагло подменяющий корень всем процессам в системе, в коде ядра прямо так и написано — «foreach (по всем задачам) { если корень == предыдущему, подменить на новый }».

Никаким другим образом подменить корень другому процессу, видимо, нельзя. pivot_root раньше использовался initrd для переключения в «реальный» корень — рамдиск при этом попадал в подпапку корня и потом отмонтировался init’ом, запускаемым exec()ом на месте «старого». Но сейчас это уже не так, initrd теперь называется initramfs, и работает из специальной НЕотмонтируемой и НЕперемещаемой файловой системы «rootfs», которая, по сути, представляет собой просто tmpfs (живущий в памяти), но по-другому названный, монтируемый в / автоматически при старте системы, и недоступный для монтирования потом. В него распаковывается содержимое initramfs (gzip -d | cpio -i, только внутри ядра), в качестве PID 1 оттуда запускается /init, а из-за того, что rootfs НЕотмонтируемый и НЕперемещаемый (так сделано тупо для удобства программирования) отличается метод переключения в новый корень — с помощью утилиты run-init (в терминах klibc) или switch_root (в терминах busybox) initramfs удаляет всё содержимое rootfs, потом монтирует (на самом деле перемещает, mount --move) новый корень прямо поверх старого, а потом делает в него chroot и выполняет там /sbin/init.

Именно поэтому на свежих ядрах в /proc/mounts корень (/) смонтирован всегда дважды, один раз как rootfs, и второй раз как обычный корень. Просто старый rootfs пустой, процессов, видящих его, в системе уже не остаётся, а смонтировать его куда-то ещё раз невозможно — есть явный запрет повторного монтирования в коде ядра — поэтому он висит и практически не отсвечивает. Пустой tmpfs, вроде как, памяти почти не занимает, и оверхед нестрашный.

Но! Если после завершения работы initramfs оставить работающий процесс, запущенный из старого корня — возможность туда попасть сразу же появляется. Достаточно сделать cd /proc/<PID>/root (или chroot туда же, если содержимое осталось). Если этот процесс вообще dropbear — тогда зайдя в него по ssh, вы тоже окажетесь в старом корне. Это, кстати, да — ещё одно откровение: разные процессы в Linux могут видеть файловую систему по-разному, причём даже в рамках одного namespace’а! То есть в разных namespace’ах-то ладно, это же часть функционала контейнеров, полностью изолирующая иерархии ФС друг от друга, но в рамках одного — вообще забавно.

Конкретно, в запущенном из старого корня процессе получается так:

  • cd / → попадаем в старый корень (rootfs).
  • ls /.. → листается новый корень.
  • ls /<любая_папка>/.. → листается новый корень.
  • cd /.. → всё-таки остаёмся в старом корне.
  • mount --move /.. /root → самое интересное. Новый корень перемещается в подпапку rootfs /root, а остальная система становится как бы запущенной в chroot’е. Но не потому, что произошёл chroot, а потому, что сам корень переместился в новое место :)

А из chroot’а, как известно, можно вылезти — нужно только получить открытый дескриптор на директорию, находящуюся ВНЕ текущего корня. Делается это путём открытия / и потом ещё одного chroot’а в его подпапку. После этого достаточно сделать fchdir в открытый дескриптор и потом «cd ..» столько раз, сколько нужно.

Отсюда у меня созрело такое вот решение.

Сначала правим initramfs (Debian: /usr/share/initramfs-tools/):

  • Чтобы вместо перемещения /dev, /dev/pts, /proc в новый корень (/root) он их туда биндил (mount --bind /dev /root/dev и т.п.).
  • Чтобы вместо run-init/switch_root, удаляющего содержимое старого корня, он просто делал
    mount --move /root /
    chroot /.. /sbin/init < dev/console > dev/console
  • Также сразу включаем в initramfs dropbear, и делаем, чтобы он НЕ выключался при переходе в новый корень. На Debian’е это делается просто, apt-get install dropbear, потом добавляем DROPBEAR=y в /etc/initramfs-tools/initramfs.conf, и потом в /usr/share/initramfs-tools/scripts/init-bottom/dropbear убираем строчку с kill. Заодно меняем ему порт с 22 на, скажем, 1022 — в scripts/init-premount/dropbear добавляем ему опцию «/sbin/dropbear -p 1022». Ключи при установке dropbear сгенерятся сами и подложатся в /etc/initramfs-tools/root/.ssh — их оттуда надо утянуть, чтобы потом иметь возможность зайти в систему.

После чего можно сделать update-initramfs -u -k `uname -r` и загрузиться в новую систему (старый initramfs на всякий случай лучше скопировать и положить рядом — вдруг чего-то не то натворили).

Ну а чтобы вытащить наружу init, я написал пару утилиток — unchroot-init и init-stub. Первая вышеописанным путём сбегает из chroot’а и делает там exec /sbin/init-stub, вторая — тупо висит и игнорирует все сигналы, кроме SIGCHLD и SIGUSR1 — по первому добивает зомби-процессы, по второму — делает «chroot /..» (переход в новый смонтированный поверх старого корень) и запускает там exec’ом /sbin/init --init — это чтобы вернуться в нормальный режим работы. Наверное, ещё можно было туда прикрутить перезапуск того же dropbear’а, если он вдруг упадёт, но фиг с ним.

Итого, чтобы вытащить «наружу» init:

  • ssh’имся в запущенный из rootfs dropbear и делаем там:
    mount --move /.. /root
    cp /root/<путь>/init-stub /sbin/init-stub
  • потом в нормальной системе говорим:
    cp /sbin/init /sbin/init1
    mount --bind /<путь>/unchroot-init /sbin/init
    /sbin/init1 U

А дальше уже дело техники — находясь в новой системе или в chroot /root, останавливаем запущенные процессы — что можем, через /etc/rc0.d, что не можем — просто убиваем. Главное — не отключить сеть и не сделать случайно reboot :).

Дальше есть ещё один маленький нюанс — запущенный udev держит «базу данных» текущих девайсов в /run/udev (по крайней мере в дебиане это так) — её нужно утащить (тупо mv) в rootfs — если быть точным, то в /dev/.udev, чтобы она потом не потерялась при отмонтировании tmpfs от /root/run, и чтобы при выходе из «аварийного режима» udev спокойно перезапустился, забрал базу из /dev/.udev и опять-таки пересунул её в /run/udev.

И после всех этих манипуляций — всё, файловые системы, в том числе корень /root, можно отмонтировать. Единственный прикол — у меня почему-то получалось так, что dropbear использовал /root/dev/null, и /root/dev отмонтироваться не хотел. ХЗ, как так получилось — я до конца не понял. Но это не так страшно, /root/dev можно сделать umount -l, всё равно это devtmpfs, а не реальная ФС на диске.

Соответственно, чтобы потом вернуться в нормальный режим работы, нужно:

  • Подмонтировать /root.
  • Забиндить/смонтировать в него /dev, /dev/pts и /sys.
  • Сделать mount --move /root /.
  • И сказать kill -USR1 1 — chroot в новый корень заглушка сделает уже сама. С этого момента всё будет выглядеть, как нормальная загрузка системы.

Ну а если нет цели разместить аварийную систему именно в initramfs, то приседания с chroot и /.. вообще не нужны, и можно обойтись pivot_root’ом (хотя init перезапускать всё равно понадобится). В таком виде вообще, наверное, можно написать скриптик, который будет систему «выводить» в tmpfs. Но мне хотелось, чтобы это был именно rootfs, поэтому способ такой, как описано выше…