Oppure

Loading
17/09/18 21:09
Roby94
Sera a tutti,
mi trovo per la prima volta a dover sviluppare un demone per un server Ubuntu, mi sto rifacendo a diversa documentazione online, ma non trovo nulla di completo, in ogni caso sono riuscito ad arrivare al punto di avere un processo in background che esegue un loop. Ora rimane la delicata questione della terminazione del processo. Da quel che ho capito i demoni vengono terminati attraverso la funzione kill, generalmente invocata da uno script in bash conoscendo il PID del processo. Arriviamo ora ai dubbi, primo, qual'è il metodo piu sicuro per trovare il PID del demone, generalmente da terminale sfrutto il comando ps con una ricerca filtrata attraverso grep, ma lo trovo un metodo piuttosto insicuro, dato che potrei incappare in processi ononimi, guardando alcuni script dalla cartella init.d mi pare di capire che all'avvio del programma venga salvato il pid in un file, è giusta questa osservazione? In tal caso come posso fare? Attualmente genero il processo demone con il comando fork() direttamente in C++.
Secondo dubbio, se è vero che devo usare il comando kill per terminare il processo demone rischio che questo sia terminato durante un operazione non sicura, come minimo necessiterei di terminare la scrittura di alcuni file e del log. La mia speranza era che la terminazione attraverso kill generasse un eccezione, cosi da poterla intercettare all'interno del loop e terminare il processo in sicurezza, ma questo non sembra vero, mi potreste indirizzare verso la strategia migliore?
Lascio lo snippet di codice finora realizzato, vi accorgerete che è per lo piu copiato, ma non credo di avere dubbi sulla parte scritta.
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <syslog.h>
#include <string.h>

void running();

int main(void) {
	pid_t pid, sid;
	
	pid = fork();
	
	openlog("testdaemon", LOG_PID, LOG_USER);
	
	if (pid < 0) {
		syslog(LOG_ERR,"The parent wasn't able to create the child and it terminated");
		exit(EXIT_FAILURE);
	}
	
	if (pid > 0) {
		syslog(LOG_INFO,"The parent created the child and it terminated");
		exit(EXIT_SUCCESS);
	}

	umask(0);       
	
			
	sid = setsid();
	if (sid < 0) {
		syslog(LOG_ERR,"The child wasn't able to create a SID and it terminated");
		exit(EXIT_FAILURE);
	}
	
	if ((chdir("/")) < 0) {
		syslog(LOG_ERR,"The child wasn't able to move in the root and it terminated");
		exit(EXIT_FAILURE);
	}
	
	close(STDIN_FILENO);
	close(STDOUT_FILENO);
	close(STDERR_FILENO);
	
	running();
}


void running()
{
	try {
		while(1) {
			sleep(30);
		}
	} catch(...) {
		syslog(LOG_ERR,"exception");
	}
}

Grazie
aaa
17/09/18 21:42
TheDarkJuster
Io non conosco l'argomento, ma ti consiglio di guardare come funziona systemctl. Di esempi ne trovi: github.com/jirihnidek/… e comincerei da quelli.

Poi ti trovi a poter fare: systemctl start mioservizio per avviarlo. Systemctl enable mioservizio per l'autostart. Systemctl stop mioservizio se ben ricordo genera un evento catturabile....
aaa
17/09/18 21:43
TheDarkJuster
Io non conosco l'argomento, ma ti consiglio di guardare come funziona systemctl. Di esempi ne trovi: github.com/jirihnidek/… e comincerei da quelli.

Poi ti trovi a poter fare: systemctl start mioservizio per avviarlo. Systemctl enable mioservizio per l'autostart. Systemctl stop mioservizio se ben ricordo genera un evento catturabile....
aaa
17/09/18 22:03
Roby94
Grazie mille TheDarkJuster, il progetto che mi hai passato sembra veramente fatto bene e soprattutto ordinato a differenza dei normali script che si trovano in init.d (ovviamente ne capisco il motivo)
Inizio a studiarmelo; ora mi piacerebbe capirci di più a livello teorico, vedrò di cercare delle dispense sul sytemctl. Se qualcun altro ha qualche articolo/guida/libro sull'argomento mi farebbe un grande favore nel condividerlo.
aaa
17/09/18 22:25
TheDarkJuster
Scusa il doppio post, problemi con il mobile.

Comunque ho visto che l'esempio cattura un SIGINT, mi sembra un modo ragionevole di sapere quando spegnersi.

Il main del processo da un fork come avevi fatto tu, quindi se hai già del codice pronto non dovrebbe essere difficile adattarlo.

Non ho libri o altro da consigliarti, ma vedo che comunque l'esempio scrive su sysloge gestisce gli eventi principali.

Io ti consiglio di dare qualche occhiata a servizi famosi, giusto per vedere come sono fatti quelli più usati in ubuntu, distribuiti con apt e conformarti agli standard.
aaa
17/09/18 22:45
Roby94
Postato originariamente da TheDarkJuster:

Comunque ho visto che l'esempio cattura un SIGINT, mi sembra un modo ragionevole di sapere quando spegnersi.

Era la direzione che avevo preso, quindi niente kill ma un signal per terminare il processo, che effettivamente mi pare un ottimo modo, alla fine mi basta bloccarlo nelle sezioni "critiche"
Postato originariamente da TheDarkJuster:
Il main del processo da un fork come avevi fatto tu, quindi se hai già del codice pronto non dovrebbe essere difficile adattarlo.

Effettivamente il codice è identico, lo prendo come un buon metodo allora.
Non sono ancora convinto al 100% che quella parte mi convinca, ma è un ottima base, sono abbastanza sicuro che alla fine sarò io adattarmi a lei e non il contrario :asd:

Inizio cosi e al massimo vediamo in un secondo momento se qualcosa puo essere scritto "meglio"

Grazie mille per l'aiuto
Ultima modifica effettuata da Roby94 18/09/18 10:21
aaa
19/09/18 1:30
pierotofy
Se ti serve una guida completa: apuebook.com/…
Il mio blog: piero.dev