Технологии обеспечения отказоустойчивости
Технологии обеспечения отказоустойчивости
Отказоустойчивость на уровне ОС
Технологии обеспечения отказоустойчивости
Создание действия
Флаги действия
Технологии обеспечения отказоустойчивости
Восстановление клиентских соединений
Функция восстановления соединения
Создание отказоустойчивых соединений
Восстановление соединения с прежним coid
Операции над отказоустойчивым соединением
Технологии обеспечения отказоустойчивости
Расширение диагностических возможностей ham
Состояния процесса
Пользовательские уведомления
Технологии обеспечения отказоустойчивости
Технологии обеспечения отказоустойчивости
Технологии обеспечения отказоустойчивости
658.40K

Технологии обеспечения отказоустойчивости_r0.0

1. Технологии обеспечения отказоустойчивости

Программа обучения
«Разработка приложений для
ЗОСРВ «Нейтрино»
Технологии обеспечения
отказоустойчивости

2. Технологии обеспечения отказоустойчивости

Темы занятия:
Введение
Комплект высокой готовности
- администратор высокой готовности
- библиотека восстановления клиентов
- расширение штатных диагностических
возможностей
Адаптивное партиционирование
Резервирование и горячая замена
администраторов ресурсов
Заключение
2

3.

Понятие отказоустойчивости
Отказоустойчивость ― cвойство системы
продолжать правильное выполнение функций
при наличии ограниченного числа аппаратных
или программных дефектов
ГОСТ Р 51904-2002. Программное обеспечение
встроенных систем. Общие требования
к разработке и документированию
3

4.

Характеристики отказоустойчивости
коэффициент готовности ― доля срока службы
системы, в течение которого она находится в рабочем
состоянии
надёжность ― вероятность безотказной работы /
определённых видов отказов системы / её элементов
за период времени
Простои изза отказов
(Toт)
Безотказная работа (Тб)
Простои изза
обслуживани
я (Тоб)
Тб
Коэффициент готовности =
Тб + Тот + Тоб
4

5.

Средства повышения отказоустойчивости
среда исполнения ЗОСРВ
«Нейтрино»
комплект высокой
готовности
Средства повышения
отказоустойчивости
нацелены на:
продление безотказной
работы ПО
сокращение времени
восстановления при отказе
сокращение времени
обслуживания
procnto
администратор
резервирование
процессов
служб и
драйверов
горячая замена
служб и драйверов
микроядро
адаптивное
партиционирование
5

6. Отказоустойчивость на уровне ОС

Архитектура ЗОСРВ «Нейтрино»
предназначена для разработки систем высокой
готовности:
микроядро
диагностика и восстановление отдельных процессов
небольшой объём кода микроядра
предсказуемый механизм планирования потоков
модель процессов POSIX
изоляция процессов и защита памяти
возможность внешнего наблюдения за процессами
обмен сообщениями
единый механизм межпроцессного взаимодействия
единый механизм локального и сетевого обмена
(посредством Qnet)
6

7. Технологии обеспечения отказоустойчивости

Темы занятия:
Введение
Комплект высокой готовности
- администратор высокой готовности
- библиотека восстановления клиентов
- расширение штатных диагностических
возможностей
Адаптивное партиционирование
Резервирование и горячая замена
администраторов ресурсов
Заключение
7

8.

Комплект высокой готовности
Программная инфраструктура для повышения
отказоустойчивости ПО под управлением ЗОСРВ
«Нейтрино»:
обнаружение сбоев в программах
завершение работы
«зависания»
реагирование на сбои
послеаварийное восстановление программ
восстановление межпроцессного взаимодействия
8

9.

Состав комплекта высокой готовности
служба ham ― администратор высокой готовности
утилита hamсtrl ― инструмент управления службой
ham
библиотека libham ― API администратора высокой
готовности
библиотека libha ― API для создания
отказоустойчивых клиентских соединений
9

10.

Архитектура комплекта высокой готовности
Процесс
Процесс
Процесс
контрольные сигналы
администратор высокой
готовности
библиотека
восстановлени
я клиентов
procnto
libha
уведомления о
завершении и
перезапуске
процессов
ham
/dev/
shmem/

ham -g
команды / сценарии
реагирования
libham
hamctrl
соединение
Процесс
Процесс
Процесс
10
нестандартные
диагностические
уведомления

11.

Управление службой ham
Запуск службы ham — из командной строки:
дублёр запускается автоматически с ключом -g
настройка журналирования:
подробность: -V уровень, -v, -vv,

файл журнала: -f файл
формат меток времени: -t relative | absolute | shortabs | none
отключение журналирования: -d
11

12.

Управление службой ham
Управление работой ham:
из командной строки ― с помощью утилиты hamctrl
завершить работу ham: -stop
увеличить/уменьшить/вывести уровень подробности
ведения журнала: +|-|=verbose
адресовать команду службе ham на удалённом узле: -node
имя
программно ― с помощью функций библиотеки
libham:
int ham_stop (void);
int ham_stop_nd (int nd);
int ham_stop_node (const char *nodename);
int ham_verbose (const char *nodename, int op, int value);
12

13.

Управление службой ham
подключение к службе ham ― с помощью функций
ham_connect*()
int ham_connect (unsigned flags);
int ham_connect_nd (int nd, unsigned flags);
int ham_connect_node (const char *nodename, unsigned flags);
узел задаётся через nd/nodename, flags не
поддерживается
отключение от ham ― с помощью функций
ham_disconnect*() с эквивалентными параметрами
ham_connect*() и ham_disconnect*() автоматически
вызываются
функциями администрирования ham:
ham_stop*(), ham_verbose()
функциями подключения/отключения процессов от ham:
ham_attach*(),ham_detach*(), некоторыми функциями
ham_entity*()
13

14.

Компоненты службы ham
Cлужба ham оперирует компонентами трёх
типов:
объекты (entity)
условия (condition)
действия (action)
14

15.

Объект
Объект ссылается на наблюдаемый процесс:
является подкаталогом /proc/ham
имеет уникальное имя в рамках экземпляра
службы ham
дескриптор объекта имеет тип ham_entity_t
15

16.

Создание объекта
Подключение процесса извне:
ham_entity_t * ham_attach (const char *ename, int nd, pid_t pid, const
char *line,
unsigned flags);
ham_entity_t * ham_attach_node (const char *ename, const char
*nodename,
pid_t pid, const char *line, unsigned
flags);
имя объекта задаётся в ename
узел задаётся идентификатором или именем (nd и nodename)
процесс задаётся через pid или командную строку line (полный
путь к исполняемому файлу + параметры)
процесс должен находиться в сеансе с идентификатором 1
поле flags:
HENTITYKEEPONDEATH ― указывает, что объект и все его условия
сохраняются, когда процесс уничтожается
16

17.

Создание объекта
Самостоятельное присоединение процесса:
ham_entity_t * ham_attach_self (const char *ename, _Uint64t hp, int hpdl, int
hpdh,
unsigned flags);
hp, hpdl и hpdh ― параметры проверки контрольных сигналов
самостоятельно присоединяемые объекты могут не находиться
в сеансе 1 (что требуется для ham_attach())
Создание объекта-заполнителя (без процесса):
ham_entity_t * ham_entity (const char *ename, int nd, unsigned flags );
ham_entity_t * ham_entity_node (const char *ename, const char
*nodename,
unsigned flags );
можно присоединять процесс к заполнителю с помощью
ham_attach*()
17

18.

Операции над объектом
получение дескриптора объекта:
ham_entity_t * ham_entity_handle (int nd, const char *ename, unsigned
flags);
ham_entity_t * ham_entity_handle_node (const char *nodename, const
char *ename,
unsigned flags);
дескриптор объекта можно передавать в различные функции
(например, ham_condition() для создания условий)
для получения дескриптора глобального объекта следует
присвоить ename значение NULL
управление свойствами объекта:
int ham_entity_control (ham_entity_t *ehdl, int command, unsigned flags);
в параметре command можно указывать команды, которые:
активируют/деактивируют объект
устанавливают, сбрасывают, считывают и записывают его флаги
18

19.

Условие
Условие ссылается на событие, которое может
произойти с объектом:
является подкаталогом объекта
имеет уникальное имя в рамках объекта
дескриптор условия имеет тип ham_condition_t
19

20.

Условие
Категории условий:
условия, связанные с жизненным циклом процесса
CONDDEATH, CONDABNORMALDEATH, CONDRESTART
пропуск контрольных сигналов
CONDHBEATMISSEDLOW, CONDHBEATMISSEDHIGH
подключение/отключение процесса от службы ham
CONDATTACH, CONDDETACH
условия механизма расширенной диагностики
CONDRAISE, CONDSTATE
20

21.

Создание условия
ham_condition_t * ham_condition( ham_entity_t *ehdl, int type, const char
*cname,
unsigned flags );
ehdl ― дескриптор объекта
type ― тип события:
CONDDEATH ― завершение процесса, указанного в объекте
CONDRESTART ― перезапуск процесса
CONDHBEATMISSEDLOW, CONDHBEATMISSEDHIGH ― пропуск
нижнего/верхнего порога количества контрольных сигналов
CONDDETACH ― отсоединение объекта от ham
cname ― имя события
flags ― флаги:
HREARMAFTERRESTART ― условие автоматически создаётся
заново после перезапуска процесса
при удалении объекта условие удаляется
и HCONDNOWAIT ― управляют
выполнением действий условия (будут рассмотрены позже)
HCONDINDEPENDENT
21

22.

Операции над условием
получение дескриптора условия:
ham_condition_t * ham_condition_handle (int nd, const char *ename,
const char *cname,
unsigned flags );
ham_condition_t * ham_condition_handle_node (const char *nodename,
const char
*ename,
const char
*cname,
unsigned flags);
cname ― имя условия
ename ― имя объекта
nodename ― имя узла
изменение параметров условия:
int ham_condition_control (ham_condition_t *chdl, int command, unsigned
flags );
command― включение/выключение условия, установка/чтение
флагов flags
22

23.

Действие
Действие выполняется при наступлении
условия, с которым оно связано
является файлом в каталоге условия
реализовано в виде функций библиотеки libham
дескриптор действия имеет тип ham_action_t
23

24.

Создание действия
перезапуск процесса:
ham_action_t * ham_action_restart (ham_condition_t *chdl, const char
*aname,
const char *path, unsigned flags );
запуск произвольной команды:
ham_action_t * ham_action_execute (ham_condition_t *chdl, const char
*aname,
const char *path, unsigned flags );
отправка импульса:
ham_action_t * ham_action_notify_pulse (ham_condition_t *chdl, const char
*aname,
int nd, pid_t topid, int chid, int
pulsecode,
int value, unsigned flags)
отправка сигнала:
ham_action_t * ham_action_notify_signal (ham_condition_t *chdl, const char
*aname,
int nd, pid_t topid, int
signum, int code,
int value, unsigned flags );
24
отправка импульсов и сигналов на удалённый узел:

25. Создание действия

ожидание создания файла и/или истечения таймаута:
ham_action_t * ham_action_waitfor (ham_condition_t *chdl, const char
*aname,
const char *path, int delay,
unsigned flags );
запись в журнал ham:
ham_action_t * ham_action_log (ham_condition_t *chdl, const char *aname,
const char *msg, unsigned attachprefix,
int verbosity, unsigned flags );
25

26. Флаги действия

флаги всех действий:
HREARMAFTERRESTART
действие автоматически перезапускается после
перезапуска объекта, которому оно принадлежит
флаги некоторых действий:
HACTIONBREAKONFAIL
если действие завершается с ошибкой и после него
должны
выполняться другие действия, эти действия не
выполняются
HACTIONKEEPONFAIL
действие, выполненное с ошибкой, не удаляется
Действие автоматически удаляется при удалении условия,
с которым оно связано
26

27.

Операции над действием
получение дескриптора действия:
ham_action_t * ham_action_handle (int nd, const char *ename, const char
*cname,
const char *aname, unsigned flags );
ham_condition_t * ham_condition_handle_node (const char *nodename,
const char *ename,
const char*cname,
unsigned flags );
изменение параметров действия:
int ham_action_control (ham_action_t *ahdl, int command, unsigned flags );
command― включение/выключение условия, установка/чтение
флагов flags
задание альтернативного действия:
int ham_action_fail_*( ham_action_t *ahdl, …)
действие, которое выполняется при неудачном выполнении
действия ahdl
27

28.

Настройка наблюдения и реагирования за
внешним процессом
#include <ha/ham.h>
...
ham_entity_t *ehdl;
ham_condition_t *chdl;
ham_action_t *ahdl;
ham_connect( 0 );
// подключение к службе ham
ehdl = ham_attach( ... );
// создание объекта
if ( ehdl != NULL ) {
chdl = ham_condition( ... );
// создание условия
if ( chdl != NULL ) {
// создание действий
ahdl = ham_action_*(...);
if ( ahdl == NULL )
perror( "Ошибка при добавлении действия\n" );
ahdl = ham_action_*( ... );
...
} else
perror( "Ошибка при добавлении условия\n" );
} else
printf( "Ошибка при добавлении объекта");
ham_disconnect( 0 );
// отключение от службы ham
28

29.

Дополнительные флаги условия
Флаги условия, влияющие на выполнение действий:
HCONDINDEPENDENT
действия условия выполняются в отдельном потоке
HCONDNOWAIT
действия waitfor игнорируются
29

30.

Потоки выполнения действий
все условия с флагом HCONDNOWAIT выполняются в
одном потоке в порядке FIFO
каждое условие с флагом HCONDINDEPENDENT (но без
HCONDNOWAIT) выполняется в отдельном потоке
все остальные условия выполняются в порядке FIFO в
одном общем потоке
максимальное количество потоков обработки условий
равно (количество условий HCONDINDEPENDENT) + 2,
где
один поток обрабатывает все условия с флагом HCONDNOWAIT
другой поток обрабатывает все остальные условия
все действия конкретного условия выполняются
последовательно независимо от состояния флагов
HCONDNOWAIT и HCONDINDEPENDENT
30

31.

Удаление компонентов ham и их
дескрипторов
удаление дескриптора действия/условия/объекта:
int ham_action_handle_free( ham_action_t *ahdl );
int ham_condition_handle_free( ham_condition_t *chdl );
int ham_entity_handle_free( ham_entity_t *ehdl );
удаление действия/условия:
int ham_action_remove( ham_action_t *ahdl, unsigned flags );
int ham_condition_remove( ham_condition_t *chdl, unsigned flags );
int ham_detach( ham_entity_t *ehdl, unsigned flags );
int ham_detach_self( ham_entity_t *ehdl, unsigned flags );
31

32.

Удаление компонентов ham и их
дескрипторов
удаление объекта, присоединённого извне:
int ham_detach (ham_entity_t *ehdl, unsigned flags);
int ham_detach_name (int nd, const char *ename, unsigned flags);
int ham_detach_name_node (const char *nodename, const char
*ename,
unsigned flags);
удаление самостоятельно присоединённого объекта:
int ham_detach_self (ham_entity_t *ehdl, unsigned flags);
дескриптор ehdl можно получать из ham_attach*() или
ham_entity_handle()
функция ham_disconnect()* вызывается автоматически
32

33.

Упражнение
В программе restart.c проекта hat:
допишите код, который настраивает наблюдение за
заданным драйвером (см. комментарии «ЗАДАНИЕ»)
при завершении драйвера служба ham должна
автоматически перезапускать его и перемонтировать
файловую систему накопителя
завершить драйвер можно командой slay <имя или pid>
проверить доступность файловой системы можно командой
ls <точка монтирования>
попробуйте передавать в программу restart:
команду запуска драйвера
команду перезапуска и pid уже запущенного драйвера
сначала запускайте драйвер из командной строки, а затем
программу restart
добавьте директивы компиляции, компоновки и
развёртывания программы в файл CMakeLists.txt
33

34.

Контрольные сигналы
Самостоятельно подключаемые процессы:
могут информировать службу ham о своей
работоспособности с помощью контрольных сигналов
задают моменты начала и окончания наблюдения, а
также условия, на которые они намерены реагировать
34

35.

Контрольные сигналы
Наблюдаемый процесс:
указывает службе ham таймаут передачи контрольных
сигналов и пороговые значения количества
пропущенных сигналов:
ham_entity_t * ham_attach_self (const char *ename, _Uint64t
hp,
int hpdl, int hpdh, unsigned
flags);
отправляет контрольные сигналы для подтверждения
своей работоспособности:
int ham_heartbeat (void);
35

36.

Контрольные сигналы
Служба ham:
выполняет сценарии реагирования на условия
CONDHBEATMISSEDLOW и CONDHBEATMISSEDHIGH
сбрасывает счётчик пропущенных контрольных
сигналов объекта и устанавливает его состояние по
умолчанию после восстановления:
ham_action_t * ham_action_heartbeat_healthy
(ham_condition_t *chdl,
const char *aname,
unsigned flags);
36

37.

Настройка обработки контрольных сигналов
#include <ha/ham.h>
ham_entity_t
*ehdl;
ham_condition_t *chdl;
ham_action_t
*ahdl;
// самостоятельное подключение к службе ham
ehdl = ham_attach_self( "client_heartbeat", 1000000000UL, 1, 5,
0 );
// обработка нижнего уровня количества пропущенных
сигналов
chdl = ham_condition (ehdl, CONDHBEATMISSEDLOW, …);
ahdl = ham_action_*(chdl,…);
ahdl = ham_action_*( chdl, … );
ahdl = ham_action_heartbeat_healthy(chdl, …);
// обработка верхнего уровня количества пропущенных
сигналов
chdl = ham_condition (ehdl, CONDHBEATMISSEDHIGH, …);

// генерация контрольного сигнала
MsgSend(coid, &msg, sizeof(msg), NULL, 0)
37
ham_heartbeat();

38.

Упражнение
В проекте hat:
программа server.c принимает от клиента команды
управления роботом в виде синхронных сообщений и
отвечает на них
команда "поднять левую руку" остаётся без ответа, что
приводит к зависанию клиента
необходимо ввести в клиентскую программу client_heartbeat.c
механизм контрольных сигналов для обнаружения зависания
службой ham
служба ham должна уничтожать и перезапускать сервер, при
этом клиент завершается с ошибкой
напишите код настройки службы ham согласно
комментариям в программе, место для генерации
контрольных сигналов определите самостоятельно
для зависания программы client_heartbeat запускайте её
с ключами -h -lr
38

39. Технологии обеспечения отказоустойчивости

Темы занятия:
Введение
Комплект высокой готовности
- администратор высокой готовности
- библиотека восстановления клиентов
- расширение штатных диагностических
возможностей
Адаптивное партиционирование
Резервирование и горячая замена
администраторов ресурсов
Заключение
39

40.

Восстановление клиентских соединений
Для восстановления неисправного процесса не
всегда достаточно перезапускать его:
требуются дополнительные команды
(монтирование и т.п.)
к неисправному процессу могут быть подключены
клиенты
при перезапуске аннулируются идентификаторы
соединений
возникают ошибки
требуется переподключение к серверу
Библиотека libha позволяет:
объявлять соединение отказоустойчивым
связывать с ним функцию восстановления
40

41. Восстановление клиентских соединений

Объявление соединения coid отказоустойчивым:
int ha_attach (int coid, RFp rfn, void *rhdl, unsigned flags);
Функция восстановления int (*RFp)( int coid, void *rhdl):
вызывается, когда операция над coid возвращает
ошибку EBADF
возвращает coid восстановленного соединения
позволяет:
подключаться к прежнему серверу и восстанавливать
контекст взаимодействия с ним
подключаться к новому серверу
отказываться от восстановления и возвращать ошибку
Флаг HAREPLACERECOVERYFN позволяет заменять функцию
восстановления
41

42. Функция восстановления соединения

Простейшая функция восстановления:
int conn_recovery (int old_coid, void *hdl)
{
wait_for_server_recovery (); // ожидание готовности сервера
coid = name_open(name, 0);
ha_attach(coid, conn_recovery, NULL, 0);
return (coid);
}
42

43. Создание отказоустойчивых соединений

Функции создания отказоустойчивого соединения:
ha_open(), ha_open64()
ha_fopen()
ha_creat(), ha_creat64()
ha_ConnectAttach()/ha_ConnectDetach()
принимают аргументы стандартных библиотечных
функций и аргументы rfn, rhdl и flags функции ha_attach()
возвращают отказоустойчивый coid или fd
Другие функции библиотеки libha:
создание копии отказоустойчивого fd:
int ha_dup (int oldfd)
повторное подключение с возвратом прежнего coid/fd:
int ha_ReConnectAttach( int oldcoid, _Uint32t nd, pid_t pid, int
chid,
unsigned index, unsigned flags
)
int ha_reopen( int oldfd, const
char *path, int oflag, ... )
43

44. Восстановление соединения с прежним coid

Пример:
int conn_recovery (int old_coid, void *hdl)
{
wait_for_server_recovery (); // ожидание готовности сервера
int new_fd = ha_reopen (old_fd, filename, O_RDONLY, 0);
lseek(new_fd, nbytes, SEEK_SET);
return (new_fd);
}
44

45. Операции над отказоустойчивым соединением

int ha_connection_ctrl (int coid, int command, void *args );
Параметр command:
HA_RECOVERY_ACOUNT задаёт максимальное
суммарное количество попыток восстановления
соединения за время существования coid
HA_RECOVERY_ICOUNT задаёт максимальное
количество попыток восстановления соединения при
отдельном разрыве (счётчик сбрасывается при
успешном восстановлении соединения)
HA_RECOVERY_RESET_ACOUNT,
HA_RECOVERY_RESET_ICOUNT обнуляют
соответствующие счётчики восстановлений
HA_RECOVERY_SUSPEND, HA_RECOVERY_ENABLE
временно отключают/подключают соединение к
библиотеке восстановления
45

46.

Упражнение
В программе readfile_ha.c проекта hat:
реализуйте и зарегистрируйте функцию
восстановления recover_conn(), которая:
восстанавливает соединение с сервером после его
перезапуска
назначает ему прежний файловый дескриптор
передаёт серверу текущее положение файлового указателя
возвращает файловый дескриптор библиотеке
выполните команду readfile_ha <файл>, где файл
находится на накопителе под управлением драйвера из
первого упражнения
уничтожьте драйвер и убедитесь, что после его
перезапуска программа readfile_ha продолжает
считывать файл с позиции на момент разрыва
соединения
46

47. Технологии обеспечения отказоустойчивости

Темы занятия:
Введение
Комплект высокой готовности
- администратор высокой готовности
- библиотека восстановления клиентов
- расширение штатных диагностических
возможностей
Адаптивное партиционирование
Резервирование и горячая замена
администраторов ресурсов
Заключение
47

48. Расширение диагностических возможностей ham

Разработчик может расширять диагностические
возможности службы ham:
определять состояния процесса
создавать собственные уведомления
передавать информацию об изменениях состояния и
уведомления службе ham
48

49. Состояния процесса

Состояния процесса задаются в виде
целочисленных кодов:
смысл кодов определяется разработчиком
передача кода состояния службе ham:
int ham_entity_condition_state (ham_entity_t *ehdl, unsigned
tostate,
unsigned flags);
создание условия изменения состояния объекта:
ham_condition_t * ham_condition_state (ham_entity_t *ehdl,
const char *cname,
unsigned fromstate,
unsigned tostate,
unsigned flags);
fromstate и tostate ― прежнее и новое состояния объекта
при переходе из fromstate в tostate срабатывает условие
CONDSTATE
49

50.

Упражнение
В проекте hat:
скопируйте программу readfile_ha.c в readfile_state.c
будем считать, что программа переходит:
в состояние 1 после считывания очередного фрагмента
файла
в состояние 2 после перехода в функцию восстановления
соединения
в состояние 3 после завершения считывания файла
добавьте отправку службе ham уведомлений о
переходе в состояния 1, 2 и 3
добавьте условия типа CONDSTATE для переходов 1->2,
2->1 и 1->3
при срабатывании каждого из них размещайте запись в
журнале ham
50

51. Пользовательские уведомления

Процесс может направлять пользовательские
уведомления службе ham:
int ham_entity_condition_raise (ham_entity_t *ehdl, unsigned
rtype,
unsigned rclass, unsigned rseverity,
unsigned flags);
rtype, rclass, rseverity ― тип, класс и серьёзность условия
(смысл определяется разработчиком)
создание условия приёма уведомления:
ham_condition_t * ham_condition_raise (ham_entity_t *ehdl,
const char *cname,
unsigned rtype,
unsigned rclass,
unsigned rseverity,
unsigned flags);
при приёме уведомления срабатывает условие CONDRAISE
51

52.

Упражнение
В проекте hat:
скопируйте программу readfile_state.c в readfile_raise.c
в ней мы будем отправлять службе ham три уведомления
формата (класс, тип, важность)
замените в программе readfile_raise.c:
переход в состояние 1 на отправку уведомления (1,1,1)
переход в состояние 2 на отправку уведомления (1,1, 3)
переход в состояние 3 на отправку уведомления (1,1,2)
замените условия типа CONDSTATE на условия типа
CONDRAISE для трёх указанных уведомлений
при срабатывании каждого из них размещайте запись в
журнале ham
52

53. Технологии обеспечения отказоустойчивости

Темы занятия:
Введение
Комплект высокой готовности
- администратор высокой готовности
- библиотека восстановления клиентов
- расширение штатных диагностических
возможностей
Адаптивное партиционирование
Резервирование и горячая замена
администраторов ресурсов
Заключение
53

54.

Адаптивное партиционирование
В системах жёсткого реального времени
возможна монополизация вычислительного
ресурса приоритетными задачами:
на двухъядерной платформе
запускаются три экземпляра
программы greedy,
выполняющей непрерывные
вычисления
экземпляр с приоритетом 9
перестаёт выполняться через 1
секунду, когда экземпляры с
приоритетом 10 запускаются и
монополизируют оба
процессорных ядра
54

55.

Адаптивный планировщик потоков
В ЗОСРВ «Нейтрино» предусмотрен
адаптивный планировщик потоков:
активируется в сценарии сборки загрузочного
образа
обеспечивает жёсткое реальное время при
нагрузке менее 100%
предоставляет гарантированную долю
вычислительного ресурса процессам или группам
процессов (партициям) при нагрузке 100%
партиции создаются и настраиваются с помощью
API системной библиотеки и командно-строковыми
средствами
55

56.

Адаптивный планировщик потоков
Адаптивный планировщик:
начисляет время
выполнения
каждого потока
соответствующей
партиции
рассчитывает
текущие доли
процессорного
времени,
израсходованног
о партициями, в
пределах
скользящего
окна усреднения
partitionA: 20%
System: 50%
partitionB: 30%
Суммарный бюджет =
100%
Окно усреднения
Текущее
время
Окно усреднения
Текущее
время
56
Время
Время

57.

Адаптивное планирование в зависимости от
нагрузки
неполная нагрузка:
планирование строго по
приоритетам
полная нагрузка: планирование
по приоритетам с учётом
бюджетов
имеется доступный
бюджет
6
7
8
partitionA
бюджет
исчерпан
6
5
7
6
имеется доступный
бюджет
5
7
7
6
6
6
9
8
9
partitionB
partitionA
partitionB
RUNNING
(второй по старшинству приоритет)
RUNNING
(максимальный приоритет)
57

58.

Применение адаптивного партиционирования
Ограничение вычислительного ресурса
программ, которые могут монополизировать его
потребление:
когда поведение программы известно
когда поведение программы неизвестно
Резервирование вычислительного ресурса для
нештатных ситуаций:
послеаварийное восстановление
отладка
58

59.

Параметры адаптивного партиционирования
Параметры партиций:
имя
идентификатор
бюджет
критический бюджет
Параметры адаптивного планировщика:
размер скользящего окна
политика планирования
политика банкротства
политика безопасности
Средства управления параметрами адаптивного
партиционирования:
функция ядра SchedCtl()
утилита aps
59

60.

Функция SchedCtl()
#include <sys/sched_aps.h>
#include <sys/neutrino.h>
int SchedCtl (int cmd, void *data, int length);
cmd ― команда SCHED_APS_*
data и length ― адрес и размер аргумента
необходимо инициализировать все поля аргумента
(например, с помощью memset() или APS_INIT_DATA())
в качестве аргументов используются структуры
sched_aps_*
Пример:
// присоединение процесса к партиции 1
sched_aps_join_parms process;
memset(&process, 0, sizeof(process)); // либо
APS_INIT_DATA(&process);
process.id = 1;
process.pid = getpid();
process.tid = -1;
SchedCtl(SCHED_APS_JOIN_PARTITION,
&process, sizeof(process))
60

61.

Параметры партиций
по умолчанию все процессы выполняются в партиции
System
бюджет новой партиции вычитается из родительской
партиции
можно создавать до 8 партиций на устройстве
имена партиций должны быть уникальными
идентификаторы назначаются партициям
автоматически
оптимальное соотношение бюджетов партиций
обычно определяется опытным путём:
задать бюджеты партиций
применить различные нагрузки к устройству
проверить длительность выполнения задач реального
времени с помощью трассировки
61

62.

Наследование партиций
при получении сообщения поток перемещается в
партицию потока-отправителя
время обработки сообщения начисляется партиции
клиента
аналог механизма наследования приоритетов
при отправке импульса адресат остаётся в своей
партиции
функция-обработчик прерывания выполняется в
партиции вытесняемого потока
можно вручную помещать поток в заданную партицию
с помощью команды SCHED_APS_JOIN_PARTITION
функции SchedCtl()
62

63.

Назначение нулевого бюджета
Целесообразно назначать партиции нулевой
бюджет в следующих случаях:
в партиции отсутствуют выполняемые потоки
бездействующая партиция с нулевым бюджетом не
генерирует свободное время
партиция с ненулевым бюджетом без активных потоков
переводит планировщик в постоянный режим свободного
времени, что не всегда желательно
требуется выполнять неприоритетный код только если
другая партиция бездействует
все программы партиции только обрабатывают
сообщения (например, администраторы ресурсов)
время обработки сообщений зачисляется на счёт клиентов
если сервер/администратор выполняет другие задачи,
следует размещать его в партиции с ненулевым бюджетом
63

64.

Резервный бюджет
Резервный бюджет предоставляется критически
важным потокам партиции при исчерпании её
основного бюджета
поток становится критически важным:
по команде SCHED_APS_MARK_CRITICAL функции
SchedCtl()
при получении сообщения/события от критически важного
потока
резервный бюджет:
задаётся в виде абсолютного значения (мс)
должен быть достаточным для завершения действий,
выполняемых в реальном времени
при исчерпании резервного бюджета возникает
событие банкротства партиции
ОС реагирует на него в соответствии с заданной
политикой банкротства
64

65.

Команды управления параметрами партиции
команда SCHED_APS_CREATE_PARTITION создаёт новую
партицию, заданную в структуре
typedef struct {
char
*name;
_Uint16t
budget_percent;
_Int16t
critical_budget_ms;
_Int16t
id;
} sched_aps_create_parms;
команда SCHED_APS_MODIFY_PARTITION изменяет
параметры партиции id:
typedef struct {
_Int16t
id;
_Int16t
new_budget_percent;
_Int16t
new_critical_budget_ms;
} sched_aps_modify_parms;
65

66.

Создание уведомления о банкротстве
партиции
команда SCHED_APS_ATTACH_EVENTS задаёт событие,
которое генерируется при банкротстве партиции id:
typedef struct {
const struct sigevent *bankruptcy_notification;
const struct sigevent *overload_notification;
_Int16t
id;
} sched_aps_events_parm;
66

67.

Чтение параметров партиции
команда SCHED_APS_QUERY_PARTITION считывает
параметры партиции id в структуру
typedef struct {
_Int16t id;
_Uint64t
budget_cycles;
_Uint64t
critical_budget_cycles;
char
name[APS_PARTITION_NAME_LENGTH+1];
_Int16t
parent_id;
_Uint16t
budget_percent;
_Int32t
notify_pid;
_Int32t
notify_tid;
_Uint32t
pinfo_flags;
_Int32t
pid_at_last_bankruptcy;
_Int32t
tid_at_last_bankruptcy;
} sched_aps_partition_info;
67

68.

Чтение статистики работы партиции
команда SCHED_APS_PARTITION_STATS считывает
параметры текущего состояния партиции id:
typedef struct {
_Int16t
id;
_Uint64t run_time_cycles;
_Uint64t critical_time_cycles;

} sched_aps_partition_stats;
68

69.

Упражнение
В программе partitions.c проекта ap:
создайте партиции partA и partB с бюджетами 20% и
15% соответственно
запустите в каждом из них программу greedy (см. код)
назначьте партиции partB бюджет 10%
назначьте партиции partA резервный бюджет 10 мс
установите политику свободного времени
SCHED_APS_SCHEDPOL_FREETIME_BY_RATIO
верните политику свободного времени
SCHED_APS_SCHEDPOL_DEFAULT
запустите программу greedy в партиции System (см. код)
и пронаблюдайте работу системы при 100%
вычислительной нагрузке
просмотр текущего состояния партиций: aps show -l
просмотр параметров процессов и потоков: pidin sched
69

70.

Параметры процессов и потоков
Параметры потока:
флаг критической важности
номинальная партиция
текущая партиция
Параметры процесса:
партиция
70

71.

Задание параметров потоков
команда SCHED_APS_MARK_CRITICAL отмечает поток tid
процесса pid как критически важный:
typedef struct {
_Int32t pid;
_Int32t tid;
} sched_aps_mark_crit_parms;
команда SCHED_APS_CLEAR_CRITICAL аннулирует
статус критической важности потока
использует структуру sched_aps_clear_crit_parms, идентичную
sched_aps_mark_crit_parms
команда SCHED_APS_JOIN_PARTITION помещает поток
(pid, tid) в партицию id:
typedef struct {
_Int16t
id;
_Int32t
pid;
_Int32t
tid;
} sched_aps_join_parms;
71

72.

Чтение параметров процессов и потоков
команда SCHED_APS_QUERY_THREAD считывает
номинальную и текущую партиции потока (pid, tid):
typedef struct {
_Int32t pid;
_Int32t tid;
_Int16t id;
_Int16t inherited_id;
_Uint32t
crit_state_flags;
} sched_aps_query_thread_parms;
команда SCHED_APS_QUERY_PROCESS возвращает
партицию, в которой находится процесс pid:
typedef struct {
_Int32t
pid;
_Int16t
id;
} sched_aps_query_process_parms;
72

73.

Параметры адаптивного планировщика
Окно усреднения:
от 8 до 400 мс
размер окна усреднения влияет на точность
балансировки нагрузки
погрешность составляет +/- (длительность_такта /
размер_окна_усреднения)
в экстремальных случаях влияет на максимальные
задержки готовых к выполнению потоков
практический опыт: если в системе имеется 8
активных партиций, размер окна должен составлять
не менее 8 квантов
в большинстве систем – 32 мс
73

74.

Параметры адаптивного планировщика
Политика планирования:
SCHED_APS_SCHEDPOL_DEFAULT (по умолчанию)
планировщик выбирает потоки строго по приоритету
SCHED_APS_SCHEDPOL_FREETIME_BY_RATIO
cвободное время делится между активными партициями
пропорционально их бюджетам
SCHED_APS_SCHEDPOL_BMP_SAFETY
предотвращает ошибки планирования при наличии
нескольких партиций, бюджеты которых по отдельности
составляют менее 50%, а в сумме — 50% или более
74

75.

Параметры адаптивного планировщика
Политика банкротства:
SCHED_APS_BNKR_BASIC (по умолчанию)
генерирует уведомление о банкротстве и переводит
раздел в состояние «исчерпанного бюджета» на
оставшееся время в окне планирования
SCHED_APS_BNKR_REBOOT
инициирует аварийную остановку системы
SCHED_APS_BNKR_CANCEL_BUDGET
обнуляет критический бюджет партиции; исключается
возникновение повторного банкротства
SCHED_APS_BNKR_RECOMMENDED
= SCHED_APS_BNKR_CANCEL_BUDGET
75

76.

Параметры адаптивного планировщика
Политика безопасности:
SCHED_APS_SEC_OFF
любой пользователь системы может создавать партиции и
изменять их атрибуты (по умолчанию)
SCHED_APS_SEC_BASIC
только процессы с привилегиями суперпользователя в
партиции System могут задавать глобальные параметры
диспетчеризации и резервные бюджеты
SCHED_APS_SEC_FLEXIBLE
аналог basic, но процессы с привилегиями
суперпользователя могут создавать и использовать
субпартиции в своей партиции
SCHED_APS_SEC_RECOMMENDED
только процессы с привилегиями суперпользователя в
партиции System могут создавать и использовать партиции
76

77.

Задание параметров адаптивного
планировщика
команда SCHED_APS_SET_PARMS задаёт размер окна,
политики планирования и банкротства, указанные в
структуре
typedef struct {
_Int16t windowsize_ms;
_Uint32t
*scheduling_policy_flagsp;
_Uint32t
*bankruptcy_policyp;
} sched_aps_parms;
команда SCHED_APS_ADD_SECURITY задаёт размер
окна, политики планирования и банкротства,
указанные в структуре
typedef struct {
_Uint32t
sec_flags;
} sched_aps_security_parms;
77

78.

Чтение параметров адаптивного
планировщика
команда SCHED_APS_QUERY_PARMS считывает текущие
настройки планировщика:
typedef struct {
_Uint64t
cycles_per_ms;
_Uint64t
windowsize_cycles;
_Uint32t
scheduling_policy_flags;
_Uint32t
sec_flags;
_Uint32t
bankruptcy_policy;
_Uint16t
num_partitions;
_Uint16t
max_partitions;
} sched_aps_info;
команда SCHED_APS_OVERALL_STATS считывает
текущую статистику работы планировщика:
typedef struct {
_Uint64t idle_cycles;
_Int16t
id_at_last_bankruptcy;
_Int32t
pid_at_last_bankruptcy;
_Int32t
tid_at_last_bankruptcy;
….
} sched_aps_overall_stats;
78

79.

Упражнение
В проекте ap:
в программе critical отметьте поток, обрабатывающий
прерывание, как критически важный
в программе bankruptcy_monitor добавьте код, который
указывает ядру генерировать событие при каждом
банкротстве партиции, в которой она запущена
запустите программу bankruptcy_monitor в партиции partA
запускайте программу critical в партиции partA с
различными аргументами (см. комментарии), чтобы в
конечном счёте вызвать банкротство партиции
пронаблюдайте в реакцию bankruptcy_monitor
79

80. Технологии обеспечения отказоустойчивости

Темы занятия:
Введение
Комплект высокой готовности
- администратор высокой готовности
- библиотека восстановления клиентов
- расширение штатных диагностических
возможностей
Адаптивное партиционирование
Резервирование и горячая замена
администраторов ресурсов
Заключение
80

81.

Взаимодействие клиента с
администратором ресурса
2
procnto
1
запрос списка
администраторов
(0, 12345, … )
(0, 67890, …)

/dev/resource
3
fd = open
(“/dev/resource”
,
…)
Клиент
read (fd, …)
write (fd,
…)
81
Администратор
1
pid = 12345
4
Администратор
2
pid = 67890

82.

Формирование списка администраторов
ресурсов
Администратор ресурса указывает своё
положение в списке при регистрации
файла/точки монтирования:
resmgr_attach(…, “/dev/resource”, …,
RESMGR_FLAG_BEFORE)
помещается в начало списка (становится основным)
используется по умолчанию
resmgr_attach(…, “/dev/resource”, …,
RESMGR_FLAG_AFTER)
помещается в конец списка (становится резервным)
82

83.

Резервирование администратора ресурса
Клиент устанавливает соединение с резервным
администратором, если основной
администратор:
возвращает ошибку
отключается от файла / точки монтирования
завершает работу
83

84.

Горячая замена администратора ресурса
запустить администратор 2 без флага или с флагом
RESMGR_FLAG_BEFORE
все новые клиенты будут подключаться к администратору
2
дать администратору 1 возможность завершить
обслуживание подключённых клиентов
вывести администратор 1 из эксплуатации
84

85.

Упражнение
В программе example.c проекта rm_writing:
добавьте поддержку ключей:
-b запуск в резервном режиме
-e отправка клиенту ошибки ENOSYS при открытии
файла /dev/example
в вызове getopt() замените строку "v" на "vbe"
добавьте переменные-флаги optb и opte и
устанавливайте их аналогично optv в функции
options()
запустите в комплекте разработчика три командных
строки ― две для программы example и одну для
команды echo Hi > /dev/example
пронаблюдайте взаимодействие клиента с
экземплярами example в различных режимах:
(продолжение на следующем слайде)
85

86.

Упражнение
горячая замена одного экземпляра на другой:
/tmp/example -v
/tmp/example -v
echo Hi > /dev/example
резервирование, при котором основной экземпляр
example работает исправно:
/tmp/example -v
echo Hi > /dev/example
/tmp/example -vb
echo Hi > /dev/example
резервирование, при котором основной экземпляр
возвращает ошибку и клиент автоматически
подключается к резервному экземпляру:
/tmp/example -ve
echo Hi > /dev/example
/tmp/example -vb
echo Hi > /dev/example
86

87. Технологии обеспечения отказоустойчивости

Темы занятия:
Введение
Комплект высокой готовности
- администратор высокой готовности
- библиотека восстановления клиентов
- расширение штатных диагностических
возможностей
Адаптивное партиционирование
Резервирование и горячая замена
администраторов ресурсов
Заключение
87

88.

Заключение
ЗОСРВ «Нейтрино» включает в себя широкий
спектр технологий обеспечения
отказоустойчивости ПО:
комплект высокой готовности восстанавливает
программы и соединения между ними
адаптивное партиционирование предотвращает
монополизацию вычислительного ресурса в системах
жёсткого реального времени
штатный механизм открытия файлов позволяет
реализовывать резервирование и горячую замену
служб и драйверов (администраторов ресурсов)
88
English     Русский Rules