воскресенье, 18 июня 2017 г.

Flash-плагин для Chromium и Iceweasel/Firefox в Debian

В 2012 году Adobe объявил о прекращении выхода новых версий Flash-плагина для Linux: 01.04.2012 14:29 Релиз Adobe Flash 11.2, последней версии с поддержкой Linux. Мне этот плагин не нужен, но вот люди, любящие играть во Flash-игры под Linux в социальных сетях, опечалились - многие игры отказываются работать в старых версиях плагина.

Надо сказать, что браузер Iceweasel/Firefox, являющийся далёким потомком браузера Netscape, предоставляет интерфейс для подключения к нему плагинов. Этот интерфейс называется NPAPI - Netscape Plugin Application Programming Interface - программный интерфейс подключаемых модулей Netscape.

У браузера Chromium, являющегося свободной версией браузера Chrome, разрабатываемого Google, имеется собственный интерфейс для подключения плагинов. В Google решили не использовать NPAPI, посчитав что в нём имеется масса проблем и нет нужных функций. Взамен Google предложили новый интерфейс - PPAPI - Pepper Plugin Application Program Interface - программный интерфейс подключаемых модулей Pepper.

Когда Adobe объявил, что новые версии Flash-плагина для Linux выпускаться не будут, это объявление не касалось Flash-плагина, который выпускался Google. Google продолжил поддержку выпуска Flash-плагина в варианте PPAPI для своего браузера Chrome. Этот плагин можно было использовать и в Linux.

И вот в прошлом году я прочитал такие две новости: 05.09.2016 16:52 Adobe возобновляет выпуск NPAPI-плагина с Flash Player для Linux, 20.12.2016 12:10 Релиз Adobe Flash 24 для Linux. "Неплохо" - сказал я и решил попробовать обновить Flash-плагин. На тот момент плагины без проблем обновились штатными средствами.

1.1. Штатная установка Flash-плагина в Chromium

Штатно Flash-плагин для Chromium устанавливается так:
# apt-get install pepperflashplugin-nonfree
# update-pepperflashplugin-nonfree --install

1.2. Штатная установка Flash-плагина в Iceweasel/Chromium

Для Iceweasel/Firefos штатно Flash-плагин устанавливается так:
# apt-get install flashplugin-nonfree
# update-flashplugin-nonfree --install

2.1. Проблемы при установке Flash-плагина в Chromium

Я бы и не стал писать эту небольшую заметку, если бы штатные средства продолжали бы работать и сейчас. Но, к сожалению, сейчас они работать перестали. Например, при попытке обновить Flash-плеер PPAPI для Chromium выдаются такие ошибки:
# update-pepperflashplugin-nonfree --install
--2017-03-28 22:28:55--  http://dl.google.com/linux/chrome/deb/pool/main/g/google-chrome-stable/google-chrome-stable_57.0.2987.110-1_amd64.deb
Распознаётся dl.google.com (dl.google.com)… 209.85.233.190, 209.85.233.91, 209.85.233.136, ...
Подключение к dl.google.com (dl.google.com)|209.85.233.190|:80... соединение установлено.
HTTP-запрос отправлен. Ожидание ответа... 200 OK
Длина: 47312644 (45M) [application/x-debian-package]
Сохранение в: «/tmp/pepperflashplugin-nonfree.VjH7fdoXcK/google-chrome-stable_57.0.2987.110-1_amd64.deb»

     0K .......... .......... .......... .......... ..........  0%  483K 95s
------------------8<------------------8<------------------8<------------------
 46150K .......... .......... .......... .......... .......... 99% 5,47M 0s
 46200K ...                                                   100% 7160G=11s

2017-03-28 22:29:07 (4,01 MB/s) - «/tmp/pepperflashplugin-nonfree.VjH7fdoXcK/google-chrome-stable_57.0.2987.110-1_amd64.deb» сохранён [47312644/47312644]

mv: не удалось выполнить stat для «unpackchrome/opt/google/chrome/PepperFlash/libpepflashplayer.so»: Нет такого файла или каталога

2.2. Проблемы при установке Flash-плагина в Iceweasel/Firefox

При попытке обновить Flash-плагин для Iceweasel/Firefox происходит другая ошибка:
# update-flashplugin-nonfree --install
--2017-03-28 22:48:07--  https://fpdownload.adobe.com/get/flashplayer/pdc/24.0.0.186/flash_player_npapi_linux.x86_64.tar.gz
Распознаётся fpdownload.adobe.com (fpdownload.adobe.com)… 2.17.215.70
Подключение к fpdownload.adobe.com (fpdownload.adobe.com)|2.17.215.70|:443... соединение установлено.
HTTP-запрос отправлен. Ожидание ответа... 404 Not Found
2017-03-28 22:48:07 ОШИБКА 404: Not Found.

ERROR: wget failed to download https://fpdownload.adobe.com/get/flashplayer/pdc/24.0.0.186/flash_player_npapi_linux.x86_64.tar.gz
More information might be available at:
  http://wiki.debian.org/FlashPlayer

3.1. Решение проблемы с установкой Flash-плагина в Chromium

Чинить будем в том же порядке. Во-первых, чтобы починить Flash-плагин для Chromium, из браузера Chromium заходим на официальную страницу Adobe, переходим по ссылке внизу Продукты, справа в списке "Загрузить" переходим по ссылке Adobe Flash Player, в выпадающем списке выбираем формат ".tar.gz для Linux" и жмём на кнопку "Загрузить". Извлечём из скачанного архива с именем "flash_player_ppapi_linux.x86_64.tar.gz" интересующий нас файл динамической библиотеки и поместим его в нужное место:
# tar xzvf flash_player_ppapi_linux.x86_64.tar.gz libpepflashplayer.so
# mv libpepflashplayer.so /usr/lib/pepperflashplugin-nonfree/
# chown root:root /usr/lib/pepperflashplugin-nonfree/libpepflashplayer.so
# chmod u=rw,go=r /usr/lib/pepperflashplugin-nonfree/libpepflashplayer.so

3.2. Решение проблемы с установкой Flash-плагина в Iceweasel/Firefox

Теперь точно такие же действия можно проделать из браузера Iceweasel/Firefox. В результате должен скачаться архив с именем "flash_player_npapi_linux.x86_64.tar.gz". Поступаем с ним аналогично - извлекаем интересующий нас файл динамической библиотеки и помещаем его в нужное место. В случае Iceweasel кладём файл в каталог /usr/lib/flashplugin-nonfree/:
# tar xzvf flash_player_npapi_linux.x86_64.tar.gz libflashplayer.so
# mv libflashplayer.so /usr/lib/flashplugin-nonfree/libflashplayer.so
# chown root:root /usr/lib/flashplugin-nonfree/libflashplayer.so
# chmod u=rw,go=r /usr/lib/flashplugin-nonfree/libflashplayer.so
В случае Firefox кладём файл в каталог /usr/lib/mozillz/plugins/:
# tar xzvf flash_player_npapi_linux.x86_64.tar.gz libflashplayer.so
# mv libflashplayer.so /usr/lib/mozilla/plugins/libflashplayer.so
# chown root:root /usr/lib/mozilla/plugins/libflashplayer.so
# chmod u=rw,go=r /usr/lib/mozilla/plugins/libflashplayer.so

4. Использование PPAPI-плагина в Iceweasel/Firefox

Когда Adobe объявила о прекращении поддержки NPAPI-плагина для Linux, наш соотечественник Ринат Ибрагимов - программист из Казани, занялся разработкой специального адаптера интерфейсов, который бы позволил использовать PPAPI-плагин в браузерах, предоставляющих NPAPI-интерфейс. Проект называется FreshPlayer и устанавливается в браузер как NPAPI-плагин. Вместо использования git-репозитория и сборки адаптера из исходных текстов мы воспользуемся готовым репозиторием для Debian Jessie. Добавим в файл /etc/apt/sources.list такую строчку:
deb http://http.debian.net/debian jessie-backports main contrib
Теперь обновим списки пакетов, доступных для установки из репозиториев:
# apt-get update
И установим пакет с адаптером:
# apt-get install install browser-plugin-freshplayer-pepperflash

Заключение

Как правило, Flash-плагин без проблем работает в Chromium. А вот с Iceweasel/Firefox могут возникнуть сложности. Например, в Iceweasel плагин NPAPI у меня не заработал, зато заработал PPAPI-плагин через адаптер FreshPlayer. В Firefox заработали оба варианта - и плагин NPAPI и плагин PPAPI через адаптер FreshPlayer. Если не получается заставить работать первый попавшийся вариант - попробуйте другой: попробуйте сначала плагин NPAPI, затем попробуйте обновить Iceweasel до Firefox, а если это не поможет - вместо плагина NPAPI можно попробовать воспользоваться плагином PPAPI через FreshPlayer.

воскресенье, 11 июня 2017 г.

Настройка zswap в Debian

Современные браузеры увеличивают свои требования к объёму оперативной памяти темпами, за которыми сложно поспевать. Я лично не часто меняю компьютер, да и добавить в систему ещё немного модулей оперативной памяти иногда оказывается не самым дешёвым решением, особенно если на материнской плате уже заняты все слоты, а устаревшие модули памяти в магазинах продаются по цене выше, чем модули памяти для новых компьютеров.

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

Для сжатия страниц памяти воспользуемся новым алгоритмом сжатия LZ4, который обладает более высокой производительностью по сравнению с предлагаемым по умолчанию алгоритмом сжатия LZO. Несмотря на то, что LZ4 сжимает чуть хуже, он меньше грузит процессор. Таким образом соблюдается более приемлемый баланс между экономией памяти и нагрузкой на процессор.

Модули ядра для поддержки LZ4

Для начала впишем в файл /etc/initramfs-tools/modules модули ядра, реализующие быстрый алгоритм сжатия LZ:
lz4
lz4_compress
И пересоберём образ загрузочной файловой системы, чтобы в него попали добавленные нами модули:
# update-initramfs -u -k all

Модуль ядра для сжатия страниц подкачки

Теперь прописываем автоматическое включение zswap при загрузке ядра в конфигурации загрузчика GRUB в файле /etc/default/grub. Для этого добавим ряд новых настроек в GRUB_CMDLINE_LINUX_DEFAULT:
zswap.enabled=1 zswap.compressor=lz4 zswap.max_pool_percent=80
Значение настроек:
  • zswap.enabled=1 - включает использование zswap,
  • zswap.compressor=lz4 - выбирает более быстрый алгоритм сжатия lz4 вместо алгоритма сжатия по умолчанию lzo,
  • zswap.max_pool_percent=80 - разрешает использовать до 80 процентов оперативной памяти для хранения сжатых данных.
После изменения конфигурации загрузчика обновим его автоматически генерируемые файлы с настройками:
# update-grub
Всё готово, теперь нужно перезагрузить систему. Очень редкое действие, но этом случае перезагрузка действительно необходимо, т.к. загрузить модули без перезагрузки мне лично не удалось:
# reboot

Проверка

После перезагрузки можно проверить, работает ли модуль и какой алгоритм сжатия используется:
$ dmesg | grep zswap:
[    0.830940] zswap: loading zswap
[    0.835122] zswap: using lz4 compressor

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

воскресенье, 4 июня 2017 г.

Статистика ввода-вывода diskstats в Linux через Zabbix

Как и во FreeBSD, для оценки производительности дисковой подсистемы Linux тоже можно воспользоваться утилитой iostat. Однако, в отличие от версии iostat из FreeBSD, в iostat из Linux нет опции, позволяющей выводить накопленные значения счётчиков. Чтобы получить полную статистику за интересующий нас интервал времени, можно воспользоваться файлом /proc/diskstats из специальной файловой системы /proc. Эта файловая система позволяет узнавать состояние различных подсистем ядра Linux и менять некоторые настройки.

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

В этой статье речь пойдёт о том, как собирать статистику из файла /proc/diskstats в Zabbix. Этот метод я считаю более правильным, чем встречающиеся в интернете шаблоны, использующие для сбора статистики программу iostat, работающую некоторое время. Как я уже говорил, во-первых, такой способ не позволяет собрать статистику в промежутках между запусками команды, а во-вторых, приводит к необходимости использовать промежуточный файл, чтобы не ждать сбора статистики при запросе значения каждого отдельного счётчика.

Прежде чем что-то делать, ознакомимся с краткой документацией на этот файл по ссылке
https://www.kernel.org/doc/Documentation/ABI/testing/procfs-diskstats. Значения столбцов этого файла таковы:
  1. старший номер устройства (номер драйвера),
  2. младший номер устройства (порядковый номер устройства, управляемого этим драйвером),
  3. имя устройства в файловой системе /dev,
  4. количество успешно выполненных операций чтения,
  5. количество объединённых операций чтения,
  6. количество прочитанных секторов,
  7. время, потраченное на чтение, в миллисекундах,
  8. количество успешно выполненных операций записи,
  9. количество объединённых операций записи,
  10. количество записанных секторов,
  11. время, потраченное на запись, в миллисекундах,
  12. количество активных операций ввода-вывода (фактически - длина очереди транзакций),
  13. время, потраченное на выполнение операций ввода-вывода, в миллисекундах,
  14. взвешенное время выполнения операций ввода-вывода, в миллисекундах.
В этом файле имеется ссылка на ещё один документ - https://www.kernel.org/doc/Documentation/iostats.txt. В документе описываются те же самые колонки, но в нём пропущены первые три колонки, в которых указывается информация о самом диске. Применительно к столбцам файла /proc/diskstats там написано следующее:
  1. старший номер устройства (номер драйвера),
  2. младший номер устройства (порядковый номер устройства, управляемого этим драйвером),
  3. имя устройства в файловой системе /dev,
  4. количество выполненных операций чтения - общее количество успешно завершённых операций чтения,
  5. количество объединённых операций чтения - операции чтения соседних областей могут быть объединены друг с другом для повышения эффективности. Две операции чтения 4 килобайт можно объединить в одну операцию чтения 8 килобайт, прежде чем команда будет передана на диск. Такая операция будет поставлена в очередь и выполнена как одна операция. Это поле позволяет узнать, как часто происходит объединение операций,
  6. количество прочитанных секторов - общее количество успешно прочитанных секторов,
  7. время, потраченное на чтение, в миллисекундах - общее количество миллисекунд, потраченных всеми операциями чтения (замеренное между __make_request() и end_that_request_last()),
  8. количество выполненных операций записи - общее количество успешно завершённых операций записи,
  9. количество объединённых операций записи - см. описание поля 5,
  10. количество записанных секторов - общее количество успешно записанных секторов,
  11. время, потраченное на запись, в миллисекундах - общее количество миллисекунд, потраченных всеми операциями записи (замеренное между __make_request() и end_that_request_last()),
  12. количество активных операций ввода-вывода - единственное поле, которое сбрасывается в ноль. Увеличивается на единицу, когда запрос попадает в соответствующую структуру request_queue и уменьшается на единицу, когда этот запрос завершается,
  13. время, потраченное на выполнение операций ввода-вывода, в миллисекундах - это поле увеличивается, пока поле 12 отличается от нуля,
  14. взвешенное время выполнения операций ввода-вывода, в миллисекундах - это поле увеличивается с началом каждой операции ввода-вывода, завершением операции ввода-вывода, объединением операций ввода-вывода или при чтении этой статистики. Количество активных операций ввода-вывода (поле 12), помноженное на количество миллисекунд, потраченных на ввод-вывод с момента последнего обновления этого поля. Это поле позволяет легко оценить как время завершения ввода-вывода, так и время ожидания операции ввода-вывода в очереди.
Итак, что из этого удалось понять и что не удалось понять:
  • поле 12 не является накопительным и содержит текущее значение количества операций в очереди,
  • точный смысл поля 14 понять не удалось, будем считать что там находится некое "взвешенное" значение, по смыслу аналогичное полю 13,
  • размер сектора в полях 6 и 10 не известен.
На вопрос о размере сектора я нашёл очень подробный ответ How to get disk read/write bytes per second from /proc in programming on linux?, суть которого сводится к тому, что размер сектора в этом файле жёстко зафиксирован и всегда равен 512 байтам.

Теперь приступим к настройке Zabbix-агента. Для этого впишем в его файл конфигурации /etc/zabbix/zabbix_agentd.conf следующие строки:
UserParameter=diskstats.discovery,cat /proc/diskstats | awk 'BEGIN { printf "{\"data\":["; } { if (NR > 1) printf ","; printf "{\"{#DEVNAME}\":\"" $3 "\"}"; } END { printf "]}"; }'
UserParameter=diskstats.read.ops[*],cat /proc/diskstats | awk '$$3 == "$1" { print $$4; }'
UserParameter=diskstats.read.merged[*],cat /proc/diskstats | awk '$$3 == "$1" { print $$5; }'
UserParameter=diskstats.read.sectors[*],cat /proc/diskstats | awk '$$3 == "$1" { print $$6; }'
UserParameter=diskstats.read.duration[*],cat /proc/diskstats | awk '$$3 == "$1" { print $$7; }'
UserParameter=diskstats.write.ops[*],cat /proc/diskstats | awk '$$3 == "$1" { print $$8; }'
UserParameter=diskstats.write.merged[*],cat /proc/diskstats | awk '$$3 == "$1" { print $$9; }'
UserParameter=diskstats.write.sectors[*],cat /proc/diskstats | awk '$$3 == "$1" { print $$10; }'
UserParameter=diskstats.write.duration[*],cat /proc/diskstats | awk '$$3 == "$1" { print $$11; }'
UserParameter=diskstats.queue.length[*],cat /proc/diskstats | awk '$$3 == "$1" { print $$12; }'
UserParameter=diskstats.busy.duration[*],cat /proc/diskstats | awk '$$3 == "$1" { print $$13; }'
UserParameter=diskstats.transactions.duration[*],cat /proc/diskstats | awk '$$3 == "$1" { print $$14; }'
После внесения изменений в файл конфигурации Zabbix-агента, не забудьте его перезапустить:
# /etc/init.d/zabbix-agent restart
Я подготовил два варианта шаблона:
В шаблоне имеется правило низкоуровневого обнаружения, которое находит все дисковые устройства, статистику по которым выдаёт diskstats:

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

Для каждого найденного устройства создаются одиннадцать элементов данных, соответствующих колонкам производительности диска из файла diskstats:

Страница последних данных для одного из дисков выглядят следующим образом:

Элемент данных с названием "Загрузка диска" показывает процент времени, в течение которого диск занимается обработкой хотя бы одной транзакции.