Sat, Apr 13, 2013

Диагностика ядра Linux

Сбои в ядре Linux приводят к возникновению чрезвычайно разнообразных симптомов. Некоторые авторы дают следующую неполную классификацию проблем, с которыми может столкнуться пользователь:
  • kernel oops — проблема при выполнении кода в ядре, например кто-нибудь попытался разыменовать нулевой указатель. С кем из программистов на C такого не случалось?
  • kernel panic — кто-то попытался разыменовать нулевой указатель в обработчике прерываний. После чего ядро уходит в полную несознанку и начинает мигать caps-lock-ом.
  • soft lockup ­— что-то заблокировалось (вероятно наткнувшись на не освобожденную блокировку), несмотря на это прерывания продолжают обрабатываться. Хорошее упражнение — попинговать машину или попытаться зажечь numlock.
  • hard lockup — компьютер жужжит вентиляторами и ни на что не реагирует. Провести какую-то диагностику в этом случае особенно сложно. Проблема может быть вызвана как вышедшим из строя железом, так и неаккуратной обработкой прерываний.
кроме того, можно добавить:
  • hung — индуцированное неправильной блокировкой последовательное попадание всех или большинства процессов системы в состояние TASK_UNINTERRUPTIBLE (известного так-же как D-состояние, по обозначению в top или ps). Согласно книге Р.Лава такой «наводящий ужас» процесс нельзя убить, завершить, и вообще что-то с ним сделать. При этом с точки зрения пространства пользователя программа просто заблокирована на каком-то системном вызове (например ввода-вывода). При попадании в подобное состояние всех критических процессов системы можно получить симптом похожий на soft lockup.
Получить как можно более подробную информацию о сути возникающей проблемы важно как для правильного написания сообщения об ошибке, так и для временного переконфигурирования системы с целью избегания выполнения проблемного кода и повышения её живучести.

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

printk


Одним из механизмов общения ядра с внешним миром является printk. При неправильной настройке сообщение скорее всего будет просто потеряно как не обладающее значимостью. Для настройки используется /proc/sys/kernel/printk, соответствующий ему параметр sysctl, утилита klogconsole, SysRq-клавиша и т.п. Ядро обладает восемью уровнями важности сообщений, поэтому установка уровня в 8 заведомо напечатает все на консоль.

sysrq


Магическая кнопка включается в /proc/sys/kernel/sysrq или соответствующим ему параметром sysctl. Предлагается просто записать туда 1, несмотря на то, что новые ядра позволяют изысканный контроль над функционалом. В данной ситуации незачем себя ограничивать, хотя для нормальной работы разумно ограничить функционал на случай случайных нажатий. Если осталась рабочая терминальная сессия (например удаленная сессия по ssh), можно использовать как альтернативу, например, echo b > /proc/sysrq-trigger; с последовательной консоли поведение активируется кнопкой 'break'.

Важно помнить, что SysRq-w, например, выдает сообщение с уровнем KERN_INFO, то есть выдача printk должна быть настроена правильно, чтобы можно было что-то увидеть. Полный список команд SysRq.

softlockup_panic


Параметр ядра softlockup_panic или параметр kernel.softlockup_panic для sysctl включают панику ядра при обнаружении soft lockup. Описание внутреннего устройства. Включение паники позволит остановить выполнение системы и проанализировать выдачу, снабженную трассировкой, хотя контроль блокировки исполняется постоянно. Существует аналогичный механизм отслеживания hard lockup для многопроцессорных систем (если остались живые процессоры — есть шанс что сработает), с соответствующим параметром hardlockup_panic. Время срабатывания обычно в пределах одной минуты.

hung_task_timeout_sec


Механизм отслеживания процессов, надолго застрявших в состоянии TASK_UNINTERRUPTIBLE, параметры настраиваются через sysctl и /proc:
  • kernel.hung_task_panic — включает/отключает панику при обнаружении не прерываемого процесса;
  • kernel.hung_task_warnings — счетчик сообщений. Иными словами, если паника отключена, будет сообщено о таком количестве зависших процессов;
  • kernel.hung_task_timeout_secs — сколько секунд процесс должен непрерывно пробыть в TASK_UNINTERRUPTIBLE, чтобы вызвать сообщение. По умолчанию бывает либо выключено (0), либо очень большое число порядка 10 минут.
Сообщения снабжаются трассировкой, которая подсказывает в какой подсистеме происходит сбой.

Sun, Feb 24, 2013

svn+ssh: коллективные соединения

При командах выполняемых на удаленном URL, типа copy или merge, subversion иногда требует несколько соединений. Для облегчения работы, можно применить стандартную возможность ssh — использовать одно TCP/IP соединение для нескольких сессий.

Чтобы не испортить настройки клиентского ssh, в секции [tunnels] файла конфигурации ~/.subversion/config зададим нужные настройки как параметры командной строки:
ssh = $SVN_SSH ssh -o "ControlMaster=auto" -o "ControlPath=/home/user/.ssh/svn_ssh-%r@%h:%p" -o "ControlPersist=60"

При этом соединение будет создаваться каждый раз при необходимости, и закрываться через 60 секунд после того, как оно становится невостребованным. ControlPersist=yes оставит соединение навсегда, что, вероятно, не очень безопасно, но зато позволяет комфортно исполнять разные команды, типа commit или update в течении работы, если расходы на создание соединения велики.

Sun, Feb 17, 2013

quilt и rpm

quilt — это система контроля патчей, в каком-то смысле предыдущая ступень эволюции систем контроля версий.

Пусть есть rpm-пакет и нужно обновить его версию, используя новый архив исходных кодов. При этом патчи останутся старыми, и не гарантируется, что они наложатся на новую версию, или не потребуется вмешательство человека, из-за того, что какой-то патч устарел. После того, как новый архив получен и Version: исправлен, можно прибегнуть к помощи quilt:
quilt setup libdc1394.spec

Эта команда создаст новую директорию в которой будут лежать распакованные исходные коды, символическая ссылка на директорию patches (хранит сами файлы патчей) и файл series (хранит порядок в котором патчи нужно применять). quilt не всегда успешно справляется с патчами, которые завернуты в %if.

Идеологически происходит следующее, у нас есть команда quilt, что-то вроде аналога git или hg, дерево исходников и стек патчей. Стек патчей в чем-то аналогичен ревизиям в системах контроля версий. Используя стек можно переходить от текущего состояния к следующему (применяя патч, quilt push) или к предыдущему (откатывая, quilt pop). Первоначально, мы находимся в самом нижнем состоянии (не модифицированные исходные коды):
>quilt top
Нет применённых патчей
>quilt applied 
Нет применённых патчей
>quilt unapplied 
patches/libdc1394.no-x11.patch
patches/libdc1394.ac.patch
patches/libdc1394-swab_fix.patch
patches/libdc1394.raw1394_set_iso_handler.patch
patches/libdc1394-v4l-2.6.38.patch
patches/libdc1394-visibility.patch

Дальше попробуем наложить первый патч (здесь потребовалась предварительная обработка из-за хитрой структуры директорий в конкретном случае),
>quilt push
Наложение патча patches/libdc1394.no-x11.patch
patching file libdc1394-1.2.2/examples/Makefile.am
patching file libdc1394-2.2.1/configure.in

Текущий патч: patches/libdc1394.no-x11.patch
>quilt top
patches/libdc1394.no-x11.patch
>quilt applied
patches/libdc1394.no-x11.patch

И так далее, пока не закончится весь стек патчей, но скорее всего так просто он не закончится. Задача — обновляя патчи, устранить конфликты. После принудительного применения (quilt push -f) следует вручную просмотреть все конфликтные места и исправить их нужным образом. Каждый патч отслеживает только некоторое число файлов (quilt files), но если отредактирован файл не из списка, то его нужно добавить (quilt add). После того как все исправлено, нужно обновить текущий патч: quilt refresh (это такой аналог commit, который исправляет текущий наложенный патч, основываясь на рабочей директории и предыдущей спрятанной копии)
>quilt refresh
Патч patches/libdc1394-v4l-2.6.38.patch обновлён



Tue, Jan 22, 2013

udev и camsource

(Пере)запускалка camsource (программы для показывания картинок с веб-камер) с помощью udev:

SUBSYSTEM=="video4linux", ACTION=="add", RUN+="/usr/bin/camsource -r /etc/camsource.conf"

Запускается на старте (когда udev обнаруживается usb-устройства), и перезапускается при их перетыкании (или перетыкивании).

Можно было бы сделать более красиво, т.е. использовать события "add" и "remove" и переменную DEVICE. Однако этому мешает, во-первых, использование нескольких источников в моей конфигурации (и camsource -k выключил бы сразу все), во-вторых какой-то встроенный глюк в самой программе. Дело в том, что запускаясь, процесс почему-то уходит в состояние зомби, и в /proc/NNNNN/fd оказывается пустота. А при использовании параметра [device] код ищет процесс именно по файловым дескрипторам. Иначе говоря, этот параметр вообще не работает.

Применив фантазию к udev, можно например включать трансляцию видео-потока. Что даже удобнее, чем вписывание не комплектуемых init.d-скриптам запуска camsource, ffserver и т.п. во всякие странные места типа /etc/init.d/boot.local.

Sat, Jan 19, 2013

OBS tar_scm: versionformat

Сервис для OBS под названием tar_scm позволяет автоматически создавать архивы из указанных репозиториев систем контроля версий исходных кодов. Естественно, имеет много параметров, описание которых не так просто найти. На головном web-интерфейсе взаимодействие с сервисами куда-то с недавних пор вообще пропало, там хоть какие-то подсказки содержались.

versionformat — один из самых любопытных параметров, позволяющих хоть как-то оформить название архива, для последующего действия сервиса set_version.

  • Для git в это поле можно указать:
    • @PARENT_TAG@ — bash любезно заменит на ближайший тег
    • поля из --pretty=format для последнего по времени коммита — полный список внизу, какой-то смысл в данной ситуации имеют %ct %cd %h (UNIX таймштамп, дата YYYYMMDD, короткий хэш коммита), причем дефисы будут любезно удалены по дороге sed'ом (даты будут получается в духе 20121221).
  • Для mercurial (hg):
    • поля из --template для последнего по времени коммита — полный список внизу. Огромное богатство для фантазии, есть встроенная опция для latesttag. Во время написания этого текста, не было способа выдать дату в виде YYYYMMDD, без дефисов. Сейчас все дефисы удаляются sed'ом, однако последняя версия tar_scm может быть еще не загружена на головной сервис.
  • svn понимает только %r — номер ревизии

  1. github: obs-service-tar_scm
  2. git show(1)
  3. hg templates

Sun, Dec 16, 2012

pwdutils RIP

Широко анонсированный конец света начал потихоньку наступать. Спустя пару месяцев с момента написания моего предыдущего поста shadow-utils vs. pwdutils, основной разработчик pwdutils Торсен Кукук (Thorsten Kukuk) взял и «тихо и незаметно» выпилил pwdutils из следующего релиза openSUSE 12.3 в пользу shadow (Вероятно восклицая в этот момент «Стой и не шевелись! Я тебя породил, я тебя и убью!»).

Репортаж с места события:

Возрадуемся же необходимости оборачивать свои spec-файлы очередными несвежими условными операторами, впрочем я уже давно и так это делаю:
%if 0%{?fedora} || 0%{?rhel_version} || 0%{?centos_version}
%define usermod_A /usr/sbin/usermod -a -G
%else
%define usermod_A /usr/sbin/usermod -A
%endif

p.s. Неужели pam_unix2.so будет следующей жертвой унификации?

Sat, Oct 20, 2012

OBS submit request top

There was a discussion on submit requests. Adrian Schröter and Jos Poortvliet suggested to use OBS api to generate some kind of reports on pending times. Here is a test (I will publish this python script on github or something like that). I've filtered out all "home:" projects and built following table. To my surprise, there are only a little stalled requests.


Generated at: 2013-04-13 05:27:41.044818
Request Pending time Project Package
1317 1680 days system:management puppet
25359 1227 days YaST:Web:STABLE webyast-vendor_en
31953 1158 days Moblin:Factory gnome-session
33643 1138 days Moblin:Factory gnome-settings-daemon
33644 1138 days Moblin:Factory dalston
33868 1136 days Moblin:Factory icon-theme-dmz-cursors
38905 1081 days Moblin:2.0 dalston
55428 855 days security:CASA CASA-kwallet
55429 855 days security:CASA CASA_auth_token_client
55431 855 days security:CASA CASA_auth_token_server
69864 705 days system:wicd wicd
72401 681 days isv:dell:community python-ctypes-rhel
74258 661 days net-snmp
74259 661 days net-snmp
74260 661 days net-snmp
75895 644 days network:ifolder:server_stable
110363 387 days Maemo:Mer:Extras:Import opengfx
123245 315 days isv:microsoft RHEL6
131196 236 days openSUSE:11.0:Update:Test
134952 206 days Banshee:Legacy ipod-sharp
134958 206 days Banshee:Legacy podsleuth
134959 206 days Banshee:Legacy ndesk-dbus-glib
134960 206 days Banshee:Legacy ndesk-dbus
136458 195 days GNOME:Evolution:mapi evolution-mapi
137714 184 days Maemo:Mer:Extras:Import
138490 177 days devel:languages:lua luaexpat
145153 121 days games:WorldForge wfmath
145154 121 days games:WorldForge skstream
145155 121 days games:WorldForge libwfut
145156 121 days games:WorldForge libdevil
145162 119 days devel:languages:lua tolua++
145501 119 days Novell:NTS supportutils-plugin-susecloud
145520 119 days isv:ownCloud:community patchinfo
147640 94 days devel:languages:lua lua-lgi
147641 94 days devel:languages:lua lua51-lgi
151409 66 days Arch:Extra
151535 65 days Arch:Core
153990 64 days Mono:Beta
154756 64 days Virtualization:openSUSE11.4
154759 64 days spins:open-pc:kde
155682 54 days Apache:Modules apache2-mod_authz_unixgroup
155683 54 days Apache:Modules pwauth
158065 35 days Apache:Modules apache2-mod_authn_sasl
158089 34 days openSUSE:Evergreen:11.4 drbd.64
158089 34 days openSUSE:Evergreen:11.4 drbd.64
158089 34 days openSUSE:Evergreen:11.4 drbd.64
158089 34 days openSUSE:Evergreen:11.4 drbd.64
158089 34 days openSUSE:Evergreen:11.4 drbd.64
158089 34 days openSUSE:Evergreen:11.4 drbd.64
158089 34 days openSUSE:Evergreen:11.4 drbd.64
158089 34 days openSUSE:Evergreen:11.4 drbd.64
158089 34 days openSUSE:Evergreen:11.4 drbd.64
158089 34 days openSUSE:Evergreen:11.4 drbd.64
158089 34 days openSUSE:Evergreen:11.4 drbd.64
158089 34 days openSUSE:Evergreen:11.4 drbd.64
158089 34 days openSUSE:Evergreen:11.4 drbd.64
158089 34 days openSUSE:Evergreen:11.4 drbd.64
158089 34 days openSUSE:Evergreen:11.4 drbd.64
158089 34 days openSUSE:Evergreen:11.4 drbd.64
158089 34 days openSUSE:Evergreen:11.4 drbd.64
158089 34 days openSUSE:Evergreen:11.4 drbd.64
158089 34 days openSUSE:Evergreen:11.4 drbd.64
158089 34 days openSUSE:Evergreen:11.4 drbd.64
158089 34 days openSUSE:Evergreen:11.4 drbd.64
158556 32 days windows:mingw:win32 mingw32-cross-nsis
158558 32 days windows:mingw:win32 mingw32-cross-nsis-plugin-zipdll
159540 28 days Java:base clojure
159797 25 days security:netfilter SuSEfirewall2
159894 25 days drivers:nic r8168
160430 22 days network:ha-clustering:Factory corosync
160446 22 days security:passwordmanagement password-store
160510 22 days network:telephony:asterisk-11
160725 20 days isv:ownCloud:community
160726 20 days isv:ownCloud:community owncloud
160727 20 days isv:ownCloud:community qtkeychain
160794 19 days network:storage bcache-tools
160846 19 days X11:wxWidgets wxWidgets
160961 18 days Archiving:Backup rsync
160962 18 days Archiving:Backup librsync
161043 18 days Archiving:Backup dkopp
160885 17 days KDE:Qt50 libqt5-qtwebkit
161474 16 days X11:Cinnamon:Factory cinnamon-screensaver
161616 15 days security:passwordmanagement
162321 10 days Apache:Modules apache2-mod_authn_otp
162491 9 days utilities byobu
162528 9 days filesystems libvshadow
162537 9 days openSUSE:Tools obs-service-verify_file
162581 8 days vdr
162074 7 days, 22 hours devel:openSUSE:Factory:legal-queue which
162691 7 days, 21 hours openSUSE:12.3:Update pesign-obs-integration.1510
162691 7 days, 21 hours openSUSE:12.3:Update pesign-obs-integration.1510
162691 7 days, 21 hours openSUSE:12.3:Update pesign-obs-integration.1510
162691 7 days, 21 hours openSUSE:12.3:Update pesign-obs-integration.1510
158276 7 days, 16 hours devel:openSUSE:Factory:legal-queue sazanami-fonts
162931 7 days, 6 hours filesystems libsmdev
162932 7 days, 6 hours filesystems libsmraw
162933 7 days, 6 hours filesystems libodraw

Sat, Oct 06, 2012

shadow-utils vs. pwdutils

Существуют два пакета утилит: shadow-utils и pwdutils (применяется в SUSE). Служат они для одной цели — редактирования групп и пользователей, но при этом значения набора параметров отличаются. Среди шестерки утилит user{add,mod,del} и group{add,mod,del}, к счастью, наблюдается некоторая систематика.

В shadow-utils следующие параметры имеют всегда одинаковое значение (в pwdutils отсутствуют, если явно не указано обратное):
Ключ Значение
-D изменяет значения по умолчанию
-K key=value для значений по умолчанию
-R запускать в chroot
-Z пользователь SELinux

При этом ключи pwdutils другое (в shadow-utils отсутствуют, если явно не указано обратное):
Ключ Значение
-D DN для LDAP
-P путь к /etc/passwd и /etc/shadow

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

С проблемами первой условной группы можно было бы бороться используя явные длинные названия. Это делает скрипт более длинным, но и более явным. Однако, для -e длинные варианты отличаются: --expiredate и --expire.

useradd

Ключ Shadow Pwd
-M не создавать /home нет
-N не создавать группу пользователю нет
-U создать пользователю одноименную группу маска umask для домашней директории
-b базовый каталог, вместо /home нет
-l не добавлять в lastlog нет

usermod

Ключ Shadow Pwd
-A нет добавить в группу (аналог -a -G)
-R запускать в chroot удалить из группы
-a (вместе с -G) добавить в группу недокументированный

groupadd

Ключ Shadow Pwd
-f не ругаться, если группа уже есть недокументированный

groupmod

Ключ Shadow Pwd
-A нет добавить пользователя в группу
-R запускать в chroot удалить пользователя из группы
-n переименовать недокументированный

Tue, Jun 12, 2012

Mercurial

Минимальная инфраструктура для работы с распределенной системой контроля версий Mercurial настраивается следующим образом.

Во-первых, нужно где-то разместить репозитории. Поскольку никаких других рекомендаций не поступало, по аналогии с cvs и svn будем класть все в /srv/hg/repos. Во-вторых, нужно обеспечить теперь доступ разным пользователям, которые счастливо существуют на компьютере и что-то там делают. Основная инструкция тут: http://mercurial.selenic.com/wiki/MultipleCommitters. Краткая инструкция: по аналогии с cvs и svn, создаем системную группу hg, системного пользователя hg, добавляем всех пользователей в группу hg.

Схема создания нового репозитория выглядит следующим образом:
cd repos/
mkdir test
chown -R hg:hg test
cd test/
hg init
chown -R hg:hg .hg
chmod -R g+w .hg
chmod g+s .hg .hg/store .hg/store/data

Mercurial >1.0 сам, о чудо, разбирается с правами доступа и делает так, чтобы все кому надо могли туда писать. Вообще говоря, данный подход (пулить всем вместе в один репозиторий) полностью противоречит идеологии hg.

В-третьих, никак не обойтись без веб-интерфейса. В /usr/share/doc/packages/mercurial живет пример под названием hgweb.cgi. Кладем его в /srv/hg/bin/hgweb.fcgi и меняем примерно следующим образом (чтобы через FastCGI работал):
#!/usr/bin/python

config = "/srv/hg/config"

from mercurial import demandimport; demandimport.enable()
from mercurial.hgweb import hgweb, wsgicgi
from flup.server import fcgi
application = hgweb(config)
fcgi.WSGIServer(application).run()

Конфигурация для lighttpd (обычно кладется куда-нибудь в /etc/lighttpd/vhosts.d/hgweb.conf):
fastcgi.server += (
        "/hg" => ((
                        "bin-path" => "/srv/hg/bin/hgweb.fcgi",
                        "socket" => socket_dir + "/hgweb.sock",
                        "max-procs" => 1,
                        "check-local" => "disable",
                        "fix-root-scriptname" => "enable",
        ))
)

Что писать в /srv/hg/config подсказывают в hg help hgweb:
[paths]
/ = /srv/hg/repos/*
/home/user = /home/user/hg/**

Последняя строчка для того, чтобы пользователям было не обидно, там они хранят свои личные репозитории. Вот только . Поля "Description" и "Contact" настраиваются в .hg/hgrc персонально для каждого репозитория. Кроме того, теперь через http возможно анонимное клонирование.

В openSUSE перерабатывают страницу software.

В openSUSE перерабатывают страницу software.opensuse.org и придумали полезную вещь, встраиваемый в веб-страницы виджет с информацией о пакетах; инструкция здесь.

Выглядит примерно так: