Browse Source

Reorder elogind startup to utilize new upstream utilities

Signed-off-by: Sven Eden <sven.eden@prydeworx.com>
suites/experimental upstream/v246.0_rc2
Sven Eden 1 year ago
parent
commit
0d5291182a
  1. 70
      src/login/elogind.c
  2. 5
      src/login/elogind.h
  3. 38
      src/login/logind.c
  4. 20
      src/shared/service-util.c
  5. 4
      src/shared/service-util.h

70
src/login/elogind.c

@ -107,19 +107,21 @@ static void write_pid_file( void ) {
* The parent and child return their forks PID.
* On error, a value < 0 is returned.
**/
static int elogind_daemonize( void ) {
int elogind_daemonize( void ) {
pid_t child;
pid_t grandchild;
pid_t SID;
int r;
log_debug_elogind("Double forking elogind");
log_set_target(LOG_TARGET_CONSOLE);
log_set_open_when_needed(true);
log_debug_elogind("%s", "Double forking elogind");
log_debug_elogind("Parent PID : %5d", getpid_cached());
log_debug_elogind("Parent SID : %5d", getsid(getpid_cached()));
r = safe_fork( "elogind-forker", FORK_LOG | FORK_WAIT | FORK_REOPEN_LOG | FORK_CLOSE_ALL_FDS | FORK_NULL_STDIO, &child );
#if ENABLE_DEBUG_ELOGIND
if ( r ) {
log_debug_elogind("Fork 1 returned: %5d", r);
log_debug_elogind("Fork child PID : %5d", child);
@ -127,7 +129,6 @@ static int elogind_daemonize( void ) {
log_debug_elogind("Child PID : %5d", getpid_cached());
log_debug_elogind("Child SID : %5d", getsid(getpid_cached()));
}
#endif // ENABLE_DEBUG_ELOGIND
if ( r < 0 )
return log_error_errno( r, "Failed to fork daemon leader: %m" );
@ -150,7 +151,6 @@ static int elogind_daemonize( void ) {
/* Now the grandchild, the true daemon, can be created. */
r = safe_fork( "elogind-daemon", FORK_LOG | FORK_REOPEN_LOG | FORK_CLOSE_ALL_FDS | FORK_RESET_SIGNALS, &grandchild );
#if ENABLE_DEBUG_ELOGIND
if ( r ) {
log_debug_elogind("Fork 2 returned: %5d", r);
log_debug_elogind("Grandchild PID : %5d", grandchild);
@ -158,7 +158,6 @@ static int elogind_daemonize( void ) {
log_debug_elogind("Grand child PID: %5d", getpid_cached());
log_debug_elogind("Grand child SID: %5d", getsid(getpid_cached()));
}
#endif // ENABLE_DEBUG_ELOGIND
if ( r < 0 )
return log_error_errno( r, "Failed to fork daemon: %m" );
@ -172,12 +171,14 @@ static int elogind_daemonize( void ) {
/* Take care of our PID-file now */
write_pid_file();
log_set_target(LOG_TARGET_AUTO);
return 0;
}
/// Simple tool to see, if elogind is already running
static pid_t elogind_is_already_running( bool need_pid_file ) {
static pid_t elogind_is_already_running( void ) {
_cleanup_free_ char* s = NULL, * comm = NULL;
pid_t pid;
int r;
@ -209,8 +210,7 @@ static pid_t elogind_is_already_running( bool need_pid_file ) {
/* Take care of our PID-file now.
If the user is going to fork elogind, the PID file
will be overwritten. */
if ( need_pid_file )
write_pid_file();
write_pid_file();
return 0;
}
@ -327,64 +327,20 @@ int elogind_setup_cgroups_agent( Manager* m ) {
/** 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.
* return > 0 if elogind is already running, exit with success.
**/
int elogind_startup( int argc, char* argv[] ) {
bool daemonize = false;
int elogind_startup(void) {
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;
log_set_target(LOG_TARGET_CONSOLE);
log_set_open_when_needed(true);
log_debug_elogind("elogind startup: Daemonize: %s, Show Help: %s, Wrong arg: %s",
daemonize ? "True" : "False",
show_help ? "True" : "False",
wrong_arg ? "True" : "False");
/* try to get some meaningful output in case of an error */
if ( wrong_arg ) {
log_error( "Unknown arguments" );
show_help = true;
r = -EINVAL;
}
if ( show_help ) {
log_info( "%s [<-D|--daemon>|<-h|--help>]", basename( argv[0] ) );
return r;
}
/* Do not continue if elogind is already running */
pid = elogind_is_already_running( !daemonize );
pid = elogind_is_already_running( );
if ( pid ) {
log_error( "elogind is already running as PID "
PID_FMT, pid);
return pid;
}
/* elogind allows to be daemonized using one argument "-D" / "--daemon" */
if ( daemonize ) {
r = elogind_daemonize();
if ( r < 0 )
return log_error_errno( r, "Failed to daemonozie: %m" );
}
log_set_target(LOG_TARGET_AUTO);
return r;
return 0;
}

5
src/login/elogind.h

@ -30,8 +30,11 @@
/// Add-On for manager_connect_bus()
int elogind_setup_cgroups_agent(Manager *m);
/// daemonize elogind by double forking
int elogind_daemonize( void );
/// elogind has some extra functionality at startup, as it is not hooked into systemd.
int elogind_startup(int argc, char *argv[]);
int elogind_startup(void);
/// Add-On for manager_free()
void elogind_manager_free(Manager* m);

38
src/login/logind.c

@ -1216,21 +1216,19 @@ static int run(int argc, char *argv[]) {
_cleanup_(manager_unrefp) Manager *m = NULL;
int r;
#if 1 /// perform extra checks for elogind startup
r = elogind_startup(argc, argv);
if (r)
return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
#endif // 1
elogind_set_program_name(argv[0]);
log_set_facility(LOG_AUTH);
log_setup_service();
#if ENABLE_DEBUG_ELOGIND
log_set_max_level(LOG_DEBUG);
log_set_target(LOG_TARGET_SYSLOG_OR_KMSG);
#endif // ENABLE_DEBUG_ELOGIND
log_setup_service();
r = service_parse_argv("elogind.service",
#if 0 /// This is elogind
r = service_parse_argv("systemd-logind.service",
#else // 0
r = service_parse_argv("elogind",
#endif // 0
"Manager for user logins and devices and privileged operations.",
BUS_IMPLEMENTATIONS(&manager_object,
&log_control_object),
@ -1238,16 +1236,38 @@ static int run(int argc, char *argv[]) {
if (r <= 0)
return r;
#if 1 /// perform extra checks for elogind startup
r = elogind_startup();
if (r)
return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
/* elogind allows to daemonize itself via -D/--daemon argument */
if ( daemonize ) {
r = elogind_daemonize();
if ( r < 0 )
return log_error_errno( r, "Failed to daemonozie: %m" );
if ( r > 0 )
return EXIT_SUCCESS;
// Re-setup logging
log_set_facility(LOG_AUTH);
log_setup_service();
#if ENABLE_DEBUG_ELOGIND
log_set_max_level(LOG_DEBUG);
log_set_target(LOG_TARGET_SYSLOG_OR_KMSG);
#endif // ENABLE_DEBUG_ELOGIND
}
#endif // 1
umask(0022);
r = mac_selinux_init();
if (r < 0)
return r;
#if 0 /// elogind can not rely on systemd to help, so we need a bit more effort than this
/* Always create the directories people can create inotify watches in. Note that some applications might check
* for the existence of /run/systemd/seats/ to determine whether logind is available, so please always make
* sure these directories are created early on and unconditionally. */
#if 0 /// elogind can not rely on systemd to help, so we need a bit more effort than this
(void) mkdir_label("/run/systemd/seats", 0755);
(void) mkdir_label("/run/systemd/users", 0755);
(void) mkdir_label("/run/systemd/sessions", 0755);

20
src/shared/service-util.c

@ -9,6 +9,10 @@
#include "terminal-util.h"
#include "util.h"
#if 1 /// NEEDED by elogogind
bool daemonize = false;
#endif // 1
static int help(const char *program_path, const char *service, const char *description, bool bus_introspect) {
_cleanup_free_ char *link = NULL;
int r;
@ -21,6 +25,9 @@ static int help(const char *program_path, const char *service, const char *descr
"%s%s%s\n\n"
"This program takes no positional arguments.\n\n"
"%sOptions%s:\n"
#if 1 /// elogind allows to be daemonized
" -D --daemon Daemonize as a background service\n"
#endif // 1
" -h --help Show this help\n"
" --version Show package version\n"
" --bus-introspect=PATH Write D-Bus XML introspection data\n"
@ -46,6 +53,9 @@ int service_parse_argv(
};
static const struct option options[] = {
#if 1 /// elogind allows to be daemonized
{ "daemon", no_argument, NULL, 'D' },
#endif // 1
{ "help", no_argument, NULL, 'h' },
{ "version", no_argument, NULL, ARG_VERSION },
{ "bus-introspect", required_argument, NULL, ARG_BUS_INTROSPECT },
@ -57,9 +67,19 @@ int service_parse_argv(
assert(argc >= 0);
assert(argv);
#if 0 /// Add options for elogind
while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0)
#else // 0
while ((c = getopt_long(argc, argv, "Dh", options, NULL)) >= 0)
#endif // 0
switch(c) {
#if 1 /// elogind allows to be daemonized
case 'D':
daemonize = true;
break;
#endif // 1
case 'h':
return help(argv[0], service, description, bus_objects);

4
src/shared/service-util.h

@ -3,6 +3,10 @@
#include "bus-object.h"
#if 1 /// NEEDED by elogogind
extern bool daemonize;
#endif // 1
int service_parse_argv(
const char *service,
const char *description,

Loading…
Cancel
Save