linux

Linux: произвольное падение приложений на mono

53395Столкнулся со странной проблемой: без сторонней помощи стал закрываться RepetierHost. Ему было все равно печатал он модель, слайсил или просто был открытым. Сам хост я всегда открывал на отдельном воркспейсе и поначалу грешил на то, что какие-то проблемы могут быть у cinnamon, который сейчас использую как дефолтный стол. Если оставить хост отрытым и не менять рабочие столы, не запускать никаких приложений, то все нормально и приложение не отваливалось. Гугл ничего не смог сказать мне про систематический вылеты. Откат на предыдушие версии не помог — они так же вылетали.

Добавил в repetierHost строки, которые перенаправляли лог запуска в файл и он стал выглядеть вот так.

#!/usr/bin/env bash
cd /home/penguin/.soft/RepetierHost
env LANG=en_US.utf8 mono RepetierHost.exe -home {$HOME}.soft/RepetierHost &> {$HOME}/log&

После пары запусков я таки поймал в лог креш приложения. Да, не обращаете внимание на то, что принудительно используется локаль en_US — это решает проблему слайсера Slic3r, который по каким-то причинам отказывается работать с группами объектов названными символами, отличными от латинских.

/usr/bin/slic3r --load "slic3r_settings.ini" --print-center 100.00,100.00 -o "composition.gcode" "composition.amf"
Wide character at /usr/lib64/perl5/vendor_perl/Encode.pm line 212.

В amf-файле все группы должны иметь латинские имена, а repetier генерирует имена в текущей локали.

Пойманный трейс выглядит следующим образом.

Stacktrace:

at <unknown> <0xffffffff>
at (wrapper managed-to-native) System.Windows.Forms.X11Keyboard.Xutf8LookupString (intptr,System.Windows.Forms.XEvent&,byte[],int,intptr&,System.Windows.Forms.XLookupStatus&) <0x000a4>
at System.Windows.Forms.X11Keyboard.LookupString (System.Windows.Forms.XEvent&,int,System.Windows.Forms.XKeySym&,System.Windows.Forms.XLookupStatus&) <0x000bb>
at System.Windows.Forms.X11Keyboard.EventToVkey (System.Windows.Forms.XEvent) <0x0003f>
at System.Windows.Forms.X11Keyboard.ToUnicode (int,int,string&) <0x0034f>
at System.Windows.Forms.X11Keyboard.TranslateMessage (System.Windows.Forms.MSG&) <0x0011f>
at System.Windows.Forms.XplatUIX11.TranslateMessage (System.Windows.Forms.MSG&) <0x00027>
at System.Windows.Forms.XplatUI.TranslateMessage (System.Windows.Forms.MSG&) <0x00024>
at System.Windows.Forms.Application.RunLoop (bool,System.Windows.Forms.ApplicationContext) <0x00d6b>
at System.Windows.Forms.Application.Run (System.Windows.Forms.ApplicationContext) <0x00047>
at System.Windows.Forms.Application.Run (System.Windows.Forms.Form) <0x00037>
at RepetierHost.Program.Main (string[]) <0x0003f>
at (wrapper runtime-invoke) <Module>.runtime_invoke_void_object (object,intptr,intptr,intptr) <0x000d1>

Native stacktrace:

mono(+0xc3794) [0x55d10cc73794]
mono(+0x11a8ce) [0x55d10ccca8ce]
mono(+0x3c633) [0x55d10cbec633]
/lib64/libpthread.so.0(+0x115c0) [0x7f4b23cea5c0]
/lib64/libc.so.6(strlen+0x26) [0x7f4b23788fe6]
/lib64/libX11.so.6(_XimLocalUtf8LookupString+0xde) [0x7f4b1870b8fe]
[0x4249f8b5]

Debug info from gdb:

[New LWP 5108]
[New LWP 5112]
[New LWP 5116]
[New LWP 5117]
[New LWP 5118]
[New LWP 5119]
[New LWP 5121]
[New LWP 5122]
[New LWP 5123]
warning: File "/usr/bin/mono-sgen-gdb.py" auto-loading has been declined by your `auto-load safe-path' set to "$debugdir:$datadir/auto-load".
To enable execution of this file add
add-auto-load-safe-path /usr/bin/mono-sgen-gdb.py
line to your configuration file "/home/penguin/.gdbinit".
To completely disable this security protection add
set auto-load safe-path /
line to your configuration file "/home/penguin/.gdbinit".
For more information about this security protection see the
"Auto-loading safe path" section in the GDB manual.  E.g., run from the shell:
info "(gdb)Auto-loading safe path"
warning: File "/usr/bin/mono-sgen-gdb.py" auto-loading has been declined by your `auto-load safe-path' set to "$debugdir:$datadir/auto-load".
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
0x00007f4b23ce9fdb in waitpid () from /lib64/libpthread.so.0
Id   Target Id         Frame
* 1    Thread 0x7f4b247fa780 (LWP 5104) "mono" 0x00007f4b23ce9fdb in waitpid () from /lib64/libpthread.so.0
2    Thread 0x7f4b1c3ff700 (LWP 5108) "mono" 0x00007f4b23ce6460 in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0
3    Thread 0x7f4b1cb62700 (LWP 5112) "Finalizer" 0x00007f4b23ce8957 in do_futex_wait.constprop () from /lib64/libpthread.so.0
4    Thread 0x7f4b0c301700 (LWP 5116) "Timer-Scheduler" 0x00007f4b23ce6809 in pthread_cond_timedwait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0
5    Thread 0x7f4b18044700 (LWP 5117) "Timer-Scheduler" 0x00007f4b23ce6809 in pthread_cond_timedwait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0
6    Thread 0x7f4b06eef700 (LWP 5118) "Threadpool work" 0x00007f4b23ce6809 in pthread_cond_timedwait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0
7    Thread 0x7f4b06cee700 (LWP 5119) "Threadpool work" 0x00007f4b23ce6809 in pthread_cond_timedwait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0
8    Thread 0x7f4b05af4700 (LWP 5121) "Threadpool work" 0x00007f4b23ce6809 in pthread_cond_timedwait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0
9    Thread 0x7f4b06241700 (LWP 5122) "Threadpool work" 0x00007f4b237f801d in poll () from /lib64/libc.so.6
10   Thread 0x7f4b04c93700 (LWP 5123) "Threadpool work" 0x00007f4b23ce6809 in pthread_cond_timedwait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0

Thread 10 (Thread 0x7f4b04c93700 (LWP 5123)):
#0  0x00007f4b23ce6809 in pthread_cond_timedwait@@GLIBC_2.3.2 () at /lib64/libpthread.so.0
#1  0x000055d10cd6b9ab in worker_thread ()
#2  0x000055d10cd661d6 in start_wrapper ()
#3  0x000055d10ce1af4a in inner_start_thread ()
#4  0x00007f4b23ce06ca in start_thread () at /lib64/libpthread.so.0
#5  0x00007f4b23803f7f in clone () at /lib64/libc.so.6

Thread 9 (Thread 0x7f4b06241700 (LWP 5122)):
#0  0x00007f4b237f801d in poll () at /lib64/libc.so.6
#1  0x000055d10cd6d2f2 in poll_event_wait ()
#2  0x000055d10cd6e136 in selector_thread ()
#3  0x000055d10cd661d6 in start_wrapper ()
#4  0x000055d10ce1af4a in inner_start_thread ()
#5  0x00007f4b23ce06ca in start_thread () at /lib64/libpthread.so.0
#6  0x00007f4b23803f7f in clone () at /lib64/libc.so.6

Thread 8 (Thread 0x7f4b05af4700 (LWP 5121)):
#0  0x00007f4b23ce6809 in pthread_cond_timedwait@@GLIBC_2.3.2 () at /lib64/libpthread.so.0
#1  0x000055d10cd6b9ab in worker_thread ()
#2  0x000055d10cd661d6 in start_wrapper ()
#3  0x000055d10ce1af4a in inner_start_thread ()
#4  0x00007f4b23ce06ca in start_thread () at /lib64/libpthread.so.0
#5  0x00007f4b23803f7f in clone () at /lib64/libc.so.6

Thread 7 (Thread 0x7f4b06cee700 (LWP 5119)):
#0  0x00007f4b23ce6809 in pthread_cond_timedwait@@GLIBC_2.3.2 () at /lib64/libpthread.so.0
#1  0x000055d10cd6b9ab in worker_thread ()
#2  0x000055d10cd661d6 in start_wrapper ()
#3  0x000055d10ce1af4a in inner_start_thread ()
#4  0x00007f4b23ce06ca in start_thread () at /lib64/libpthread.so.0
#5  0x00007f4b23803f7f in clone () at /lib64/libc.so.6

Thread 6 (Thread 0x7f4b06eef700 (LWP 5118)):
#0  0x00007f4b23ce6809 in pthread_cond_timedwait@@GLIBC_2.3.2 () at /lib64/libpthread.so.0
#1  0x000055d10cd6b9ab in worker_thread ()
#2  0x000055d10cd661d6 in start_wrapper ()
#3  0x000055d10ce1af4a in inner_start_thread ()
#4  0x00007f4b23ce06ca in start_thread () at /lib64/libpthread.so.0
#5  0x00007f4b23803f7f in clone () at /lib64/libc.so.6

Thread 5 (Thread 0x7f4b18044700 (LWP 5117)):
#0  0x00007f4b23ce6809 in pthread_cond_timedwait@@GLIBC_2.3.2 () at /lib64/libpthread.so.0
#1  0x000055d10ce19a7d in mono_thread_info_sleep ()
#2  0x000055d10cd6a91e in monitor_thread ()
#3  0x000055d10cd661d6 in start_wrapper ()
#4  0x000055d10ce1af4a in inner_start_thread ()
#5  0x00007f4b23ce06ca in start_thread () at /lib64/libpthread.so.0
#6  0x00007f4b23803f7f in clone () at /lib64/libc.so.6

Thread 4 (Thread 0x7f4b0c301700 (LWP 5116)):
#0  0x00007f4b23ce6809 in pthread_cond_timedwait@@GLIBC_2.3.2 () at /lib64/libpthread.so.0
#1  0x000055d10cdefb3f in _wapi_handle_timedwait_signal_handle ()
#2  0x000055d10ce06304 in wapi_WaitForSingleObjectEx ()
#3  0x000055d10cd659d8 in mono_wait_uninterrupted.isra.18.constprop ()
#4  0x000055d10cd65aa3 in ves_icall_System_Threading_WaitHandle_WaitOne_internal ()
#5  0x00000000420b2604 in  ()
#6  0x0000000000000002 in  ()
#7  0x0000000000000001 in  ()
#8  0x0000000000000064 in  ()
#9  0x00007f4b1c6a7bb0 in  ()
#10 0x0000000000000063 in  ()
#11 0x00007f4b08001960 in  ()
#12 0x00007f4b1c6a7bb0 in  ()
#13 0x00007f4b0c300660 in  ()
#14 0x00007f4b0c3005d0 in  ()
#15 0x00000000420b23d0 in  ()
#16 0x0000000000000000 in  ()

Thread 3 (Thread 0x7f4b1cb62700 (LWP 5112)):
#0  0x00007f4b23ce8957 in do_futex_wait.constprop () at /lib64/libpthread.so.0
#1  0x00007f4b23ce8a04 in __new_sem_wait_slow.constprop.0 () at /lib64/libpthread.so.0
#2  0x00007f4b23ce8aaa in sem_wait@@GLIBC_2.2.5 () at /lib64/libpthread.so.0
#3  0x000055d10cd877bb in finalizer_thread ()
#4  0x000055d10cd661d6 in start_wrapper ()
#5  0x000055d10ce1af4a in inner_start_thread ()
#6  0x00007f4b23ce06ca in start_thread () at /lib64/libpthread.so.0
#7  0x00007f4b23803f7f in clone () at /lib64/libc.so.6

Thread 2 (Thread 0x7f4b1c3ff700 (LWP 5108)):
#0  0x00007f4b23ce6460 in pthread_cond_wait@@GLIBC_2.3.2 () at /lib64/libpthread.so.0
#1  0x000055d10cde963f in thread_func ()
#2  0x00007f4b23ce06ca in start_thread () at /lib64/libpthread.so.0
#3  0x00007f4b23803f7f in clone () at /lib64/libc.so.6

Thread 1 (Thread 0x7f4b247fa780 (LWP 5104)):
#0  0x00007f4b23ce9fdb in waitpid () at /lib64/libpthread.so.0
#1  0x000055d10cc73870 in mono_handle_native_sigsegv ()
#2  0x000055d10ccca8ce in mono_arch_handle_altstack_exception ()
#3  0x000055d10cbec633 in mono_sigsegv_signal_handler ()
#4  0x00007f4b23cea5c0 in <signal handler called> () at /lib64/libpthread.so.0
#5  0x00007f4b23788fe6 in strlen () at /lib64/libc.so.6
#6  0x00007f4b1870b8fe in _XimLocalUtf8LookupString () at /lib64/libX11.so.6
#7  0x000000004249f8b5 in  ()
#8  0x0000000000000000 in  ()

=================================================================
Got a SIGSEGV while executing native code. This usually indicates
a fatal error in the mono runtime or one of the native libraries
used by your application.
=================================================================

Ок. Теперь уже проще гуглить. Ответ был найден на форуме arch-linux в ветке, которая посвящена keepass: это оказался баг в библиотеке WinForms, который не сильно важен для разработчиков и никто фиксить его пока не будет (оригинальный репорт).

Временное решение — добавить опцию —verify-all в качестве аргумента mono.

env LANG=en_US.utf8 mono --verify-all RepetierHost.exe -home {$HOME}.soft/RepetierHost

С этой опцией вылетов не наблюдается, но случаются фризы приложения.

linux

Fedora перестает грузиться на UEFI после обновения (и показывает MOK)

Никогда бы не подумал, но вчера столкнулся с проблемой при которой после обновления fedora начисто отказалась загружаться постоянно выдавая при старте окно MokManager с просьбой добавить ключи или хеши с secureboot.

Что меня больше всего удивило так это то, что efibootmgr -v выдавал кучу записей загрузчиков shim.efi с некорректными uuid разделов на которых они размещены.

$ efibootmgr -v
BootCurrent: 0002
Timeout: 0 seconds
BootOrder: 0007,0002,2001,2002,2003
Boot0000* Fedora    HD(1,GPT,f627bf87-5440-4997-8310-aa80dba7e383,0x800,0x64000)/File(\EFI\Fedora\shim.efi)
Boot0001* Fedora    HD(1,GPT,f627bf87-5440-4997-8310-aa80dba7e383,0x800,0x64000)/File(\EFI\fedora\shim.efi)
Boot0002* Linux    PciRoot(0x0)/Pci(0x1c,0x4)/Pci(0x0,0x0)/NVMe(0x1,00-00-00-00-00-00-00-00)/HD(1,GPT,f627bf87-5440-4997-8310-aa80dba7e383,0x800,0x64000)/File(\EFI\BOOT\BOOTX64.EFI)A01 ..
Boot0003* Fedora    HD(1,GPT,f627bf87-5440-4997-8310-aa80dba7e383,0x800,0x64000)/File(\EFI\fedora\shim.efi)
Boot0004* Fedora    HD(1,GPT,f627bf87-5440-4997-8310-aa80dba7e383,0x800,0x64000)/File(\EFI\fedora\shim.efi)
Boot0005* Fedora    HD(1,GPT,f627bf87-5440-4997-8310-aa80dba7e383,0x800,0x64000)/File(\EFI\fedora\shim.efi)
Boot0006* Fedora    HD(1,GPT,f627bf87-5440-4997-8310-aa80dba7e383,0x800,0x64000)/File(\EFI\fedora\shim.efi)
Boot0007* Fedora    HD(1,GPT,f627bf87-5440-4997-8310-aa80dba7e383,0x800,0x64000)/File(\EFI\fedora\shim.efi)
Boot2001* EFI USB Device    RC
Boot2002* EFI DVD/CDROM    RC
Boot2003* EFI Network    RC

Конечно в данном листинге уже все верно поскольку он был сделан на рабочей машине, но в оригинальном листинге в идентификаторе HD были прописаны несуществующие uuid разделов. И подобных записей было далеко за 20 штук.

К сожалению мне неизвестна причина по которой система прописывает неверные данные, но мне нужно было оживить машину. Для этого следует сначала зайти в chroot окружение убитой системы.

Далее нам потребуется удалить все записи загрузчика с неверными данными. Это записи вида Boot0ХХХ.

Сначала надо переустановить grub-efi и shim как это рекомендует документация.

# dnf reinstall grub-efi shim

Теперь удаляем невалидные записи. Для их удаления нам потребуется выполнять команду

# efibootmgr -B -b XXXX
  • -B — удалить запись
  • -b XXXX — выбрать активной запись XXXX

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

Последним шагом будет добавление правильной записи.

efibootmgr -c -w -L Fedora -d /dev/nvme0n1 -p 1 -l '\EFI\Fedora\shim.efi'
  • -c — создать запись
  • -w — сделать запись в mbr если это требуется
  • -L Fedora — метка новой записи в загрузчике
  • -d /dev/nvme0n1 — жесткий диск на котором размещен efi-раздел (у вас может быть /dev/sda или любой другой)
  • -p 1 — номер раздела на диске (если efi у вас это /dev/sda1, то 1, sda2 — 2 и т.д.)
  • -l ‘\EFI\Fedora\shim.efi’ — расположение файла загрузчика относительно корня диска efi (а не корня файловой системы в которую он подмонтирован). Обратите внимание, что тут нам обязательно надо указать загрузчик shim.efi, а не что-то другое.

После завершения можно перезагружаться и пробовать войти в систему. Mok Manager больше не должен появляться. Если это не так, то где-то вы допустили ошибку.

Литература

HowTo, linux

OpenWRT: блокировка рекламы

1280px-openwrt_logo-svgЕсть отличная прошивка на базе всеми любимого линупса для всякой разной техники вроде роутеров и микрокомпьютеров — это OpenWRT.

А поскольку эта штука работает в качестве локального днс-сервера, то грех не научить ее блокировать на корню всякие даблклик.нет и другое непотребство.

Рассматривать будем ситуацию при которой у нас установлена дефолтная конфигурация c dnsmasq.

Сначала нам потребуется поставить пакет dnsmasq-full взамен стандартного (он чуть больше по объему и тянет больше зависимостей, и предоставляет больше возможностей по настройке).

# opkg update
# opkg remove dnsmasq
# opkg install dnsmasq-full
# /etc/init.d/dnsmasq restart

Посмотрим на файл /tmp/etc/dnsmasq.conf. Нас будут интересовать следующие два параметра.

addn-hosts=/tmp/hosts
conf-dir=/tmp/dnsmasq.d

Буквально это значит, что дополнительные файлы в формате /etc/hosts хранятся в /tmp/hosts, а дополнительные конфиги — в /tmp/dnsmasq.d.

Теперь нам потребуется скрипт, который будет скачивать листы. Поместим его в /root/bin/adblock.sh

#!/bin/sh
echo "download adblock rules"

if [ ! -d /tmp/dnsmasq.d ]; then
 mkdir /tmp/dnsmasq.d
fi

if [ ! -d /tmp/hosts ]; then
 mkdir /tmp/hosts
fi

touch /tmp/dnsmasq.d/adblock.conf

wget -O /tmp/dnsmasq.d/adblock.conf "http://pgl.yoyo.org/adservers/serverlist.php?hostformat=dnsmasq&amp;showintro=0&amp;mimetype=plaintext"

echo "" > /tmp/hosts/adblock

wget -O /tmp/adblock https://hosts-file.net/ad_servers.txt
sed 's/^\(.*\).$/\1/' /tmp/adblock >> /tmp/hosts/adblock
wget -O /tmp/adblock https://adaway.org/hosts.txt
sed 's/^\(.*\).$/\1/' /tmp/adblock >> /tmp/hosts/adblock
wget -O /tmp/adblock http://winhelp2002.mvps.org/hosts.txt
sed 's/^\(.*\).$/\1/' /tmp/adblock >> /tmp/hosts/adblock

if [ -f /tmp/adblock ]; then
 rm /tmp/adblock
fi

/etc/init.d/dnsmasq enabled && /etc/init.d/dnsmasq restart

Первым мы скачиваем файл с блокировками в формате dnsmasq, а последующие запросы — это блокировки в формате hosts. Соответственно раскладываем их по разным папкам и рестартим сервис.

Не забываем поставить +x на файл.

Теперь нужно добавить этот скрипт в крон дабы он обновлялся.

 # crontab -e

и пишем туда что-то вроде

* */12 * * *  /bin/sh /root/bin/adblock.sh

Это означает, что раз в 12 часов списки будут обновляться.

Естественно, что надо включить крон. По дефолту он выключен.

# /etc/init.d/cron enable
# /etc/init.d/cron enabled && /etc/init.d/cron start

Теперь осталось сделать так, чтобы при поднятии сетевого интерфейса скрипт сразу же обновлял правила.

А для этого нам потребуется создать файл /etc/hotplug.d/iface/50-adblock примерно следующего вида.

#!/bin/sh
[ ifup = "$ACTION" -a "$DEVICE" = eth1 ] && {
	/bin/sh /root/bin/update_adblock.sh
}

Где eth1 — это ваш wan-интерфейс.

Все. Можно перезагрузить роутер для проверки что все настроено корректно.

Рекламные домены вроде doubleclick.de должны резолвиться либо на 0.0.0.0, либо на 127.0.0.1.

$ nslookup  doubleclick.de
Server:		192.168.0.1
Address:	192.168.0.1#53

Name:	doubleclick.de
Address: 127.0.0.1

Чтобы точно убедиться, что все работает как надо — проверяйте что сразу после поднятия wan появились файлы /tmp/dnsmasq.d/adblock.conf и /tmp/hosts/adblock.

Учтите, что в сумме размер списков блокировки составит более 100 тысяч записей. И если роутер слабоват, то придется какой-то из списков отключать.

И да — это не панацея. Это просто хороший способ обезопасить электронные читалки, телефоны и разную мелкую технику, которая ходит в инет от баннеров и прочего добра.

Источники:

HowTo, linux

Как жить в локальной сети без dns для локальных ресурсов

Extra-BonjourИли сказ о том, как перестать бояться и начать раздавать динамические адреса в локальной сети.

Задача:

  • необходимо автоматизировать распределение имен различным устройствам в сети.

Проблемы

  • доисторический (ископаемый) роутер, который не умеет dd-wrt/openwrt и иже. А вместе с этим он не умеет статические адреса или локальный dns.
  • много iot-желаза в локальной сети к которому хочется получать доступ по имени (доменному конечно же).
  • Очень много железа, которое появляется в сети лишь на короткое время, а доступ к нему по сети нужен (ну не прописывать же ему постоянно статику?)
  • большое количество скриптов автоматизации, которым надо откуда-то брать именя устройств.

Проблему можно решить несколькими путями:

  • Поставить слабую железку, поставить на нее bind, поднять локальную доменную зону и убрать с роутера роль dhcp и dns-сервера. Минус в том, что слабой железки может и не быть.
  • Поменять роутер на менее доисторический. Минус в том, что роутера может не быть под рукой.
  • Воспользоваться протоколом zeroconf. Минусы тоже есть — возможный конфликт имен устройств.

Если с первыми двума вариантами все более-менее понятно, то на третьем стоит остановиться подробно. Так как он решает проблему наименее затратным способом.

Протокол описывает:

  • назначение адресов устройствам в сети (диапазон 169.254.*)
  • разрешение имен
  • обнаружение сервисов

Поскольку адреса у устройств уже есть (dhcp же), то нас будет интересовать только та часть протокола, где рассказывается про обнаружение сервисов и разрешение имен. Это mDNS+DNSSD.

В nix\bsd за эту часть протокола отвечает сервис avahi

В ряде дистрибутивов он включен и нормально настроен сразу.

На примере федоры посмотрим как его поставить и настроить.

$ sudo dnf install avahi-daemon avahi-utils
$ sudo systemctl enable avahi-daemon
$ sudo systemctl start avahi-daemon

Если у вас в сети уже есть устройства, где активирован avahi, то можно посмотреть на то, найдет ли оно какие-либо устройства

$ avahi-browse -alr
+   eth0 IPv4 workstation                                   Remote Disk Management local
=   eth0 IPv4 workstation                                   Remote Disk Management local
   hostname = [workstation.local]
   address = [192.168.1.10]
   port = [22]
   txt = []

Как видим что-то нашло.

Мы можем попробовать его попинговать.

$ ping workstation.local
ping: unknown host workstation.local

Если вы увидели такую картину, то это означает лишь одно — mdns для получения имен доменов у вас не подключен.

Чтобы его включить требуется отредактировать /etc/nsswitch.conf.

В строчку hosts нужно добавить mdns_minimal [NOTFOUND=return] перед dns.

hosts: files mdns_minimal [NOTFOUND=return] dns myhostname mymachines

После перезагрузки или перезапуска соотвествующего сервиса пингуем снова.

$ ping -c 4 workstation.local
PING workstation.local (192.168.1.10) 56(84) bytes of data.
64 bytes from workstation.local (192.168.1.10): icmp_req=1 ttl=64 time=0.449 ms
64 bytes from workstation.local (192.168.1.10): icmp_req=2 ttl=64 time=0.469 ms
64 bytes from workstation.local (192.168.1.10): icmp_req=3 ttl=64 time=0.467 ms
64 bytes from workstation.local (192.168.1.10): icmp_req=4 ttl=64 time=0.393 ms

--- workstation.local ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3004ms
rtt min/avg/max/mdev = 0.393/0.444/0.469/0.037 ms

Если у вас очень медленно резолвятся локальные домены, то стоит попробовать использовать модуль mdns4_minimal.

Задача раздачи локальных имен полностью решена. В данном случае я не затрагиваю dnssd поскольку цель была лишь обеспечить доступность хостов по имени.

При желании поднять zeroconf можно как на ардуине, так и на модулях esp8266.

Вы можете столнуться с проблемами из-за того, что некоторые продукты используют зону local для своих целей.

Например торренты часто используют retracker.local для обозначения внутрисетевого трекера.

Разработка, HowTo, linux

Обновление нескольких git-репозитариев в папке

2016-03-08-22:48:31_580x134 Порой у нас в каталоге накапливается много-много git-репозитариев, которые хочется обновить в один заход. Для этого есть маленький скрипт, который обновляет все репозитарии, которые сможет найти в папке, переданной в качестве аргумента.

#!/bin/bash

if test "$#" -ne 1; then
    echo "usage: $0 <dirname>"
		echo "Find and update all git repos in specified folder"
    exit 1
fi

if [ -d $1 ]; then
	find $1 -type d -name .git | xargs -n 1 dirname | sort | while read line; do echo "Update repo $line" && pushd `pwd` > /dev/null && cd $line && git pull && popd > /dev/null; done
else
	echo "\"$1\" does not exists"
fi

Использование очень простое

$ gitup ~/projects

Репозитарий на github.

linux

PHPStorm (PyCharm и др.) и XMonad

2016-02-28-23:48:47_708x493После запуска PHPStorm вместо самое среды появляется лишь серое окно без ничего.
Работаю я в xmonad и произошло это после очередной правки конфига под себя.
В документации сказано, что для java-приложений нужен

startupHook = setWMName "LG3D"

Но этот хук перестал почему-то оказывать должный эффект (без него в ряде java-приложений тоже был пустой экран).
А все оказалось просто: я добавил хук ewmhDesktopsEventHook.

handleEventHook = do
  ewmhDesktopsEventHook -- вот он
  docksEventHook
  fullscreenEventHook -- Full screen setup

Хук нужен для перехвата сообщений по активации окна, перемещению его на другой рабочий стол и переключении рабочих столов. Можно почитать документацию и код.

Но беда в том, что этот хук трет имя wm, которое устанавливается в конфиге (ставит «xmonad»). Этот wmname (который lg3d) служит решением для бага из awt.

Чтобы использовать ewmhDesktopsEventHook нужно указать java окольными путями, что она работает в «non reparenting» (не подобрал я нормального перевода :)) окружении.

Для этого служит переменная окружения _JAVA_AWT_WM_NONREPARENTING.

Пишем в ~/.bashrc или ~/.profile

export _JAVA_AWT_WM_NONREPARENTING=1

И теперь все хорошо.

2016-02-28-23:50:36_708x495

linux

Raspbian — это не Debian

img_raspbian_logo Raspbian — это не Debian. Хотя картинка нас убежлает в обратном.

В чем проблема? Проблема в обозначении архитектуры.

Давеча захотел я поставить на малинку пакет из репозитария собранного под Debian.

Прописал как положено в /etc/apt/sources.list.d/<repository>.list

deb <repourl> wheezy main

Установил и получил segmentation fault. Казалось бы — архитектура armhf (как на малинке), но почему-то не работает.

А дело все в том, что разработчики raspbian перекомпилировали дебиановский armhf (ARMv7) для совместимости с ARMv6, но название архитектуры не поменяли. В итоге попытки установить какой-нибудь пакет *.armhf из дебиана может закончится сегментейшнфаултом.

Для того, чтобы решить все проблемы с софтом из дебиановских репозитариев нужно использовать архитектуру armel, которой разработчики обозначают как раз v6. И явно ее указывать в настройках.

В итоге конфигурация репозитариев deb будет выглядеть так:

deb [arch=armel] <repourl> wheezy main

Ключевое здесь — добавить спецификацию архитектуры как [arch=armel] и таким образом можно успешно подключать даже репозитарии с какого-нибудь ланчпада.

Пруф