tag:blogger.com,1999:blog-39541360863753385412024-03-01T08:39:17.543+03:000x2207Matwey V. Kornilovhttp://www.blogger.com/profile/10954558557636278561noreply@blogger.comBlogger96125tag:blogger.com,1999:blog-3954136086375338541.post-11578976330876199772023-05-21T14:56:00.003+03:002023-05-21T15:27:43.537+03:00Fixing console UART on Quartz64 Model B<p>Recently, I've obtained Quartz64 Model B single board computer (the board revision is 1.4 2022.06.06). It is equipped with so-called RasbperryPi-compatible 40-pin extension header, which provides access to UART console. The board is powered by Rockchip RK3566 Quad-Core ARM Processor and default UART baudrate is 1500000 as it was for RK3328 for instance.</p>
<p>Surprisingly, I had nothing on the console when I powered the board up. Even though HDMI output works fine, and the board was booting successfully. It took some time to realize that something is wrong with the board itself. Then it appeared that other people also suffer from the similar issue:
<a href="https://forum.pine64.org/showthread.php?tid=17131&pid=115539#pid115539" target="_blank">https://forum.pine64.org/showthread.php?tid=17131&pid=115539#pid115539</a></p>
<p>At some point I attached an oscilloscope to the UART TX pin:</p>
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgZL8FOAih-rIrFEE3CCsNdv67FrnIYW_ZfTuvV8wJAZxpAm_PhGEkVl0qE7gnNs7_ZyHfl2gP8pUCUY-VKFGcqwaqKtAV01JVsARXaOnIkjx1wsZaCCsRiVe10UFc2JqI6RFn3SH4wcDfgevUzC0Ia9rxBCFv8YcaWDY9uzTyzk38EcYZ6Bq5zSuYosQ/s800/F0004TEK.JPG" style="display: block; padding: 1em 0; text-align: center; "><img alt="" border="0" width="400" data-original-height="480" data-original-width="800" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgZL8FOAih-rIrFEE3CCsNdv67FrnIYW_ZfTuvV8wJAZxpAm_PhGEkVl0qE7gnNs7_ZyHfl2gP8pUCUY-VKFGcqwaqKtAV01JVsARXaOnIkjx1wsZaCCsRiVe10UFc2JqI6RFn3SH4wcDfgevUzC0Ia9rxBCFv8YcaWDY9uzTyzk38EcYZ6Bq5zSuYosQ/s400/F0004TEK.JPG"/></a></div>
<p>
These saw teeth are supposed to be rectangular for not-disturbed signal. So, the hardware origin of the issue became more evident. Unfortunately, Pine64 support didn't help me with this issue, they only adviced to try different OS, different power supply, etc. All of that didn't helped.
</p>
<p>
<a href="https://files.pine64.org/doc/quartz64/Quartz64_model-B_Schematic-V1.3_20220124.pdf" target="_blank">The board schematic</a> is not very complicated for UART TX (the same is valid for RX):</p>
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvsXe5NEtn0vsviyDWXf1ysJclVwJDU27DQWtmjqVyozIe__4wBlPbhDrjHyQSTxfXnXjuDZcvHqyAP6gUh-GLVMRC_Xp5qpE-GwXZt9mxKFMRwvjy-LxIEizP1PVvLwm88awNpCGlPIAAbMMupf_iYGECF6lyIQp5LVLbd9TR2G0LGFSY4wbQ5ss9Xw/s514/uart2_tx_sch.png" style="display: block; padding: 1em 0; text-align: center; "><img alt="" border="0" width="400" data-original-height="138" data-original-width="514" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvsXe5NEtn0vsviyDWXf1ysJclVwJDU27DQWtmjqVyozIe__4wBlPbhDrjHyQSTxfXnXjuDZcvHqyAP6gUh-GLVMRC_Xp5qpE-GwXZt9mxKFMRwvjy-LxIEizP1PVvLwm88awNpCGlPIAAbMMupf_iYGECF6lyIQp5LVLbd9TR2G0LGFSY4wbQ5ss9Xw/s400/uart2_tx_sch.png"/></a></div>
<p>
The resistors can be probed relatively easily, it appeared that all of them have correct nominals.
So, the final decision appeared to replace Q1 (for RX line) and Q2 (for TX line) SOT-323 MOSFETs.
There are only two components of SOT-323 size on the board and they can be easily located with the help of <a href="https://files.pine64.org/doc/quartz64/Quartz64_model-B_PCB_Components_Placement-V1.2_20211014.pdf" target="_blank">components placement</a>:
</p>
<table style="margin: auto">
<tr>
<td><div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhdqPY7F0jpx76Ndwbh20t5G1G9eoVmed7tQnHFJC-ViAApUi_oEvByGzNSfQ5AUtu3d4gml_4lNUrbUIUbzKTHaaFCiU5CgXG3jrb5A42hJ0um8E_2RZCQp8qRWS1Z1K4v8KtB2kBUkgfo891Bs-foEhk5Mde9Vp_iapCHvsjdv64PNIKdbYdB3uUzBw/s366/Q1_photo.png" style="display: block; padding: 1em 0; text-align: center; "><img alt="" border="0" width="200" data-original-height="252" data-original-width="366" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhdqPY7F0jpx76Ndwbh20t5G1G9eoVmed7tQnHFJC-ViAApUi_oEvByGzNSfQ5AUtu3d4gml_4lNUrbUIUbzKTHaaFCiU5CgXG3jrb5A42hJ0um8E_2RZCQp8qRWS1Z1K4v8KtB2kBUkgfo891Bs-foEhk5Mde9Vp_iapCHvsjdv64PNIKdbYdB3uUzBw/s200/Q1_photo.png"/></a></div></td><td><div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgx6sbSEDYpyJja9eF5vpi1vlPpMOIee2ha0MCBJ-n3ko1ySyYtAEPPoWhftoPkMUAHHGGbRsDHlRS4DxxcXvqYXUDOX2dQa-aWg1b_ez57j4HdYuns7iZUHDEn7f9yY2_7p8TDlT9Jw9pzK66dabXXa_5vz_eKtKNgmum3T-fg3y7YckPepQpN5LHvlw/s292/Q1_place.png" style="display: block; padding: 1em 0; text-align: center; "><img alt="" border="0" width="200" data-original-height="209" data-original-width="292" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgx6sbSEDYpyJja9eF5vpi1vlPpMOIee2ha0MCBJ-n3ko1ySyYtAEPPoWhftoPkMUAHHGGbRsDHlRS4DxxcXvqYXUDOX2dQa-aWg1b_ez57j4HdYuns7iZUHDEn7f9yY2_7p8TDlT9Jw9pzK66dabXXa_5vz_eKtKNgmum3T-fg3y7YckPepQpN5LHvlw/s200/Q1_place.png"/></a></div></td>
</tr>
</table>
<table style="margin: auto">
<tr>
<td><div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgpip0yoDdPRSRlv8Hj4Kw6nmfE5oyxG7cTmWq8Mlym9zYyn6Nt2C_hu_uKNrkcYsBLpemaaj1QN_I58ry0x6t6vKO80vKcw9ssjXeJTKZQOHd-doerAhTr53cE7Rgt13izO2izJ7SRN4wo2hwGmDO9Elm2gbgPJ7V21aClXWiUPf-D3IEbVVb4ZmTMMw/s315/Q2_photo.png" style="display: block; padding: 1em 0; text-align: center; "><img alt="" border="0" width="200" data-original-height="215" data-original-width="315" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgpip0yoDdPRSRlv8Hj4Kw6nmfE5oyxG7cTmWq8Mlym9zYyn6Nt2C_hu_uKNrkcYsBLpemaaj1QN_I58ry0x6t6vKO80vKcw9ssjXeJTKZQOHd-doerAhTr53cE7Rgt13izO2izJ7SRN4wo2hwGmDO9Elm2gbgPJ7V21aClXWiUPf-D3IEbVVb4ZmTMMw/s200/Q2_photo.png"/></a></div></td><td><div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhSViLUAcj8256UQaOzVbBJ0nDuNvzcgo-rH5_ybfqvxNPbRq3Q8z0T7Oll2rZ3M0T8memAdU-_V4SAbqC8IN4rtS4UqYJ5oRXD-QFS8XPeQ19-xEz-97ZttE4u5FTEg9itTNI9lGtmi53UINfw2SvwaHn-j82ujQG6JmTBwWmTiQWJrU920DsLS5GuJA/s271/Q2_place.png" style="display: block; padding: 1em 0; text-align: center; "><img alt="" border="0" width="200" data-original-height="189" data-original-width="271" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhSViLUAcj8256UQaOzVbBJ0nDuNvzcgo-rH5_ybfqvxNPbRq3Q8z0T7Oll2rZ3M0T8memAdU-_V4SAbqC8IN4rtS4UqYJ5oRXD-QFS8XPeQ19-xEz-97ZttE4u5FTEg9itTNI9lGtmi53UINfw2SvwaHn-j82ujQG6JmTBwWmTiQWJrU920DsLS5GuJA/s200/Q2_place.png"/></a></div></td>
</tr>
</table>
<p>The MOSFETs have KN on their case and three pins and each located at its own side of the board. The pars are relatively big to be manually resoldered. I used Pine64 Pencil with ILS soldering tip. It seems that high-temperature lead-free soldering was used on the factory, so the temperature close to 400C was required to unsolder the parts. After the parts were replaced with the spares supplied by local electronic distributor, UART console has been working as initially expected.</p>Matwey V. Kornilovhttp://www.blogger.com/profile/10954558557636278561noreply@blogger.com0tag:blogger.com,1999:blog-3954136086375338541.post-12627640664091535142021-10-31T00:21:00.001+03:002021-10-31T00:21:22.000+03:00Использование chrony для синхронизации времени с GPS<p>
Возможность использования систем спутниковой навигации в качестве источника точного времени востребована в настоящее время, во многом благодаря обилию доступных по цене приёмников. Сервер точного времени <a href="https://chrony.tuxfamily.org/">chrony</a>, развиваемый как легковесная замена <a href="https://www.ntp.org/downloads.html">ntpd</a>, выбран во многих дистрибутивах в качестве сервера времени по умолчанию, и, конечно, поддерживает такую возможность.
</p>
<p>
Де-факто стандартом приёмников является, пришедший с водного транспорта, протокол NMEA 0183, зачастую используемый поверх RS232. Для целей синхронизации времени как правило используется отдельная линия с TTL сигналом с частотой 1 Гц. При использовании линий RS232 для передачи TTL сигнала используется DCD (первый пин разъема DB9). На популярных в последнее время одноплатных компьютерах для приема сигнала 1 Гц используется интерфейс GPIO.
</p>
<p>
На стороне ядра Linux сигнал обрабатывается подсистемой PPS: модулем <tt>pps-ldisc</tt> в случае DCD, или модулем <tt>pps-gpio</tt> для GPIO. Пользовательские приложения получают доступ к таблице событий через символьные устройства <tt>/dev/pps<i>X</i></tt>.
</p>
<p>
Данные, передаваемые по протоколу NMEA, доступны для чтения через соответсвующее устройство: <tt>/dev/tty<i>Y</i></tt>. В отличии от ntpd, chrony не содержит код для разбора протокола NMEA, поэтому полагается на <a href="https://gpsd.gitlab.io/gpsd/">gpsd</a>, который, в свою очередь, передает chrony данные о точном времени через unix сокет.
</p>
<p>
gpsd обладает скудными возможностями конфигурации, а собственные способности автоконфигурации его зачасную подводят. При запуске gpsd необходимо использовать следующие аргументы командной строки:
</p>
<ul>
<li><tt>-n</tt> начать приём данных сразу после запуска; по умолчанию, gpsd ждет клиентских подключений для начала работы;</li>
<li><tt>-s 9600</tt> указывается скорость обмена для приёмника;</li>
<li><tt>/dev/tty<i>Y</i></tt> устройсто с NMEA.</li>
</ul>
<p>
При использовании устройств с именами вида <tt>/dev/tty<i>Y</i></tt> gpsd пытается активировать на них линейную дисциплину PPS для получения сигнала с линии DCD. Сигнала, да и самой линии, может не быть, особенно в случаях с одноплатными компьютерами, а сообщить gpsd об этом явно возможности не предусмотрено. Однако, если устройство имеет имя <tt>/dev/gpsd0</tt>, то gpsd пытается открыть уже готовое устройство <tt>/dev/pps0</tt>, которое очень удачно может обслуживаться модулем <tt>pps-gpio</tt>.
В последнем случае, придётся пойти на поклон к udev и попросить его делать символическую ссылку для нужного нам tty устройства.
Примерное содержимое <tt>/etc/udev/rules.d/98-gpsd.rules</tt>:
</p>
<pre>
ACTION=="remove", GOTO="gpsd_end"
KERNEL=="ttyS2", SYMLINK+="gpsd0", MODE="0600", OWNER="root", GROUP="root"
LABEL="gpsd_end"
</pre>
<p>
Для chrony следует указать источник точного времени в виде сокета следующим образом.
Примерное содержимое <tt>/etc/chrony.d/gps.conf</tt>:
</p>
<pre>
refclock SOCK /run/chrony.gpsd0.sock refid GPS
</pre>
<p>
Имя сокета для подключения не может быть задано произвольно. Дело в том, что gpsd нельзя указать, куда он должен передавать информацию о времени, вместо этого он самостоятельно начинает запись в сокет с именем <tt>/run/chrony.gpsd0.sock</tt> если его обнаружит. Следует убедиться, что gpsd запускается после chronyd. Текст <tt>gpsd0</tt> после первой точки в имени файла соответсвует имени устройства используемого gpsd для чтения NMEA.
</p>
<p>
С помощью утилиты <tt>chronyc</tt> можно проверить, что всё работает корректно.
</p>
<pre>
chronyc> sources
MS Name/IP address Stratum Poll Reach LastRx Last sample
===============================================================================
#* GPS 0 4 377 21 -721ns[-2140ns] +/- 1333ns
^- 2a00:ab00:203:9::1000:1 2 6 337 2 +9783us[+9783us] +/- 65ms
^- ftpshare1.corbina.net 2 6 377 2 -4050us[-4050us] +/- 39ms
^- tms04.deltatelesystems.ru 2 6 377 63 +11ms[ +11ms] +/- 104ms
^- 2a00:ab00:203:9::1000:6 2 6 177 1 +12ms[ +12ms] +/- 63ms
</pre>
<p>
Возможные значения колнки "S":
</p>
<ul>
<li><tt>*</tt> — используется в качестве основного источника,</li>
<li><tt>+</tt> — используется,</li>
<li><tt>-</tt> — не используется,</li>
<li><tt>?</tt> — не используется, идёт сбор информации о стабильности источника.</li>
</ul>Matwey V. Kornilovhttp://www.blogger.com/profile/10954558557636278561noreply@blogger.com0tag:blogger.com,1999:blog-3954136086375338541.post-1769736678511557472020-12-13T11:10:00.000+03:002020-12-13T11:10:24.878+03:00Изменение размера шард для InfluxDB 1.7<p>Хранилище сервера баз данных временных рядов InfluxDB 1.x использует шарды фиксированного по времени размера независимо от количества хранящихся в них записей. Шарды не могут быть слиты или разделены. При устаревании данные удаляются отдельными шардами. Использование слишком маленького размера шарда приводит к проблемам с производительностью и избыточному потреблению памяти: на каждый шард требуется хранить в памяти отдельный дескриптор, даже если используется TSI1 индексирование.</p>
<p>Размер шарда является свойством политики хранения (retention policy), и, хотя настройка может быть изменена в онлайне, её изменение не приводит к перебалансировке уже существующих шард. Это приводит к проблемам для баз данных где требуется бесконечный или достаточно длительный срок хранения, т.е. шарды удаляются медленно, так как, несмотря на <a href="https://docs.influxdata.com/influxdb/v1.8/concepts/schema_and_data_layout/#shard-group-duration-recommendations" target="_blank">собственные рекомендации</a>, настройки политики хранения по умолчанию состоят в том чтобы хранить данные бесконечно и разделять на шарды по 1 неделе.</p>
<p>Одним из возможных способов перебалансировки шардов в онлайн является создание новой политики хранения с нужными параметрами, и последующего копирования туда данных запросом (что скорее всего приведет к избыточному потреблению оперативной памяти и потребует копирования по частям). Проблема этого подхода состоит в том, что невозможно переименовать политику хранения, поэтому потребуется перенастройка всех непрерывных запросов (continuous queries) и, возможно, перенастройка клиентских приложений.</p><p>В качестве альтернативного решения предлагается следующая оффлайн (при остановленном сервере) процедура: экспорт данных из существующей политики хранения в бинарном виде, удаление политики хранения, создание новой политики хранения (с прежним именем и новыми настройками) и импорт сохраненных данных. Для процедуры используется <a href="https://github.com/matwey/influxdb/tree/influx_tools/droprp">модифицированная</a> (добавлена команда droprp) утилита influx_tools:</p>
<pre>git clone -b influx_tools/droprp https://github.com/matwey/influxdb.git
cd influxdb/cmd/influx_tool
go build .
</pre>
<p>Экспорт данных производится следующим образом:</p>
<pre>
./influx_tools export -config /etc/influxdb/config.toml -no-conflict-path -database ${DB_NAME} -rp ${RP_NAME} -duration 8736h -format binary | xz -3 -c - > /tmp/ifx_dump
</pre>
<p>здесь <i>8736h</i> — новый размер шарда, в данном случае 52 недели. Сжатие можно опустить, но оно весьма эффективно работает в данном месте.</p>
<p>Удалим политику хранения <tt>${RP_NAME}</tt>:</p>
<pre>
./influx_tools droprp -config /etc/influxdb/config.toml -database ${DB_NAME} -rp ${RP_NAME}
</pre>
<p>
В этот момент будут удалены файлы старых шард, удалены файлы журналов упреждающей записи, и модифицирован файл <tt>meta/meta.db</tt>, который представляет из себя сериализованный документ в формате ProtoBuf, хранящий список политик хранения и шард.
</p>
<p>Загрузим данные на прежнее место с новыми настройками политики хранения:</p>
<pre>
xzcat /tmp/ifx_dump | ./influx_tools import -config /etc/influxdb/config.toml -database ${DB_NAME} -rp ${RP_NAME} -replace -shard-duration 8736h
</pre>
<p>
Пересобирем индекс для новых шард:
</p>
<pre>
influx_inspect buildtsi -datadir /var/lib/influxdb/data/ -waldir /var/lib/influxdb/wal -v
</pre>
<p>
Восстановим права доступа:
</p>
<pre>
chown -R influxdb:influxdb /var/lib/influxdb/*
</pre>Matwey V. Kornilovhttp://www.blogger.com/profile/10954558557636278561noreply@blogger.com0tag:blogger.com,1999:blog-3954136086375338541.post-27299580456384143092016-11-28T11:00:00.000+03:002016-11-28T11:00:27.350+03:00Миграция InfluxDB 0.9 до InfluxDB 1.1Между 0.9 и 1.1 нет прямой совместимости, поэтому прежде всего понадобится какая-нибудь промежуточная версия на короткий промежуток времени:<br />
<pre># wget https://dl.influxdata.com/influxdb/releases/influxdb-0.11.1-1_linux_amd64.tar.gz
</pre><br />
Сначала рекомендуется сбросить WAL (write-ahead log), для этого рекомендуется изолировать сервер InfluxDB от записи и выполнить его restart.<br />
Далее, останавливаем InfluxDB 0.9 и с помощью утилиты <tt>influx_tsm</tt> из пакета InfluxDB версии 1.1 конвертируем директорию <tt>data</tt>.<br />
Предполагается, что резервную копию данных мы уже сделали внешним образом.<br />
<pre># influx_tsm -parallel -nobackup /var/lib/influxdb/data
</pre><br />
Утилита выводит список всех найденных файлов устаревшего формата <tt>b1</tt> или <tt>bz1</tt> и спрашивает <tt>Proceed? y/N:</tt><br />
После подтверждения данные преобразуются в новый формат <tt>tsm</tt>.<br />
<br />
Далее осталось преобразовать в новый формат <tt>/var/lib/influxdb/meta</tt>. Для этого на некоторое время придется запустить InfluxDB версии 0.11<br />
<pre># ./influxdb-0.11.1-1/usr/bin/influxd -config /etc/influxdb/config.toml
</pre><br />
И попросить его сделать резервную копию:<br />
<pre># influxd backup /tmp/backup/
2016/11/27 17:41:37 backing up metastore to /tmp/backup/meta.00
2016/11/27 17:41:37 backup complete
</pre><br />
После этого сервер 0.11 можно выключить и загрузить резервную копию назад, но уже используя InfluxDB версии 1.1:<br />
<pre># influxd restore -metadir=/var/lib/influxdb/meta/ /tmp/backup/
Using metastore snapshot: /tmp/backup/meta.00
</pre><br />
После этого восстановим права доступа<br />
<pre># chown -R influxdb:influxdb /var/lib/influxdb/
</pre><br />
И можно запускать сервер InfluxDB 1.1<br />
<pre># systemctl start influxd
</pre><br />
Открываем консоль <tt>influx</tt> и проверяем что все наши данные доступны.<br />
Matwey V. Kornilovhttp://www.blogger.com/profile/10954558557636278561noreply@blogger.com0tag:blogger.com,1999:blog-3954136086375338541.post-5319899907987219442015-10-12T11:00:00.000+03:002015-10-12T11:00:11.685+03:00Настройка звука в конфигурации с несколькими одинаковыми звуковыми картамиИмеется следующая конфигурация. Два звуковых устройства, оба управляются одним и тем же модулем <tt>snd-hda-intel</tt>. Первое устройство отвечает за звуковой канал в HDMI, встроенной в процессор графической системы. Второй устройство — обычный интегрированный на материнскую плату аудио-контроллер.<br />
<pre>00:03.0 Audio device [0403]: Intel Corporation Xeon E3-1200 v3/4th Gen Core Processor HD Audio Controller [8086:0c0c] (rev 06)
00:1b.0 Audio device [0403]: Intel Corporation 9 Series Chipset Family HD Audio Controller [8086:8ca0]</pre>Пользователи жалуются, что звук не работает. Проблема состоит в том, что YaST создаёт следующую конфигурацию в <tt>50-sound.conf</tt>:<br />
<pre>options snd slots=snd-hda-intel,snd-hda-intel
alias snd-card-0 snd-hda-intel
alias snd-card-1 snd-hda-intel</pre>Здесь <tt>snd-card-0</tt> — звуковое устройство "по умолчанию". Очевидно, что в таком подходе ситуация, когда один и тот же модуль отвечает за два устройства, обрабатывается не корректно. Кто из устройств первый попал в функцию <tt>azx_probe</tt> модуля, тот и станет <tt>snd-card-0</tt>. В нашем случае, это не то устройство, которое нам хотелось бы. Это можно проверить, сделав<br />
<pre>ls -l /sys/class/sound/card0/device
lrwxrwxrwx 1 root root 0 окт 9 21:36 /sys/class/sound/card0/device -> ../../../0000:00:03.0</pre><br />
Для восстановления правильного порядка предлагается делать следующее.<br />
Во-первых, внимательно изучив исходники модуля, добавляем в <tt>50-sound.conf</tt>:<br />
<pre>options snd-hda-intel index=1,0</pre>Во-вторых, надеемся, что при следующих загрузках порядок инициализации не будет меняться случайным образом, потому-что кто первый попадет в функцию <tt>azx_probe</tt>, тот теперь и будет <tt>card1</tt>. И это всё происходит в 2015 году, когда повсюду systemd и прочий udev, а звуковую карту за её DeviceId привязать нельзя.Matwey V. Kornilovhttp://www.blogger.com/profile/10954558557636278561noreply@blogger.com0tag:blogger.com,1999:blog-3954136086375338541.post-476401817390952642015-09-28T22:47:00.000+03:002015-09-28T22:47:00.549+03:00Настройка вложенной виртуализации в ESXi 6.0Иногда в гостевой системе требуется в свою очередь запускать виртуальные машины. В нашем случае, гипервизор VMWare ESXi 6.0 (он же известен под названием vSphere Hypervisor) используется для запуска различных операционных систем, сервисы в одной из которых, в свою очередь, динамически запускают qemu-kvm. Для того, чтобы kvm в гостевой системе работал, необходимо включить вложенную (nested) виртуализацию. Делается это следующим замысловатым образом.<br />
<br />
Во-первых, в vmx-файл настроенной гостевой системы дописывается директива <tt>vhv.enable = "TRUE"</tt>. Включить эту настройку из клиентского приложения, видимо, нельзя. Для редактирования файла можно сначала загрузить его на локальную машину, а затем отредактированную версию загрузить назад, используя браузер датастора гипервизора.<br />
Во-вторых, нужно попросить гипервизор перечитать vmx-файл, как описано в тикете <a href="http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1026043">1026043 базы знаний VMWare</a>. А именно, используя ssh для доступа к командной строке гипервизора выполнить команды:<br />
<pre># vim-cmd vmsvc/getallvms
# vim-cmd vmsvc/reload Vmid</pre>Первая команда просто отображает список всех виртуальных машин гипервизора, она нужна чтобы определить Vmid интересующей нас машины, это число используется во второй команде.<br />
<br />
После этого стартуем виртуальную машину и проверяем, что аппаратная виртуализация стала доступна нам в гостевой системе:<br />
<pre># cat /proc/cpuinfo | grep vmx
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts mmx fxsr sse sse2 ss ht syscall nx rdtscp lm constant_tsc arch_perfmon pebs bts nopl xtopology tsc_reliable nonstop_tsc aperfmperf pni pclmulqdq vmx ssse3 cx16 sse4_1 sse4_2 popcnt aes hypervisor lahf_lm ida arat epb dtherm tpr_shadow vnmi ept vpid
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts mmx fxsr sse sse2 ss ht syscall nx rdtscp lm constant_tsc arch_perfmon pebs bts nopl xtopology tsc_reliable nonstop_tsc aperfmperf pni pclmulqdq vmx ssse3 cx16 sse4_1 sse4_2 popcnt aes hypervisor lahf_lm ida arat epb dtherm tpr_shadow vnmi ept vpid
# lsmod | grep kvm
kvm_intel 151704 3
kvm 493230 1 kvm_intel</pre>Matwey V. Kornilovhttp://www.blogger.com/profile/10954558557636278561noreply@blogger.com0tag:blogger.com,1999:blog-3954136086375338541.post-77174736545176210942015-08-17T11:00:00.000+03:002015-08-17T11:00:06.010+03:00Удаленная сетевая консоль ядра LinuxИногда, когда ядро Linux испытывает проблемы, одними из способов сбора отладочной информации являются консоль последовательного порта или сетевая консоль. Сразу обратим внимание, что второй вариант имеет как недостатки, например, предполагает, что сетевая подсистема ядра остается функциональной во время возникновения проблем, так и преимущества, например, можно сконфигурировать удаленно.<br />
<br />
<a href="https://www.kernel.org/doc/Documentation/networking/netconsole.txt">Полное описание</a> сетевой консоли находится в документации ядра. Для настройки достаточно добавить в <tt>modprobe.d/99-local.conf</tt>:<br />
<pre>options netconsole netconsole=@/,514@192.168.10.7/00:0C:29:F3:92:97</pre>Здесь, <tt>514</tt> - номер UDP порта, <tt>192.168.10.7</tt> - IP удаленного хоста куда будет отсылаться информация, <tt>00:0C:29:F3:92:97</tt> - его MAC адрес, если его не указать явно то будет использоваться широковещательный адрес <tt>FF:FF:FF:FF:FF:FF</tt>, что может затруднить передачу информации в зависимости от настроек сетевого оборудования.<br />
И загрузить модуль <tt>netconsole</tt> или, по желанию, поставить его на автозагрузку при старте системы.<br />
<br />
После загрузки модуля <tt>netconsole</tt>, сетевая консоль начинает немедленно функционировать, а в системном журнале можно увидеть примерно следующее:<br />
<pre>May 1 18:57:51 192.168.10.4 kernel: [162255.522603] netconsole: local port 6665
May 1 18:57:51 192.168.10.4 kernel: [162255.522673] netconsole: local IP 0.0.0.0
May 1 18:57:51 192.168.10.4 kernel: [162255.522710] netconsole: interface eth0
May 1 18:57:51 192.168.10.4 kernel: [162255.522746] netconsole: remote port 514
May 1 18:57:51 192.168.10.4 kernel: [162255.522784] netconsole: remote IP 192.168.10.7
May 1 18:57:51 192.168.10.4 kernel: [162255.522826] netconsole: remote ethernet address 00:0c:29:f3:92:97
May 1 18:57:51 192.168.10.4 kernel: [162255.522881] netconsole: local IP 192.168.10.4
May 1 18:57:51 192.168.10.4 kernel: [162255.523032] console [netcon0] enabled
May 1 18:57:51 192.168.10.4 kernel: [162255.523349] netconsole: network logging started</pre><br />
Данные приходят в самом простом текстовом виде и их можно читать самым простым способом:<br />
<pre>netcat -u -l 514</pre>Если у нас в наличии есть <tt>syslog-ng</tt> — можно использовать его следующим образом:<br />
<pre>source s_remote_udp {
network(transport("udp") ip(0.0.0.0) port(514));
};
filter f_remote_remhost {
netmask(192.168.10.4);
};
destination d_remote_remhost {
file("/var/log/remote/remhost.log");
};
log {
source(s_remote_udp);
filter(f_remote_remhost);
destination(d_remote_remhost);
};</pre><br />
Проверить, что всё работает можно следующим образом:<br />
<pre>echo '<7>Hello world!' > /dev/kmsg
dmesg -n 8</pre>Сообщение должно появиться в журнале и быть передано по сети на удаленный хост.Matwey V. Kornilovhttp://www.blogger.com/profile/10954558557636278561noreply@blogger.com0tag:blogger.com,1999:blog-3954136086375338541.post-89196476510471405872015-08-11T11:00:00.000+03:002015-08-11T11:00:06.832+03:00Удаленная отладка ядра Linux Ядро Linux периодически ломается, иногда это происходит на стадии загрузки. Одним из методов исследования проблемы является удаленная отладка с использованием последовательного порта.<br />
<br />
Опции конфигурации ядра должны быть такими:<br />
<pre>CONFIG_KGDB=y
CONFIG_KGDB_SERIAL_CONSOLE=y</pre>Кроме того, драйвер последовательного порта должен быть включен в состояние <tt>Y</tt>.<br />
<br />
Далее нам понадобятся отладочные символы и исходные коды ядра, которые находятся в пакетах <tt>-debuginfo</tt> и <tt>-debugsource</tt>. Скорее всего, архитектуры удаленной и локальной системы не будут совпадать, так как особенно часто ядро Linux не работает на архитектуре armv7l, поэтому просто распакуем данные следующим образом:<br />
<pre>> rpm2cpio kernel-default-base-debuginfo-4.2.rc4-1.1.gaf243bc.armv7hl.rpm | cpio -id
> rpm2cpio kernel-default-debuginfo-4.2.rc4-1.1.gaf243bc.armv7hl.rpm | cpio -id
> rpm2cpio kernel-default-debugsource-4.2.rc4-1.1.gaf243bc.armv7hl.rpm | cpio -id</pre>В текущей директории будет создана поддиректория <tt>/usr</tt> содержащая отладочные символы и исходные коды в стандартной иерархии. Кроме того, нам понадобятся сами бинарные файлы ядра:<br />
<pre>> rpm2cpio kernel-default-base-4.2.rc4-1.1.gaf243bc.armv7hl.rpm | cpio -id
> rpm2cpio kernel-default-4.2.rc4-1.1.gaf243bc.armv7hl.rpm | cpio -id</pre><br />
Далее, следует подключить последовательный порт, и открыть удаленную консоль следующим, например, образом:<br />
<pre>> screen /dev/ttyUSB0 115200</pre>и начать загрузку целевого устройства. Для активации механизма <tt>kgdb</tt> потребуется добавить параметры командной строки ядра в загрузчике:<br />
<pre>U-Boot# setenv append "kgdboc=ttyO0,115200 kgdbwait"
U-Boot# boot</pre><br />
Если все пойдет правильно, то загрузка ядра остановится после примерно следующих строк:<br />
<pre>[ 3.753423] 44e09000.serial: ttyO0 at MMIO 0x44e09000 (irq = 154, base_baud = 3000000) is a OMAP UART0
[ 4.497783] console [ttyO0] enabled
[ 4.502387] STMicroelectronics ASC driver initialized
[ 4.507960] KGDB: Registered I/O driver kgdboc
[ 4.512673] KGDB: Waiting for connection from remote gdb...
Entering kdb (current=0xdb0b3480, pid 1) on processor 0 due to Keyboard Entry
[0]kdb> </pre>kdb ождает ввода команд, среди прочего доступна команда <tt>help</tt>, выводящая список базовых команд. На этом консоль можно закрыть: <tt>Ctrl-A :quit</tt> и открыть отладчик <tt>gdb</tt>.<br />
<br />
Для начала установим пути к отладочным символам и исходным кодам и загрузим объектный файл ядра целевой системы (внимание, сначала этот файл нужно будет распаковать командой <tt>gz</tt>).<br />
<pre>(gdb) set debug-file-directory /tmp/dbg/usr/lib/debug
(gdb) directory /tmp/dbg/usr/src/debug/kernel-default-4.2.rc4/linux-4.2-rc4/linux-obj
(gdb) file /tmp/dbg/boot/vmlinux-4.2.0-rc4-1.gaf243bc-default
Reading symbols from /tmp/dbg/boot/vmlinux-4.2.0-rc4-1.gaf243bc-default...Reading symbols from /tmp/dbg/usr/lib/debug/boot/vmlinux-4.2.0-rc4-1.gaf243bc-default.debug...done.
done.</pre>После этого нужно подключиться к целевой системе:<br />
<pre>(gdb) target remote /dev/ttyUSB0
Remote debugging using /dev/ttyUSB0
0xc031dc08 in arch_kgdb_breakpoint () at ../arch/arm/include/asm/outercache.h:142</pre><br />
Далее можно использовать отладчик как обычно. Через команду <tt>monitor</tt> доступны все команды из консоли kdb, среди них есть достаточно полезные, например <tt>dmesg</tt> или <tt>lsmod</tt>:<br />
<pre>(gdb) monitor lsmod
Module Size modstruct Used by
musb_am335x 1431 0xbf000278 1 (Loading) 0xbf000000 [ ]</pre>Обратите внимание, что команда <tt>lsmod</tt> любезно нам показывает адрес <tt>0xbf000000</tt>, куда в памяти загружен модуль <tt>musb_am335x</tt>. Этот адрес нужен чтобы отлаживать код из модуля:<br />
<pre>(gdb) add-symbol-file /tmp/dbg/lib/modules/4.2.0-rc4-1.gaf243bc-default/kernel/drivers/usb/musb/musb_am335x.ko 0xbf000000</pre>Matwey V. Kornilovhttp://www.blogger.com/profile/10954558557636278561noreply@blogger.com0tag:blogger.com,1999:blog-3954136086375338541.post-14087929317135210712015-05-11T12:32:00.001+03:002015-05-11T12:32:26.119+03:00Устойчивые имена сетевых интерфейсовРазработчики systemd продолжают вести нас в светлое будущее. В udev уже давно реализован механизм <a href="http://www.freedesktop.org/wiki/Software/systemd/PredictableNetworkInterfaceNames/">Predictable Network Interface Names</a>, который представляет из себя кусочек кода на C, заполняющий переменные <tt>ID_NET_NAME_*</tt> исходя из свойств расположения физического сетевого устройства.<br />
<br />
Считается, что подобный подход дает больше информации, чем прибитие гвоздями имен интерфейсов <tt>eth?</tt> к MAC-адресам в <tt>70-persistent-net.rules</tt>. Однако, не обходится без недостатков. Например, при запуске системы под гипервизором VMWare ESXi, единственный сетевой интерфейс у меня называется <tt>eno16777728</tt>. Устройства, определяемые в DTB для одноплатных компьютеров на базе ARM, не поддерживаются схемой именования и имеют обычные имена <tt>eth?</tt>. А при подключении USB устройств, типа мобильных телефонов или модемов, схема именования генерирует скорее неустойчивые имена, потому-что в имя входит расположение устройства на шине USB, которое изменится при следующем подключении, таким образом придется настраивать интерфейс заново, потому-что предыдущие сохраненные настройки будут относиться к интерфейсу с другим именем.<br />
<br />
К счастью, udev заполняет переменную <tt>ID_NET_NAME_MAC</tt>, представляющую имя интерфейса, основанное исключительно на его MAC-адресе. По-умолчанию, эта переменная не используется, но можно поменять стандартное поведение для USB-устройств. Один способ - через настройку udev, второй - используя <a href="http://www.freedesktop.org/software/systemd/man/systemd.link.html">systemd.link</a>, файл, используемый systemd, для конфигурации сетевых интерфейсов.<br />
<br />
Создадим файл <tt>/etc/systemd/network/90-usb.link</tt> следуя инструкции:<br />
<pre>[Match]
Path=*-usb-*
[Link]
NamePolicy=mac
</pre>Юнит-файл состоит из двух секций: <tt>[Match]</tt> для описания устройств к которым он относится и <tt>[Link]</tt> для описания того, что с ними делать. В примере выше мы просим systemd использовать политику именования основанную на MAC-адресах для всех устройств подключенных через USB. После выполнения <tt>systemctl daemon-reload</tt> можно подключить устройство и увидеть его интерфейс с именем <tt>enx112233445566</tt>. Достаточно длинное, но уникальное (в известных пределах) и не изменится при следующем подключении устройства.<br />
<br />
Кроме изменения имени через systemd.link можно настроить WOL, MTU, ограничить скорость на интерфейсе, назначить устройству другой MAC-адрес.Matwey V. Kornilovhttp://www.blogger.com/profile/10954558557636278561noreply@blogger.com4tag:blogger.com,1999:blog-3954136086375338541.post-86873068102820722512015-03-20T23:07:00.000+03:002015-03-20T23:07:00.064+03:00Изменение размера раздела Имеется диск с тремя разделами sda1 (/boot), sda2 (swap), sda3 (/). Необходимо увеличить размер раздела /boot за счет swap.<br />
<br />
Сначала отмонтируем все разделы и проверим файловую систему.<br />
<pre># swapoff /dev/sda2
# umount /dev/sda1
# e2fsck /dev/sda1
e2fsck 1.42.6 (21-Sep-2012)
/dev/sda1: clean, 49/14056 files, 47157/56196 blocks
</pre><br />
Используем <tt>parted</tt> для того, чтобы сначала уменьшить и передвинуть второй раздел, а затем расширить первый на освободившееся место. Так как второй раздел - swap, то его мы просто передвинем, не заботясь о содержимом. Иначе говоря, сначала мы совсем сломаем, а потом заново её разметим. <br />
<br />
<pre># parted /dev/sda
GNU Parted 2.4
Using /dev/sda
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) unit s
(parted) print
Model: ATA QEMU HARDDISK (scsi)
Disk /dev/sda: 120103200s
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Number Start End Size Type File system Flags
1 63s 112454s 112392s primary ext2 boot, type=83
2 112455s 1686824s 1574370s primary linux-swap(v1) type=82
3 1686825s 120101939s 118415115s primary reiserfs type=83</pre><br />
Для изменения раздела используется команда <tt>resize номер_раздела начало конец</tt><br />
<br />
<pre>(parted) resize 2 224973 1686824
WARNING: you are attempting to use parted to operate on (resize) a file system.
parted's file system manipulation code is not as robust as what you'll find in
dedicated, file-system-specific packages like e2fsprogs. We recommend
you use parted only to manipulate partition tables, whenever possible.
Support for performing most operations on most types of file systems
will be removed in an upcoming release.
(parted) print
Model: ATA QEMU HARDDISK (scsi)
Disk /dev/sda: 120103200s
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Number Start End Size Type File system Flags
1 63s 112454s 112392s primary ext2 boot, type=83
2 224973s 1686824s 1461852s primary linux-swap(v1) type=82
3 1686825s 120101939s 118415115s primary reiserfs type=83</pre><br />
К сожалению в этот момент оно само подмонтировало всё назад, поэтому нужно снова отмонтировать первый раздел. Раздел swap в данный момент уже должен быть работоспособен, потому-что mkswap на нем выполнился сам автоматически. К сожалению, я не нашел способа отключить всю эту самодеятельность.<br />
<br />
<pre># umount /dev/sda1
# e2fsck -p /dev/sda1
</pre><br />
Снова идем в <tt>parted</tt>:<br />
<br />
<pre># parted
GNU Parted 2.4
Using /dev/sda
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) unit s
(parted) print
Model: ATA QEMU HARDDISK (scsi)
Disk /dev/sda: 120103200s
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Number Start End Size Type File system Flags
1 63s 112454s 112392s primary ext2 boot, type=83
2 224973s 1686824s 1461852s primary linux-swap(v1) type=82
3 1686825s 120101939s 118415115s primary reiserfs type=83
(parted) resize 1 63 224972
WARNING: you are attempting to use parted to operate on (resize) a file system.
parted's file system manipulation code is not as robust as what you'll find in
dedicated, file-system-specific packages like e2fsprogs. We recommend
you use parted only to manipulate partition tables, whenever possible.
Support for performing most operations on most types of file systems
will be removed in an upcoming release.
(parted) quit
Warning: You should reinstall your boot loader before rebooting. Read section 4 of the Parted User documentation for more
information.
Information: You may need to update /etc/fstab. </pre><br />
Готово, <tt>parted</tt> не только изменил размер раздела, но еще и молча расширил для нас файловую систему, а теперь предупреждает о необходимости обновить загрузчик. Matwey V. Kornilovhttp://www.blogger.com/profile/10954558557636278561noreply@blogger.com0tag:blogger.com,1999:blog-3954136086375338541.post-83083159221835122602014-12-30T16:16:00.000+03:002014-12-30T16:16:22.319+03:00snapper: настройка снимков подтомовПоказать список подтомов можно командой <tt>btrfs subvolume list /</tt>. Выберем какой-нибудь, например <tt>/var/lib/pgsql</tt>.<br />
Создадим новую конфигурацию (профиль) для этого подтома: <tt>snapper -c pgsql create-config /var/lib/pgsql</tt>, здесь <tt>pgsql</tt> произвольное имя:<br />
<pre># snapper list-configs
Config | Subvolume
-------+---------------
root | /
pgsql | /var/lib/pgsql
</pre><br />
Далее, все команды нужно выполнять с ключом <tt>-c pgsql</tt>, чтобы оперировать нужным профилем.<br />
<br />
<pre># snapper -c pgsql get-config
...
NUMBER_CLEANUP | yes
NUMBER_LIMIT | 50
NUMBER_LIMIT_IMPORTANT | 10
NUMBER_MIN_AGE | 1800
</pre><br />
Здесь <tt>NUMBER_CLEANUP</tt> разрешает удалять старые снимки если их число превышает <tt>NUMBER_LIMIT</tt> и одновременно возраст (в секундах) больше <tt>NUMBER_MIN_AGE</tt>.<br />
<br />
<pre>TIMELINE_CLEANUP | yes
TIMELINE_CREATE | yes
TIMELINE_LIMIT_DAILY | 10
TIMELINE_LIMIT_HOURLY | 10
TIMELINE_LIMIT_MONTHLY | 10
TIMELINE_LIMIT_YEARLY | 10
TIMELINE_MIN_AGE | 1800
</pre><br />
Здесь соответствующая настройка разрешает автоматическое создание снимков раз в час. Команда <tt>TIMELINE_CLEANUP</tt> удаляет старые снимки, используя следующие правила: удаляется снимок только если он старше <tt>TIMELINE_MIN_AGE</tt> секунд и одновременно после удаления останутся <tt>TIMELINE_LIMIT_*</tt> снимков с соответствующими интервалами.<br />
Таким образом, в вышеописанном стандартном случае всегда будут доступны снимки: 10 с интервалом в час с текущего момента, 10 с интервалом в один день с текущего момента, 10 с интервалом в один месяц и так далее.Matwey V. Kornilovhttp://www.blogger.com/profile/10954558557636278561noreply@blogger.com0tag:blogger.com,1999:blog-3954136086375338541.post-78749054284210984572014-08-27T14:17:00.000+04:002014-08-27T14:17:02.114+04:00Конвертация CVS в MercurialВ системе контроля версий CVS есть так называемые <a href="http://ximbiot.com/cvs/manual/cvs-1.12.13/cvs_18.html#SEC180">модули с амперсандом</a>, представляющие собой поддиректорию общую для нескольких модулей. Концепция похожая на <a href="http://git-scm.com/docs/git-submodule">сабмодули</a> в git или <a href="http://mercurial.selenic.com/wiki/Subrepository">сабрепозитории</a> в mercurial.<br />
<br />
Поскольку CVS немного устарел, нужно куда-то переехать. К сожалению, правильную работу с моделями с амперсандом не поддерживает ни одна из найденных утилит миграции. Об инкрементальной миграции (когда существуют два параллельных репозитория (разных систем контроля), которые каким-то чудом остаются друг с другом синхронизированы) тоже придется забыть. <br />
<br />
Краткая схема действий. Сначала все модули из CVS конвертируются в формат <a href="https://www.kernel.org/pub/software/scm/git/docs/git-fast-import.html">fastimport</a>, далее полученные дампы преобразуются и конвертируются в mercurial. Mercurial имеет в данной ситуации преимущество над git в том, что сабрепозитории управляются просто служебными файлами в дереве репозитория.<br />
<br />
Все CVS модули можно разделить на две категории: те, которые содержат в себе модули с амперсандом, и те, которые нет (сами являются ими). Второй набор конвертируется просто. Для преобразования первого набора нужно пойти в cvsroot и вставить символические ссылки в те места, где должны были быть директории, соответствующие модулям с амперсандом. После преобразования каждый модуль из первого набора потеряет связь со своими вложенными модулями, и файлы с путями, соответствующими им, окажутся преобразованы несколько раз — один раз в репозитории относящимся к вложенному модулю и по разу в каждом репозитории модуля первого типа. Перед импортом в mercurial данная связь будет восстановлена.<br />
<br />
Использование <tt>cvs2git</tt> из пакета <a href="http://cvs2svn.tigris.org/">cvs2svn</a> не требует особой внимательности, кроме параметра <tt>COMMIT_THRESHOLD</tt> который склеивает коммиты. Дело в том, что в CVS каждый файл имеет свою историю, а в формате fast-import (как в git и mercurial) историю имеет весь репозиторий, поэтому отдельные изменения файлов надо слепить в прообразы будущих коммитов. По-умолчанию <tt>COMMIT_THRESHOLD</tt> равен 5 минутам, это значит, что изменения всех файлов попадающих в пятиминутное окно будут слеплены в один коммит.<br />
Кроме того, можно задать отображение тегов, отображение авторов и другие параметры.<br />
<br />
Для преобразования из формата fastimport в репозиторий mercurial используется расширение <a href="https://bitbucket.org/matwey/hg-fastimport">hg-fastimport</a>. Отметим, что изначальный автор забросил этот проект и считает его неудачным, а более правильным подходом к преобразованию называет <a href="http://hg.gerg.ca/cvs2svn">другой свой проект</a>. Видимо поэтому расширение очень странным образом обрабатывает TAG.FIXUP ветви (в CVS можно было накладывать теги на те ревизии файлов, которые во времени друг с другом вообще никогда не встречались, поэтому для отображения таких тегов создается отдельная специальная ветка), что обычно требует подправления кода.<br />
<br />
Формат fastimport представляет из себя файл (или несколько), задающий дерево репозитория в топологическом порядке. Каждый узел дерева, который затем станет коммитом, помечается уникальным текстовым идентификатором, например ":1000000003". После преобразования модулей второго типа в соответствующих новых репозиториях будет лежать файл <tt>.hg/shamap</tt>, с отображением коммитов mercurial в идентификаторы fastimport. Кроме того, каждый узел дерева в текстовом виде содержит список измененных файлов, например<br />
<pre>M 100644 :30 sub/Makefile</pre>здесь :30 — маркер блоба, т.е. фактически содержания файла. Используя путь файла можно идентифицировать все файлы занесенные к нам из вложенных модулей. Нам бы хотелось преобразовать fastimport дамп таким образом чтобы в этих местах возникли ссылки на внешние репозитории, например так<br />
<pre>M 160000 2d1eb0523f244f7bb1d58f016583a25ba3d40426 sub</pre><br />
Для этого предлагается следующих алгоритм. У нас есть два дерева в виде дампов fastimport: дерево вложенного репозитория и дерево основного. Кроме того, есть отображение маркеров узлов вложенного репозитория на хэш коммита. Обойдя каждое из деревьев для каждого узла, мы можем полностью восстановить состояние, т.е. набор всех существовавших файлов и их содержимое. Кроме того, для основного репозитория возможно определить состояние вложенной директории (будущего сабрепозитория). На рисунке схематично изображены узлы основного дерева (пронумерованы арабскими цифрами) и узлы дерева сабрепозитория (пронумерованы латинскими буквами). Черными стрелками показана очередность коммитов, стрелка идет от более нового коммита к его предку.<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiUO-sqwrxyrgv1P2VwqALgvRbzmpndkp-nWAvmkKNiX6GsxfcJv1O_AV7B-YGLZfEN_F1WfPey1t1eMrPfK5e99QpWFyI-RAMOU7I9gp9yczv0FwPblPq_xau9AWPM9fMsgujKT6u4Vh5h/s1600/out.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiUO-sqwrxyrgv1P2VwqALgvRbzmpndkp-nWAvmkKNiX6GsxfcJv1O_AV7B-YGLZfEN_F1WfPey1t1eMrPfK5e99QpWFyI-RAMOU7I9gp9yczv0FwPblPq_xau9AWPM9fMsgujKT6u4Vh5h/s1600/out.png" /></a></div>Далее, сравнивая состояния вложенного репозитория и соответствующие под-состояния основного репозитория, можно построить отображение узлов основного дерева на вложенное (красные стрелки на рисунке).<br />
<br />
Возможны ситуации когда связь многозначная. Вообразим, что в предложенном примере G откатывает F, поэтому имеет такое же содержимое что и E, кроме того, в другой ветке есть C с таким же содержимым. Сообщения коммитов могут отсутствовать, время коммитов может отличаеться. В данной ситуации предлагаются следующие критерии разрешения конфликта.<br />
<br />
Так как основное дерево обходится в топологическом порядке, то к моменту когда мы оказывается в узле 5 узел 4 уже обработан и мы знаем что ему соответствует узел D. Для всех возможных кандидатов C, E, G рассчитаем расстояние между ними и узлом D. Узел D не достижим из C, поэтому C отбрасывается. Оставшийся выбор производится на основании сообщения коммита и близости времени. Либо можно представить простой алгоритм, который за не полиномиальное время назначит соответствие, однако без информации о времени и сообщениях коммитов все-равно не обойтись.<br />
<br />
Таким образом, у нас есть отображение меток дерева основного репозитория на метки (или хэши) вложенного репозитория. Этой информации достаточно, чтобы заменить все нужные вхождения об изменениях файлов в дампе. После этого, дамп можно скормить в <a href="https://bitbucket.org/matwey/hg-fastimport">hg-fastimport</a>.<br />
<br />
Наиболее удобным способом расположения иерархии репозиториев на сервере оказался следующий. Каждый вложенный репозиторий кладется в корень иерархии, кроме того, в каждый проект. Причем этим вторичным клонам мы запретим запись. А на первичный репозиторий навесим хуки, которые будут дергать pull во всех клонах.<br />
<pre>[extensions]
hgext.acl=
[hooks]
pretxnchangegroup.acl = python:hgext.acl.hook
[acl]
sources = serve push bundle
[acl.deny]
** = *
[paths]
default = /repos/subrepo</pre><br />
<ul><li><a href="http://cvs2svn.tigris.org/">cvs2svn</a></li>
<li><a href="https://www.kernel.org/pub/software/scm/git/docs/git-fast-import.html">git-fast-import</a></li>
<li><a href="https://bitbucket.org/matwey/hg-fastimport">hg fastimport</a></li>
</ul>Matwey V. Kornilovhttp://www.blogger.com/profile/10954558557636278561noreply@blogger.com0tag:blogger.com,1999:blog-3954136086375338541.post-23898668487097204442014-08-19T12:56:00.001+04:002014-08-19T12:56:06.998+04:00OBS: локальная сборка под ARMКогда требуется локально пересобрать пакет под одну из архитектур ARM, например для тестирования сборки, можно воспользоваться следующим медленным подходом.<br />
<br />
<pre>osc build --clean --alternative-project openSUSE:Factory:ARM qemu armv7l name.spec</pre><br />
Здесь указывается, что используется альтернативный проект для сборки — <tt>openSUSE:Factory:ARM</tt> (версию подставить по желанию), используется репозиторий <tt>qemu</tt>, который есть в этом проекте. Поэтому и указывается этот альтернативный проект.<br />
<br />
Несмотря на то, что в данном примере указана архитектура armv7l, технически, это x86_64. В среду сборки будет установлен бинарный транслятор qemu, работающий через подсистему ядра binfmt. При инициализации ядро настраивается таким образом, что при виде сигнатуры ELF для архитектуры ARM вызывает бинарик как <tt>qemu-arm /usr/bin/...</tt>, подобно тому, как при виде символов "#!" в начале исполняемого файла вызывается указанный интерпретатор. Работает поэтому достаточно медленно.<br />
<br />
К сожалению, с пакетами kiwi такое не проходит.Matwey V. Kornilovhttp://www.blogger.com/profile/10954558557636278561noreply@blogger.com0tag:blogger.com,1999:blog-3954136086375338541.post-8338499376760692942014-03-10T12:29:00.001+04:002014-03-10T12:29:07.038+04:00Сетевой стек на ATSAMD20В предыдущих выпусках рассматривалась демонстрационная плата на базе 32-битного микроконтроллера ATSAMD20. Далее рассмотрим как прикрутить к нему сетевое приложение. Так как сам микроконтроллер не снабжен интерфейсом Ethernet, возьмем <a href="http://www.ebay.com/bhp/enc28j60-ethernet-lan-module">какое-нибудь готовое решение</a> на базе ENC28J60 и прикрутим его через SPI.<br />
<br />
Нам понадобится:<br />
<ul><li><a href="http://www.atmel.com/tools/AVRSOFTWAREFRAMEWORK.aspx">Atmel Software Framework</a> — распространяемая под странным образом модифицированной BSD лицензией библиотека, реализующая удобный уровень индирекции при работе с переферией микроконтроллеров Atmel. Мы ей воспользуемся для работы через SPI. Внутри библиотеки весьма красивый код, понятный API и гора документации, исполненной в doxygen. Поэтому, основываясь на чувстве прекрасного, будем её использовать.</li>
<li><a href="https://gitorious.org/enc28j60driver/matweys-enc28j60driver/source/2194323eb5c23ca06ba3a76faac5adb5842e1892:">ec28j60driver</a> — драйвер для ENC28J60, реализует высокоуровневые функции работы с Ethernet путем обмена через SPI. Возьмем этот, потому-что написан он не левой пяткой и был достаточно легко портирован для работы с Atmel Software Framework. (см. ветку <tt>asf</tt>)</li>
<li><a href="http://savannah.nongnu.org/projects/lwip/">lwIP</a> — легковесный стек TCP/IP. Он отсылает или принимает Ethernet-пакеты через драйвер устройства и дальше разбирается что-же там внутри пришло. На сайте присутствует куча примеров.</li>
</ul><br />
Настройки для lwIP следующие:<br />
<br />
<tt>lwoptions.h:</tt><br />
<pre>#define MEM_LIBC_MALLOC 1
#define MEMP_MEM_MALLOC 1
#define MEM_ALIGNMENT 4</pre><br />
<tt>cc.h:</tt><br />
<pre>#define BYTE_ORDER LITTLE_ENDIAN</pre><br />
Стиль программирования <a href="http://git.savannah.gnu.org/cgit/lwip/lwip-contrib.git/tree/apps/tcpecho_raw/echo.c">приложений</a>, определяемый использованием RAW API библиотеки lwIP, через 5 минут создает полное ощущение, что ты пишешь gen_server на erlang, но последний почему-то кривой, неудобный и недоделанный. <br />
<br />
Далее в таблице приводится размер кода прошивки, получаемый при различных вариантах конфигурации:<br />
<table><tr> <th>config</th> <th>-O3</th> <th>-Os</th> </tr>
<tr> <td>TCP/IP + DHCP + DEBUG(printf)</td> <td>96k</td> <td>82k</td> </tr>
<tr> <td>TCP/IP + DHCP</td> <td>54k</td> <td>40k</td> </tr>
<tr> <td>TCP/IP</td> <td>45k</td> <td>36k</td> </tr>
<tr> <td>UDP/IP + SNMP</td> <td>54k</td> <td>43k</td> </tr>
<tr> <td>UDP/IP</td> <td>28k</td> <td>24k</td> </tr>
</table><br />
Как-то так оно и работает.<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjX-PcvdpFk7N9wyf_UIU7wOq5k1iZu-xMREA2DXhVgtdftf0lpvJq4go4rWScoWDs-vDpX1iyqIz8-Tgsg-aDu1sRKW0xGNzv-Bt82c_3blrNPHU1afiLg6KOF82WOwIWlOhprc88Bihsv/s1600/DSC_0007.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjX-PcvdpFk7N9wyf_UIU7wOq5k1iZu-xMREA2DXhVgtdftf0lpvJq4go4rWScoWDs-vDpX1iyqIz8-Tgsg-aDu1sRKW0xGNzv-Bt82c_3blrNPHU1afiLg6KOF82WOwIWlOhprc88Bihsv/s400/DSC_0007.jpg" /></a></div>Matwey V. Kornilovhttp://www.blogger.com/profile/10954558557636278561noreply@blogger.com0tag:blogger.com,1999:blog-3954136086375338541.post-42893400048722303772014-01-02T15:19:00.000+04:002014-07-08T10:48:54.106+04:00openSUSE 13.1 на BeagleBone Black<a href="http://beagleboard.org/Products/BeagleBone+Black">BeagleBone Black</a> — одноплатный компьютер на основе процессора TI AM3358 (Cortex-A8), выпущенный весной прошлого года:<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhfEJdjXmxvpOeqO5aNgeYvkPzNihTXNFoZd6nFMwzEKNybDgrU1EaWYVXHoXTz_Ox6VlyP5_sBDrzdLtYGWw1EjZbvhWt3gvrYV1CfopQLEGk4Do0R3OEsXZsvgmgVgHjIcxlH6SVPGIT1/s1600/DSC00002.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhfEJdjXmxvpOeqO5aNgeYvkPzNihTXNFoZd6nFMwzEKNybDgrU1EaWYVXHoXTz_Ox6VlyP5_sBDrzdLtYGWw1EjZbvhWt3gvrYV1CfopQLEGk4Do0R3OEsXZsvgmgVgHjIcxlH6SVPGIT1/s320/DSC00002.JPG" /></a></div><br />
На нем вполне успешно может загрузиться и даже работать openSUSE 13.1. Готовые образы для нанесения на microSD карточку находятся <a href="http://download.opensuse.org/repositories/devel:/ARM:/13.1:/Contrib:/Beaglebone/images/">здесь</a>. Эти же самые образы должны в теории работать и на <a href="http://beagleboard.org/Products/BeagleBone">BeagleBone</a>. Конечно, пока все на этапе интеграции и поиска ошибок, поэтому имеется подробная инструкция по запуску:<br />
<ol><li>Скачать, распаковать и сделать <tt>dd</tt> на карточку образ системы <tt>*.raw.xz</tt></li>
<li>Подключить отладочный TTL-RS232 порт (можно использовать, например, <a href="http://cgi.ebay.com/ws/eBayISAPI.dll?ViewItem&item=141127391596">такой</a>, но важно помнить, что разработчики BeagleBone Black не поставили на свою плату преобразователь уровней и сигнал с отладочного RS232 идет в виде 3.3V. Подключение через обычный COM-порт на большом компьютере обречено на провал.), руководствуясь <a href="http://elinux.org/Beagleboard:BeagleBoneBlack#Hardware_Files">распиновкой</a>. Используя <tt>screen /dev/ttyUSB0 115200</tt>, во-первых, можно будет легко видеть все этапы начиная от работы u-boot. Во-вторых, запустится Yast2 firstboot и попросит вас задать root пароль, завести пользователя, установить временную зону и системное время (аналогично тому, как это происходит на соответствующем этапе установки с DVD), а для этого потребуется интерактивное взаимодействие.</li>
<li>Помните, что для загрузки с внешней карты памяти при подаче питания на устройство нужно удерживать кнопку S2 (она же boot select switch). Подсказка — загрузившись с SD карты можно подмонтировать раздел встроенной MMC памяти и переименовать или удалить файл загрузчика <tt>MLO</tt>, после этого загрузка будет всегда начинаться с SD, но загрузиться с MMC больше не получится.</li>
</ol><br />
Технические подробности (тем, кто хочет продолжить ковыряния) изложены в списке рассылки: <a href="http://lists.opensuse.org/opensuse-arm/2014-01/msg00001.html">http://lists.opensuse.org/opensuse-arm/2014-01/msg00001.html</a>.Matwey V. Kornilovhttp://www.blogger.com/profile/10954558557636278561noreply@blogger.com0tag:blogger.com,1999:blog-3954136086375338541.post-14525549941626254802013-12-21T14:51:00.000+04:002013-12-21T14:51:31.323+04:00Atmel ATSAMD20-XPRO: собираем компиляторПоскольку сборка компилятора привела к боли и страданиям, она будет тут сохранена для истории (такими историями гугл полнится).<br />
<br />
Возьмем последний binutils-2.24:<br />
<pre>./configure --target=arm-none-eabi -enable-interwork --enable-multilib --disable-nls --disable-libssp --prefix=/opt/arm-none-eabi
make
make install-strip
export PATH=$PATH:/opt/arm-none-eabi/bin</pre><br />
Возьмем newlib-2.0.0 и распакуем его, пусть проветривается.<br />
<br />
Возьмем gcc-4.8.2 который слышал о cortex-m0plus. Возьмем дебиановские патчи <a href="http://ftp.de.debian.org/debian/pool/main/g/gcc-arm-none-eabi/gcc-arm-none-eabi_4.tar.gz">отсюда</a>. Наложим их и скомпилируем: <br />
<pre>mkdir build
../configure --target=arm-none-eabi --prefix=/opt/arm-none-eabi --enable-languages="c,c++" --enable-interwork --enable-multilib --with-
newlib --with-headers=/path/to/src/newlib-2.0.0/newlib/libc/include/ --disable-nls --disable-libssp --with-system-zlib --with-multilib-lis
t=armv6-m
# в этом месте ./configure может ругаться, надо проследить чтобы он заголовки смог переписать на место
make
make all-gcc
make install-gcc
</pre><br />
newlib собирается со следующими ключами (без <tt>--disable-newlib-supplied-syscalls</tt> не собираются некоторые куски для armv6-m, и atmel-овский asf ругается на дублирующиеся определения функций из syscalls):<br />
<pre>./configure --target=arm-none-eabi -enable-interwork --enable-multilib --disable-libssp --disable-nls --prefix=/opt/arm-none-eabi --disable-newlib-supplied-syscalls --enable-newlib-register-fini --enable-newlib-io-long-long
make
make install</pre><br />
После доделываем gcc:<br />
<pre>cd build
make all
make install
</pre><br />
Matwey V. Kornilovhttp://www.blogger.com/profile/10954558557636278561noreply@blogger.com1tag:blogger.com,1999:blog-3954136086375338541.post-5933763899101499892013-12-14T11:51:00.001+04:002014-01-27T19:53:56.440+04:00Atmel ATSAMD20-XPRO<br />
<a href="http://www.atmel.com/tools/atsamd20-xpro.aspx">ATSAMD20-XPRO</a> оценочный набор для новой серии микроконтроллеров Atmel ATSAMD20 на ядре Cortex-M0+. Выглядит следующим образом:<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://1.bp.blogspot.com/-lC648_sJxW0/Uqsy6JRwXtI/AAAAAAAACHg/IZ90Ub_-lRs/s1600/DSC00001.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://1.bp.blogspot.com/-lC648_sJxW0/Uqsy6JRwXtI/AAAAAAAACHg/IZ90Ub_-lRs/s320/DSC00001.JPG" /></a></div>Купить в России можно например тут: <a href="http://www.deltel.ru/">Дельта Электроника</a>.<br />
<br />
Этот пост о том как подключать эту плату в GNU/Linux. Плата снабжена интерфейсом micro-USB для отладки, реализуемым через отдельную микросхему. Atmel называет это «Embedded Debugger», анонсируется наличие виртуального последовательного интерфейса (прикрученного к основному чипу) и собственно средств отладки и программирования.<br />
<br />
При подключении появляется устройство:<br />
<pre>Bus 001 Device 010: ID 03eb:2111 Atmel Corp.</pre><br />
<pre>[13761.329235] usb 1-1.5: New USB device found, idVendor=03eb, idProduct=2111
[13761.329240] usb 1-1.5: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[13761.329242] usb 1-1.5: Product: EDBG CMSIS-DAP
[13761.329245] usb 1-1.5: Manufacturer: Atmel Corp.
[13761.329247] usb 1-1.5: SerialNumber: ATML1873040200000110
[13761.330868] hid-generic 0003:03EB:2111.000A: hiddev0,hidraw3: USB HID v1.11 Device [Atmel Corp. EDBG CMSIS-DAP] on usb-0000:00:1a.0-1.5/input0
[13761.330964] cdc_acm 1-1.5:1.1: ttyACM0: USB ACM device</pre><br />
Устройство, как видно, отдает нам виртуальный последовательный интерфейс на <tt>/dev/ttyACM?</tt> и интерфейс <a href="http://www.arm.com/products/processors/cortex-m/cortex-microcontroller-software-interface-standard.php">CMSIS-DAP</a> на <tt>/dev/hid*</tt>.<br />
<br />
В <a href="http://openocd.sourceforge.net/">openocd</a> недавно добавили поддержку этого интерфейса. Пока пакеты openocd с поддержкой CMSIS-DAP доступны здесь:<br />
<iframe src="http://software.opensuse.org/download/package.iframe?project=home%3amatwey%3aatsamd20_xpro&package=openocd"></iframe><br />
В пакетах есть небольшой баг, связанный с тем, что udev стремится поставить на <tt>/dev/hidraw*</tt> группу владельца plugdev, которая по-умолчанию в системе не существует и в пакете не создается. openocd будет искать свой devel-project и потом попадет в Factory.<br />
<br />
Запускаем и убеждается, что таки оно работает:<br />
<pre>> openocd -f /usr/share/openocd/scripts/board/atmel_samd20_xplained_pro.cfg
Open On-Chip Debugger 0.8.0-dev-snapshot (2013-12-13-18:45)
Licensed under GNU GPL v2
For bug reports, read
http://openocd.sourceforge.net/doc/doxygen/bugs.html
Info : only one transport option; autoselect 'cmsis-dap'
Info : CMSIS-DAP: SWD Supported
Info : CMSIS-DAP: Interface Initialised (SWD)
adapter speed: 500 kHz
adapter_nsrst_delay: 100
cortex_m reset_config sysresetreq
Info : CMSIS-DAP: FW Version = 01.0F.00DB
Info : SWCLK/TCK = 1 SWDIO/TMS = 1 TDI = 1 TDO = 1 nTRST = 0 nRESET = 1
Info : DAP_SWJ Sequence (reset: 50+ '1' followed by 0)
Info : CMSIS-DAP: Interface ready
Info : clock speed 500 kHz
Info : IDCODE 0x0bc11477
Info : at91samd20j18.cpu: hardware has 4 breakpoints, 2 watchpoints
</pre><br />
<ul><li><a href="http://openocd.sourceforge.net/doc/html/index.html">Инструкция к openocd</a></li>
</ul>Matwey V. Kornilovhttp://www.blogger.com/profile/10954558557636278561noreply@blogger.com0tag:blogger.com,1999:blog-3954136086375338541.post-64633437680133869712013-08-15T14:48:00.000+04:002013-08-15T14:48:42.117+04:00Быстродействие UNIX сокетовСравнение скорости работы unix-сокетов. Выполнялась передача большого объема данных от одного процесса другому через unix-сокет. Изменялся размер данных, передаваемых за один вызов <tt>write/read</tt> (chunk). С каждым размером производилось пять измерений, результат усреднялся.<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjeNZ6n1zKTwNvG4tQ_Sfh0vBmKxBuzvaictrJc6frhcXye_03vAMLTak3fsRG5dL1MzT2DGC5O1lLWrNLwwBP-m9NB6XzyF-V7ijuIR1lJeCt3JQ8S2vx-F_hHRxFeCErRE4kVzu77HNHQ/s1600/Rplot001.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjeNZ6n1zKTwNvG4tQ_Sfh0vBmKxBuzvaictrJc6frhcXye_03vAMLTak3fsRG5dL1MzT2DGC5O1lLWrNLwwBP-m9NB6XzyF-V7ijuIR1lJeCt3JQ8S2vx-F_hHRxFeCErRE4kVzu77HNHQ/s1600/Rplot001.png" /></a></div><br />
На графике черная кривая — производительность unix-сокетов, красная и зеленая — для сравнения копирование памяти <tt>memcpy</tt> в рамках одного процесса и, соответственно, копирование из разделяемой (shared) памяти. Если рост производительности при увеличении "размера пакета" для сокетов не является чем-то не очевидным, то падение производительности операции <tt>memcpy</tt> при росте значения третьего аргумента функции не тривиально.<br />
<br />
Характеристики тестового стенда. Процессор: Intel(R) Core(TM) i5-3470 CPU @ 3.20GHz, память: DDR3 Kingston HyperX KHX1600C9D3P1K2/8G. Ядро: 3.7.10.Matwey V. Kornilovhttp://www.blogger.com/profile/10954558557636278561noreply@blogger.com1tag:blogger.com,1999:blog-3954136086375338541.post-64170090577795641842013-07-08T16:55:00.000+04:002013-07-08T16:55:43.377+04:00Xen: проброс USB устройствXen умеет пробрасывать USB-устройства (по отдельности) в гостевые непривилегированные домены. Для этого используется механизм, называемый PVUSB (подозреваю, что сокращение от Para-Virtualized USB), концептуально состояний из модулей <tt>usbbk</tt> (Xen USB backend driver) и <tt>xen_hcd</tt> (Xen USB Virtual Host Controller driver). Соответственно, первый модуль съедает устройство в dom0, делая его недоступным для других драйверов, а все URB отправляет через гипервизор в нужный выбранный домен, где их получает перавиртуальный контроллер. Утверждается, что потеря производительности минимальна.<br />
<br />
Вся конструкция управляется несколькими командами. Посмотреть, какие устройства доступны: <pre># xm usb-list-assignable-devices
4-2 : ID 067b:2303 Prolific Technology Inc. USB-Serial Controller</pre>Создать в домене паравиртуальный USB хост контроллер: <tt>xm usb-hc-create Domain UsbVer PortNum</tt>, где параметры — название домена, версия USB (поддерживаются 1 и 2) и количество USB-портов. После этого, в гостевом домене с помощью lsusb видно появившийся контроллер. Для удаления есть обратная команда <tt>xm usb-hc-destroy</tt><br />
<br />
Для присваивания устройства есть команда <tt>xm usb-attach Domain HostNum PortNum Device</tt>, где параметры — название домена, номер хост контроллера (их можно хоть пачку создать), номер порта на виртуальном контроллере, первая колонка выдачи <tt>usb-list-assignable-devices</tt>. Обратная команда — <tt>xm usb-destroy</tt>. При этом, в dom0 устройство пропадет на глазах у изумленного драйвера:<pre>[12129.803899] pl2303 ttyUSB0: pl2303 converter now disconnected from ttyUSB0
[12129.803938] pl2303 4-2:1.0: device disconnected</pre>но появится в гостевом домене: <pre># lsusb
Bus 001 Device 002: ID 067b:2303 Prolific Technology, Inc. PL2303 Serial Port
Bus 001 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub</pre><br />
Важное замечание. Если в гостевом домене ничего не появилось, кроме записей в dmesg: <pre>[12332.892117] usb 1-1: new full-speed USB device number 70 using vusb
[12332.892126] usb 1-1: parent hub has no TT</pre>то скорее всего, устройство не поддерживает USB 2.0, к которому его прицепили, нужно сделать другой контроллер с правильным параметром <tt>UsbVer</tt>.<br />
<br />
Кроме того, устройство можно прибить гвоздями в конфигурационном файле домена: <pre>vusb=['usbver=1, numports=4, port_1=4-2']</pre>Список литературы:<br />
<ul><li><a href="http://doc.opensuse.org/products/draft/SLES/SLES-xen_sd_draft/cha.xen.config.html#sec.xen.config.pvusb">Assigning USB Devices with PVUSB</a></li>
<li><a href="http://www.xen.org/files/xensummit_intel09/PVUSBStatusUpdate.pdf">Status Update of PVUSB</a></li>
</ul>Matwey V. Kornilovhttp://www.blogger.com/profile/10954558557636278561noreply@blogger.com0tag:blogger.com,1999:blog-3954136086375338541.post-35080817261145440482013-07-05T12:24:00.001+04:002013-07-05T12:24:22.101+04:00ElixirБольше маргинальных языков в openSUSE. <a href="http://elixir-lang.org/">Elixir</a> — основываясь на Erlang, является еще более маргинальным языком.<br />
<br />
Брать здесь — <a href="http://software.opensuse.org/package/elixir">http://software.opensuse.org/package/elixir</a>.<br />
Matwey V. Kornilovhttp://www.blogger.com/profile/10954558557636278561noreply@blogger.com0tag:blogger.com,1999:blog-3954136086375338541.post-47588576307564458862013-06-20T22:02:00.000+04:002013-06-20T22:02:09.494+04:00gen_bunny для RabbitMQ 3.0<br />
Немного подправил gen_bunny для новых версий клиентской библиотеки amqp_client. Поменялся только вызов <tt>amqp_connection:start/1</tt> и связанные с ним записи. Брать здесь: <a href="https://github.com/matwey/gen_bunny/tree/amqp_client-3.0.4">https://github.com/matwey/gen_bunny/tree/amqp_client-3.0.4</a>, пока больше ничего не отваливается, если отвалится — поправлю еще.<br />
Matwey V. Kornilovhttp://www.blogger.com/profile/10954558557636278561noreply@blogger.com0tag:blogger.com,1999:blog-3954136086375338541.post-62218581387570023292013-06-17T20:31:00.001+04:002013-06-17T20:31:43.673+04:00Настройка сети в XenСеть в Xen работает по принципу виртуального моста, как рассказывается здесь: <a href="http://wiki.xen.org/wiki/Xen_Networking">http://wiki.xen.org/wiki/Xen_Networking</a>.<br />
<br />
Сначала, надо сделать этот самый мост. В <tt>/etc/sysconfig/network/ifcfg-br0</tt> надо написать буквально следующее:<br />
<pre>BOOTPROTO='dhcp4'
# как для простого интерфейса, можно и статический адрес задать
BRIDGE='yes'
BRIDGE_FORWARDDELAY='0'
BRIDGE_PORTS='eth0 eth1'
BRIDGE_STP='on'
# если два активных физических интерфейса в мост собраны,
# то пакеты могут и по кругу пойти без Spanning Tree Protocol.
STARTMODE='auto'
</pre><tt>ifcfg-eth0</tt> и <tt>ifcfg-eth1</tt> лучше просто удалить, чтобы не мешались.<br />
<br />
Теперь у нас есть самый настоящий мост, который можно вписывать в параметры конфигураций доменов: <a href="http://xenbits.xen.org/docs/4.2-testing/misc/xl-network-configuration.html">http://xenbits.xen.org/docs/4.2-testing/misc/xl-network-configuration.html</a>.<br />
<br />
Дальше запускаем домены, и проверяем, что появились их бэкендные интерфейсы:<br />
<pre># brctl show br0
bridge name bridge id STP enabled interfaces
br0 8000.52540035c714 yes eth0
eth1
<b>vif1.0</b></pre><br />
Дальше настраиваем внутренний интерфейс домена, как это происходит обычно.<br />
Matwey V. Kornilovhttp://www.blogger.com/profile/10954558557636278561noreply@blogger.com1tag:blogger.com,1999:blog-3954136086375338541.post-182115440750957442013-04-13T15:59:00.002+04:002013-04-28T15:09:57.266+04:00Диагностика ядра LinuxСбои в ядре Linux приводят к возникновению чрезвычайно разнообразных симптомов. <a href="http://en.opensuse.org/openSUSE:Bugreport_kernel">Некоторые авторы</a> дают следующую неполную классификацию проблем, с которыми может столкнуться пользователь:<br />
<ul><li>kernel oops — проблема при выполнении кода в ядре, например кто-нибудь попытался разыменовать нулевой указатель. С кем из программистов на C такого не случалось?</li>
<li>kernel panic — кто-то попытался разыменовать нулевой указатель в обработчике прерываний. После чего ядро уходит в полную несознанку и начинает мигать caps-lock-ом.</li>
<li>soft lockup — что-то заблокировалось (вероятно наткнувшись на не освобожденную блокировку), несмотря на это прерывания продолжают обрабатываться. Хорошее упражнение — попинговать машину или попытаться зажечь numlock.</li>
<li>hard lockup — компьютер жужжит вентиляторами и ни на что не реагирует. Провести какую-то диагностику в этом случае особенно сложно. Проблема может быть вызвана как вышедшим из строя железом, так и неаккуратной обработкой прерываний.</li>
</ul>кроме того, можно добавить:<br />
<ul><li>hung — индуцированное неправильной блокировкой последовательное попадание всех или большинства процессов системы в состояние TASK_UNINTERRUPTIBLE (известного так-же как D-состояние, по обозначению в <tt>top</tt> или <tt>ps</tt>). Согласно книге Р.Лава такой «наводящий ужас» процесс нельзя убить, завершить, и вообще что-то с ним сделать. При этом с точки зрения пространства пользователя программа просто заблокирована на каком-то системном вызове (например ввода-вывода). При попадании в подобное состояние всех критических процессов системы можно получить симптом похожий на soft lockup.</li>
</ul>Получить как можно более подробную информацию о сути возникающей проблемы важно как для правильного написания сообщения об ошибке, так и для временного переконфигурирования системы с целью избегания выполнения проблемного кода и повышения её живучести. <br />
<br />
К счастью, ядро обладает неким набором средств первичной самодиагностики, пригодным для постановки примерного диагноза. Согласно, видимо всеобщей, философской парадигме, наиболее устойчивыми и надежными являются наиболее простые подсистемы, поэтому сообщения ядра имеет смысл искать в текстовой и последовательной консолях. Конечно, при достаточном уровне везения нужное сообщение будет сброшено syslog-демону, записано на диск, отправлено по сети на удаленный syslog-демон и прочее, но при недостаточном везении монитор (и фотоаппарат на телефоне), клавиатура и COM-порт являются последней надеждой.<br />
<br />
<h2>printk</h2><br />
Одним из механизмов общения ядра с внешним миром является printk. При неправильной настройке сообщение скорее всего будет просто потеряно как не обладающее значимостью. Для настройки используется <tt>/proc/sys/kernel/printk</tt>, соответствующий ему параметр sysctl, утилита <tt>klogconsole</tt>, SysRq-клавиша и т.п. Ядро обладает восемью уровнями важности сообщений, поэтому установка уровня в 8 заведомо напечатает все на консоль.<br />
<br />
<h2>sysrq</h2><br />
Магическая кнопка включается в <tt>/proc/sys/kernel/sysrq</tt> или соответствующим ему параметром sysctl. Предлагается просто записать туда 1, несмотря на то, что новые ядра позволяют изысканный контроль над функционалом. В данной ситуации незачем себя ограничивать, хотя для нормальной работы разумно ограничить функционал на случай случайных нажатий. Если осталась рабочая терминальная сессия (например удаленная сессия по ssh), можно использовать как альтернативу, например, <tt>echo b > /proc/sysrq-trigger</tt>; с последовательной консоли поведение активируется кнопкой 'break'.<br />
<br />
Важно помнить, что SysRq-w, например, выдает сообщение с уровнем <tt>KERN_INFO</tt>, то есть выдача printk должна быть настроена правильно, чтобы можно было что-то увидеть. <a href="https://www.kernel.org/doc/Documentation/sysrq.txt">Полный список команд SysRq</a>.<br />
<br />
<h2>softlockup_panic</h2><br />
Параметр ядра <tt>softlockup_panic</tt> или параметр <tt>kernel.softlockup_panic</tt> для sysctl включают панику ядра при обнаружении soft lockup. <a href="http://lhwdb.org/doc/lockup-watchdogs.txt">Описание внутреннего устройства</a>. Включение паники позволит остановить выполнение системы и проанализировать выдачу, снабженную трассировкой, хотя контроль блокировки исполняется постоянно. Существует аналогичный механизм отслеживания hard lockup для многопроцессорных систем (если остались живые процессоры — есть шанс что сработает), с соответствующим параметром <tt>hardlockup_panic</tt>. Время срабатывания обычно в пределах одной минуты.<br />
<br />
<h2>hung_task_timeout_sec</h2><br />
Механизм отслеживания процессов, надолго застрявших в состоянии TASK_UNINTERRUPTIBLE, параметры настраиваются через sysctl и <tt>/proc</tt>:<br />
<ul><li>kernel.hung_task_panic — включает/отключает панику при обнаружении не прерываемого процесса;</li>
<li>kernel.hung_task_warnings — счетчик сообщений. Иными словами, если паника отключена, будет сообщено о таком количестве зависших процессов;</li>
<li>kernel.hung_task_timeout_secs — сколько секунд процесс должен непрерывно пробыть в TASK_UNINTERRUPTIBLE, чтобы вызвать сообщение. По умолчанию бывает либо выключено (0), либо очень большое число порядка 10 минут.</li>
</ul>Сообщения снабжаются трассировкой, которая подсказывает в какой подсистеме происходит сбой.<br />
<br />
Matwey V. Kornilovhttp://www.blogger.com/profile/10954558557636278561noreply@blogger.com0tag:blogger.com,1999:blog-3954136086375338541.post-62643617930784061692013-04-12T21:17:00.000+04:002013-04-12T21:17:05.777+04:00FastCGI в Lighttpd и NginxСравнение настроек, приводящих к одинаковому результату в Lighttpd и Nginx.<br />
<br />
Настройки Lighttpd:<br />
<pre>url.rewrite-once += ( "^/testfc$" => "/testfc/", )
fastcgi.server += (
"/testfc" => ((
"bin-path" => "/path/to/fcgi/server.py",
"socket" => socket_dir + "/viewvc.sock",
"max-procs" => 1,
"check-local" => "disable",
"fix-root-scriptname" => "enable",
))
)</pre><br />
Настройки Nginx:<br />
<pre>location /testfc/ {
fastcgi_pass unix:/path/to/fcgi/sock;
fastcgi_split_path_info ^(/testfc)(.*)$;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
include fastcgi_params;
}
</pre><br />
Nginx сам запускать приложения не умеет, поэтому об этом нужно заботиться заранее. Например можно использовать изысканное <a href="http://b.mtjm.eu/fastcgi-systemd-socket-activation.html">решение с помощью systemd</a>.Matwey V. Kornilovhttp://www.blogger.com/profile/10954558557636278561noreply@blogger.com0tag:blogger.com,1999:blog-3954136086375338541.post-52631648074430187812013-02-24T15:35:00.001+04:002013-02-24T15:35:50.815+04:00svn+ssh: коллективные соединенияПри командах выполняемых на удаленном URL, типа <tt>copy</tt> или <tt>merge</tt>, subversion иногда требует несколько соединений. Для облегчения работы, можно применить стандартную возможность ssh — использовать одно TCP/IP соединение для нескольких сессий. <br />
<br />
Чтобы не испортить настройки клиентского ssh, в секции <tt>[tunnels]</tt> файла конфигурации <tt>~/.subversion/config</tt> зададим нужные настройки как параметры командной строки:<br />
<pre>ssh = $SVN_SSH ssh -o "ControlMaster=auto" -o "ControlPath=/home/user/.ssh/svn_ssh-%r@%h:%p" -o "ControlPersist=60"</pre><br />
При этом соединение будет создаваться каждый раз при необходимости, и закрываться через 60 секунд после того, как оно становится невостребованным. <tt>ControlPersist=yes</tt> оставит соединение навсегда, что, вероятно, не очень безопасно, но зато позволяет комфортно исполнять разные команды, типа <tt>commit</tt> или <tt>update</tt> в течении работы, если расходы на создание соединения велики.Matwey V. Kornilovhttp://www.blogger.com/profile/10954558557636278561noreply@blogger.com0