Возможная утечка памяти при записи файлов на SD с FAT fs

У меня есть IP-камера с поддержкой HI3516A SoC с гнездом для SD-карт. Операционная система на камере – это обычное ядро ​​Linux 3.4.45. Все работает хорошо, но мне нужно иметь копию видео с камеры на моем удаленном хранилище в Azure, поэтому я написал программу на C, которая захватывает внутренний поток RTP, разбивает его на сегменты, записывает эти сегменты на SD-карту и отправляет их на мое лазурное хранилище.

Я устанавливаю 64 ГБ SD-карту на камеру, создаю FAT fs на ней и монтирую на / mnt / sd_card. Моя программа работает так, как я ожидаю, но после 1 – 3 дней безотказной работы я увидел, что вся оперативная память камеры где-то исчезла.

Прежде всего, я решаю, что у меня есть утечка памяти в моей программе, и убейте ее, используя следующую команду:

kill -S SIGKILL 1223 

но память не вернулась к системе. Я думаю, странное поведение. Через несколько дней после исправления ошибок я неожиданно обнаружил, что после того, как я отключу SD-карту, вся память вернется обратно в систему. Теперь я решаю, какие у меня ошибки в части создания файла в моей программе. Чтобы проверить этот случай, я написал следующую программу:

 #include <stdarg.h> #include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <string.h> #include <errno.h> #include <unistd.h> #include <stdint.h> #include <limits.h> #include <inttypes.h> #include <time.h> #define KB 1024 #define MB KB * 1024 #define GB MB * 1024 static void print_msg(const char *fmt, ...) { va_list args; time_t timer = time(NULL); printf("%s\t", ctime(&timer)); va_start(args, fmt); vfprintf(stdout, fmt, args); va_end(args); } static int generate_file(const char *dest_fname, const size_t file_size) { char buffer[BUFSIZ]; const char *source_fname = "/dev/urandom"; size_t bytes_to_operate, avaliable_bytes = file_size; int bytes_readed, bytes_writed, source_fd = -1, dest_fd = -1, rc = EXIT_SUCCESS; source_fd = open(source_fname, O_RDONLY); if (source_fd < 0) { printf("Can't open source file '%s': %s.\n", source_fname, strerror(errno)); rc = EXIT_FAILURE; goto end; } dest_fd = open(dest_fname, O_CREAT | O_WRONLY | O_TRUNC, 0666); if (dest_fd < 0) { printf("Can't open destination file '%s': %s.\n", dest_fname, strerror(errno)); rc = EXIT_FAILURE; goto end; } bytes_to_operate = avaliable_bytes - BUFSIZ; print_msg("Write random data to file\n"); while(avaliable_bytes > 0) { bytes_to_operate = (avaliable_bytes > BUFSIZ) ? BUFSIZ : avaliable_bytes; bytes_readed = read(source_fd, buffer, bytes_to_operate); if (bytes_readed < 0) { printf("Error while reading data from '%s': %s", source_fname, strerror(errno)); rc = EXIT_FAILURE; goto end; } if (bytes_readed != bytes_to_operate) { // don't read write more than read bytes_to_operate = bytes_readed; } bytes_writed = write(dest_fd, buffer, bytes_to_operate); if (bytes_writed < 0) { printf("Error while writing data to '%s': %s", dest_fname, strerror(errno)); rc = EXIT_FAILURE; goto end; } avaliable_bytes -= bytes_writed; } end: print_msg("Close file\n"); close(source_fd); close(dest_fd); return rc; } static void generate_fpath(char *out, const char *dest_path, uint16_t index) { snprintf(out, PATH_MAX, "%s/file_%"SCNu16, dest_path, index); } int main(int argc, char** argv) { size_t file_size; const char *dest_path = argv[3]; char fpath[PATH_MAX]; uint16_t del_index = 0, cur_index = 0; switch(argv[2][0]) { case 'K': file_size = atoi(argv[1]) * KB; break; case 'M': file_size = atoi(argv[1]) * MB; break; default: file_size = atoi(argv[1]); break; } print_msg("Generate files of size %s%s to %s\n", argv[1], argv[2], argv[3]); while (cur_index < UINT16_MAX) { generate_fpath(fpath, dest_path, cur_index); generate_file(fpath, file_size); printf("Created file %s\n", fpath); cur_index++; del_index++; sleep(1); } return EXIT_SUCCESS; } 

То, что у меня было до начала моих тестов:

 /mnt # free total used free shared buffers Mem: 125044 58540 66504 0 480 -/+ buffers: 58060 66984 Swap: 0 0 0 

Теперь я запустил свой тестовый код и попросил его создать 10 МБ файлов на SD-карте

 /mnt # mount /dev/sd_card2 /mnt/sd_card2 /mnt # ./random_size_file_generator 10 M /mnt/sd_card2 

и в другом окне я начинаю контролировать свою память

 ~ # free total used free shared buffers Mem: 125044 60988 64056 0 2180 -/+ buffers: 58808 66236 Swap: 0 0 0 ~ # free total used free shared buffers Mem: 125044 65464 59580 0 2204 -/+ buffers: 63260 61784 Swap: 0 0 0 ... ~ # free total used free shared buffers Mem: 125044 123004 2040 0 1104 -/+ buffers: 121900 3144 Swap: 0 0 0 

Только 2 МБ свободной оперативной памяти. Теперь я останавливаю свой код и отключаю SD-карту и просматриваю статус памяти

 /mnt # ./random_size_file_generator 10 /mnt/sd_card2 Created file /mnt/sd_card2/file_0 Created file /mnt/sd_card2/file_1 Created file /mnt/sd_card2/file_2 Created file /mnt/sd_card2/file_3 Created file /mnt/sd_card2/file_4 Created file /mnt/sd_card2/file_5 Created file /mnt/sd_card2/file_6 Created file /mnt/sd_card2/file_7 Created file /mnt/sd_card2/file_8 Created file /mnt/sd_card2/file_9 ^C /mnt # umount /mnt/sd_card2/ /mnt # free total used free shared buffers Mem: 125044 58500 66544 0 472 -/+ buffers: 58028 67016 Swap: 0 0 0 

Итак, может кто-нибудь объяснить мне, что происходит? Я думаю, что Linux резервирует некоторую память для буферов, чтобы убедиться, что все данные будут записаны на SD-карту, но когда моя программа остановится, память не освобождается, пока не отключите SD-карту.

Заранее спасибо.

  • Ошибки ввода-вывода на жестком диске при загрузке Linux
  • Почему фоновые процессы иногда останавливаются спонтанно?
  • как o_sync запускает pdflush?
  • Как мне запустить команду в другом tty?
  • Почему IO настолько высок, когда почти не хватает памяти
  • Как читать из stdin при замене процесса?
  • Является ли настройка более высокого уровня для процесса эффективным способом снижения его влияния на загрузку системы / процессорное время?
  • Создавать несколько грязных потоков flusher страниц на устройство
  • лучший язык программирования для интенсивных задач ввода / вывода
  • почему blktrace только пишет блоки из 8?
  • Проблема с устройством хранения: ошибки ввода-вывода, но нет поврежденных секторов?
  • производительность на Linux-системе при последовательном соединении нескольких USB-накопителей на USB-концентраторах?
  • Interesting Posts

    Как установить инструменты программирования в корневой каталог, чтобы они могли использоваться пользователями, не являющимися администраторами?

    Подстановочный знак имени файла

    grub не может найти CentOS 7

    Как установить StackApplet на Debian?

    Как переместить окно в другое рабочее пространство в Xfce?

    Почему команда «hwclock» применяет положительное смещение для местного времени, тогда как команда «date» применяет отрицательное смещение?

    Я хочу увидеть список всех интерфейсов dbus с командой в терминале .h

    Редактирование gnome-shell.css не изменяет внешний вид

    Что означает ошибка = продолжить настройку монтирования?

    GNOME отказывается от обновлений, не связанных с безопасностью – это снижает безопасность существующих сторонних приложений?

    Как сделать отказоустойчивость HA Heartbeat, когда потеряно одно из двух соединений NIC?

    awk для удаления строки из переменной

    Xrandr не сохраняет настройки

    Какие коды клавиш соответствуют запросам на включение сенсорной панели и сенсорной панели?

    Разница между cp -r и cp -R (команда копирования)

    Linux и Unix - лучшая ОС в мире.