summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSven Eden <yamakuzure@gmx.net>2017-08-30 07:47:40 +0200
committerSven Eden <yamakuzure@gmx.net>2017-08-30 07:47:40 +0200
commitdf846cfdf1109116d0bd67149f349f1d36de7e57 (patch)
tree44e4db4fcab9ad0bce25bcc1c46ca84b576591a3 /src
parent03539feb5202c9503c7dfb6faf4156accff0121c (diff)
Prep v235: optimize elogind extra startup functionality
Diffstat (limited to 'src')
-rw-r--r--src/login/elogind.c123
-rw-r--r--src/login/elogind.h6
-rw-r--r--src/login/logind.c21
3 files changed, 115 insertions, 35 deletions
diff --git a/src/login/elogind.c b/src/login/elogind.c
index 73e2a52b3..0dace0eff 100644
--- a/src/login/elogind.c
+++ b/src/login/elogind.c
@@ -25,6 +25,7 @@
#include "fileio.h"
#include "fs-util.h"
#include "mount-setup.h"
+#include "parse-util.h"
#include "process-util.h"
#include "socket-util.h"
#include "stdio-util.h"
@@ -44,13 +45,33 @@ static void remove_pid_file(void) {
}
-/* daemonize elogind by double forking.
- The grand child returns 0.
- The parent and child return their forks PID.
- On error, a value < 0 is returned.
-*/
-int elogind_daemonize(void) {
+static void write_pid_file(void) {
char c[DECIMAL_STR_MAX(pid_t) + 2];
+ pid_t pid;
+ int r;
+
+ pid = getpid_cached();
+
+ xsprintf(c, PID_FMT "\n", pid);
+
+ r = write_string_file(ELOGIND_PID_FILE, c,
+ WRITE_STRING_FILE_CREATE |
+ WRITE_STRING_FILE_VERIFY_ON_FAILURE);
+ if (r < 0)
+ log_error_errno(-r, "Failed to write PID file %s: %m",
+ ELOGIND_PID_FILE);
+
+ /* Make sure the PID file gets cleaned up on exit! */
+ atexit(remove_pid_file);
+}
+
+
+/** daemonize elogind by double forking.
+ * The grand child returns 0.
+ * The parent and child return their forks PID.
+ * On error, a value < 0 is returned.
+**/
+static int elogind_daemonize(void) {
pid_t child;
pid_t grandchild;
pid_t SID;
@@ -92,19 +113,37 @@ int elogind_daemonize(void) {
umask(0022);
/* Take care of our PID-file now */
- grandchild = getpid_cached();
+ write_pid_file();
- xsprintf(c, PID_FMT "\n", grandchild);
+ return 0;
+}
+
+
+/// Simple tool to see, if elogind is already running
+static pid_t elogind_is_already_running(void) {
+ _cleanup_free_ char *s = NULL;
+ pid_t pid;
+ int r;
+
+ r = read_one_line_file(ELOGIND_PID_FILE, &s);
- r = write_string_file(ELOGIND_PID_FILE, c,
- WRITE_STRING_FILE_CREATE |
- WRITE_STRING_FILE_VERIFY_ON_FAILURE);
if (r < 0)
- log_error_errno(-r, "Failed to write PID file %s: %m",
- ELOGIND_PID_FILE);
+ goto we_are_alone;
- /* Make sure the PID file gets cleaned up on exit! */
- atexit(remove_pid_file);
+ r = safe_atoi32(s, &pid);
+
+ if (r < 0)
+ goto we_are_alone;
+
+ if ( (pid != getpid_cached()) && pid_is_alive(pid))
+ return pid;
+
+we_are_alone:
+
+ /* Take care of our PID-file now.
+ If the user is going to fork elogind, the PID file
+ will be overwritten. */
+ write_pid_file();
return 0;
}
@@ -138,6 +177,7 @@ static int manager_dispatch_cgroups_agent_fd(sd_event_source *source, int fd, ui
return 0;
}
+
/// Add-On for manager_connect_bus()
/// Original: src/core/manager.c:manager_setup_cgroups_agent()
int elogind_setup_cgroups_agent(Manager *m) {
@@ -216,6 +256,57 @@ int elogind_setup_cgroups_agent(Manager *m) {
return 0;
}
+
+/** Extra functionality at startup, exclusive to elogind
+ * return < 0 on error, exit with failure.
+ * return = 0 on success, continue normal operation.
+ * return > 0 if elogind is already running or forked, exit with success.
+**/
+int elogind_startup(int argc, char *argv[]) {
+ bool daemonize = false;
+ pid_t pid;
+ int r = 0;
+ bool show_help = false;
+ bool wrong_arg = false;
+
+ /* add a -h/--help and a -d/--daemon argument. */
+ if ( (argc == 2) && argv[1] && strlen(argv[1]) ) {
+ if ( streq(argv[1], "-D") || streq(argv[1], "--daemon") )
+ daemonize = true;
+ else if ( streq(argv[1], "-h") || streq(argv[1], "--help") ) {
+ show_help = true;
+ r = 1;
+ } else
+ wrong_arg = true;
+ } else if (argc > 2)
+ wrong_arg = true;
+
+ /* try to get some meaningful output in case of an error */
+ if (wrong_arg) {
+ fprintf(stderr, "ERROR: Unknown arguments\n");
+ show_help = true;
+ r = -EINVAL;
+ }
+ if (show_help) {
+ fprintf(stderr, "%s [<-D|--daemon>|<-h|--help>]\n", argv[0]);
+ return r;
+ }
+
+ /* Do not continue if elogind is already running */
+ pid = elogind_is_already_running();
+ if (pid) {
+ fprintf(stderr, "elogind is already running:" PID_FMT "\n", pid);
+ return pid;
+ }
+
+ /* elogind allows to be daemonized using one argument "-D" / "--daemon" */
+ if (daemonize)
+ r = elogind_daemonize();
+
+ return r;
+}
+
+
/// Add-On for manager_free()
void elogind_manager_free(Manager* m) {
@@ -233,6 +324,7 @@ void elogind_manager_free(Manager* m) {
strv_free(m->hybrid_sleep_state);
}
+
/// Add-On for manager_new()
int elogind_manager_new(Manager* m) {
int r = 0;
@@ -263,6 +355,7 @@ int elogind_manager_new(Manager* m) {
return r;
}
+
/// Add-On for manager_reset_config()
void elogind_manager_reset_config(Manager* m) {
diff --git a/src/login/elogind.h b/src/login/elogind.h
index 637f564e9..7f11a150a 100644
--- a/src/login/elogind.h
+++ b/src/login/elogind.h
@@ -26,12 +26,12 @@
#include "sd-bus.h"
-/// Add-On for main() to daemonize elogind upon request with a double fork
-int elogind_daemonize(void);
-
/// Add-On for manager_connect_bus()
int elogind_setup_cgroups_agent(Manager *m);
+/// elogind has some extra functionality at startup, as it is not hooked into systemd.
+int elogind_startup(int argc, char *argv[]);
+
/// Add-On for manager_free()
void elogind_manager_free(Manager* m);
diff --git a/src/login/logind.c b/src/login/logind.c
index 5cc118ae9..996be1e47 100644
--- a/src/login/logind.c
+++ b/src/login/logind.c
@@ -1281,23 +1281,10 @@ int main(int argc, char *argv[]) {
umask(0022);
-#if 1 /// elogind allows to be daemonized using one argument "-D" / "--daemon"
- if (argc == 2) {
-
- if (!argv[1] || (0 == strlen(argv[1]))
- || ( !streq(argv[1], "-D")
- && !streq(argv[1], "--daemon") ) ) {
- fprintf(stderr, "%s [-D|--daemon]\n", argv[0]);
- r = -EINVAL;
- goto finish;
- }
-
- r = elogind_daemonize();
- if (r)
- return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;;
-
- argc = 1; /* Use the rest of main() as usual */
- }
+#if 1 /// elogind has some extra functionality at startup.
+ r = elogind_startup(argc, argv);
+ if (r)
+ return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
#endif // 1
if (argc != 1) {