Импортозамещение! Это очень популярное нынче слово затмило даже нанотехнологии! Оно несет как большие перспективы так и множество проблем. Не так давно это коснулось и меня. Мне была поставлена задача запустить наше программное обеспечение на операционной системе ОС МСВС. Очень интересное дело, учитывая, что Линукс я видел последний раз лет 8 назад, а наше ПО написано под .Net.
Знакомство с ОС МСВС
Итак, википедия говорит, что ОС МСВС — это Мобильная Система Вооруженных Сил. А именно, защищенная операционная система общего назначения. Разработала ее организация ВНИИНС. Система создана на базе Linux в соответствии с требованиями Министерства Обороны РФ.
Существует две ветки системы:
- МСВС 3.0 — 32х разрядная версия с ядром 2.4;
- МСВС 5.0 — 64-х разрядная версия с ядром 2.6.
В каждой ветке существует несколько версий, называемых «изменениями». Наиболее свежими сертифицированными версиями являются:
- ОС МСВС 3.0 ФЛИР.80001-12 изм. №6;
- ОС МСВС 5.0 ЦАВМ.11004-01 изм. №7.
В постановке задачи не была указана конкретная версия системы, поэтому, посоветовавшись с техподдержкой ВНИИНС, была выбрана наиболее актуальная на сегодняшний день ОС МСВС 5.0 ЦАВМ.11004-01 изм. №7.
Примерно месяц ушел на покупку официальной версии и еще несколько дней на подбор “железа” и установку системы. Однозначно можно сказать что ОС МСВС 5.0 не ставится на процессоры х86 и ноутбуки с 2-мя видеокартами.
Так выглядит графическая оболочка МС ОСВС:
Производитель указывает следующие параметры системы:
- Дата сборки по команде «uname -a»: 01 февраля 2013;
- Ядро: 2.6.32;
- QT: 3.3.8b, 4.8.5;
- gcc: 4.1.2, 4.4.7;
- glibc: 2.5;
- KDE: 3.5.
Немного познакомившись с системой, я получил следующую информацию:
- ОС МСВС 5.0 создана на основе Red Hat Enterprice Linux или его производных;
- Судя по версии ядра и дате сборки это RHEL 6.3;
- Библиотеки glibc очень старые: от сентября 2006 года;
- Для разработки рекомендуется использовать QT тоже не самой первой свежести.
Можно предположить, что такое состояние дел вызвано трудностями с сертификацией составных частей системы.
Что ж, задача стала конкретнее. Теперь нужно выбрать решение. Их всего два:
- переписывать все под QT либо под glibc;
- попробовать запустить то, что есть, с помощью Mono.
С целью экономии сил, времени и нервов был выбран второй вариант. Потенциальными проблемами этого варианта являются как невозможность нормально все запустить в принципе, так и последующая сертификация ПО совместно с Mono. Однако все равно это быстрее и проще, чем все переписывать.
Установка Mono
А что же такое Mono? Википедия подсказывает, что это
проект по созданию полноценного воплощения системы .NET Framework на базе свободного программного обеспечения.А так же, что
Реализации Mono существуют для следующих операционных систем: Windows, Linux, BSD (FreeBSD, OpenBSD, NetBSD), Solaris, Mac OS X, Apple iOS, Wii. Поддерживаются платформы: s390, SPARC, PowerPC, x86/x86-64, IA64, ARM, Alpha, MIPS, HPPA.
Идем на сайт проекта и видим там, что для установки нужно выполнить всего лишь 3 команды:
rpm --import "http://keyserver.ubuntu.com/pks/lookup?op=get&search=0x3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF"
yum-config-manager --add-repo http://download.mono-project.com/repo/centos/
yum install mono-complete
Первая команда добавляет ключ подписи для доступа в репозиторий, вторая настраивает репозиторй, третья инсталлирует Mono.
Программное обеспечение устанавливается в ОС МСВС (как в наследнике RHEL) в виде RPM пакетов. Для удобства этого процесса часто используется менеджер пакетов YUM. В состав ОС МСВС входит графическая оболочка менеджера пакетов, но я пользовался консольной версией. Пакеты находятся в репозиториях, которые могут находиться как на локальной машине, так и где-то в сети. Добавив ссылки на репозитории в менеджер пакетов YUM, можно довольно удобно обновлять систему. Как правило, в RHEL и его наследниках репозитории уже добавлены и настроены, однако в ОС МСВС имеется только один репозиторий, расположенный на установочном компакт-диске.
Проблемы начались уже на второй команде. Оказалось, что
yum-config-manager
отсутствует в системе:Значит, репозиторий нужно добавить вручную. Они находятся в каталоге
/etc/yum.repos.d
. Там нужно создать файл <reponame>.repo
. Например, mono.repo
. В этот файл нужно добавить следующее:[mono_repository]
name=mono repository
baseurl=http://download.mono-project.com/repo/centos/
enabled=1
gpgcheck=0
После сохранения файла проверяю, что репозиторий добавлен, выполнив команду
yum repolist
. При этом диск с дистрибутивом должен быть вставлен и смонтирован. Либо должен быть отключен репозиторий на диске: enabled = 0
в файле server.repo
.Однако и теперь ничего не получилось:
Ошибка
[Errno -3] Error performing checksum
говорит о том, что YUM не может посчитать контрольную сумму. Как выяснилось, репозиторий использует хэш-функцию sha256
, которую и не может посчитать YUM. Опытные люди пишут, что в данном случае нужно поставить библиотеку python-hashlib
. Так как репозитории не настроены, я вручную установил вот эту версию.После этого репозитории заработали, как нужно:
Но выполнить инсталляцию Mono все равно не получается.:
При установке проверяются зависимости пакетов. Оказалось, что инсталляция Mono из данного репозитория требует, чтобы в системе были версии библиотек не ниже:
GLIBC_2.16
PNG15_0
LIBTIFF_4.0
LIBJPEG_6.2
Можно было бы попробовать обновить все эти библиотеки, однако это может привести к проблемам в работе другого ПО, использующего их.
StackOverFlow подсказал мне другое решение: нужно попробовать поставить более раннюю версию Mono. Оказывается, существует архив версий. Опытным путем удалось определить, что самой свежей версией Mono, которая нормально ставится на ОС МСВС 5.0 ЦАВМ.11004-01 изм. №7 является версия 2.10.2. Репозиторий находится тут.
В итоге, чтобы все установить, нужно сделать следующее:
1. Создать (или поправить) файл
<reponame>.repo
репозитория в /etc/yum.repos.d
Например mono.repo
.Этот файл должен содержать следующее:
[Mono]
name=Mono Stack (RHEL_5)
type=rpm-md
baseurl=http://origin-download.mono-project.com/archive/2.10.2/download/RHEL_5/
gpgcheck=1
gpgkey=http://origin-download.mono-project.com/archive/2.10.2/download/RHEL_5/repodata/repomd.xml.key
enabled=1
2. Выполнить команду
yum install monotools-addon-server
для установки основных библиотек.3. Выполнить команду
yum install mono-addon-winforms-2.10.2-5.1.x86_64
для установки библиотек winforms.4. Выполнить команду
yum install mono-addon-libgdiplus0.x86_64 0:2.10-6.2
для установки реализации GDI+.Можно установить и другие библиотеки. Описание состава дистрибутива можно посмотреть тут. Mono устанавливается в
/opt/novell/mono
. Версия Mono 2.10.2 содержит следующие версии .Net: 2.0, 3.5 и 4.0.Проверить правильность установки можно следующим образом:
- настроить окружение командой
source /opt/novell/mono/bin/mono-addon-environment.sh
- узнать версию командой
mono --version
В результате должно получиться так:
Кроме того, можно проверить работоспособность, запустив пару программ.
Проблемы портирования
Чтобы работать в привычной среде, я установил ту же версию Mono для Windows.
Для отладки удобно пользоваться выводом в консоль. Чтобы он отображался, нужно запускать приложение с параметром
--debug
. Например, mono --debug helloworld.exe
.Чтобы изолировать код, предназначенный только для Mono, я создал в VisualStudio две новые конфигурации
MonoRelease<.code> и <code>MonoDebug
.В каждой из них я добавил опцию компилятора
/define MONO
Теперь можно использовать такую вот конструкцию:
#if MONO
#else
#endif
С первого раза, конечно же, ничего не заработало. В первую очередь — получение имени процессов:
var count = 0;
foreach (var clsProcess in Process.GetProcesses())
{
if(clsProcess.ProcessName.Contains(Process.GetCurrentProcess().ProcessName)) count++;
}
Этот код возвращает количество таких же запущенных в системе процессов. Проблема решилась, путем игнорирования исключений от не нужных нам процессов.
var count = 0;
foreach (var clsProcess in Process.GetProcesses())
{
#if MONO
try
{
#endif
if(clsProcess.ProcessName.Contains(Process.GetCurrentProcess().ProcessName)) count++;
#if MONO
}
catch
{
}
#endif
}
При этом код продолжил выполнять свою функцию.
Затем на форме “уехали” кнопки. Должно быть так:
А получилось так:
Это решилось небольшим изменением расположения элементов на форме:
#if MONO
tableLayoutPanel1.RowStyles[1].Height = 60;
#endif
Также были проблемы с путями. В Linux используется символ
‘/’
для разделения директорий, а в Windows ‘\’
. Проблема решается использованием System.IO.Path.DirectorySeparatorChar
. Это статическое поле всегда имеет правильное значение на любой операционной системе.Но самой главной проблемой стал маршалинг. В нашем ПО
Marshal.StructureToPtr
и Marshal.PtrToStructure
используются для сериализации специально размеченных классов в байтовый массив и обратно для передачи по сети. Причем классы имеют сложную иерархию и вложенность. Microfoft .NET с этой задачей справляется “на ура”, а Mono не смог. Я думаю, что это следствие различий в работе с памятью.В итоге пришлось переписывать весьма внушительную часть кода, заменяя автоматическую сериалиацию на “ручную” сборку класса из массива.
Результат
В результате задача была решена. Непосредственно на портирование ушло около 2-х недель. Еще где-то неделю заняли исследования процесса установки Mono. И месяц заняла покупка операционной системы.
Что дальше?
А дальше нужно формировать собственный репозиторий, который автоматически будет устанавливать Mono и само ПО. После этого должна быть сертификация…
Но, как обычно, все поменялось на самом интересном месте. В самом разгаре работы оказалось, что ОС МСВС уже не актуальна. Нужно все делать на AstraLinux… А это уже немного другая история.
knagaev
Заинтересовало что актуально — пошёл на сайт AstraLinux.
Решил почитать отзывы, понял как глубоко засекречено всё.
Может отзывы пишут как Ильич, молоком из хлебной чернильницы?
AlexandrSurkov
К сожалению, не могу ничего сказать про AstraLinux, не видел его еще в живую. Но могу сказать что разработчики и техподдержка там хорошие. Во первых, они бесплатно предложили версию для разработки, а во вторых предложили помощь в установке Mono.
Ну а секретность — куда же без нее. Все-таки система для военных.
knagaev
Да я даже не про ОС :)
И никаких намёков на «Поповых».
Просто реально стало интересно какие отзывы, а там пустая страница.
А так, если у нас сделают хороший (пусть даже не наших корней) линукс, то почему бы и нет.
AlexandrSurkov
Нашел обзор AstraLinux на хабре. Не все так уж и секретно :)
knagaev
Да я только пошутил :)