Мне удалось решить эту проблему, выгрузив/занеся в черный список модуль ядра i2c _hid . Я не заметил потери функциональности после того, как (клавиатура и тачпад все еще работают ).
Я обнаружил, что патч совсем недавно был добавлен в ядро, которое отключает эти сообщения ядра. Я протестировал его, но обнаружил, что, хотя он и исправляет сообщения, по-прежнему наблюдается высокая загрузка ЦП (около 25% одного ядра )из-за постоянного срабатывания прерывания. Выгрузка модуля ядра остановила это.
И даже если бы это было возможно с помощью какого-то хака, каналы буферизируются и к тому времени, когда считыватель каналов попытается "сигнализировать" писателю каналов, последний мог уже записать данные который вызывает ошибку в дальнейшем, уже получил успешный статус (> 0 )и соответственно обновил свое состояние. Чтобы это сработало, процесс написания должен был вернуться в прошлое. Вдобавок ко всему, сам считыватель каналов может выполнять свою собственную буферизацию и сохранение состояния, что может привести к рассинхронизации.
Единственный выход tar
состоит в том, чтобы вызывать процедуры шифрования напрямую, вместо передачи данных по какому-либо каналу. Вместо того, чтобы изменять исходный код и перекомпилировать его, это можно было бы сделать, исправив его с помощью LD_PRELOAD
хака, который переопределяет write()
библиотечную функцию и обрабатывает данные перед передачей их оригиналу write()
.
ENOSPC
с помощью LD_PRELOAD
хака Это приведет к сбою записи в fd 1 (stdout )с ENOSPC
, как только он попытается записать в него более 40960 байт, после чего он сбрасывает счетчик и снова завершается успешно и т. д.
Если вы хотите, чтобы он работал с tar -cf filename
,вместо tar -cf -
вам, вероятно, следует изменить тест fd == 1
на fd != 2
.
$ cat <<'EOT' >enospc.c
#define _GNU_SOURCE
#include <unistd.h>
#include <dlfcn.h>
#include <err.h>
#include <errno.h>
#define MAX 40960
ssize_t write(int fd, const void *b, size_t z){
ssize_t w;
static typeof (write) *o_write;
static size_t count;
if(!o_write) o_write = dlsym(RTLD_NEXT, "write");
if(fd == 1 && count + z > MAX){
count = 0;
errno = ENOSPC;
return -1;
}
w = o_write(fd, b, z);
if(w > 0) count += w;
return w;
}
EOT
$ cc -Wall -shared enospc.c -o enospc.so -ldl
$ seq -f 'n foo%04g.tar' 1 10000 |
LD_PRELOAD=./enospc.so tar -M -cf- /etc/X11 > foo0000.tar
tar: Removing leading `/' from member names
Prepare volume #2 for ‘-’ and hit return: Prepare volume #3 for ‘/tmp/foo0001.tar’ and hit return: Prepare volume #4 for ‘/tmp/foo0002.tar’ and hit return: Prepare volume #5 for ‘/tmp/foo0003.tar’ and hit return: Prepare volume #6 for ‘/tmp/foo0004.tar’ and hit return: Prepare volume #7 for ‘/tmp/foo0005.tar’ and hit return: Prepare volume #8 for ‘/tmp/foo0006.tar’ and hit return: Prepare volume #9 for ‘/tmp/foo0007.tar’ and hit return: $
$ ls foo000*
foo0000.tar foo0002.tar foo0004.tar foo0006.tar foo0008.tar
foo0001.tar foo0003.tar foo0005.tar foo0007.tar
В вашем вопросе есть несколько проблем:
Правильный способ обнаружения ситуации с концом ленты — проверка записи (2 ), которая возвращает 0 без установки ошибки errno. Таким образом, правильная реализация tar, которая поддерживает многотомные ленточные архивы, проверяет запись (2 ), чтобы вернуть 0.
errno ENOSPC создается только при записи в обычный файл в файловой системе, поэтому этот errno не подходит для использования в качестве основы для многотомных -ленточных архивов.
Невозможно передать ошибку записи обратно через канал.
Команда tar UNIX не поддерживает многотомные -архивы томов
.gtar поддерживает запись многотомных -архивов, но не может их корректно прочитать с вероятностью прибл. 5%, потому что он не всегда может распознать последующий архив как правильный номер тома по порядку. Это вызвано конструктивным недостатком gtar, который нельзя исправить, не введя новый несовместимый многотомный формат -.
star пытается заблокировать память FIFO только в том случае, если она вызывается как root. Код ошибки, который он пишет в цитируемом вами сообщении, означает :не sueruser (root ). Вы запускаете этот звездный экземпляр в среде, где «root» имеет ограниченные права?
star не запускает программу сжатия, если вывод не является простым файлом, потому что вывод программы сжатия не блокируется, но блокировка вывода требуется для реализаций tar. Если вам нравится сжимать в таком случае, вызовите что-то вроде:star -c... | compress...
В общем, если вы действительно хотите зашифровать вывод программы tar, вам нужно будет направить вывод программы шифрования через программу, которая управляет многотомным выводом на ленту -.
Кстати, :не стесняйтесь присылать дополнительную информацию, чтобы получить более подробный ответ.