16 июля 2013

Узнать свой текущий IP адрес

Чтобы узнать свой текущий IP адрес можно воспользоваться услугами DynDNS http://checkip.dyndns.com/. Вывод страницы простой и легко поддается разбору в скриптах.

Вы можете следить за обновлениями блога с помощью Atom/RSS и Telegram.

03 июля 2013

Ошибка при удалении снапшота LVM: Can't remove open logical volume

Выкроил пару часов времени чтобы переписать скрипты резервного копирования на работу с LVM снапшотами.

В процессе работы скрипт создает снапшоты для всех точек монтирования, которые нужно бэкапить и которые расположены на LVM. У меня это все, кроме /boot.

Снапшот создается как обычно

# lvcreate --snapshot --name rootfs-backup --size 500M /dev/VolGroup0/rootfs

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

# lvremove -f /dev/VolGroup0/rootfs-backup
Can't remove open logical volume "rootfs-backup"

Ошибка проявляется не всегда, что наводит на мысли о гонке. Пробую гуглить и натыкаюсь на обсуждение аналогичной проблемы. Оказывается корень проблемы в установленном udisks, который использует современный десктопный софт в Linux.

Как вариант, можно закомментировать строку KERNEL=="dm-*", OPTIONS+="watch" в файле /lib/udev/rules.d/80-udisks.rules, но вместо этого я добавил костыльworkaround в свой скрипт, который несколько раз повторяет действие, если была ошибка.

for i in rootfs usr var home
do
  for j in 1 2 3 4 5 6 7 8 9 10
    lvremove -f /dev/VolGroup0/${i}-backup && break
    sleep 3
  done
  if [ -e /dev/VolGroup0/${i}-backup ]; then
    echo "Failed to remove LVM snapshot VolGroup0/${i}-backup"
    exit 1
  fi
done

Вы можете следить за обновлениями блога с помощью Atom/RSS и Telegram.

01 июля 2013

Анонимные комментарии

Сегодня окончательно решил отключить анонимное комментирование. Причин для этого действия несколько:
  • мне лень разбираться в какофонии, которую порой генерируют анонимные комментаторы. Одно дело, когда оставленный комментарий не подразумевает диалога и другое дело, когда несколько человек одновременно что-то спрашивают и ждут ответа - поди разберись что и кому писать;
  • сегодня у большинства есть аккаунты, позволяющие комментировать не регистрируясь в моем блоге (google, facebook, openid, etc);
  • сетевые партизаны мне не интересны.

Вы можете следить за обновлениями блога с помощью Atom/RSS и Telegram.

08 июня 2013

Привязка контейнера OpenVZ к определенным ядрам процессора в Debian Squeeze

Поскольку в debian squeeze утилита vzctl довольно лохматой версии и не поддерживает опцию --cpumask, то пришлось городить велосипед, чтобы прикрепить конкретный контейнер на выделенные ядра процессора.

У подопытного сервера 4 ядра с hyper-threading - итого система видит 8 ядер. Перемещаем все процессы системы, для которых еще не задан явно affinity на ядра 4,5

for _PID in `ps --no-headers -A -o pid`
do
    taskset -p -c $_PID 2>/dev/null | grep -q 0-7$ && taskset -p -c 4,5 $_PID
done

Контейнер с VEID 300 на ядра 0-3

ps --no-headers -A -o pid | xargs vzpid | tail -n+2 | awk '{if ($2 == 300) print $1}' | xargs -n 1 taskset -p -c 0-3

Посмотреть все привязки в системе можно так:

ps --no-headers -A -o pid | xargs -I {} taskset -p -c {} 2>/dev/null

Вы можете следить за обновлениями блога с помощью Atom/RSS и Telegram.

31 мая 2013

Сломанный collation utf8_general_ci в MySQL 5.1.x

Наступил на забавные грабли при копировании базы с mysql 5.0.51 на mysql 5.1.49. Сделал дамп базы и скопировал на тестовый сервер, но при импорте произошла ошибка

ERROR 1062 (23000) at line 8615879: Duplicate entry 'Voß' for key 'ticketwords'

Пробую найти значение в уже добавленных строках, которое конфликтует со значением 'Voß'

mysql> select * from swticketwords where contents = 'Voß';
+--------------+----------+
| ticketwordid | contents |
+--------------+----------+
|        20080 | Vos      |
+--------------+----------+
1 row in set (0.00 sec)

Ерунда какая-то. Получается, что база считает 'Vos' = 'Voß' и отказывается добавлять значение. Начинаю гуглить и сразу натыкаюсь на репорты в багтрекере MySQL [1] [2]. Если в кратце, то разрабы поломали collation utf8_general_ci (который работал в mysql 5.0.x) и отказываются его чинить в mysql 5.1.x, мотивируя это тем, что фикс сломает еще больше.

Чтобы хоть как-то решить проблему был создан отдельный collation utf8_general_mysql500_ci, который возвращает старое поведение. Я поправил дамп, указав явный collation для таблицы swticketwords, и база успешно импортировалась. Чтобы показать разницу между utf8_general_ci и utf8_general_mysql500_ci я сделал запросы со старым и новым collation.

mysql> select * from swticketwords where contents = 'Voß' collate utf8_general_ci;
+--------------+----------+
| ticketwordid | contents |
+--------------+----------+
|        20080 | Vos      |
|       126378 | Voß      |
+--------------+----------+
2 rows in set (0.00 sec)

На поле contents создан уникальный ключ ticketwords, и двух значений быть не должно.
mysql> select * from swticketwords where contents = 'Voß' collate utf8_general_mysql500_ci;
+--------------+----------+
| ticketwordid | contents |
+--------------+----------+
|       126378 | Voß      |
+--------------+----------+
1 row in set (0.00 sec)

Ссылки:
1) http://bugs.mysql.com/bug.php?id=27877
2) http://bugs.mysql.com/bug.php?id=43593
3) http://dev.mysql.com/doc/refman/5.1/en/charset-unicode-sets.html

Вы можете следить за обновлениями блога с помощью Atom/RSS и Telegram.

03 мая 2013

Восстановление TP-Link TL-WA901ND после неудачной прошивки

Этот пост ориентирован на технически грамотную аудиторию. Если вы не обладаете необходимыми навыками - не пытайтесь повторить описанное. Я не несу никакой ответственности за ваши ошибки или возможный ущерб, возникший в следствии попытки повторить описанное.


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

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

Если же вы все еще не передумали, то начать нужно с загрузки в fail safe режиме. Если кратко, то железку нужно выключить, затем включить и когда индикатор "SYS" начнет мигать - нажать кнопку "RESET". После этого индикатор "SYS" должен начать мигать чаще и вы сможете зайти в консоль через telnet по адресу 192.168.1.1. Перед тем, как куда-то заходить, вы должны настроить адрес своего компьютера для сети 192.168.1.0/24.

В том конкретном случае мне повезло и у человека железка была включена в коммутатор (ethernet switch), в котором водится интернет и адрес его сети как раз 192.168.1.0/24. Если у вас не так, то придется пошевелить мозгами, чтобы заполнить пробелы, не описанные в этом посте.

Чтобы зайти в консоль железки вам потребуется telnet клиент. Для Windows подойдет putty. Настройте параметры "Host Name (or IP address)", "Port" и "Connection type" как показано на скриншоте и жмите кнопку "Open".



Воскрешаемая железка имела аппаратную ревизию 1.x и все примеры будут даны исходя из этого. Не пытайтесь слепо повторить примеры, если у вас другая ревизия.

Сначала нужно перейти в /tmp и проверить, что хватает свободного места.

root@(none):/# df -h /tmp
Filesystem                Size      Used Available Use% Mounted on
tmpfs                    14.3M     56.0K     14.2M   0% /tmp

В моём случае свободно 14M, далее нужно настроить сеть

root@(none):/# echo 'nameserver 8.8.8.8' > /etc/resolv.conf
root@(none):/# route add default gw 192.168.1.15
root@(none):/# ping ya.ru

Если после этих действий у вас начал пинговаться ya.ru, то можно переходить к следующему этапу - загрузке новой прошивки. Тут есть список всех прошивок из trunk проекта openwrt. Поскольку ревизия устройства 1.x, то я выбираю вариант openwrt-ar71xx-generic-tl-wa901nd-v1-squashfs-sysupgrade.bin. Теперь нужно скачать прошивку в устройство и на всякий случай проверить контрольную сумму.

root@(none):/# cd /tmp
root@(none):/tmp# wget http://downloads.openwrt.org/snapshots/trunk/ar71xx/openwrt-ar71xx-generic-tl-wa901nd-v1-squashfs-sysupgrade.bin
root@(none):/tmp# wget http://downloads.openwrt.org/snapshots/trunk/ar71xx/md5sums
root@(none):/tmp# md5sum -c md5sums 2>/dev/null | grep -v FAILED$
openwrt-ar71xx-generic-tl-wa901nd-v1-squashfs-sysupgrade.bin: OK

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

root@(none):/tmp# mtd -r write openwrt-ar71xx-generic-tl-wa901nd-v1-squashfs-sysupgrade.bin firmware

После успешного выполнения команды точка доступа должна перезагрузиться и у вас появится возможность зайти на нее через telnet. Дальнейшая настройка идентична первоначальной и описана тут.


Этот пост ориентирован на технически грамотную аудиторию. Если вы не обладаете необходимыми навыками - не пытайтесь повторить описанное. Я не несу никакой ответственности за ваши ошибки или возможный ущерб, возникший в следствии попытки повторить описанное.

Вы можете следить за обновлениями блога с помощью Atom/RSS и Telegram.

30 апреля 2013

Включение maintenance режима в Nginx без помощи системного администратора

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

Имеем два ip адреса, с которых нужно пускать клиентов независимо от текущего режима сайта (для примера 67.81.43.124 и 67.23.44.5). Чтобы для включения maintenance режима не нужно было дергать администратора, будем считать наличие файла maintenance.flag в корне сайта, признаком включения maintenance режима.

Я использую nginx из Debian Squeeze и примеры будут ориентированы на него.

Для поддержки нового режима я добавил несколько секций в /etc/nginx/sites-enabled/www.example.com

geo $show_maintenance_page {
    default yes;
    67.81.43.124 no;
    67.23.44.5 no;
}

server {
    listen 80;
    server_name www.example.com example.com;

    if ( -f /var/www/www.example.com/maintenance.flag ) {
        set $maintenance y;
    }

    if ( $show_maintenance_page = yes ) {
        set $maintenance y$maintenance;
    }

    if ( $maintenance = yy ) {
        return 503;
    }

    error_page 503 @maintenance;

    location @maintenance {
        root /var/www/maintenance;
        rewrite ^(.*)$ /maintenance.html break;
    }

    # All other config

}

Содержимое /var/www/maintenance у меня существует еще с прежнего варианта, который я описывал ранее. Теперь чтобы перевести сайт в режим maintenance нужно создать файл maintenance.flag в корне сайта (/var/www/www.example.com). После этого всем посетителям будет выдавать maintenance страницу, а для тех, кто заходит с адресов 67.81.43.124 или 67.23.44.5 будет доступен сайт. Чтобы выключить maintenance достаточно удалить файл maintenance.flag.

Вы можете следить за обновлениями блога с помощью Atom/RSS и Telegram.