суббота, 7 апреля 2012 г.

Проблемы с засыпанием на диск с подключенными USB устройствами

После очередного глюка с мышью из-за "раздербаненого" за несколько лет порта PS/2 я наконец решил, что пора сделать апгрейд. Заодно проапгрейдить и клавиатуру (с ней проблем почти не было, но приглянулась слим модель).

Поискав по интернет магазинам, я остановил свой выбор на продукции A4Tech. Кандидатом на новую клавиатуру стала модель A4Tech KV-300H. У этой модели помимо "ноутбучных" клавиш еще есть USB 2.0 хаб на два порта что делает более удобной работу с флешками и прочей USB-мелочевкой.

На роль нового грызуна была выбрана A4Tech N-360.
У этой модели нет никаких излишеств вроде кучи кнопок или геймерских примочек. Простая и надежная рабочая лошадка. К тому же производитель обещает уверенную работу на любой поверхности благодаря технологии V-Track.

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

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

На следующий день я стал изучать интернет на предмет упоминания аналогичных ситуаций - наиболее частое решение - выгружать модуль ehci_hcd в процессе засыпания. Поскольку у меня используется pm-utils + uswsusp для реализации засыпания на диск, то я просто дописал два модуля, ответственных за работу USB на моем компе. Получилось так:

$ cat /etc/pm/config.d/modules
SUSPEND_MODULES="ath9k_htc ohci_hcd ehci_hcd"

После этого засыпание и пробуждение стало работать как и прежде. Появилась проблема с раскладкой клавиатуры, посколько у меня она применяется при логине в профиль и не прописана в систему. Скорее всего есть способ реализовать вызов пользовательских скриптов на событие "пробуждение из suspend2disk". Пока же приходится просто выполнять это руками:

$ setxkbmap $(cat ~/.Xkbmap)

UPDATE. Добавил немного автоматизации.

вторник, 3 апреля 2012 г.

Прерывание проверки дискового массива в mdadm

MDADM, поставляемый вместе с дистрибутивом Debian, содержит задание CRON, которое раз в месяц запускает проверку целостности массива. На больших массивах, размер которых превышает несколько терабайт, такая проверка может занять слишком много времени. Прогресс выполнения проверки можно узнать в /proc/mdstat

# cat /proc/mdstat
Personalities : [raid1] 
md1 : active raid1 sdb2[0] sda2[1]
      1911569360 blocks super 1.2 [2/2] [UU]
      [>....................]  check =  0.0% (8832/1911569360) finish=7201.4min speed=4416K/sec
      
md0 : active raid1 sdb1[0] sda1[1]
      41941944 blocks super 1.2 [2/2] [UU]
      
unused devices: <none>

Прервать такую проверку можно так:

# echo idle > /sys/block/md1/md/sync_action

После чего можно проверить, что массив действительно перестал проверяться:
# cat /proc/mdadm
Personalities : [raid1] 
md1 : active raid1 sdb2[0] sda2[1]
      1911569360 blocks super 1.2 [2/2] [UU]
      
md0 : active raid1 sdb1[0] sda1[1]
      41941944 blocks super 1.2 [2/2] [UU]
      
unused devices:  <none>

Чтобы отменить такую проверку в будущем, нужно установить параметр AUTOCHECK=false в /etc/default/mdadm

пятница, 30 марта 2012 г.

Быстрое создание образа для виртуальных машин QEMU/KVM/VirtualBox/etc

После начала изучения puppet мне частенько приходится генерировать образы для виртуальных машин, причем порой десятками. Когда-то давно, для упрощения процесса инсталяции я писал скрипт-обертку над debootstrap, который устанавливал минимальную систему, ядро и загрузчик на предварительно размеченный диск. Для этого приходилось загружать livecd, размечать там диск и после этого запускать скрипт. В принципе этого хватало, если нужно создать одну, максимум две машинки. Но если их нужно сделать десяток, то минусы этого решения вставали в полный рост.

Чтобы решить проблему более полно, я дописал недостающий функционал. Получившийся скрипт назвал bootstrapper.sh, его последнюю версию можно взять тут. Сразу после создания образа его можно использовать в KVM/Qemu.

$ sudo ./bootstrapper.sh test.raw 4G
$ kvm -m 512 -hda test.raw

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

$ VBoxManage convertfromraw test.raw test.vdi --format VDI

После этого test.vdi можно подключить в виртуальную машину VirtualBox. Скорее всего аналогично можно поступить и для VMWare, если сконвертировать в VMDK формат:

$ VBoxManage convertfromraw test.raw test.vmdk --format VMDK

вторник, 27 марта 2012 г.

MySQL: backup and partial restore

Одна из методик создания резервных копий баз данных MySQL основывается на использовании снимков LVM. Скрипт, который отвечает за создание резервной копии выглядит примерно так:

#!/bin/bash
MYSQL_VG="VolGroup00"
MYSQL_LV="mysql"
MYSQL_SRC="/mnt/mysql-root"
MYSQL_DST="root@backup.server:/backup/mysql-server"

echo "FLUSH TABLES WITH READ LOCK; \! /sbin/lvcreate -s -n ${MYSQL_LV}-backup -L 1G ${MYSQL_VG}/${MYSQL_LV}" | mysql
echo "UNLOCK TABLES" | mysql
mkdir ${MYSQL_SRC}
mount /dev/${MYSQL_VG}/${MYSQL_LV} ${MYSQL_SRC} -o ro
rsync -avzxHS --delete --numeric-ids ${MYSQL_SRC}/ ${MYSQL_DST}/
umount ${MYSQL_SRC}
rmdir ${MYSQL_SRC}
lvchange -an ${MYSQL_VG}/${MYSQL_LV}-backup
lvremove ${MYSQL_VG}/${MYSQL_LV}-backup

Примечание: примеры ориентированы на Debian Squeeze и в других дистрибутивах могут потребоваться доработки.

В самом начале буферы таблиц в MySQL базах сбрасываются на диск и вводится блокировка операций записи в таблицы. Затем создается снимок LVM тома, на котором расположены базы MySQL. После создания снимка снимается блокировка записи и MySQL продолжает работать в нормальном режиме. Расплатой за это удобство является снижение скорости дисковых операций записи в MySQL в то время, пока активен снимок LVM.

Далее снимок монтируется как обычное блочное устройство и файлы, в которых MySQL хранит базы данных, переносятся в резервную копию любым удобных способом. В примере используется rsync, что позволяет передавать по сети только измененившиеся части файлов. По окончании переноса файлов, снимок LVM размонтируется и удаляется из менеждера томов.

Таким образом делается бэкап без остановки работы сервера. Однако создание резервных копий не самоцель, их нужно также восстанавливать в случае потери данных или необходимости получить доступ к более раннему состоянию баз данных. Самый простой способ восстановить резервную копию, созданную описанных выше способом, это остановить сервер MySQL и скопировать данные обратно.

# service mysql stop
# rsync -avxzHS --delete --numeric-ids root@backup.server:/backup/mysql-server/ /var/lib/mysql/
# service mysql start

Такой способ восстановления подходит, если нужно вернуть все базы в исходное состояние на момент создания резервной копии. Но что делать, если нужно восстановить только одну базу, одну таблицу или только несколько записей из конкретной таблицы? Что если основной сервер не допускает остановки? Конечно можно поднять отдельный MySQL сервер на другом сервере, скопировать туда бэкап и после запуска вытащить из него нужные данные посредством mysqldump. Но что делать, если другого сервера нет или версия MySQL сервера содержит патчи, которые делают резервную копию несовместимой с дистрибутивной версией? Я постараюсь дать одно из возможных решений этой проблемы.

В своем способе я также буду запускать отдельную копию MySQL сервера, но основная идея заключается в том, чтобы не копировать данные из бэкапа, а примонтировать их через сеть. Я буду использовать sshfs для этих целей. Чтобы при запуске второго сервера не изменились данные в бэкапе я применю оверлей на базе AUFS. Одна из его частей будет примонтированным бэкапом, а вторая - хранить все изменения относительно бэкапа. Таким образом я избегаю любых модификаций резервной копии.

# mkdir /mnt/mysql-{backup,datadir,tmp}
# sshfs root@backup.server:/backup/mysql-server /mnt/mysql-backup
# mount -t aufs none /mnt/mysql-datadir -o dirs=/mnt/mysql-tmp:/mnt/mysql-backup=ro
# mysqld_safe --defaults-file=/root/mysql-backup-restore.cnf

/root/mysql-backup-restore.cnf - конфигурация для второго сервера, которую я сделал на базе конфига из дистрибутива.

[mysqld]
user=root
pid-file        = /root/mysql-restore.pid
socket          = /root/mysql-restore.sock
basedir         = /usr
datadir         = /mnt/mysql-datadir
tmpdir          = /tmp
language        = /usr/share/mysql/english
skip-networking
skip-external-locking
key_buffer              = 16M
max_allowed_packet      = 16M
thread_stack            = 192K
thread_cache_size       = 8
myisam-recover         = BACKUP
query_cache_limit       = 1M
query_cache_size        = 16M
expire_logs_days        = 10
max_binlog_size         = 100M

[mysqldump]
quick
quote-names
max_allowed_packet      = 16M

[isamchk]
key_buffer              = 16M

!includedir /etc/mysql/conf.d/

После запуска вторая копия MySQL сервера доступна только через сокет /root/mysql-restore.sock, чем позволяет исключить посторонний доступ на время восстановления данных. Чтобы подключиться к запущенному серверу, нужно явно указать сокет:

# mysql -S /root/mysql-restore.sock
# mysqldump -S /root/mysql-restore.sock --add-drop-table dbname table1 table2 > dbrestore.sql

После того, как данные сняты посредством mysqldump нужно остановить вторую копию сервера. Для этого нужно выполнить:

# mysqladmin -S /root/mysql-restore.sock shutdown

Когда дополнительный сервер остановится можно отмонтировать /mnt/mysql-datadir и /mnt/mysql-backup, и удалить директории /mnt/mysql-{backup,datadir,tmp}

Несомненным преимуществом такого подхода является время, которое тратится на частичное восстановление резервной копии. Из недостатков пожалуй отсутствие sshfs и aufs во многих дистрибутивах (для centos я так и не смог найти пакета для добавления поддержки aufs). Возможно его следует заменить на любую другую реализацию union fs, но я это делать не пробовал.

вторник, 20 марта 2012 г.

New Midnight Commander releases

Today midnight commander development team announced new releases:

Debian/Ubuntu packages build process running just now and after it finished packages will be available in my repository.

About a week ago I notice that debian distribution now provide 4.8.1 release in it's archive. I hope in near future debian could include fresh versions rapidly after upstrem releases it.

понедельник, 19 марта 2012 г.

Показ скрытых файлов в CuteFTP

Сегодня наткнулся на отсутствие скрытых файлов вроде .htaccess в листинге директорий в CuteFTP. В других ftp клиентах проблемы не было, т.к. там есть аналоги опций "Show hidden files".

Поизучав опции cuteftp сходу решение так и не нашлось. Зато пробежка в гугле дала результат:

Рецепт

Выбрать нужное соединение в "Site manager" и редактировать его свойства. На вкладке "Actions" нужно нажать кнопку "Filters...".


В открывшемся окне отметить пункт "Enable filtering", затем "Enable server-side filtering". В поле ввода вбить "-al" (без кавычек).


После этого в CuteFTP станут видны скрытые файлы.

среда, 14 марта 2012 г.

Перенос почтовых аккаунтов и форвардеров в WHM/сPanel

Сегодня очередной раз переносил почтовые аккаунты с одного сервера на другой (оба под управлением WHM/cPanel). Потому сделаю себе пометку, чтобы не забыть в будущем как это делается.

Аккаунты и пароли переносятся на новый сервер простым копированием пользовательских ~/etc и ~/mail. Я это делаю через FTP. Чтобы перенести почтовые форвардеры, нужно копировать содержимое /etc/valiases. Обычно там больше, чем реально нужно, поэтому можно ограничиться нужными доменами.

Привязку unix юзера к домену в cPanel можно глянуть в /etc/domainusers.