LINUX.ORG.RU

Сигналы от не-root'а


0

1

Есть демон, который управляется сигналами SIGUSR1 и SIGUSR2. Как сделать, чтобы не-root смог отправлять эти сигналы (кроме установки SUID-аттрибута)?

P.S. Отправлять сигналы можно без kill: сама программа (которая демонизируется при запуске с определённым параметром) может отправлять нужный сигнал демону (при запуске с другими параметрами). Ставить SUID на саму программу тоже не хочется.


Ответ на: комментарий от no-dashi

Либо бинарник с suid

Если бы тема была в разделе Development, то можно было бы ещё посоветовать POSIX Capabilities.

Deleted
()

очевидно же

CAP_KILL

x0r ★★★★★
()
Ответ на: комментарий от toady2

>В частности, мой демон открывает /dev/console.

Ну и?

chmod g+rw /dev/console

chgrp console_group /dev/console

и запускай демон от пользователя, входящего в группу console_group

Led ★★★☆☆
()

Переделать управление демоном на FIFO и не заморачиваться с сигналами. Если не выйдет переделать основной, можно еще один демон влепить.

segfault ★★★★★
()
Ответ на: комментарий от segfault

Переделать управление демоном на FIFO и не заморачиваться с сигналами.

А что лучше для управления демоном — сокеты или fifo? Под управлением я понимаю отсылку демону команд (которые он немедленно обрабатывает). Демон бОльшую часть времени не работает, а тупо простаивает в памяти. Хочется минимизировать его затраты системных ресурсов.

Хочу, чтобы управлять демоном мог управлять не-root.

toady2
() автор топика
Ответ на: комментарий от toady2

Объясню подробнее. Демон — мигалка светодиодом. Управление заключается в включении/выключении мигания. Мигание происходит внутри демона в цикле. Сигналы были хороши тем, что при их появлении программа сразу обрабатовала мой обработчик сигнала (он состоит в изменении глобальной булевой переменной blink), потом шло возвращение в цикл; он имеет вид типа

while (!stop) {
  if (blink)
    led_toogle();
  sleep(1);
}

Если использовать для управления fifo: демон открывает на чтение fifo файл, начинает читать — она останавливается до тех пор, пока в этот файл не начнут что-то писать. Когда начнут, демон читает записанное, что-то делает и снова пытается читать fifo файл, ожидая записи в него. Я так понял? Тогда проблема — как мне (при определённой команде в fifo файле) запустить (теоретически бесконечный; фактически — до команды остановки мигания) цикл мигания светодиодов?

toady2
() автор топика
Ответ на: комментарий от toady2

> А что лучше для управления демоном — сокеты или fifo?

И то, и другое куда лучше, чем сигналы - я такую задачу решал через FIFO, заодно стало возможным управление из баша (echo «something» > fifo_name). С не-IP сокетами не разбирался.

segfault ★★★★★
()
Ответ на: комментарий от segfault

Да, мне тоже очень понравилась идея с FIFO. Но только непонятно, как одновременно ожидать записи в FIFO-файл и крутить цикл, который мигает диодами. С сигналами это получалось само собой.

toady2
() автор топика
Ответ на: комментарий от toady2

> открывает на чтение fifo файл, начинает читать — она останавливается до тех пор, пока в этот файл не начнут что-то писать.

http://linux.die.net/man/2/select (Если язык - Си)

В общем, вот урезанный код моего демона, управляемого FIFO (Си). Может быть, будет полезным:

char pipe_addr[] = "/var/...";

int main(int argc, char** arg)
{
	//Создание FIFO
	mkfifo(pipe_addr, 0777);
	chmod(pipe_addr, 0777);
	int fd = open(pipe_addr, O_RDONLY | O_NONBLOCK);
	if(!fd) _die("Error opening pipe");

	//Форкаемся, оставляем чайлд фоновым, выходим
	int forkres = fork();
	if(forkres == -1) _die("fork() failed");
	else if(forkres) return 0;

	int active = 0; //0=ждем сигнала, 1=работаем
	int main_sleep = 30; //секунд

	fd_set descriptorSet;
	struct timeval timer;
	while(1){
		void *_timer = NULL;
		if(active){
			//Ставим таймер
			timer.tv_sec = main_sleep;
			timer.tv_usec = 0;
			_timer = &timer;
		}

		FD_ZERO (&descriptorSet);
		FD_SET (fd, &descriptorSet);
		if(select (fd + 1, &descriptorSet, NULL, NULL, _timer) == 0){
			//выход по таймеру, обрабатываем действия
			// ** здесь был код **
			continue;
		}

		if(!read(fd, &recvChar, 1)){
			//FIFO был закрыт - переоткрываем
			close(fd);
			fd = open(pipe_addr, O_RDONLY | O_NONBLOCK);
			if(!fd) _die("Error opening pipe");
			continue;
		}

		// ** Код, обрабатывающий значение считанного "recvChar" **
	}

	return 0;
}

Это нечто тоже основное время простаивает, выполняет периодические действия. И да, в моем варианте принимаемые команды - однобуквенные.

segfault ★★★★★
()
Ответ на: комментарий от segfault

Спасибо. Поправьте меня, пожалуйста, если я не так понял.

Суть моего демона я описал выше. Если я хочу мигать диодами с частотой 1Гц, то мне нужно выставить timer.tv_sec=0, timer.tv_usec=500000. Затем вызывать select: если в течении пол-секунд в fifo-файл кто-нибудь что-нибудь запишет, select остановится и вернёт >0; если же в fifo-файл данных не поступит, то через пол-секунды select сама завершиться и вернёт 0. Так?

Ещё вот, у меня есть какое-то потаённое тревожное чувство: все эти манипуляции примерно каждые пол-секунды будут повторяться впустую (демон мой 99% времени ничего не делает) — наверное это будет (пусть немного, но всё же) отъедать системные ресурсы (особ. процессор)? С сигналами-то проще было: когда мигание выключено я ставил sleep на 10 минут, а во время ожидания sleep'ом ресурсы вроде бы практически не тратятся. Есть смысл в моих опасениях?

toady2
() автор топика
Ответ на: комментарий от toady2

> Поправьте меня, пожалуйста, если я не так понял.

Все верно. Одна проблема - при попадании команды в FIFO, select завершится раньше, чем через полсекунды, и мигание собъется.

Ещё вот, у меня есть какое-то потаённое тревожное чувство: все эти манипуляции примерно каждые пол-секунды будут повторяться впустую (демон мой 99% времени ничего не делает)

Т.е. демон, по сути, должен быть в режиме ожидания? так я ж как раз для этого оставил переменную «active» - в случае, когда она ноль, вместо timeval в select передается NULL, и выход из нее по таймеру отключается как понятие - т.е. она будет ждать ввода через FIFO хоть вечность.

segfault ★★★★★
()
Ответ на: комментарий от toady2

А в принципе, что мешает в этом случае менять интервал ожидания в зависимости от состояния демона?

segfault ★★★★★
()
Ответ на: комментарий от segfault

Т.е. демон, по сути, должен быть в режиме ожидания?

Да, он висит в памяти и ничего не трогает до тех пор, пока ему не скажут «мигай!». Потом скажут «хватит!» и он опять пошёл спать.

так я ж как раз для этого оставил переменную «active» - в случае, когда она ноль, вместо timeval в select передается NULL, и выход из нее по таймеру отключается как понятие - т.е. она будет ждать ввода через FIFO хоть вечность.

Супер! Спасибо. То есть при загрузке ставим active=0 и демон просто ждёт записи в fifo-файл. Записали команду, которая включает мигание: ставим active 0 и далее происходит то, что я описал в предыдущем посте. При команде «хватит!» снова ставится active=0. Так?

Ожидание данных в fifo-файле, как я понимаю, процессора не ест почти (так же как ожидание sleep)?

toady2
() автор топика
Ответ на: комментарий от toady2

s/мигание: ставим active 0/мигание: ставим active 1/

toady2
() автор топика
Ответ на: комментарий от toady2

Да, верно.

Ожидание данных в fifo-файле, как я понимаю, процессора не ест почти

Оно его вообще не ест, как и sleep. Кроме, разве что, моментов постановки и снятия с ожидания.

segfault ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.