четверг, 10 ноября 2016 г.

Поиск библиотеки, содержащей определение функции

Переодически при компиляции сторонних продуктов возникает ошибка
 undefined reference to <function>
для какой либо функции. Обычно я гуглил имя функции и искал, что кто-нибудь скажет какую библиотеку надо прилинковать к проекту.
Вчера, в очередной раз столкнувшись с подобной проблемой написал, в терминале команду, которая ищет данную функцию.

function="dbus_watch_set_data"; \
for library in $(ls /usr/lib/*.so); do \
    res=$(readelf -s ${library} 2> /dev/null | grep ${function} | grep -v 00000000); \
    if [ ! -z "$res" ]; then \
        echo "${library}: $res"; \
        break; \
    fi; \
done; \
if [ -z "$res" ]; then \
    echo "function '${function}' not found"; \
fi

Соответственно вместо dbus_watch_set_data нужно подставлять имя искомой функции.
Также можно вместо /usr/lib/ вставлять другие директории, например /usr/local/lib.

Пример удачного поика:
[grin@grinvbox-ol65-x86 ~]$ function="dbus_watch_set_data"; for library in $(ls /usr/lib/*.so); do res=$(readelf -s ${library} 2> /dev/null | grep ${function} | grep -v 00000000); if [ ! -z "$res" ]; then echo "${library}: $res"; break; fi; done; if [ -z "$res" ]; then echo "function '${function}' not found"; fi
/usr/lib/libdbus-1.so:    473: 0002bdd0   111 FUNC    GLOBAL DEFAULT   12 dbus_watch_set_data@@LIBDBUS_1_3
  1410: 0002bdd0   111 FUNC    GLOBAL DEFAULT   12 dbus_watch_set_data

Функция dbus_watch_set_data найдена (2 раза) в библиотеке /usr/lib/libdbus-1.so


Пример неудачного поиска:
[grin@grinvbox-ol65-x86 ~]$ function="dbusx_watch_set_data"; for library in $(ls /usr/lib/*.so); do res=$(readelf -s ${library} 2> /dev/null | grep ${function} | grep -v 00000000); if [ ! -z "$res" ]; then echo "${library}: $res"; break; fi; done; if [ -z "$res" ]; then echo "function '${function}' not found"; fi
function 'dbusx_watch_set_data' not found

Функция dbusx_watch_set_data не найдена (нет такой функции).


P.S. для более детального понимания, рекомендую man readelf.

четверг, 29 января 2015 г.

Квота на размер папки в Linux

Предыстория
Для ftp сервера на Linux-е потребовалось установить ограничение на размер папки Upload.
В итоге был выбран следующий вариант ( оригинал был прочитан тут: forum.ubuntu.ru ).

Суть метода в следующем:
Создаём файл фиксированного размера (2 GiB - 512 блоков по 4 MiB).
dd if=/dev/zero of=/opt/ftp_upload_fs bs=4M count=512
Чем больше размер блока, тем быстрее будет создаваться, но блок полностью размещается в оперативной памяти, так что не задавайте размер блока в 1 GB, если в системе у вас всего 512 MB =)

Создаём внутри этого файла файловую систему.
mke2fs -F /opt/ftp_upload_fs

Создаём папку, куда будет примонтирован данный файл.
mkdir -p /srv/ftp/upload

Теперь можно вручную примонтировать файл к папке, и задать владельца для данной папки (т.к. после примонтирования владельцем папки станет root:root).
sudo mount -o loop /opt/ftp_upload_fs /srv/ftp/upload
sudo chown ftp:ftp /srv/ftp/upload

Что бы после перезагрузки файл автоматически монтировался к папке, пропишем в /etc/fstab соответствующую инструкцию.
sudo echo "/opt/ftp_upload_fs /srv/ftp/upload auto defaults 0 1" >> /etc/fstab

После перезагрузки файл будет подмонтирован в папку, но владельцем папки будет root. Сам файл монтируется как /dev/loop устройство, для которого не поддерживается опция uid. Поэтому в /etc/rc.local прописываем владельцем данной папки пользователя ftp.
echo "chown ftp:ftp /srv/ftp/upload" >> /etc/rc.local

пятница, 23 января 2015 г.

Упаковка своего ПО в rpm-пакет

Детально описание rpm-пакетов, и особенности их создания описаны тут (оригиналперевод).
В данной статье будет дана краткая справка для ленивых =).

среда, 21 января 2015 г.

Развёртывание своего YUM-репозитория

Мотивация

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

Плюсы данного подхода видятся следующие:

  • легко отслеживать версию установленного ПО ( от разработчиков не требуется встраивать механизм поддержки версий в само ПО - версия в обязательном порядке указывается для RPM-пакета ).
  • легко обновлять ПО до новой версии ( делается одной командой с клиентской машины, на которую можно зайти удалённо по ssh ).
  • легко откатить ПО к старой версии, если с обновлённой версией заметны проблемы.
  • легко устанавливать ПО на ЗИП-машину, в соответствии с той ролью, для которой её настраивают.

пятница, 16 января 2015 г.

Тонкости создания rpm-пакетов

Внимательное отношение к эпохе пакета

При разрешении зависимостей, эпоха (Epoch) имеет более важное значение чем версия пакета.
Например если в пакете указать зависимость без эпохи

Requires: qt >= 4.7.4

А в системе установлена версия 4.6.3 первой эпохи

[grin@grinvb i686]$ yum info qt
Loaded plugins: refresh-packagekit, security
Installed Packages
Name        : qt
Arch        : i686
Epoch       : 1
Version     : 4.6.3
Release     : 1.el6
Size        : 35 M
Repo        : installed

То, при установки нашего пакета, rpm решит, что 4.6.3 более новая, чем требуемая 4.7.4, следовательно зависимость удовлетворена и можно ставить пакет, что является ошибкой.

среда, 19 ноября 2014 г.

Локальная загрузка в Linux без пароля ( single user mode )

Предыстория:
    Позвонил вечером коллега. Сказал, что не загружается компьютер на объекте. А утром 48-часовой тестовый прогон и всё должно обязательно работать. У него на объекте уже была ночь. С собой только ноут с виндой и загрузочной флешки с линуксом у него нет. В ходе обсуждения выяснилось, что на проблемном компьютере убился файл /lib/security/pam_unix.so - который отвечает за авторизацию. Задача была скопировать на данный комп файл со "здорового" компьютера. Но для этого нужен root-доступ.
Итак, нужно загрузиться локально ( имея физический доступ к компьютеру ), под пользователем root. Следовательно нужно загрузиться в Single User Mode.
В меню Grub данной опции на компьютере нет.

пятница, 29 ноября 2013 г.

Включение git-репозитория в svn-проект как svn:externals

Несмотря на то, что в своей работе я предпочитаю использовать распределённые системы контроля версий ( git / hg ), но переодически приходится работать в командах, использующих svn.

Итак, потребовалось, в svn-проекте использовать библиотеки, написанные другой ( дружественной командой ), но которые лежат в git репозитории.

После поиска в интернете решил сделать скриптового бота, для которого инициализирую git-svn репозиторий. Дальше робот будет опрашивать git - репозиторий, и при наличии изменений заливать их в svn - репозиторий.