resmgr_attach()

Установить связь между путём и администратором ресурса

Прототип:

#include <sys/iofunc.h>
#include <sys/dispatch.h>
int resmgr_attach ( dispatch_t *dpp,
resmgr_attr_t *attr,
const char *path,
enum _file_type file_type,
unsigned flags,
const resmgr_connect_funcs_t *connect_funcs,
const resmgr_io_funcs_t *io_funcs,
RESMGR_HANDLE_T *handle );

Аргументы:

dpp
Структура диспетчеризации, созданная при помощи dispatch_create().
attr
Указатель на структуру resmgr_attr_t, определяющую атрибуты менеджера ресурсов.
path
NULL, или путь, который требуется зарегистрировать в менеджере ресурсов.
file_type
Тип файла; один из нижеследующих (определены в <sys/ftype.h>):
_FTYPE_ANY
имя пути может быть любым.
_FTYPE_LINK
зарезервировано для менеджера процессов.
_FTYPE_MOUNT
получать запросы на монтирование по пути (path должен быть NULL).
_FTYPE_MQUEUE
зарезервировано для менеджера очереди сообщений.
_FTYPE_PIPE
зарезервировано для менеджера каналов.
_FTYPE_SEM
зарезервировано для менеджера семафоров.
_FTYPE_SHMEM
зарезервировано для объекта разделяемой области памяти.
_FTYPE_SOCKET
зарезервировано для менеджера сокетов.
_FTYPE_SYMLINK
зарезервировано для менеджера процессов.
flags
Флаги, управляющие разрешением пути:
_RESMGR_FLAG_AFTER
_RESMGR_FLAG_BEFORE (по умолчанию)
_RESMGR_FLAG_DIR
_RESMGR_FLAG_FTYPEALL
_RESMGR_FLAG_FTYPEONLY
_RESMGR_FLAG_OPAQUE
_RESMGR_FLAG_SELF
connect_funcs
Указатель на структуру resmgr_connect_funcs_t, определяющую функции установки соединения на уровне POSIX.
io_funcs
Указатель на структуру resmgr_io_funcs_t, определяющую функции ввода/вывода на уровне POSIX.
handle
Указатель на произвольную структуру, которую требуется связать с присоединяемым путем. Для большинства менеджеров ресурсов это структура iofunc_attr_t.

Библиотека:

libc

Описание:

Функция resmgr_attach() помещает path в пространство имен и связывает запросы по этому пути со структурой диспетчеризации dpp.

Большинство из перечисленных выше типов файлов используются для специальных служб, с которыми связана их собственная функция открытия. Например, менеджер mqueue указывает file_type как _FTYPE_MQUEUE, а mq_open() запрашивает совпадение пути того же типа.

Следует указать _FTYPE_ANY для обычных файловых систем и простых устройств, таких как последовательные порты, которые не имеют своего собственного типа открытия, или если диспетчер ресурсов может обрабатывать тип службы или действовать как узел перенаправления для диспетчера, который имеет тип открытия. Большинство менеджеров ресурсов относятся к этому типу.

Пользовательский менеджер ресурсов не будет получать сообщения об открытии неподходящего типа. В следующей таблице показаны различные типы открытых функций и типы путей, которым они будут соответствовать.

Функция: file_type: Соответствует пути для типа:
mq_open() _FTYPE_MQUEUE _FTYPE_ANY или _FTYPE_MQUEUE
open() _FTYPE_ANY Все типы
pipe() _FTYPE_PIPE _FTYPE_ANY или _FTYPE_PIPE
sem_open() _FTYPE_SEM _FTYPE_ANY или _FTYPE_SEM
shm_open() _FTYPE_SHMEM _FTYPE_ANY или _FTYPE_SHMEM
socket() _FTYPE_SOCKET _FTYPE_ANY или _FTYPE_SOCKET

Универсальный вызов open() можно использовать для открытия пути любого типа.

Если требуется использовать функции POSIX, то существует возможность вызвать iofunc_func_init(), чтобы заполнить таблицы функций подключения и ввода/вывода функциями-обработчиками по умолчанию, предоставляемыми библиотекой слоев POSIX. Затем можно переопределить обработчики по умолчанию, размещенные в структурах, с помощью собственных обработчиков.


Note: Функция resmgr_attach() копирует именно pointers в структуры resmgr_connect_funcs_t и resmgr_io_funcs_t, а не сами структуры. Следует выделить память под структуры, объявить их статическими или сделать их глобальными переменными. Если менеджер ресурсов предназначен для более чем одного устройства с разными обработчиками, следует создать отдельные структуры, которые определяют обработчики.

В наиболее общем случае последний аргумент, handle - это произвольная структура, которую требуется связать с присоединяемым путем. На практике, однако, рекомендуется, чтобы он содержал четко определенную структуру атрибутов уровня POSIX, iofunc_attr_t, потому что это позволяет использовать библиотеку по умолчанию для уровня POSIX. Можно расширить данные, содержащиеся в структуре атрибутов, чтобы они содержали любые данные для конкретного устройства, которые могут понадобиться.

Чтобы использовать библиотеку по умолчанию уровня POSIX, структура атрибутов должна быть связана с OCB, и тогда следует использовать OCB iofunc_ocb_t уровня POSIX. Это описано в документации для resmgr_open_bind(), а также в приведенной выше ссылке.

Аргумент flags

Аргумент flags функции resmgr_attach() содержит дополнительную информацию для управления разрешением пути.


Note: Не стоит путать эти flags с теми, что устанавливаются в поле flags структуры resmgr_attr_t. Имена этих флагов начинаются с подчеркивания (_).

Флаги (определенные в <sys/resmgr.h>) включают в себя как минимум следующие биты:

_RESMGR_FLAG_AFTER
Принудительно разрешить путь после других файлов с тем же путем в той же точке монтирования.
_RESMGR_FLAG_BEFORE
Принудительно разрешить путь до других файлов с тем же путем в той же точке монтирования.
_RESMGR_FLAG_DIR
Рассматривать имя пути как каталог и позволить разрешение более длинных путей. Сообщение _IO_CONNECT содержит путь, переданный клиентскому вызову open() с удаленным совпавшим префиксом. Без этого флага имя пути рассматривается как простой файл, требующий точного совпадения.
Прикрепленный путь Открытый путь _RESMGR_FLAG_DIR установлен _RESMGR_FLAG_DIR сброшен
/a/b /a/b Совпадение "" Совпадение ""
/a/b /a/b/c Совпадение c Нет совпадения
/a/b /a/b/c/d Совпадение c/d Нет совпадения
/a/b /a/bc Нет совпадения Нет совпадения
Невозможно прикрепить путь к каталогу, который содержит в качестве подмножества существующий путь к файлу. Точно так же невозможно прикрепить путь к файлу, который является подмножеством существующего пути к каталогу.
Существующий путь Новый путь Разрешен ли новый путь?
Директория /a/b Директория /a Да
Директория /a/b Директория /a/b/c Да
Файл /a/b Директория /a Да
Файл /a/b Директория /a/b/c Нет; каталог находится под файлом
Директория /a/b Файл /a Нет; каталог находится под файлом
Директория /a/b Файл /a/b/c Да
Файл /a/b Файл /a Да
Файл /a/b Файл /a/b/c Да
_RESMGR_FLAG_FTYPEALL
Обрабатывать запросы для всех типов файлов. Необходимо указать тип файлов регистрации FTYPE_ALL.
_RESMGR_FLAG_FTYPEONLY
Обрабатывать только запросы для указанного типа файла. Имя пути должно быть NULL.
_RESMGR_FLAG_OPAQUE
Не разрешать пути к точкам монтирования для путей короче данного (т.е. найти самое длинное совпадение со всеми прикрепленными путями).
_RESMGR_FLAG_SELF
Позволить запросам разрешаться обратно на этот сервер; другими словами, позволить менеджеру ресурсов открыть путь к самому себе.

Caution: Следует быть осторожным при установке флага _RESMGR_FLAG_SELF, поскольку возможна взаимная блокировка (deadlock).

Возвращаемое значение:

Уникальный идентификатор ссылки данной связи.

Если возникла ошибка функция возвращает -1, код ошибки записывается в errno.

Возвращенный идентификатор необходим для последующего отвязывания пути с помощью resmgr_detach(). Идентификатор также передается в resmgr_handler() как ctp->id.

Коды ошибок:

ENOMEM
Недостаточно свободной памяти для завершения операции.
ENOTDIR
Компонент пути не является каталогом.

Примеры:

Пример простого однопоточного диспетчера ресурсов:

#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <sys/iofunc.h>
#include <sys/dispatch.h>
static resmgr_connect_funcs_t connect_funcs;
static resmgr_io_funcs_t io_funcs;
static iofunc_attr_t attr;
int main( int argc, char **argv )
{
dispatch_t *dpp;
resmgr_attr_t resmgr_attr;
resmgr_context_t *ctp;
int id;
/* initialize dispatch interface */
if ( (dpp = dispatch_create()) == NULL )
{
fprintf( stderr, "%s: Unable to allocate dispatch handle.\n", argv[0] );
return (EXIT_FAILURE);
}
/* initialize resource manager attributes */
memset( &resmgr_attr, 0, sizeof resmgr_attr );
resmgr_attr.nparts_max = 1;
resmgr_attr.msg_max_size = 2048;
/* initialize functions for handling messages */
iofunc_func_init( _RESMGR_CONNECT_NFUNCS, &connect_funcs,
_RESMGR_IO_NFUNCS, &io_funcs );
/* initialize attribute structure */
iofunc_attr_init ( &attr, S_IFNAM | 0666, 0, 0 );
/* attach our device name (passing in the POSIX defaults
from the iofunc_func_init and iofunc_attr_init functions) */
if ( (id = resmgr_attach( dpp, &resmgr_attr, "/dev/mynull", _FTYPE_ANY, 0,
&connect_funcs, &io_funcs, &attr )) == -1 )
{
fprintf( stderr, "%s: Unable to attach name.\n", argv[0] );
return (EXIT_FAILURE);
}
/* allocate a context structure */
ctp = resmgr_context_alloc( dpp );
/* start the resource manager message loop */
while ( 1 )
{
if ( (ctp = resmgr_block( ctp )) == NULL )
{
fprintf( stderr, "block error\n" );
return (EXIT_FAILURE);
}
resmgr_handler( ctp );
}
}

Примеры использования интерфейса диспетчеризации см. в dispatch_create(), message_attach(), и thread_pool_create().

Классификация:

ЗОСРВ «Нейтрино»

Точка остановки потока
Да
Обработчик прерываний
Нет
Обработчик сигналов
Нет
В потоке
Да

Предостережения:

Если приложение вызывает эту функцию, оно должно запускаться от имени пользователя root.

Тематические ссылки:

resmgr_attr_t, dispatch_create(), iofunc_attr_init(), iofunc_attr_t, iofunc_func_init(), iofunc_ocb_t, resmgr_block(), resmgr_connect_funcs_t, resmgr_context_alloc(), resmgr_context_free(), resmgr_detach(), resmgr_handler(), resmgr_io_funcs_t




Предыдущий раздел: Описание API системной библиотеки