aio_write () и lio_listio () POSIX AIO не работают правильно в операции записи - PullRequest
0 голосов
/ 06 февраля 2019

Я устанавливаю асинхронизированный модуль записи и хочу, чтобы порядок операций с файлом был гарантирован этим.Я использую это как писатель в другой программе, которая читает файл pcap.Учтите, что я уже пытался отдельно использовать linux-aio и POSIX aio в моем коде для записи файла pcap на диск.Мне нужно знать, гарантируется ли выполнение aio_write () и lio_listio () POSIX AIO по порядку?

В linux-aio я использую структуру iocb для представления одного запроса на операцию записи.После фиксированного числа одиночных операций io_getevents блокируется до отчета о завершении фиксированного числа.

struct iocb io_cb;
memset(&io_cb, 0, sizeof(io_cb));
io_cb.aio_fildes = file_descriptor;
io_cb.aio_lio_opcode = IOCB_CMD_PWRITE;
io_cb.aio_reqprio = 0;
io_cb.aio_buf = (__u64)(buffer);
io_cb.aio_nbytes = size;
io_cb.aio_offset = 0;
struct iocb* io_cb_pointer = &io_cb;
static int32_t BLOCKS_COUNT = 1;
syscall(SYS_io_submit, io_context, BLOCKS_COUNT, &io_cb_pointer) 
write_count++;
 if ((write_count == MAX_EVENT_COUNT) || flush == true)//flush is to flush before exit program.
    {
        struct io_event* events = (struct io_event *)malloc((write_count) * sizeof(struct io_event));
        syscall(SYS_io_getevents, io_context, write_count / 2, MAX_EVENT_COUNT, events, NULL)
    }

над фрагментом кода, который пишет ответственный, приводит к правильному выводу pcap, который может быть открыт Wireshark.

Но моя проблема с POSIX aio, который, похоже, не гарантирует порядок выполнения операций.Часть кода для записи показана ниже:

    aiocb_array = calloc(MAX_EVENT_COUNT, sizeof (struct aiocb*));
    aiocb_element = calloc(MAX_EVENT_COUNT, sizeof (struct aiocb));
...
    struct aiocb** aiocb_array;
    struct aiocb* aiocb_element;
...
    static size_t pre_nbytes = 0;
    static __off_t pre_offset = 24;//Due to pcap header file length
    aiocb_element[write_count].aio_fildes = file_descriptor;
    aiocb_element[write_count].aio_lio_opcode = LIO_WRITE;
    aiocb_element[write_count].aio_reqprio = 0;
    aiocb_element[write_count].aio_buf = (void *)(buffer);
    aiocb_element[write_count].aio_nbytes = size;
    aiocb_element[write_count].aio_offset = pre_nbytes + pre_offset;

    pre_nbytes = size;
    pre_offset = aiocb_element[write_count].aio_offset;

    aiocb_array[write_count] = &aiocb_element[write_count];
    write_count++;
        if ((write_count == MAX_EVENT_COUNT) || flush == true )//flush is to flush before exit program.
    {
        if(flush)
        {
            if(lio_listio(LIO_WAIT, aiocb_array, write_count, NULL) != 0)
            {
                 printf("Flush lio_listio errno :%d\n", errno);
                 input->error_code = errno;
                 return false;
            }
        }
        else
        {
            if(lio_listio(LIO_NOWAIT, aiocb_array, write_count, NULL) != 0)
            {
                 printf("lio_listio errno :%d\n", errno);
                 input->error_code = errno;
                 return false;
            }
        }

        if(write_count == MAX_EVENT_COUNT)
            write_count = 0;
    }

Как ясно из приведенного выше кода, я подготавливаю запрос на запись в структуре aiocb и назначаю его смещение, поскольку файл, который используется для записи, был открыт без режима добавления,фрагмент кода генерирует файл pcap, который имеет тот же байт, что и входной pcap, но, к сожалению, Wireshark не может открыть его и выдает ошибку, которая указывает: «Файл захвата, похоже, поврежден или поврежден. (pcap: Файл имеет .......-байтовый пакет, больше чем максимум 0f 65535) ".Но когда я вызываю lio_listio в режиме LIO_WAIT и устанавливаю MAX_EVENT_COUNT = 1, он генерирует надлежащий вывод pcap, который может быть правильно открыт Wireshark.

Кроме того, когда я заменяю lio_listio функцией aio_write из POSIX, он снова создает поврежденный файл,В соответствии с упомянутым условием, которое приводит к правильному выводу pcap, кажется, что lio_listio и функция aio_write порядка выполнения POSIX отличаются от порядка отправки программы !!!Проводились ли операции в произвольном порядке?если ответ «да», то почему игнорируется значение смещения, и правильный вывод не генерируется?почему linux-aio гарантирует и поддерживает порядок работы?если ответ «нет», то в чем моя проблема с кодом и логикой?

Любая помощь будет оценена.

...