СУБД ЛІНТЕР і ReactOS, технічні деталі

Багато в чому завдяки активності фонду ReactOS не буде великою помилкою припустити, що будь-постійний читач Хабра чув про дуже амбітний проект «вільного Виндоуса». Я не став винятком, і ще в ході робіт по створенню системи збирання СУБД ЛІНТЕР ідея включити підтримку цієї операційної системи мене відвідувала не раз. Зовсім недавно її вдалося втілити в життя.



Під катом вас чекають технічні деталі робіт, включаючи досвід розгортання ReactOS на реальному залозі, і трохи мого суб'єктивного думки про цей проект.

Перші експерименти: помилка блокуючого читання з mailslot
Початок був обнадійливим — інсталяція Windows дистрибутива ЛІНТЕР на ReactOS проходила успішно: служби коректно реєструвалися, бази створювалися, сервер на перший погляд працював справно. Однак, перший же функціональний тест не дав жодного результату. Ніякого в прямому сенсі цього слова — клієнт знаходив локальне ядро СУБД, намагався встановити з'єднання, проте сервер ніяк не реагував на ці спроби. Було очевидно, що проблема пов'язана з IPC. ЛІНТЕР підтримує кілька механізмів межпроцессного взаємодії: локальні сокети, поділювану пам'ять, mailslot, але саме останні як раз і були способом комунікації тестів з ядром за замовчуванням. Після повторної конфігурації і перезбирання тестів з використанням спільної пам'яті вдалося підтвердити своє припущення — проблема полягала в реалізації mailslot під ReactOS, а при детальному дослідженні вдалося знайти і причину: виклик функції CreateMailslot з параметром lReadTimeout = MAILSLOT_WAIT_FOREVER приводив до негайного повернення з кодом помилки ERROR_SEM_TIMEOUT:

hMailslotClient = CreateMailslot(LMS, 0L, MAILSLOT_WAIT_FOREVER, (LPSECURITY_ATTRIBUTES) NULL);
if (hMailslotClient == INVALID_HANDLE_VALUE)
{
dbgError(GetLastError(),__LINE__);
return 1;
}
Повний приклад доступний з посилання.

Був заведений відповідний багрепорт, виправили який досить оперативно. Як виявилося, значення MAILSLOT_WAIT_FOREVER (-1LL) передавалося без перевірки в якості параметра timeout в функцію KeWaitForSingleObject, що було помилкою, оскільки остання оперує не милисекундами, а сотнями наносекунд, негативні значення інтерпретуються як відносний таймаут, а позитивні — як абсолютний, тобто до виправлення цієї помилки MAILSLOT_WAIT_FOREVER для ReactOS дорівнював 100 наносекундам.
Звіт роботи патчбота доступний з ссылке.

Помилка асинхронного читання з слота
Проблема з таймаутами виявилася не єдиною проблемою в реалізації mailslot – практично відразу після початку комунікації клієнтського додатка з ядром поисходили deadlock-і слоти. Почавши шукати причину я виявив, що драйвер mailslot file system (msfs.sys) в реалізації ReactOS не підтримує асинхронне читання з слота:

if (!ReadFile(hMailslotClient, lpszBuffer, LENMSG, &cbRead, &stOverlapped))
{
//ERROR_IO_PENDING (997) is not a failure!!
dbgError(GetLastError(),__LINE__);

_tprintf(TEXT("starting writer...\n"));
startWriter();

if (!GetOverlappedResult( hMailslotClient, &stOverlapped, &cbTr, TRUE))
{
dbgError(GetLastError(),__LINE__);
return 1;
}
}
Повний приклад доступний з посилання.

Новий багрепорт вже не був так стрімко закритий, що й зрозуміло, враховуючи обсяг виправлень. Тому я вирішив посприяти доопрацювання драйвера, хоча, зізнаюся, останній раз драйвер для Windows писав в студентські часи.
Мої доопрацювання msfs.sys зводилися до обробки IRP пакетів за допомогою Cancel-Safe IRP черг, що дозволило організувати асинхронне читання з слота. Не самий витончений варіант, проте достатньо простий та надійний. Правки були додані коммите 69475, після чого вдалося успішно «прогнати» всі функціональні тести ядра ЛІНТЕР.
Звіт роботи патчбота доступний з ссылке.

Помилки в mbstowcs і wcstombs
Останні знайдені мною помилки в ReactOS спочатку «випливли» у вигляді артефактів у рядках графічних інтерфейсів засобів адміністрування ЛІНТЕР. Всі ці програми побудовані на базі нашої кросплатформенной UI бібліотеки — RelAPI. Як з'ясувалося, найшкідливіші баги виявилися проявом найбільш серйозних помилок в ReactOS: функцій mbstowcs і wcstombs не обробляли належним чином ситуації, коли перші параметом був NULL:

char rosStr[BUFFER_SIZE] = "Reactos";
cnt = mbstowcs NULL,rosStr,BUFFER_SIZE);

wchar_t rosStr[BUFFER_SIZE] = L"Reactos";
cnt = wcstombs NULL,rosStr,BUFFER_SIZE);
Повний приклад доступний з посилання.

Відповідний багрепорт був досить оперативно закритий, що дозволило довести випробування роботи нашого продукту під управлінням ReactOS до кінця.
Звіт роботи патчбота доступний з ссылке.

Випробування залізом
В обговоренні ReactOS часто проскакують питання в дусі «а чи працює ця ОС на реальному сучасному залозі?» — у моєму випадку відповідь ствердна: так працює, але не без проблем. Перша з них полягала в непрацездатності ehci контролера, usb клавіатура і миша, успішно эмулировались BIOS-ом як legacy і працювали, але рівно до тих пір, поки драйвер usbehci.sys не резетил контролер, тому довелося від нього (драйвера) відмовитися, зі всіма наслідками у вигляді непрацюючих USB пристроїв. Другою проблемою виявилася нестабільна робота ОС, яка періодично «падала» BSOD hdaudbus.sys драйвер шини для High Definition Audio). Цю проблему вдалося вирішити вимкнувши відповідний контролер в налаштуваннях BIOS.
Після всіх проведених маніпуляцій система під управлінням ReactOS (білд 20151025-r69700) працювала стабільно і дозволяла «прогнати» всі необхідні тести і виміри продуктивності.
Всі експерименти проводилися на обладнанні:pechenkin@big:~$ lspci -nn
00:00.0 Host bridge [0600]: Intel Corporation 2nd Generation Core Processor Family DRAM Controller [8086:0100] (rev 09)
00:01.0 PCI bridge [0604]: Intel Corporation Xeon E3-1200/2nd Generation Core Processor Family PCI Express Root Port [8086:0101] (rev 09)
00:16.0 Communication controller [0780]: Intel Corporation 6 Series/C200 Series Chipset Family MEI Controller #1 [8086:1c3a] (rev 04)
00:1a.0 USB controller [0c03]: Intel Corporation 6 Series/C200 Series Chipset Family USB Enhanced Host Controller #2 [8086:1c2d] (rev 05)
00:1c.0 PCI bridge [0604]: Intel Corporation 6 Series/C200 Series Chipset Family PCI Express Root Port 1 [8086:1c10] (rev b5)
00:1c.3 PCI bridge [0604]: Intel Corporation 82801 PCI Bridge [8086:244e] (rev b5)
00:1c.4 PCI bridge [0604]: Intel Corporation 6 Series/C200 Series Chipset Family PCI Express Root Port 5 [8086:1c18] (rev b5)
00:1c.5 PCI bridge [0604]: Intel Corporation 6 Series/C200 Series Chipset Family PCI Express Root Port 6 [8086:1c1a] (rev b5)
00:1d.0 USB controller [0c03]: Intel Corporation 6 Series/C200 Series Chipset Family USB Enhanced Host Controller #1 [8086:1c26] (rev 05)
00:1f.0 ISA bridge [0601]: Intel Corporation Z68 Express Chipset Family LPC Controller [8086:1c44] (rev 05)
00:1f.2 SATA controller [0106]: Intel Corporation 6 Series/C200 Series Chipset Family SATA AHCI Controller [8086:1c02] (rev 05)
00:1f.3 SMBus [0c05]: Intel Corporation 6 Series/C200 Series Chipset Family SMBus Controller [8086:1c22] (rev 05)
01:00.0 VGA compatible controller [0300]: NVIDIA Corporation GF104 [GeForce GTX 460] [10de:0e22] (rev a1)
01:00.1 Audio device [0403]: NVIDIA Corporation GF104 High Definition Audio Controller [10de:0beb] (rev a1)
03:00.0 PCI bridge [0604]: Integrated Technology Express, Inc. Device [1283:8892] (rev 10)
05:00.0 USB controller [0c03]: Etron Technology, Inc. EJ168 USB 3.0 Host Controller [1b6f:7023] (rev 01)
06:00.0 USB controller [0c03]: Etron Technology, Inc. EJ168 USB 3.0 Host Controller [1b6f:7023] (rev 01)

Результат роботи тесту TPC-B на ReactOS для fat32, розмір пулу ЛИНТЕРа — 390 Мб.:
Mode = PESSIMISTIC 
Accounts = 1000
....
Transactions: 817600 
Working time: 299 seconds 
Speed = 2727.333 tps


Результат роботи тесту TPC-B на Windows 7, fat32, розмір пулу ЛИНТЕРа — 390 Мб.:
Mode = PESSIMISTIC 
Accounts = 1000
....
Transactions: 688400 
Working time: 299 seconds 
Speed = 2298.881 tps 


Трохи суб'єктивного
ReactOS знаходиться зараз в стані альфа, про що чесно повідомляє офіційний сайт проекту і не придатна до використання в продакшне, однак у мене склалося враження, що в разі необхідності ОС в прийнятні терміни можна довести «до розуму» для роботи на конкретному обладнанні з обмеженим набором програмного забезпечення. Комі того, вважаю, що для любителів «завести» залізо або покопатися в нутрощах ОС цей проект, поза всяким сумнівом буде цікавий. Окремо варто відзначити доброзичливість спільноти ReactOS і його орієнтованість на досягнення результату.

Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.