Блог:Виталий Филиппов — различия между версиями

Материал из YourcmcWiki
Перейти к: навигация, поиск
м
м
Строка 1: Строка 1:
 
<big>Технические вопросы и вменяемые заметки — пока только от [[User:VitaliyFilippov|меня]]. А вдруг будет ещё от кого-то?</big>
 
<big>Технические вопросы и вменяемые заметки — пока только от [[User:VitaliyFilippov|меня]]. А вдруг будет ещё от кого-то?</big>
  
<span style="color: #a0a0a0">У меня, конечно, уже есть блог [[Файл:Ljuser.gif]][http://simply-a-man.livejournal.com/ simply_a_man]. Но там всё эмоции, эмоции, и всё не по делу.</span>
+
<span style="color: #a0a0a0">У меня, конечно, уже есть блог [[Файл:Ljuser.gif|link=http://simply-a-man.livejournal.com/]][http://simply-a-man.livejournal.com/ simply_a_man]. Но там всё эмоции, эмоции, и всё не по делу.</span>

Версия 19:48, 15 января 2010

Технические вопросы и вменяемые заметки — пока только от меня. А вдруг будет ещё от кого-то?

У меня, конечно, уже есть блог Ljuser.gifsimply_a_man. Но там всё эмоции, эмоции, и всё не по делу.

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, поэтому способ такой, как описано выше…

2013-12-15 Всё, научился насиловать корневой раздел, не перезагружаясь :)

Всё, научился насиловать корневой раздел, не перезагружаясь, и заодно при этом иметь (почти)вечнодоступную rescue-систему. Ну, не совсем вечнодоступную — если свалится ядро, сеть или произойдёт ошибка на начальном этапе работы initramfs, rescue доступна не будет.

То есть задача была такая — прямо на этапе загрузки оставить в памяти работающий dropbear на левом порту и никуда уже его не убирать, а потом, НЕ перезагружаясь, убить все процессы, отмонтировать все файловые системы, и оставить только tmpfs с минимальной системой в оперативной памяти, чтобы иметь возможность сделать с остальной системой всё, что угодно… Ну и потом вернуться из этого режима в нормальный.

Завтра соберусь и распишу, похвастаюсь, как я это сделал :-)

Кстати, сейчас ещё подумал — а может, как-то можно вообще реализовать «удалённый kvm» путём запуска системы в гипервизоре? (xen?) то есть, чтобы функция «kvm» (не который Kernel Virtual Machine, а который Keyboard Video Mouse) предоставлялась прямо самим гипервизором, а не dom0, а остатки системы чтобы грузились более-менее как обычно. Типа, чтобы и при крахе ядра тоже можно было зайти и чего-то поделать. Хотя, наверное, всё-таки такой подход затратнее. Ибо прямо в гипервизоре вряд ли такая фича есть, но скорее всего можно сделать это в каком-то сверхкастрированном dom0. А чтобы всё-таки выполнялось требование возможности «изнасилования всей системы» — видимо, надо, чтобы этот dom0 тоже висел исключительно в памяти, и наверное, не так уж он там мало места займёт…

2013-12-07 С ЛОРа про РОСУ :))

Ни в коей мере не хочу обижать творение Стаса и эпсилон-окрестности, однако коммент отличный :)))

Цитата из новости «Вышел ROSA Desktop Fresh R2» с ЛОРа: …линейка «R» предназначается для технически грамотных пользователей, желающих получить свежие версии ПО, имеющих достаточно новое оборудование и не предъявляющих повышенных требований к стабильности системы…

Коммент:

Я прямо вижу, как это набиралось.
Линейка «R» — кривое^W^W предназначается для технически грамотных пользователей, сырое^W желающих получить свежие версии ПО, прожорливое падучее гов^W^W^W имеющих достаточно новое оборудование и не предъявляющих повышенных требований к стабильности системы.

2013-11-27 KMail без двух дебилов - Непомука и Аконади

Нда, зачем KDEшники вообще сделали эти Непомуки с Аконадями — не понимаю. По градусу недовольства оно сопоставимо с ГномоЩелью (GNOME Shell то есть GNOME 3) или systemd, по-моему…

Вот даже чувак сделал форк KMail’а БЕЗ этого гогна (правда, немного старой версии — 4.4):

http://atrey.karlin.mff.cuni.cz/~pali/blog/2013-04-18-kdepim-without-akonadi.html

2013-11-27 Opera

Смешно, но я до сих пор считаю Оперу (некро-Оперу, на Presto) лучшим почтовиком.))

Банальные вещи — просмотр и написание писем во вкладках, быстрый доступ к «непрочитанному» (типа как папка), фокус ввода всегда в списке сообщений (а не как в thunderbird или kmail — там фокус всё время пытается спрыгнуть в поле, где сообщение отображается, и это не даёт скроллить список стрелочками и pageup/pagedown), дефолтная настройка написания писем в plaintext…

Вот если бы всё это запилить, kmail или thunderbird станут юзабельны. А без этого — не, нифига. Ну, в KDE 4.11 Kmail таки хотя бы стал побыстрее и вроде даже перестал дико жрать память и проц.

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

2013-11-22 Завести фреймворки андроида на нормальной системе?

Блин, ведроид — это реально винда какая-то. Монолит монолитом, ни одного нормального linux’ового куска. Гугл — уроды, пилять. Как подумаю, так расстраивает — не описать.

И вот думается мне — а нельзя ли (принципиально) завести его фреймворк на нормальной системе, выпилив при этом остальные внутренности? А именно — убрать нафиг binder, зиготу, SurfaceFlinger, всякие system_server’ы и прочую отстойные байду. Оставить — реально — ТОЛЬКО далвик и модифицированные фреймворки. Вместо SurfaceFlinger’а — то есть композитора, который, я так понимаю, сам по себе вещь довольно тупая — впилить обычный вывод в окно X11.

Вместо binder’а, красивого костыля, на котором там полсистемы работает — впилить нормальную связь через unix сокеты. Тут только пара вопросов:

  • Насколько крупными сообщениями обмениваются приложения через binder? Обычно, вроде, совсем мелкими и сериализованными (Parcelable), так что имхо ничего страшного при переходе на сокеты быть не должно. С другой стороны, вроде я где-то читал, что в binder’е есть возможность zero-copy отправки крупных буферов в адресное пространство другого процесса, и вроде это используется для графики — как раз для связи с SurfaceFlinger’ом. Соответственно, вопрос — используется ли это реально где-то ещё? Если да, можно попытаться нагородить что-то на разделяемой памяти (posix или sysv). Если нет — то вообще забить на эту фичу и всё тут.
  • Есть ли там какие-то хитрожопые фичи для аутентификации? Судя по сообщению авторши в LKML (ага-ага, binder баба какая-то изобрела) — вроде там ничего сильно хитрого нет; тогда обычных файловых пермишнов будет вполне достаточно.

Совместимости с приложениями с нативными кусками в таком подходе, естественно, добиться сложнее — потому что, во-первых, далеко не все приложения вообще есть под x86’ой андроид, а во-вторых, даже для тех, что есть, придётся обеспечивать совместимость ABI с кучей кастрированных библиотек, в частности, с этим тупым огрызком под названием «bionic libc». Хотя чисто теоретически и это, по-моему, возможно — можно модифицировать /lib/ld-linux.so.2 и научить его именно для таких *.so’шек подгружать нужные обёртки. Но вот как раз если заниматься такой фигнёй — работы уже всё-таки сильно больше.

Чисто теоретически, наверное, даже Dalvik можно попытаться ликвидировать и заменить его нормальной JVM, причём оно от этого ведь ещё и ускорится — там оптимизации умные. Но:

  • Какая-то попытка этого уже есть, называется IcedRobot, и насколько я понимаю, там всё несколько сдохло.
  • При таком подходе придётся все запускаемые приложения dex2jar’ить — преобразовывать обратно в java’шный формат (ну даже допустим ладно, это не так страшно).
  • На JVM, видимо, придётся отказаться от такой идеи (совсем уж розовая мечта) — научить dalvik разделямой памяти. То есть научить его память, выделенную под загруженный apk / dex / jar, разделять между всеми процессами, использующими этот apk / dex / jar. Типа получились бы такие so’шки на java, или что-то типа assembly в дотнете. Имхо это было бы мегакруто, потому что это решение потребления памяти Java’ой — ну, в смысле, при параллельном выполнении большого числа Java’шных программ. Тогда и никакие тупые изобретения типа «зиготы» (она как раз для разделения памяти придумана) не нужны.

UPD: Ага, блин, оказывается, далвик тоже зависит от нестандартной ядерной фичи — драйвера разделямой памяти ashmem. Круто, чо… Велосипедисты :). Хотя, конечно, как реализовать автоматическое удаление сегмента разделяемой памяти после завершения всех процессов, его использовавших — сходу не скажу…