5. [`--tal`](#--tal)
6. [`--local-repository`](#--local-repository)
7. [`--work-offline`](#--work-offline)
- 8. [`--shuffle-uris`](#--shuffle-uris)
- 9. [`--maximum-certificate-depth`](#--maximum-certificate-depth)
- 10. [`--mode`](#--mode)
- 11. [`--server.address`](#--serveraddress)
- 12. [`--server.port`](#--serverport)
- 13. [`--server.backlog`](#--serverbacklog)
- 14. [`--server.interval.validation`](#--serverintervalvalidation)
- 15. [`--server.interval.refresh`](#--serverintervalrefresh)
- 16. [`--server.interval.retry`](#--serverintervalretry)
- 17. [`--server.interval.expire`](#--serverintervalexpire)
- 18. [`--slurm`](#--slurm)
- 19. [`--log.enabled`](#--logenabled)
- 20. [`--log.level`](#--loglevel)
- 21. [`--log.output`](#--logoutput)
- 22. [`--log.color-output`](#--logcolor-output)
- 23. [`--log.file-name-format`](#--logfile-name-format)
- 24. [`--log.facility`](#--logfacility)
- 25. [`--log.tag`](#--logtag)
- 26. [`--validation-log.enabled`](#--validation-logenabled)
- 27. [`--validation-log.level`](#--validation-loglevel)
- 28. [`--validation-log.output`](#--validation-logoutput)
- 29. [`--validation-log.color-output`](#--validation-logcolor-output)
- 30. [`--validation-log.file-name-format`](#--validation-logfile-name-format)
- 31. [`--validation-log.facility`](#--validation-logfacility)
- 32. [`--validation-log.tag`](#--validation-logtag)
- 33. [`--http.enabled`](#--httpenabled)
- 34. [`--http.priority`](#--httppriority)
- 35. [`--http.retry.count`](#--httpretrycount)
- 36. [`--http.retry.interval`](#--httpretryinterval)
- 37. [`--http.user-agent`](#--httpuser-agent)
- 38. [`--http.connect-timeout`](#--httpconnect-timeout)
- 39. [`--http.transfer-timeout`](#--httptransfer-timeout)
- 40. [`--http.idle-timeout`](#--httpidle-timeout)
- 41. [`--http.ca-path`](#--httpca-path)
- 42. [`--output.roa`](#--outputroa)
- 43. [`--output.bgpsec`](#--outputbgpsec)
- 44. [`--asn1-decode-max-stack`](#--asn1-decode-max-stack)
- 45. [`--stale-repository-period`](#--stale-repository-period)
- 46. [`--rsync.enabled`](#--rsyncenabled)
- 47. [`--rsync.priority`](#--rsyncpriority)
- 48. [`--rsync.strategy`](#--rsyncstrategy)
+ 8. [`--daemon`](#--daemon)
+ 9. [`--shuffle-uris`](#--shuffle-uris)
+ 10. [`--maximum-certificate-depth`](#--maximum-certificate-depth)
+ 11. [`--mode`](#--mode)
+ 12. [`--server.address`](#--serveraddress)
+ 13. [`--server.port`](#--serverport)
+ 14. [`--server.backlog`](#--serverbacklog)
+ 15. [`--server.interval.validation`](#--serverintervalvalidation)
+ 16. [`--server.interval.refresh`](#--serverintervalrefresh)
+ 17. [`--server.interval.retry`](#--serverintervalretry)
+ 18. [`--server.interval.expire`](#--serverintervalexpire)
+ 19. [`--slurm`](#--slurm)
+ 20. [`--log.enabled`](#--logenabled)
+ 21. [`--log.level`](#--loglevel)
+ 22. [`--log.output`](#--logoutput)
+ 23. [`--log.color-output`](#--logcolor-output)
+ 24. [`--log.file-name-format`](#--logfile-name-format)
+ 25. [`--log.facility`](#--logfacility)
+ 26. [`--log.tag`](#--logtag)
+ 27. [`--validation-log.enabled`](#--validation-logenabled)
+ 28. [`--validation-log.level`](#--validation-loglevel)
+ 29. [`--validation-log.output`](#--validation-logoutput)
+ 30. [`--validation-log.color-output`](#--validation-logcolor-output)
+ 31. [`--validation-log.file-name-format`](#--validation-logfile-name-format)
+ 32. [`--validation-log.facility`](#--validation-logfacility)
+ 33. [`--validation-log.tag`](#--validation-logtag)
+ 34. [`--http.enabled`](#--httpenabled)
+ 35. [`--http.priority`](#--httppriority)
+ 36. [`--http.retry.count`](#--httpretrycount)
+ 37. [`--http.retry.interval`](#--httpretryinterval)
+ 38. [`--http.user-agent`](#--httpuser-agent)
+ 39. [`--http.connect-timeout`](#--httpconnect-timeout)
+ 40. [`--http.transfer-timeout`](#--httptransfer-timeout)
+ 41. [`--http.idle-timeout`](#--httpidle-timeout)
+ 42. [`--http.ca-path`](#--httpca-path)
+ 43. [`--output.roa`](#--outputroa)
+ 44. [`--output.bgpsec`](#--outputbgpsec)
+ 45. [`--asn1-decode-max-stack`](#--asn1-decode-max-stack)
+ 46. [`--stale-repository-period`](#--stale-repository-period)
+ 47. [`--rsync.enabled`](#--rsyncenabled)
+ 48. [`--rsync.priority`](#--rsyncpriority)
+ 49. [`--rsync.strategy`](#--rsyncstrategy)
1. [`strict`](#strict)
2. [`root`](#root)
3. [`root-except-ta`](#root-except-ta)
- 49. [`--rsync.retry.count`](#--rsyncretrycount)
- 50. [`--rsync.retry.interval`](#--rsyncretryinterval)
- 51. [`--configuration-file`](#--configuration-file)
- 52. [`rsync.program`](#rsyncprogram)
- 53. [`rsync.arguments-recursive`](#rsyncarguments-recursive)
- 54. [`rsync.arguments-flat`](#rsyncarguments-flat)
- 55. [`incidences`](#incidences)
- 56. [`init-locations`](#init-locations)
+ 50. [`--rsync.retry.count`](#--rsyncretrycount)
+ 51. [`--rsync.retry.interval`](#--rsyncretryinterval)
+ 52. [`--configuration-file`](#--configuration-file)
+ 53. [`rsync.program`](#rsyncprogram)
+ 54. [`rsync.arguments-recursive`](#rsyncarguments-recursive)
+ 55. [`rsync.arguments-flat`](#rsyncarguments-flat)
+ 56. [`incidences`](#incidences)
+ 57. [`init-locations`](#init-locations)
3. [Deprecated arguments](#deprecated-arguments)
1. [`--sync-strategy`](#--sync-strategy)
2. [`--rrdp.enabled`](#--rrdpenabled)
[--local-repository=<directory>]
[--sync-strategy=off|strict|root|root-except-ta]
[--work-offline]
+ [--daemon]
[--shuffle-uris]
[--maximum-certificate-depth=<unsigned integer>]
[--asn1-decode-max-stack=<unsigned integer>]
Otherwise, Fort will perform outgoing requests whenever this is needed. If a specific protocol needs to be deactivated, use [`--rsync.enabled`](#--rsyncenabled) or [`--http.enabled`](#--httpenabled).
+### `--daemon`
+
+- **Type:** None
+- **Availability:** `argv` and JSON
+
+If this flag is activated, Fort will run as a daemon. The process is detached from the calling terminal and sent to the background.
+
+All the enabled logs will be sent to syslog, so the configured values of [`--log.output`](#--logoutput) and [`--validation-log.output`](#--validation-logoutput) will be ignored.
+
### `--shuffle-uris`
- **Type:** None
"<a href="#--maximum-certificate-depth">maximum-certificate-depth</a>": 32,
"<a href="#--slurm">slurm</a>": "/tmp/fort/test.slurm",
"<a href="#--mode">mode</a>": "server",
+ "<a href="#--daemon">daemon</a>": false,
"server": {
"<a href="#--serveraddress">address</a>": "127.0.0.1",
#include "common.h"
#include "configure_ac.h"
+#include "daemon.h"
#include "file.h"
#include "init.h"
#include "json_handler.h"
* 'true' uses only local files located at local-repository.
*/
bool work_offline;
+ /*
+ * Run fort as a daemon.
+ */
+ bool daemon;
struct {
/** The bound listening address of the RTR server. */
.type = >_work_offline,
.offset = offsetof(struct rpki_config, work_offline),
.doc = "Disable all outgoing requests (rsync, http (implies RRDP)) and work only with local repository files.",
+ }, {
+ .id = 1006,
+ .name = "daemon",
+ .type = >_bool,
+ .offset = offsetof(struct rpki_config, daemon),
+ .doc = "Run fort as a daemon.",
},
/* Server fields */
rpki_config.maximum_certificate_depth = 32;
rpki_config.mode = SERVER;
rpki_config.work_offline = false;
+ rpki_config.daemon = false;
rpki_config.rsync.enabled = true;
rpki_config.rsync.priority = 50;
exit(error);
}
+ if (rpki_config.daemon) {
+ pr_op_warn("Executing as daemon, all logs will be sent to syslog.");
+ /* Send all logs to syslog */
+ rpki_config.log.output = SYSLOG;
+ rpki_config.validation_log.output = SYSLOG;
+ error = daemonize(log_start);
+ goto end;
+ }
+
log_start();
end:
if (error) {
--- /dev/null
+#include "daemon.h"
+
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <errno.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include "log.h"
+
+/*
+ * Daemonize fort execution. The function "daemon()" from unistd header isn't
+ * utilized since isn't standardized (too bad).
+ *
+ * The logs must be sent to syslog before this call, the @log_cb is called to
+ * initialize logging after the first fork() call.
+ *
+ * This function exits on any error once the first fork is successfully done.
+ */
+int
+daemonize(daemon_log_cb log_cb)
+{
+ char *pwd;
+ pid_t pid;
+ long int fds;
+
+ /* Already a daemon, just return */
+ if (getppid() == 1)
+ return 0;
+
+ /* Get the working dir, the daemon will use (and free) it later */
+ pwd = getcwd(NULL, 0);
+ if (pwd == NULL)
+ return pr_enomem();
+
+ pid = fork();
+ if (pid < 0)
+ return pr_op_errno(errno, "Couldn't fork to daemonize");
+
+ /* Terminate parent */
+ if (pid > 0)
+ exit(0);
+
+ /* Activate logs */
+ log_cb();
+
+ /* Child goes on from here */
+ if (setsid() < 0) {
+ pr_op_errno(errno,
+ "Couldn't create new session, ending execution");
+ exit(errno);
+ }
+
+ /*
+ * Ignore SIGHUP. SIGCHLD isn't ignored since we still do a fork to
+ * execute rsync; when that's not the case then:
+ * signal(SIGCHLD, SIG_IGN);
+ */
+ signal(SIGHUP, SIG_IGN);
+
+ /* Assure this is not a session leader */
+ pid = fork();
+ if (pid < 0) {
+ pr_op_errno(errno,
+ "Couldn't fork again to daemonize, ending execution");
+ exit(errno);
+ }
+
+ /* Terminate parent */
+ if (pid > 0)
+ exit(0);
+
+ /* Close all descriptors, getdtablesize() isn't portable */
+ fds = sysconf(_SC_OPEN_MAX);
+ while (fds >= 0) {
+ close(fds);
+ fds--;
+ }
+
+ /* No privileges revoked to create files/dirs */
+ umask(0);
+
+ if (chdir(pwd) < 0) {
+ pr_op_errno(errno,
+ "Couldn't chdir() of daemon, ending execution");
+ exit(errno);
+ }
+
+ free(pwd);
+ return 0;
+}