Блог:Виталий Филиппов
Технические вопросы и вменяемые заметки от меня, Виталика.
У меня, конечно, уже есть блог simply_a_man.
2014-02-14 debian & systemd
Хе, забавно. Недавно техкомитет дебиана, поругавшись, выбрал systemd, а вот и Шаттл-в-рот уже написал (http://www.markshuttleworth.com/archives/1316), что убунта тоже на него перейдёт. Ну в общем логично, нафига им делать лишнюю работу по написанию инитскриптов, если за них всё дебиановцы сделают =)
В принципе, ожидаемо — когда всякие говнодистры уровня mageia на него только-только начинали переходить, я даже вроде в комментах писал, что если добавят в дебиан, то, наверное, только когда уже станет юзабельным. Ну, говорят, уже юзабелен… Хотя опасность того, что какую-нибудь очередную Новую Супермодную Революционную приблуду будут жрать ВООБЩЕ ВСЕ, с переходом дебиана и убунты на эту опухоль только усилится.
Но раз уж ЭТО светит, придётся хотя бы попробовать что-то сделать с journal’ом… Он, говорят, уже отключается почти полностью — можно сказать, чтобы он свои ссаные логи в бинарном формате вообще не хранил, а только в сислог отправлял. Но это всё равно не то — надо либо (а) чтобы он вообще был отключён, даже запущен не был, либо (б) чтобы сам хранил логи в тексте + отдельный индекс для быстрого поиска. Вот что-нибудь из этого и надо будет попробовать запилить…
2014-01-24 Зигзаг МакКряк
Зигзаг МакКряк (Launchpad McQuack)
Ебанутый на всю голову пилот с пеликаньим клювом. Водить может всё, вот только впитанное с молоком матери «тормоза придумали трусы» приводит к тому, что добраться ему получается максимум до места назначения ввиду полной убитости техники (хотя фирменный самолет ЧП сажал вполне нормально). С другой стороны, это имеет и некоторую пользу ввиду нажитой способности за вменяемое время привести в состояние движения любой хлам. Раньше работал на миллиардера Скруджа МакДака, теперь является помощником Чёрного Плаща. Мозга не имеет, отчего иногда не может посадить самолёт даже на [много]километровой ВПП. Но годы, проведенные у Скруджа, всё-таки принесли определенную пользу, ибо если у Скруджа после посадки самолёт восстановлению подлежал крайне редко, то у ЧП требовал всего лишь капитального ремонта. Прототипом оного послужил пиндосский сенатор Джон Маккейн, который, будучи пилотом палубной авиации, потерпел в общей сложности 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. Круто, чо… Велосипедисты :). Хотя, конечно, как реализовать автоматическое удаление сегмента разделяемой памяти после завершения всех процессов, его использовавших — сходу не скажу…
2013-11-22 На Камчатке после пяти лет запрета разрешили ловить краба
Лента. «На Камчатке после пяти лет запрета разрешили ловить краба».
Комменты.
- Сигнал оппозиции. Сионистская закулиса сняла с Путина иммунитет.
- В баренцевом море у него нет естественных врагов и он там почти что-то типа экологической катасрофы забахал…такие дела
- Да, когда у краба мало естественных врагов, он распоясывается.
- А медведа можно ловить?
- Можно. Говорят, на айфон хорошо клюёт…
- А можно ловить крабов с галеры?
- На галере. Его тока там и можно поймать.
- 2018 год. В Москве поймали крупнейшего краба в истории наблюдений.
2013-11-20 RGBLED
Вот же ж блин. Я где-то года полтора был глубоко уверен, что на моём ноуте Dell Studio XPS 1645 матрица с RGBLED подсветкой. И радовался — ну да, цвета визуально после предыдущего ноутбука действительно были сильно лучше.
Но тут на днях я узнал про опцию утилиты Argyll viewgam -i, с помощью которой можно вычислять объём пересечения двух цветовых охватов, описываемых ICC профилями… натравил её на свой+sRGB и обнаружил, что охват sRGB-то у моего ноута всего лишь 85 %! А потом натравил на второй примерно такой же ноут (с чуть худшей начинкой), который задешёво заказал «про запас»… И обнаружил, что у его матрицы охват ровно в два раза больше, чем у моего, и составляет 120 % AdobeRGB. Опа. А я-то думал, что у меня был RGBLED.
Ещё немножко присмотревшись, я понял, что на втором ноуте даже диагональ экрана чуть-чуть другая — не 15.6", а 16". Так люди в интернетах и писали — WLED экран 15.6", а RGBLED — 16". Корпус-то такого же размера, но рамки вокруг экрана чуть меньше.
И мне тут же в жопу, естественно, впилось переставить экран.
Переставил… Попробовал поработать. И тут наконец понял, чем плохи Wide Gamut ноутбучные дисплеи. Плохи они тем, что хрен ты их откалибруешь нормально «малой кровью»: настройки контраста на ноутбуке нет, а на LUT’ах, которые только и поддерживаются видеокартой, ты далеко не уедешь — ими можно только исправить кривые каналов R/G/B/яркости НЕЗАВИСИМО друг от друга! Ну то есть я это вроде и так понимал, но как-то не прочувствовал. Из этого следует, например, что LUT’ами уменьшить насыщенность/контраст ты НЕ МОЖЕШЬ! Для нормальной цветокоррекции надо, чтобы ЧТО-ТО делало с вектором (R,G,B) кроме кривых ещё и матричное преобразование (которое, собственно, и задаётся в ICC профиле). А такого «ЧЕГО-ТО», что умело бы делать это преобразование со ВСЕЙ выводимой на экран картинкой — нету :-(… и насколько я понимаю, нету ни под виндами, ни под линуксом.
Вернее, это не совсем правильно — под линуксом такая штука как раз есть, в виде плагина к compiz’у — compicc. Но, во-первых, это получается нужно юзать compiz, а он всё-таки по ощущению тормозит (по крайней мере у меня на Mobility Radeon HD 4670 со свободным драйвером) — например, с ним скроллинг в браузере перестаёт быть плавным. А во-вторых, у меня вообще KDE, в котором есть свой композитный оконный менеджер и compiz там явно неуместен. В kwin, собственно, написаны свои реализации всех тех же самых компизовских эффектов и они там даже лучше работают, но compicc-то туда, получается, надо портировать отдельно…
Вот и получается, что настольный монитор с широким охватом — это нормально, поставил контраст поменьше и работай себе, как за обычным. А вот на ноуте всё время работать на 120 % AdobeRGB — по-моему, всё-таки охренеешь… то есть в играх/фильмах-то ок, а вот в консольке зелёный на синем — это реально ЖЕСТЬ, цвета просто ЗУБОДРОБИТЕЛЬНО ВЫРВИГЛАЗНЫЕ. Хотя как раз консолька-то фиг с ней, там цвета перенастраиваются.
Ещё одно забавное ощущение — по-видимому, засчёт той же насыщенности после калибровки сильно заметен оттенок белого — он явно желтоватый и ты к этому не привыкаешь.
А с другой стороны хз — может, он просто яркий слишком и поэтому я от него в темноте при свете настольной лампы фигею немного. Ну да, он явно ярче, чем предыдущий WLED’овый.
UPDATE: Всё ок ;-) во-первых, успешно привык за пару дней и к яркости, и к насыщенности (классный экран!), во-вторых, compicc под KDE уже портирован, то есть KWin тоже умеет полноэкранную цветокоррекцию, а в-третьих, с опцией BackingStore On в xorg.conf ушли тормоза графических эффектов на свободном radeon’е — FPS ниже 35 не опускается. :-) правда, на самом захудалом Intel’е он с теми же эффектами ниже 58 не опускается… Но что уж тут поделаешь — вот настолько драйвер радеона хуже интеловского.
2013-11-15 Всё-таки процесс отправки доработок в медиавики меня удручает
Процесс отправки доработок в медиавики меня удручает.
Code review — это, конечно, хорошо, но, по-моему, время, которое надо потратить на ревью коммита, зависит от размера самого коммита просто-таки экспоненциально. И при таких затратах я не очень понимаю, кому вообще может захотеться это делать.
У меня например доработок к медиавики (полезных, ясен хрен) — вагон и маленькая тележка (см. https://github.com/mediawiki4intranet/, http://wiki.4intra.net/Mediawiki4Intranet), и я даже иногда собираюсь с мыслью и какие-то мелкие патчики засылаю.
Но в gerrit что-то им засылать — это вообще бесполезно. Потому что оно может висеть год и никто даже не посмотрит. Или ещё лучше — может висеть пару лет несмотря на то, что кто-то посмотрел и сказал что всё ОК, но прав на мерж у него нет. Кроме того, ревьюеров надо выбирать ЛИЧНО! Это фича геррита. Отстой жуткий — во-первых, как-то неудобно лично людей push’ить. Во-вторых — вообще непонятно, кого выбирать из этой толпы.
А вот сейчас пытаюсь пропихнуть в SemanticMediaWiki простейший двухстрочный коммит, который отключает совершенно дурацкую «анти-фичу» — форсирование типа (без возможности переопределения) свойства, если оно называется так же, как тип. То есть в оригинале у них поле «Номер телефона» всегда имеет тип «Номер телефона» (который, кстати, далеко не все форматы вообще понимает), и поменять его нельзя… ну и в документации это не отражено. Так тоже, блин, проблемы — в gerrit’е Маркус Кроетсзч (хз как это произнести — Хрущ блин) сказал что чо-то ему там не нравится, и предложил мне переопределять их на уровне PHP конфигурации. Я сказал что чувак — если тебя волнует совместимость — давай я сделаю maintenance скриптик который будет на существующих виках их сам обновлять.
После чего всё… тишина…
Ок, сейчас они перешли на гитхаб и я им радостно назасылал pull request’ов. И было обрадовался — Jeroen De Dauw вроде сразу влил этот коммит (ХОТЯ БЫ этот двухстрочный коммит). Но потом пришёл другой чувак и всё испортил, напомнив что Маркусу чо-то там не нравилось, и коммит опять отменили.
Ну вот какой в этом смысл? Я удивляюсь — если двухстрочный коммит вызывает такие трудности, то что же будет с более сложными доработками?
Вернее, кое-что я представляю — я же им туда ещё пару патчей отправил вчера — во-первых, реализацию оператора отрицания в запросах, во-вторых, исправление бага выполнения запроса «(a OR b) AND (c OR d)» (он вообще не выполнялся, так как выполнялка через жопу написана). Так они вообще прикольно — про второй сказали, что да, чувак, мы видим, ты тут что-то сделал, но тут у нас вообще какой-то сложный код, в котором мы ни хрена сами не понимаем, а тестами он не покрыт, так что мы сходу проверить не можем… А про первый — рассказывают мне, что в нашем патче код мол плохой, хотя он у нас в точности такой же, как у них — в 100 % их же стиле написан :-) не буду же я за них ИХ код рефакторить. А если и буду — всё равно не примут :-D
И да, чуть не забыл — там вообще куча любителей «чрезмерной объектной ориентированности». Нет бы код попроще писать.
В общем, что будет, если отправить что-то ещё более значительное — аж представить страшно…
2013-11-13 Firefox for Android
Кстати, ещё в тему открытости: поставил себе на телефон Firefox.
Могу сказать, что он стал вполне юзабелен — на жирных страницах чуть помедленнее хрома, но в целом — пофиг. Чуть странноватый скроллинг — после начала горизонтального/вертикального таскания специально жёстко «прилипает» к горизонтали/вертикали и сдвинуть по диагонали уже, например, не даёт. Логичнее — тоже как в хроме, когда до какого-то предела оно прилипает, а потом отпускается. Чуть-чуть неудобен автозум на полях ввода — иногда делает их слишком мелкими.
Интерфейс открытия новой вкладки и переключения между оными — по мне, наоборот, удобнее. Память, если наоткрывать много вкладок, жрёт прилично; но я не верю, что хром жрёт особо меньше. В диспетчере задач хром при 10 вкладках показывает ~60-80 мб — это НЕРЕАЛЬНО МАЛО. Скорее всего потому, что хром отдельный процесс на каждую вкладку форкает, и просто их память получается не посчитана в диспетчере.
Но это всё в целом мелочи. Самое главное, что в ФФ есть расширения! Туда можно поставить нормальный AdBlock! И ещё там есть расширение, которое обрезает гугловские редиректы! И того, и другого (особенно даже второго) мне на телефоне ДИКО не хватало.
Так что всё, юзаю фокс.
2013-11-13 Да ну на хрен - цианоген тоже продался
Ой, как круто, офигеть можно! Цианоген продался!
В новых CyanogenMod не будет root доступа по умолчанию, его нужно будет ставить отдельно. Зо-е-бись. Типа им дали сколько-то там лямов инвестиций и чтобы иметь возможность официально ставить в систему гуглозонды (google apps), они теперь пилят совместимость с гугловским тестовым набором, который (surprise!) проверяет, чтобы рута не было. Кроме того, для прохождения тех же тестов они выпилили «дополнительные настройки» и возможность сохранения фотографий на внешнюю карточку памяти (последнее — совсем фарс).
Кроме того, у них все контрибьюторы изначально подписывали соглашение, которое передаёт права на код CM, таким образом позволяя его перелицензировать под закрытой лицензией и продавать производителям. Которым, соответственно, никто не мешает вообще закрыть систему и запретить установку этого дополнительного пакета с рутом.
А чуваку-автору GPL камеры Focal этот пидарас Steve Kondik хотел настойчиво предложить перелицензировать её под пермиссивной лицензией, опять-таки, чтобы иметь возможность закрыть. Чувак — молодец — отказался, и этой камеры теперь в цианогене нет. Честь и хвала.
Просто у меня реально вопрос: ну какой смысл в коммерческом цианогене? Кроме открытости, у CM изначально фич по сравнению с обычным андроидом почти никаких и не было. Именно открытость и доступность рута из коробки рулила. А так это будет просто ещё один штатный ROM.
Ну и да, всё это лишнее подтверждение того, что permissive лицензии = удел проприерастов. А главный плюс нормального свободного софта в том, что он не контролируется никакими уродами с «инвестициями». А раз эти продались (если это действительно правда), я ни им, ни их проекту ничего хорошего не желаю. Пусть RIPается.
2013-11-10 Научился делать мини-репозитории для Дебиана
И тут же радостно залил туда правильный патченый Gimp, а также subversion 1.8.4, и serf 1.3.2, требуемый для него.
Причём по поводу svn 1.8 — изрядно набодался с новым планировщиком запросов в SQLite 3.8. Пришлось впиливать туда патч, прописывающий правильные данные в таблицу статистики SQLite в каждой рабочей копии svn, чтобы оно индексы правильно юзало.
Там же лежат пакеты исходников, и они в jessie вполне успешно пересобираются (правда, в svn с DEB_BUILD_OPTIONS="nocheck", так как часть их тестов всё-таки фейлится). Вот такой мини-архивчик вышел:
deb http://vmx.yourcmc.ru/var/debian/ unstable/ deb-src http://vmx.yourcmc.ru/var/debian/ unstable/
Ключик можно брать с apt-key adv --keyserver pgp.mit.edu --recv c9d991da5f98c882.
Теперь думаю, а не попробовать ли svn 1.8.4 как-то заслать мейнтейнерам дебиана?
2013-10-30 php-apply
Вот пишут люди про PHP ерунду всякую — фрактал плохого дизайна… сравнение нетранзитивное… ещё что-то там… Так вот, это всё фигня и вообще не расстраивает ни разу (разве что соглашусь, что синтаксис и реализация неймспейсов дебильны).
А вот что меня реально всегда расстраивало — так это то, что в PHP классы после загрузки нельзя модифицировать извне. Ну то есть можно — есть runkit, и говорят, что он в последнее время даже работает (когда я его пробовал 2-3 года назад — не работал, крашился). Но он довольно нетривиален, делает всякую магию — копирует байткод функции, меняет переходы… Не факт, что это быстро, и также не факт, что не отвалится в будущем.
Особенно «модификация класса извне» становится актуальна с появлением trait’ов (примесей), которые авторы реализовали, но реализовали как-то косо и по моему ощущению они там ни к селу, ни к городу. Вроде хочется, чтобы trait был таким себе плагинчиком, который можно подоткнуть в класс в любой момент, ан нет — его надо use внутри самого определения класса, да ещё применить довольно странный синтаксис разрешения конфликтов имён:class X { use Trait1, Trait2 { Trait1::a insteadof Trait2; } }
Если взглянуть немного шире, становится ясно, что зачастую сам класс-то менять, в общем, и не обязательно, достаточно сделать ему apply(), как в js — то есть вызвать внешнюю функцию в контексте произвольного объекта. Но и этого в php сделать нельзя, потому что $this — это не просто первый аргумент функции, как в перле или питоне, а некое поле внутренних структур движка, которое просто так не поменяешь. Ну, и ещё в отличие от js есть protected/private методы.
Так вот — сегодня меня вштырило и я этот apply родил в виде тривиального экстенжна с одной функцией — apply_user_func(object $object, callable $callback, array $args).
С ним можно делать вот так:
class A { var $b = "abc\n"; private function f_a() { print "Опа!\n"; } } function f() { print $this->b; // нам будет доступно поле класса A $this->f_a(); // и его private метод тоже будет доступен } $a = new A(); apply_user_func($a, 'f', array());
Экстенжн реально тривиальный, всего сотня с лишним строчек, из которых НЕ-копипасты — на самом деле вообще строчек 8. Ну, тест ещё 76 строчек, ок. По скорости работает чууть-чуть помедленнее, чем call_user_func_array с аналогичной семантикой, и где-то на 80% медленнее, чем обычный вызов функции.
В общем, можно юзать :) под 5.4 и 5.5 работает.
- Скачать .tar.gz можно тут: http://svn.yourcmc.ru/viewvc.py/vitalif/trunk/php-apply/?view=tar
- Просмотр кода онлайн: http://svn.yourcmc.ru/viewvc.py/vitalif/trunk/php-apply/
2013-10-27 Правильный фикс USB для антенны РЭМО Коннект
Собственно, РЭМО Connect 2.0 — это вообще не антенна, а отражатель сигнала в корпусе из дешёвого пластика с гнездом для установки USB модема (3G/4G). Гнездо — тоже банальный пластиковый кожух, в который засунут конец обычного USB удлинителя длиной 3 метра. Являющегося, по сути, проводом этой антенны. Такой, типа, бюджетненький вариант.
Оно, как ни странно, вполне работает и на обещанные +8 дб сигнал усиливает. Я через него йоту подключаю (БС находится в 5-6 км, через лес) и скорость получаю нормальную.
Короче, всё бы хорошо, но вот при подключении к роутеру (TP-LINK TL-MR3420) через эту «антенну» йотовский модем не заводится — видимо, у роутера нежный USB и у модема нежный USB и, несмотря на 2 феррита на проводе (удлинителе), мощности USB сигнала для преодоления 3 метров не хватает…
К счастью, РЭМО к той же антенне прилагает USB хаб и продаёт это под названием Connect 2.2. И если подключить к роутеру хаб, а в хаб воткнуть провод от антенны — таки заводится и работает почти стабильно. Всё равно отваливается — иногда раз в минуту, а иногда раз в час — но работает.
То есть, до частичного фикса РЭМО додумалось :) а вот как этот фикс можно было улучшить — надо было сделать, чтобы хаб стоял непосредственно перед модемом, на конце удлинителя. Я вот его туда только что тупо прикрутил скотчем, и в такой конфигурации оно таки да, не отваливается вообще.
2013-10-05 Сборник ссылок по теме Gimp Save&Export
Ещё раз, вкратце — с версии 2.8 GIMP заставляет пользователей нажимать «Export», а не «Save» для сохранения в любые форматы, кроме XCF. Спецификация этого чрезвычайно дебильного и неоправданного юзабилити-решения вот тут: http://gui.gimp.org/index.php/Save_%2B_export_specification
Причём, что больше всего добивает — любые попытки доказать авторам, что новое поведение неудобно, бесполезны. Видимо, у авторов не по-детски зашкаливает ЧСВ, так как на абсолютно любые аргументы они ответят вам, что:
- Вам не нужно пользоваться GIMP, так как это слишком сложный и крутой редактор для вас. GIMP — это вам не фоточки редактировать, а суперпрофессиональный инструмент, а вы идите и пользуйтесь аналогами MS Paint.
- Вас таких недовольных вообще 3 человека (ну может максимум 10) на всё многомиллионное сообщество, а всем остальным фича нравится (опроса, естественно, никто не проводил — вы просто должны поверить, что все довольны).
- Даже если вас больше — вы не наша целевая аудитория, так что ваши аргументы нас не колышут.
Прочитав тред и окончательно взбесившись от отношения авторов к пользователям, я добрался до кода, сделал патч, а потом решил, что быть вежливым бесполезно и отписался в конец треда, что авторы — moron’ы, а само поведение — total piece of shit.
Но что же можно сделать для отключения этого говна?
- Имхо наиболее удобный путь — это мой патч (простейший,
4, нет, 19 строчек) для отключения этого говна: http://svn.yourcmc.ru/viewvc.py/vitalif/trunk/scripts/patch-gimp-unite-save_export.diff?view=markup - Python плагин Акканы для отключения этого говна (но это менее удобно, так как отдельная команда): https://github.com/akkana/gimp-plugins/blob/master/save-export-clean.py
- Форк, типа вообще без этого говна: https://github.com/mskala/noxcf-gimp (не проверял; возможно из форка (будет?) выпилен XCF?)
- UPDATE: Сделал мини-репозиторий с патченым gimp’ом в виде дебиановского пакета (патч просто добавлен в debian/patches) — добавьте в sources.list deb http://vmx.yourcmc.ru/var/debian/ unstable/ (именно с / на конце).
Темы/посты с руганью/критикой:
- Мой свежий срач на ЛОРе: http://www.linux.org.ru/forum/general/9654090
- Самый длинный тред из рассылки, теперь живущий на форуме: http://www.gimpusers.com/forums/gimp-user/14339-hate-the-new-save-vs-export-behavior
- http://registry.gimp.org/node/26273
- http://www.davidrevoy.com/article146/save-export-in-gimp-2-8
- https://mail.gnome.org/archives/gimp-user-list/2013-February/msg00161.html
- http://gimpforums.com/thread-gimp-save-save-as-versus-export
- http://pclosmag.com/html/Issues/201211/page11.html
- http://blog.balfes.net/2013/01/03/where-gimp-2-8-went-wrong/
- Аккана про свой плагин: http://shallowsky.com/blog/gimp/gimp-save-export-clean.html, http://www.gimpusers.com/forums/gimp-user/14746-a-plug-in-for-those-who-still-don-t-like-the-new-save-export
2013-10-03 Disable Gimp Save&Export
My post about gimp Save and Export to http://www.gimpusers.com/forums/gimp-user/14339-hate-the-new-save-vs-export-behavior#message74677
I want to say two things:
- The new behaviour is a TOTAL PIECE OF SHIT. And the authors are just MORONS because they argue that if you dislike it, you are an idiot, "misuse" gimp and should only use MSPAINT because of a low IQ. Just like it was with the single-window mode, yeah.
- But - Good news, everyone! That bevaviour really fucked me up and I got to the code and patched it. And the patch to DISABLE that piece of shit is very simple - you just need to comment out two if()'s in app/plug-in/gimppluginmanager-file.c (see below or get it from http://svn.yourcmc.ru/viewvc.py/vitalif/trunk/scripts/patch-gimp-unite-save_export.diff?view=co).
After patching, Gimp still suggests you to save the opened *.png or anything in XCF on Ctrl-S, but it does so only the FIRST time, and ALLOWS to actually select any other format.
Patch source:
Gimp authors are MORONS! Shame on you all for splitting "Save" and "Export" features and for arguing that everyone who dislikes the new behaviour is an idiot and should use MSPAINT instead of their super-duper GIMP! First part -- enable all formats in both save and export: --- gimp-2.8.6.orig/app/plug-in/gimppluginmanager-file.c +++ gimp-2.8.6/app/plug-in/gimppluginmanager-file.c @@ -136,13 +136,13 @@ gimp_plug_in_manager_register_save_handl gimp_plug_in_procedure_set_file_proc (file_proc, extensions, prefixes, NULL); - if (file_procedure_in_group (file_proc, FILE_PROCEDURE_GROUP_SAVE)) + //if (file_procedure_in_group (file_proc, FILE_PROCEDURE_GROUP_SAVE)) { if (! g_slist_find (manager->save_procs, file_proc)) manager->save_procs = g_slist_prepend (manager->save_procs, file_proc); } - if (file_procedure_in_group (file_proc, FILE_PROCEDURE_GROUP_EXPORT)) + //if (file_procedure_in_group (file_proc, FILE_PROCEDURE_GROUP_EXPORT)) { if (! g_slist_find (manager->export_procs, file_proc)) manager->export_procs = g_slist_prepend (manager->export_procs, file_proc); Second part -- do not suggest saving a non-xcf image into xcf format, even on the first save click. --- gimp-2.8.6.orig/app/actions/file-commands.c +++ gimp-2.8.6/app/actions/file-commands.c @@ -228,6 +228,9 @@ file_save_cmd_callback (GtkAction *actio return; uri = gimp_image_get_uri (image); + if (! uri) + uri = gimp_image_get_imported_uri (image); + uri = g_strdup (uri); switch (save_mode) { @@ -348,6 +351,8 @@ file_save_cmd_callback (GtkAction *actio { gimp_display_close (display); } + + g_free (uri); } void Third part - suggest the same type as import/export by default. --- gimp-2.8.6.orig/app/widgets/gimpfiledialog.c 2012-12-06 03:41:06.000000000 +0400 +++ gimp-2.8.6.orig/app/widgets/gimpfiledialog.c 2013-11-08 22:53:03.095326498 +0400 @@ -571,11 +571,19 @@ gimp_file_dialog_set_save_image (GimpFil /* Priority of default type/extension for Save: * * 1. Type of last Save - * 2. .xcf (which we don't explicitly append) + * 2. Type of last Export + * 3. Type of import source + * 4. .xcf (which we don't explicitly append) */ ext_uri = gimp_image_get_uri (image); if (! ext_uri) + ext_uri = gimp_image_get_exported_uri (image); + + if (! ext_uri) + ext_uri = gimp_image_get_imported_uri (image); + + if (! ext_uri) ext_uri = "file:///we/only/care/about/extension.xcf"; } else /* if (export) */