Вчера мне Installd сюрприз сделал. Конечно, можно сказать что нужно внимательнее читать документацию, но, всей документации не перечитаешь, поэтому сюрпризы не избежны. А суть сюрприза вот в чем.
Возникла задача следующего плана: надо взять приложение A, выпилить из него часть функций, воткнуть новые и в результате получить приложение B. Причем, приложения A и B должны уметь работать параллельно. Каждое из приложений содержит в себе драйвера, демоны и кучу других системных компонентов. Таким образом, на диске, получаем приблизительно такую структуру:
+--Application Suport
+-- Company Name
+--Product A
+--Product B
Где Product B – директория с системными файлами нового приложения. С учетом того, что инсталляторы в Mac OS X воспринимаются исключительно как автоматизированное средство для копирования файлов, решение было предельно простым: взять уже имеющийся инсталлятор и поменять в нем “Product A” на “Product B”, не забыв поправить конфигурирующие скрипты. Но не тут то было.
Если попытаться установить два продукта параллельно, то начиналась магия: установка продукта A деинсталлировала продукт B и vice versa. Перерыл все логи инсталлятора, греша на pred- и post- install скрипты – ни малейшего намека на то, кто удаляет продукт. Хотел уже было браться за DTrace, но тут коллеги напомнили о fs_usage… Нашелся виновник: installd. Но, казалось бы, причем тут Installd?! А вот при том, что инсталлятор не только распаковывает файлы в нужные директории, но еще и делает “обновление” для пакетов с одинаковыми идентификаторами!