Содержание статьи
- Запуск Skype под FreeBSD
- Запуск приложений OS X в Linux
- Установка пакетов deb в Red Hat подобных системах
- Обновление ядра без перезагрузки
- Модули ядра NetBSD в Linux
- Использование сетевых драйверов Windows с помощью NDISWrapper
- Горячее переключение видеокарт
- Перенос ПО с использованием Docker
- Полезные ссылки
- INFO
- Заключение
Существует великое множество различных *nix-систем и дистрибутивов Linux/BSD. Бывает, что той или иной функции или программы, к которой ты привык в твоей любимой системе, вдруг по каким-то причинам нет в другой. Есть ли аналоги или способ заставить ее заработать?
Запуск Skype под FreeBSD
Известно, что версия Skype из портов, мягко говоря, устарела — к примеру, нет возможности совершать видеозвонки. Использовать Windows-версию через wine не вариант — под вайном он не запускается. Но выход есть — установить слой совместимости с Linux, затем, после наложения патча на ядро и последующей его перекомпиляции, уже ставить Skype. Опишем, как именно это сделать.
Первым делом необходимо собрать порт emulators/linux-base-c6
— при этом, если необходим Flash-плагин, нужно произвести некоторые действия, а именно в makefile данного порта закомментировать следующую строчку:
CONFLICTS=linux_base-gentoo* linux_base-f* linux-glib2-*
Затем набрать команды:
# sysctl compat.linux.osrelease=2.6.18
# make patch
Первая установит версию ядра в 2.6.18 (затем нужно будет прописать эту переменную в/boot/loader.conf
, чтобы после перезагрузки она не сбрасывалась), а вторая применяет патч, который мы только что сделали. После этого скопируем следующие библиотеки из каталога work
в /compat/linux/
:
lib/ld-2.12.so
lib/ld-linux.so.2
lib/libc-2.12.so
lib/libc.so.6
lib/libdl-2.12.so
lib/libdl.so.2
lib/libgcc_s-4.4.6-20110824.so.1
lib/libgcc_s.so.1
lib/libglib-2.0.so.0
lib/libglib-2.0.so.0.2200.5
lib/libpthread-2.12.so
lib/libpthread.so.0
usr/lib/libstdc++.so.6
usr/lib/libstdc++.so.6.0.13
Создадим симлинк с usr/lib/libtiff.so.3
на libtiff.so.4
:
# ln -s libtiff.so.3 libtiff.so.4
Все эти действия необходимы, только если тебе нужен порт www/linux-f10-flashplugin
.
Следующим этапом будет замена заголовочного файла для поддержки видеовызовов (необходимо, если версия FreeBSD ниже девятки):
# cd /usr/ports/multimedia/linux_v4l2wrapper-kmod
# make patch
# mv -i /sys/compat/linux/linux_videodev2.h{,.bak}
# cp -i work/linux_v4l2/linux_videodev2.h /sys/compat/linux
и пересобираем ядро. Это нужно для того, чтобы вызовы ioctl Linux нормально транслировались в вызовы FreeBSD.
Также придется поставить порт multimedia/webcamd
:
# cd /usr/ports/multimedia/webcamd
# make install clean
И теперь наконец можно ставить Skype — но не абы какую версию, а конкретную. Берем отсюда, распаковываем в свой домашний каталог и, если все настроено правильно, наслаждаемся.
Хакер #177. Радиохакинг: что такое SDR?
Запуск приложений OS X в Linux
Под OS X есть немало интересных приложений. Однако формат исполняемых файлов Mach-O, используемый в ОС от Apple, отличается от ELF, да и API, хоть и POSIX-совместимый, все же с Linux несовместим. В конце 2012 года был представлен проект Darling, который позиционируется разработчиками пока как средство для запуска инструментов разработки. На данный момент поддерживается совсем немного приложений (по большей части консольных), но хочется надеяться, что их количество будет неуклонно расти. Проект, в частности, использует GNUStep — свободную реализацию API Cocoa, которая применяется в OS X.
Сборка Darling потребует установки множества пакетов, в том числе компилятора clang:
$ sudo apt-get install git cmake clang nasm g++ checkinstall libxml2-dev libgnutls-dev libicu-dev libcairo-dev libjpeg-dev libpng-dev libtiff-dev libbsd-dev libudev-dev liblcms-dev libkqueue-dev libssl-dev libbz2-dev uuid-dev libncurses-dev libxrandr-dev
Получаем из Git-репозитория утилиту GNUStep Make, компилируем и ставим:
$ git clone https://github.com/gnustep/gnustep-make.git
$ cd gnustep-make
$ CC=clang CXX=clang++ ./configure
$ sudo make install
Собираем библиотеку поддержки Objective-C - GNUstep Libobjc2:
$ git clone https://github.com/gnustep/gnustep-libobjc2.git
$ cd gnustep-libobjc2
$ OBJCFLAGS=-fblocks CC=clang CXX=clang++ cmake .
$ rm GNUmakefile
$ make
$ sudo make install
Затем базовую часть GNUStep:
$ git clone https://github.com/gnustep/gnustep-base.git
$ cd gnustep-base
$ OBJCFLAGS=-fblocks CC=clang CXX=clang++ ./configure
$ make
$ sudo make install
И его GUI:
$ git clone https://github.com/gnustep/gnustep-gui.git
$ cd gnustep-gui
$ OBJCFLAGS=-fblocks CC=clang CXX=clang++ ./configure
$ export LD_LIBRARY_PATH=/usr/local/lib
$ echo export LD_LIBRARY_PATH=/usr/local/lib >> ~/.bashrc
$ make
$ sudo make install
GNUStep CoreBase, являющийся аналогом CoreFoundation, тоже необходим:
$ git clone https://github.com/gnustep/gnustep-corebase.git
$ cd gnustep-corebase
$ OBJCFLAGS=-fblocks CC=clang CXX=clang++ ./configure
$ make
$ sudo make install
Отвечающий за рендеринг аналог Quartz 2D — Opal тоже необходимо собрать:
$ git clone https://github.com/gnustep/gnustep-opal.git
$ cd gnustep-opal
$ OBJCFLAGS=-fblocks CC=clang CXX=clang++ make
$ sudo make install
Наконец, нужно скомпилировать собственно Darling:
$ git clone https://github.com/LubosD/darling.git
$ cd darling
$ CC=clang CXX=clang++ cmake .
$ make
Все, можно запускать приложения OS X, введя команду:
./dyld <Mach-O-файл> <аргументы>
Установка пакетов deb в Red Hat подобных системах
Форматы пакетов RPM и deb друг с другом несовместимы — и в одной системе эти два пакетных менеджера не уживаются. Как правило, необходимость устанавливать пакеты неродной системы встречается редко. Но если она возникла, можно использовать средство для конвертации пакетов alien. Конечно, это не панацея — с его помощью можно конвертировать отнюдь не все пакеты, да и использовать его нужно с осторожностью. Скачаем его исходники, распакуем и установим:
# wget http://ftp.de.debian.org/debian/pool/main/a/alien/alien_8.88.tar.gz
# tar xzvf alien_8.88.tar.gz && cd alien
# make && make install
Опишу некоторые опции командной строки, относящиеся к конвертации в RPM.
- -r — собственно конвертация в RPM;
- -i — устанавливает получившийся в результате конвертации пакет и удаляет файл пакета из системы;
- -g — создает необходимый каталог с файлами, но не создает сам пакет;
- -c — конвертирует скрипты. Использовать эту опцию нужно с осторожностью, поскольку скрипты для Ubuntu не подойдут к RHEL.
В качестве примера сконвертируем пакет zsh и установим его:
# wget http://goo.gl/Fykuzu
# alien -r ./zsh_4.3.17-1_i386.deb
# rpm -ivh --nodeps ./zsh-4.3.17-2.i386.rpm
Мы устанавливаем данный пакет принудительно — alien в данном случае довольно странно сконвертировал зависимости. Если говорить конкретнее, то для установки пакета зачем-то понадобился файл /bin/zsh
, в то время как его же мы и устанавливаем. Также стоит обратить внимание, что имена файлов пакета тоже преобразуются и последняя цифра версии преобразованного пакета инкрементируется на единичку.
В моем случае пакет установился нормально и zsh запустился без проблем. Но нелишним будет еще раз предупредить, что этот метод нужно использовать с осторожностью.
Обновление ядра без перезагрузки
В Linux существует два решения, позволяющих свести к минимуму количество аппаратных перезагрузок, — kexec и ksplice. Системный вызов kexec появился в mainline-версии ядра в июне 2005-го. Предназначается он для загрузки нового ядра прямо из существующего. Работает данная технология таким образом:
- первым делом образ ядра копируется в память;
- затем этот образ перемещается в динамическую память текущего ядра;
- наконец, образ копируется на нужные страницы, и ему передается управление.
Преимущества данного способа перед обычной перезагрузкой очевидны: перезагрузка происходит быстрее, в случае со SCSI-контроллерами нет нужды ждать определения устройств, относительная независимость от загрузчиков и возможность быстрого переключения на другой установленный дистрибутив. Однако есть и недостатки. Во-первых, перед загрузкой ядра рекомендуется корректно завершить все процессы и синхронизировать файловые системы, поскольку все подсистемы ядра инициализируются заново. Во-вторых, все устройства будут находиться в неизвестном состоянии, и, если драйвер написан криво, работать он не будет.
Для практического применения kexec необходимо ядро с включенной опцией (CONFIG_KEXEC=Y) и пакет kexec-tools. Ручная загрузка ядра (в случае с Ubuntu) осуществляется следующими двумя командами:
# kexec -l /vmlinuz --initrd=/initrd.img --reuse-cmdline
# kexec -e
Первая команда грузит ядро в память, а вторая передает ему управление. При этом используется текущая строка параметров ядра. Чтобы использовать свои параметры, задай их в опции --cmdline="".
В Ubuntu можно также использовать kexec для быстрой перезагрузки — для этого установи параметр LOAD_KEXEC в файле /etc/default/kexec равным true, и после этого все стандартные процедуры перезагрузки будут осуществляться через него.
Ksplice же, по утверждениям его разработчиков, позволяет накладывать патчи безопасности на ядро на лету. При этом все работающие приложения работают по-прежнему, без необходимости их перезапускать. Проект был куплен Oracle, и для RHEL, из-за конкуренции фирм, патчи платные. Это, однако, ничуть не мешает раздавать патчи для Ubuntu. Качаем и устанавливаем пакет (для версии 12.04):
$ wget http://goo.gl/MHAZ6c
$ sudo dpkg -i ./ksplice-uptrack.deb
$ sudo apt-get -f install
Применение всех доступных патчей выполняется одной простой командой:
$ sudo uptrack-upgrade -y
Для удаления же всех патчей используется команда
$ sudo uptrack-remove --all -y
В целом, технология эта работает достаточно стабильно — тот факт, что ее купила Oracle, говорит сам за себя. Тем не менее таким способом можно устанавливать только те заплатки, которые не вносят существенных изменений в структуры ядра.
Модули ядра NetBSD в Linux
Несколько месяцев назад команде NetBSD удалось обеспечить работу модулей ядра NetBSD в Linux. Это может быть использовано, например, для монтирования разделов с файловой системой FFS2, а также добавления других специфичных возможностей NetBSD, не поддерживаемых в Linux.
Разработчикам удалось подгружать модули, собранные для ядра NetBSD, путем использования так называемых RUMP-ядер (Runnable Userspace Meta Programs). RUMP-ядро представляет собой сверхлегковесное ядро, запускающееся в режиме пользователя. Существует три реализации выполнения подобных ядер:
- реализация в виде процесса POSIX. Является основной и позволяет запускать RUMP-ядра как пользовательские процессы в POSIX-совместимых системах;
- реализация для Xen, позволяющая запустить RUMP-ядро напрямую в DomU, без необходимости ставить полноценную ОС и уже в ней запускать его;
- реализация в ядре Linux, служащая для запуска RUMP-ядер прямо в пространстве ядра.
Замечу, что RUMP-ядра не являются виртуализацией — предназначены они для выполнения исключительно модулей ядра, и процессы из хостовой системы могут их использовать. В результате таких архитектурных решений RUMP-ядро получилось действительно легковесное — оно занимает в памяти около 100 Кб. Преимущества же, по словам разработчиков, таковы:
- многие вещи, такие как стек TCP/IP, могут использовать RUMP-ядра, не требуя наличия полноценной ОС;
- возможность запустить несколько RUMP-ядер с различным функционалом — к примеру, тот же стек TCP/IP может быть запущен для разных целей и, соответственно, по-разному будет оптимизирован;
- безопасность — каждое RUMP-ядро запускается в своем адресном пространстве, и риск взлома (в случае с NetBSD и так не очень большой в силу ее малой распространенности), к примеру, через уязвимые драйверы ФС, становится еще более маловероятным;
- возможность разрабатывать и тестировать код ядра в режиме пользователя, что куда более удобно, чем использование виртуальных машин.
Однако это все теория, и пора переходить к практике. Для компиляции RUMP-ядра необходимо получить инструмент buildrump.sh, для чего используем Git:
$ git clone https://github.com/anttikantee/buildrump.sh.git
$ cd buildrump.sh
$ ./buildrump.sh
Затем нужно получить архив с модулями ядра. Поскольку он находится в снапшоте, а его дата постоянно меняется, точный адрес я дать не могу, но в моем случае команда для его получения была следующей:
$ wget http://goo.gl/gNCALo
Извлеки нужный тебе модуль в рабочий каталог. Вслед за этим, скорее всего, понадобится скомпилировать утилиты для использования с RUMP-ядром, указав пути к заголовочным и библиотечным файлам.
Использование сетевых драйверов Windows с помощью NDISWrapper
Современный Linux может работать с огромным количеством наименований сетевого оборудования. Тем не менее отдельные сетевые устройства (такие как беспроводные адаптеры) в Linux либо не совсем корректно работают, либо вовсе имеют драйвер только под Windows. Но есть способ запустить Windows-версии некоторых сетевых драйверов в Linux. Для этого нужно использовать NDISWrapper.
Как следует из названия, это инструмент-«обертка» для NDIS-совместимых драйверов. Он предоставляет им минимально необходимый набор функций ntoskrnl и hal. И что самое удивительное, все это работает.
Для того чтобы его использовать, установим соответствующий пакет:
$ sudo apt-get install ndiswrapper-common ndiswrapper-dkms cabextract
Затем заносим родной для Linux драйвер (в качестве примера далее будет использоваться один из чипсетов Broadcom) в черный список — чтобы не возникло конфликта:
/etc/modprobe.d/blacklist.conf
# <...>
blacklist bcm43xx
В случае если драйвер находится в exe- или cab-архиве, может понадобиться cabextract.
$ cabextract setup.exe
Берем файлы драйвера и устанавливаем его с помощью ndiswrapper:
$ sudo ndiswrapper -i bcnwl5.inf
Прописываем модуль ядра в автозагрузку, добавив строку ndiswrapper в файл /etc/modules
и загружаем его:
$ sudo modprobe ndiswrapper
Если все настроено нормально, сеть заработает.
Горячее переключение видеокарт
Современные видеоадаптеры поддерживают горячее подключение — естественно, при условии наличия второго адаптера. Linux (а если точнее, X.Org) с недавнего времени также поддерживает данную технологию. Это не потребует особых телодвижений со стороны пользователя — все, что ему нужно сделать, заключается в простом подключении устройства. При этом, разумеется, должна быть установлена последняя версия X.Org с драйвером xf86-video-modesetting. Тем не менее стоит чуть более подробно описать, как именно это работает.
При запуске X-сервера данный драйвер грузится с помощью udev. При этом вместо фактического отображения экрана X-сервер создает абстракцию Screen, а уж на нее проецирует DrvScreen, который как раз и является физическим устройством. При подключении второй видеокарты создается еще один экземпляр DrvScreeen, и вся деятельность на Screen дублируется на оба устройства.
В отличие от подобной же технологии Xinerama, эта технология работает не на уровне протокола X11, а на уровне взаимодействия с оборудованием. При этом можно не заботиться о том, с какого адаптера сформирован вывод, — можно выполнять все ресурсоемкие действия на одной, более мощной видеокарте, а затем передавать изображение на маломощную.
Технология довольно новая, временем не проверенная, но перспективная. Если у тебя две видеокарты, ты можешь ее опробовать прямо сейчас.
Перенос ПО с использованием Docker
Есть множество путей для создания и изолированного запуска приложений в Linux. Некоторые из них сложные, некоторые попроще, но многие требуют развертывания ФС, что может занять длительное время. Относительно недавно компания DotCloud, предоставляющая облачный хостинг, открыла проект Docker. Он написан на языке Go и предназначен для управления контейнерами LXC, расширяя и дополняя их базовые возможности. Он позволяет изолировать не всю систему, а лишь отдельные процессы и клонировать/переносить их на другие компьютеры (естественно, с той же аппаратной архитектурой). Проект предназначен для переноса проектов, всевозможного развертывания и автоматизации распределенных систем. Основные его особенности:
- возможность размещения в контейнере различной нагрузки — скриптов, бинарников, библиотек, Jar-файлов…
- переносимость — он запускается на любом современном x64-процессоре с новыми ядрами Linux (рекомендуется ядро не ниже 3.8 с поддержкой AUFS);
- изоляция процессов от основной системы и от других изолированных процессов;
- поскольку каждый контейнер использует свою ФС, не важно, в каком окружении он запускается;
- из-за того, что эта изоляция достаточно высокоуровневых сущностей, не теряется машинное время на виртуализацию.
Установка на Ubuntu 12.04 потребует обновления ядра до версии 3.8, которое, к счастью, бэкпортировано из 13.04:
# apt-get install linux-image-generic-lts-raring linux-headers-generic-lts-raring
# reboot
После перезагрузки добавим PPA с Docker и установим его:
# apt-get install python-software-properties && add-apt-repository ppa:dotcloud/lxc-docker
# apt-get update
# apt-get install lxc-docker
Docker установлен.
Приведу наиболее часто применяемые команды:
- docker pull — получить образ из репозитория;
- docker run — запустить какое-либо приложение в контейнере;
- docker ps — просмотреть исполняемые контейнеры;
- docker diff — просмотреть изменения в файловой системе контейнера;
- docker commit — сохранить изменения в образ.
В качестве примера давай установим демон Redis. Первым делом запустим Docker в режиме демона и получим базовый образ.
$ sudo docker -d &
$ sudo docker pull ubuntu
Запуск через sudo здесь нужен по той причине, что демон запускается от root и использует UNIX-сокет, владельцем которого является тоже root. Если создать группу docker и включить в нее себя, то это не понадобится. В дальнейшем предполагается, что именно так и сделано.
Запускаем оболочку и устанавливаем Redis:
$ docker run -i -t ubuntu /bin/bash
# apt-get update
# apt-get install redis-server
# exit
Сделаем снапшот с установленным сервером. Для этого нужно сначала узнать идентификатор контейнера:
$ docker ps -a
Полученный ID нужно использовать в следующей команде:
$ docker commit 691b3214f7de rom/redis
Наконец, запускаем Redis в фоновом режиме, пробрасывая порт 6379 в контейнер:
$ docker run -d -p 6379 rom/redis /usr/bin/redis-server
Redis готов к использованию.
INFO
Скомпилированные пакеты Docker есть только для платформы x64, для x86 они отсутствуют.
Заключение
В статье было описано несколько способов сделать то, что, казалось бы, невозможно. Однако все сценарии рассмотреть довольно затруднительно, тем более что *nix-системы отличаются гибкостью — в них всегда есть больше одного способа сделать что-либо.