Это охвачено в главе 10 Драйверов устройств Linux, 3-го выпуска, Corbet и др. Это доступно бесплатно онлайн, или можно бросить некоторого O'Reilly шекелей путь к мертвому дереву или формам электронной книги. Часть, относящаяся к Вашему вопросу, начинается на странице 278 в первой ссылке.
Если это имеет значение вот моя попытка перефразировать те три страницы плюс другие биты, которые я Погуглил:
При регистрации общего обработчика IRQ ядро проверяет что также:
a. никакой другой обработчик не существует для того прерывания, или
b. все ранее зарегистрированные также требуемое совместное использование прерывания
Если любой случай применяется, он затем проверяет что Ваш dev_id
параметр уникален, так, чтобы ядро могло дифференцировать несколько обработчиков, например, во время демонтажа обработчика.
Когда PCI ¹ устройство повышает линию IRQ, обработчика прерываний ядра низкого уровня называют, и это в свою очередь называет всех зарегистрированных обработчиков прерываний, пасуя назад каждого dev_id
Вы раньше регистрировали обработчик через request_irq()
.
dev_id
оцените должно быть уникальным для машины. Распространенный способ сделать, который должен передать указатель на для каждого устройства struct
Ваше использование драйвера для управления тем устройством. Так как этот указатель должен быть в пространстве памяти Вашего драйвера для него, чтобы быть полезным для драйвера, это в силу самого факта уникально для того драйвера. ²
Если будет несколько драйверов, зарегистрированных для данного прерывания, то их все назовут, когда любое из повышений устройств, которые совместно использовали линию прерывания. Если это не было устройство Вашего драйвера, которое сделало это, обработчик прерываний Вашего драйвера будет передан a dev_id
значение, которое не принадлежит ему. Обработчик прерываний Вашего драйвера должен сразу возвратиться, когда это происходит.
Другой случай - то, что Ваш драйвер управляет несколькими устройствами. Обработчик прерываний драйвера получит один из dev_id
значения известны драйверу. Ваш код, как предполагается, опрашивает каждое устройство для обнаружения, какой повысил прерывание.
Примером, который и др. дают Corbet, является пример параллельного порта ПК. Когда это утверждает линию прерывания, это также устанавливает главный бит в своем первом регистре устройства. (Таким образом, inb(0x378) & 0x80 == true
, принятие стандартной нумерации порта I/O.), Когда Ваш обработчик обнаруживает это, он, как предполагается, делает свою работу, затем очищает IRQ путем записи значения, считанного из порта I/O назад к порту с главным очищенным битом.
Я не вижу оснований, что конкретный механизм является особенным. Другое устройство могло выбрать другой механизм. Единственная важная вещь состоит в том, что, чтобы устройство позволило совместно использованные прерывания, оно должно иметь некоторый путь к драйверу для чтения состояния прерывания устройства и некоторого способа очистить прерывание. Необходимо будет прочитать таблицу данных устройства или руководство по программированию для обнаружения, какой механизм конкретное устройство использует.
Когда Ваш обработчик прерываний говорит ядру, что это обработало прерывание, которое не мешает ядру продолжить называть любые другие обработчики зарегистрированными для того же самого прерывания. Это неизбежно, если необходимо совместно использовать линию прерывания при использовании инициированных уровнем прерываний.
Предположите, что два устройства утверждают ту же линию прерывания одновременно. (Или по крайней мере, так закройтесь вовремя, что ядро не имеет времени для вызова обработчика прерываний, чтобы очистить строку и таким образом рассматривать второе утверждение как отдельное.) Ядро должно назвать все обработчики для той линии прерывания, чтобы дать каждому шанс запросить его связанные аппаратные средства, чтобы видеть, необходимо уделять внимание ли этому. Для двух различных драйверов довольно возможно успешно обработать прерывание в том же, проходят через список обработчика для данного прерывания.
Из-за этого обязательно, чтобы Ваш драйвер сказал устройству, что этому удается очистить его утверждение прерывания когда-то перед возвратами обработчика прерываний. Мне не ясно, что происходит иначе. Непрерывно утверждаемая линия прерывания будет или приводить к ядру, непрерывно называя общих обработчиков прерываний, или это замаскирует способность ядра видеть новые прерывания, таким образом, обработчики никогда не будут называть. Так или иначе, авария.
Сноски:
Я указал PCI выше, потому что все вышеупомянутое принимает инициированные уровнем прерывания, как используется в исходной спецификации PCI. ISA использовал инициированные фронтом сигнала прерывания, которые сделали совместное использование хитрого в лучшем случае и возможного даже затем только при поддержке аппаратными средствами. PCIe использует сообщенные сообщению прерывания; сообщение прерывания содержит уникальное значение, которое ядро может использовать для предотвращения циклической игры предположения, требуемой с совместным использованием прерывания PCI. PCIe может избавить от самой необходимости совместное использование прерывания. (Я не знаю, делает ли это на самом деле, просто что это имеет потенциал к.)
Драйверы ядра Linux вся доля то же пространство памяти, но несвязанный драйвер, как предполагается, не слоняется без дела в чьем-либо пространстве памяти. Если Вы не раздаете тот указатель, можно быть вполне уверены, другой драйвер не собирается придумывать то же самое значение случайно самостоятельно.
Попробуйте что-то вроде этого:
$ ssh -t yourserver "$(<your_script)"
-t
вызывает tty выделение, $(<your_script)
читает целый файл, и в этом случается, передает содержание как один аргумент ssh
, который будет выполняться оболочкой удаленного пользователя.
Если для сценария нужны параметры, передайте их после сценария:
$ ssh -t yourserver "$(<your_script)" arg1 arg2 ...
Работы для меня, не уверенный, если это универсально все же.
Ваша проблема - это ssh
запускает вход в систему, неинтерактивную оболочку на удаленной машине. Очевидное легкое решение состояло бы в том, чтобы скопировать сценарий в удаленный сервер и выполнить его оттуда:
scp myscript.sh root@server:/tmp && ssh root@server /tmp/myscript.sh
Если бы копирование не является опцией по любой причине, я изменил бы сценарий, чтобы сначала соединить и проверить если $1
установлен, затем повторно подключите и установите по мере необходимости:
OUT=$(ssh root@server rpm -qa | grep "$1");
if [ "$OUT" != "" ] ; then
echo "$1 already installed"
else
read -p "Package $1 is not installed. Do you want to install it (y/n)?" choice
if [ "$choice" -eq "y" ]; then
ssh root@server yum install "$1"
fi
fi
$OUT=$(ssh root@server rpm -qa | grep "$1");
выходы и затем 2-е соединение займут столько же времени сколько первое.Я неправ?
– terdon♦
10.11.2013, 22:18
ssh -M foo.example.com sleep 99999999
или ssh -M foo.example.com read <somefifo
как ведущее устройство и уничтожают его явно (с kill
или echo done >somefifo
) когда Вы сделаны.
– Gilles 'SO- stop being evil'
10.11.2013, 22:30
Вот хорошее объяснение.
Таким образом, я адаптировал сценарий к
hostname
echo -n "Make your choice :"
read choice
echo "You typed " ${choice}
echo done
и это не работало.
таким образом, я переместил сценарий в удаленное для предотвращения локального перенаправления на ssh. (Мои команды находятся в файле, названном f),
cat f | ssh user@remotehost.com 'cat >remf'
ssh user@remotehost bash remf
Это работало. Вот вывод:
christian@clafujiu:~/tmp$ ssh localhost bash tmp/f
christian@localhost's password:
Linux clafujiu 2.6.32-52-generic #114-Ubuntu SMP Wed Sep 11 19:00:15 UTC 2013 i686 GNU/Linux
Sun Nov 10 14:58:56 GMT 2013
Make your choice :abc
You typed abc
done
Поскольку @terdon упомянул, что исходное содержание должно было запустить локальные скрипты удаленно, удаленная копия может быть автоматизирована, это - всего один пример все на одной строке.
REMID=`cat f |ssh user@remotehost 'cat > remf_$$; echo $$'` ;ssh root@redtoadservices.com "bash remf_${REMID} ; rm -v remf_${REMID}"
bash -s < script.sh
как OP сделал? Вы могли включать объяснение в свой ответ вместо того, чтобы связаться с ним?
– terdon♦
10.11.2013, 16:33
В прошлом я несколько раз искал решение этой проблемы, но так и не нашел полностью удовлетворительного решения. При подключении к ssh ваша интерактивность теряется. Два соединения (scp/ssh )медленнее, и ваш временный файл может остаться без дела. И весь скрипт в командной строке часто заканчивается адом.
Недавно я обнаружил, что размер буфера командной строки обычно довольно велик ('getconf ARG _MAX > 2MB, где я смотрел ). И это заставило меня задуматься о том, как я мог бы использовать это и смягчить проблему побега.
Результат:
ssh -t <host> /bin/bash "<(echo "$(cat my_script | base64 | tr -d '\n')" | base64 --decode)" <arg1>...
или используя здесь документ и кошку:
ssh -t <host> /bin/bash $'<(cat<<_ | base64 --decode\n'$(cat my_script | base64)$'\n_\n)' <arg1>...
Я расширил эту идею, чтобы создать полностью работающий пример сценария BASH sshx
, который может запускать произвольные сценарии (, а не только BASH ), где аргументы могут быть также локальными входными файлами через ssh. См. здесь .
your script
, при сохранении преимуществ синтаксиса Вы использовали в своем ответе? Используяssh -t yourserver "$(<your_script --some_arg)"
просто результаты вbash: --some_arg: command not found
. – sampablokuper 02.01.2018, 20:50ssh ... $(<script) script_arg1 script_arg2 ...
– Mat 02.01.2018, 22:13