diff options
author | Tollef Fog Heen <tfheen@err.no> | 2010-06-05 08:03:15 +0200 |
---|---|---|
committer | Tollef Fog Heen <tfheen@err.no> | 2010-06-05 08:03:15 +0200 |
commit | 6aa3df795bcccabab9ff82d8ff8a00cb7b39049b (patch) | |
tree | cbc682e3d83cc2a6761a6c3e3a58cfe84cdbeff1 | |
parent | 68fd55f23f1d6d4357a654224a0c1f3457302179 (diff) | |
parent | dfd8eeed3911ce1a4ffc51b9c444f3f18d545040 (diff) | |
download | systemd-6aa3df795bcccabab9ff82d8ff8a00cb7b39049b.tar.gz |
Merge remote branch 'origin/master'
70 files changed, 729 insertions, 284 deletions
diff --git a/Makefile.am b/Makefile.am index 53f485e05b..a1c08364d9 100644 --- a/Makefile.am +++ b/Makefile.am @@ -17,13 +17,20 @@ ACLOCAL_AMFLAGS = -I m4 +# Dirs of external packages dbuspolicydir=$(sysconfdir)/dbus-1/system.d udevrulesdir=@udevrulesdir@ +interfacedir=$(datadir)/dbus-1/interfaces +# Our own, non-special dirs pkgsysconfdir=$(sysconfdir)/systemd -systemunitdir=$(pkgdatadir)/system sessionunitdir=$(pkgdatadir)/session -interfacedir=$(datadir)/dbus-1/interfaces + +# And these are the special ones for / +rootdir=@rootdir@ +rootbindir=$(rootdir)/bin +rootlibexecdir=$(rootdir)/lib/systemd +systemunitdir=$(rootdir)/lib/systemd/system AM_CPPFLAGS = \ -include $(top_builddir)/config.h \ @@ -33,22 +40,20 @@ AM_CPPFLAGS = \ -DSYSTEM_SYSVRCND_PATH=\"$(SYSTEM_SYSVRCND_PATH)\" \ -DSESSION_CONFIG_UNIT_PATH=\"$(pkgsysconfdir)/session\" \ -DSESSION_DATA_UNIT_PATH=\"$(sessionunitdir)\" \ - -DCGROUP_AGENT_PATH=\"$(pkglibexecdir)/systemd-cgroups-agent\" \ - -DSYSTEMD_BINARY_PATH=\"$(sbindir)/systemd\" \ + -DCGROUP_AGENT_PATH=\"$(rootlibexecdir)/systemd-cgroups-agent\" \ + -DSYSTEMD_BINARY_PATH=\"$(rootbindir)/systemd\" \ -I $(top_srcdir)/src -sbin_PROGRAMS = \ - systemd - -bin_PROGRAMS = \ +rootbin_PROGRAMS = \ + systemd \ systemctl if HAVE_GTK -bin_PROGRAMS += \ +bin_PROGRAMS = \ systemadm endif -pkglibexec_PROGRAMS = \ +rootlibexec_PROGRAMS = \ systemd-logger \ systemd-cgroups-agent \ systemd-initctl @@ -82,6 +87,7 @@ interface_DATA = \ dist_systemunit_DATA = \ units/emergency.service \ + units/basic.target \ units/getty.target \ units/halt.target \ units/local-fs.target \ @@ -106,8 +112,6 @@ dist_systemunit_DATA = \ units/dev-mqueue.mount \ units/proc-sys-fs-binfmt_misc.automount \ units/proc-sys-fs-binfmt_misc.mount \ - units/sys-fs-fuse-connections.automount \ - units/sys-fs-fuse-connections.mount \ units/sys-kernel-debug.automount \ units/sys-kernel-debug.mount \ units/sys-kernel-security.automount \ @@ -116,7 +120,7 @@ dist_systemunit_DATA = \ units/var-run.mount systemunit_DATA = \ - units/basic.target \ + units/sysinit.target \ units/getty@.service \ units/graphical.target \ units/multi-user.target \ @@ -132,7 +136,7 @@ sessionunit_DATA = \ units/session/exit.service EXTRA_DIST = \ - units/basic.target.m4 \ + units/sysinit.target.m4 \ units/getty@.service.m4 \ units/graphical.target.m4 \ units/multi-user.target.m4 \ @@ -163,6 +167,13 @@ dist_systemunit_DATA += \ units/debian/reboot.service endif +if TARGET_SUSE +dist_systemunit_DATA += \ + units/suse/halt.service \ + units/suse/poweroff.service \ + units/suse/reboot.service +endif + if TARGET_GENTOO dist_systemunit_DATA += \ units/gentoo/halt.service \ @@ -285,7 +296,7 @@ test_engine_LDADD = $(systemd_LDADD) test_job_type_SOURCES = \ $(COMMON_SOURCES) \ - src/test-engine.c + src/test-job-type.c test_job_type_CPPFLAGS = $(systemd_CPPFLAGS) test_job_type_LDADD = $(systemd_LDADD) @@ -365,11 +376,10 @@ systemadm_LDADD = $(DBUSGLIB_LIBS) $(GTK_LIBS) SED_PROCESS = \ $(AM_V_GEN)$(MKDIR_P) $(dir $@) && \ - $(SED) -e 's,@libexecdir\@,$(libexecdir),g' \ - -e 's,@pkglibexecdir\@,$(pkglibexecdir),g' \ + $(SED) -e 's,@rootlibexecdir\@,$(rootlibexecdir),g' \ -e 's,@SPECIAL_SYSLOG_SERVICE\@,$(SPECIAL_SYSLOG_SERVICE),g' \ -e 's,@SPECIAL_DBUS_SERVICE\@,$(SPECIAL_DBUS_SERVICE),g' \ - -e 's,@SYSTEMCTL\@,$(bindir)/systemctl,g' \ + -e 's,@SYSTEMCTL\@,$(rootbindir)/systemctl,g' \ < $< > $@ units/%: units/%.in Makefile @@ -396,7 +406,7 @@ CLEANFILES = \ units/systemd-initctl.service \ units/systemd-logger.service \ units/syslog.target \ - units/basic.target \ + units/sysinit.target \ units/getty@.service \ units/graphical.target \ units/multi-user.target \ @@ -468,7 +478,7 @@ install-data-hook: $(DESTDIR)$(systemunitdir) \ $(DESTDIR)$(sessionunitdir) \ $(DESTDIR)$(systemunitdir)/sockets.target.wants \ - $(DESTDIR)$(systemunitdir)/basic.target.wants \ + $(DESTDIR)$(systemunitdir)/sysinit.target.wants \ $(DESTDIR)$(pkgsysconfdir)/system \ $(DESTDIR)$(pkgsysconfdir)/system/getty.target.wants \ $(DESTDIR)$(pkgsysconfdir)/system/multi-user.target.wants \ @@ -486,10 +496,10 @@ install-data-hook: $(LN_S) ../systemd-initctl.socket systemd-initctl.socket ) ( cd $(DESTDIR)$(sessionunitdir) && \ rm -f shutdown.target sockets.target local-fs.target swap.target && \ - $(LN_S) ../system/shutdown.target shutdown.target && \ - $(LN_S) ../system/sockets.target sockets.target && \ - $(LN_S) ../system/local-fs.target local-fs.target && \ - $(LN_S) ../system/swap.target swap.target ) + $(LN_S) $(systemunitdir)/shutdown.target shutdown.target && \ + $(LN_S) $(systemunitdir)/sockets.target sockets.target && \ + $(LN_S) $(systemunitdir)/local-fs.target local-fs.target && \ + $(LN_S) $(systemunitdir)/swap.target swap.target ) ( cd $(DESTDIR)$(systemunitdir) && \ rm -f runlevel0.target runlevel1.target runlevel6.target && \ $(LN_S) poweroff.target runlevel0.target && \ @@ -514,21 +524,20 @@ install-data-hook: $(LN_S) $(systemunitdir)/getty@.service getty@tty5.service && \ $(LN_S) $(systemunitdir)/getty@.service getty@tty6.service ) ( cd $(DESTDIR)$(pkgsysconfdir)/system/multi-user.target.wants && \ - rm -f getty.target && \ - $(LN_S) $(systemunitdir)/getty.target getty.target ) - ( cd $(DESTDIR)$(systemunitdir)/basic.target.wants && \ + rm -f getty.target remote-fs.target && \ + $(LN_S) $(systemunitdir)/getty.target getty.target && \ + $(LN_S) $(systemunitdir)/remote-fs.target remote-fs.target ) + ( cd $(DESTDIR)$(systemunitdir)/sysinit.target.wants && \ rm -f dev-hugepages.automount \ dev-mqueue.automount \ proc-sys-fs-binfmt_misc.automount \ sys-kernel-debug.automount \ - sys-fs-fuse-connections.automount \ sys-kernel-security.automount && \ $(LN_S) ../dev-hugepages.automount dev-hugepages.automount && \ $(LN_S) ../dev-mqueue.automount dev-mqueue.automount && \ $(LN_S) ../proc-sys-fs-binfmt_misc.automount proc-sys-fs-binfmt_misc.automount && \ $(LN_S) ../sys-kernel-debug.automount sys-kernel-debug.automount && \ - $(LN_S) ../sys-kernel-security.automount sys-kernel-security.automount && \ - $(LN_S) ../sys-fs-fuse-connections.automount sys-fs-fuse-connections.automount ) + $(LN_S) ../sys-kernel-security.automount sys-kernel-security.automount ) if TARGET_FEDORA ( cd $(DESTDIR)$(pkgsysconfdir)/system && \ rm -f display-manager.service && \ @@ -555,4 +564,5 @@ if TARGET_GENTOO endif DISTCHECK_CONFIGURE_FLAGS = \ - --with-udevrulesdir=$$dc_install_base/$(udevrulesdir) + --with-udevrulesdir=$$dc_install_base/$(udevrulesdir) \ + --with-rootdir=$$dc_install_base/$(rootdir) diff --git a/bootstrap.sh b/bootstrap.sh index cb87bf782c..f59a8156bf 100755 --- a/bootstrap.sh +++ b/bootstrap.sh @@ -65,7 +65,7 @@ else run_versioned automake "$AM_VERSION" --copy --foreign --add-missing if [ "x$1" != "xac" ]; then - CFLAGS="$CFLAGS -g -O0" ./configure --sysconfdir=/etc --localstatedir=/var "$@" + CFLAGS="$CFLAGS -g -O0" ./configure --sysconfdir=/etc --localstatedir=/var --with-rootdir= "$@" make clean fi fi diff --git a/configure.ac b/configure.ac index ffdedeedff..af20151fbb 100644 --- a/configure.ac +++ b/configure.ac @@ -269,7 +269,14 @@ AC_ARG_WITH([udevrulesdir], [with_udevrulesdir=/lib/udev/rules.d]) AC_SUBST([udevrulesdir], [$with_udevrulesdir]) -AC_OUTPUT([Makefile]) +AC_ARG_WITH([rootdir], + AS_HELP_STRING([--with-rootdir=DIR], [Root directory for files necessary for boot]), + [], + [with_rootdir=${ac_default_prefix}]) +AC_SUBST([rootdir], [$with_rootdir]) + +AC_CONFIG_FILES([Makefile]) +AC_OUTPUT echo " $PACKAGE_NAME $VERSION @@ -280,5 +287,7 @@ echo " Syslog service: ${SPECIAL_SYSLOG_SERVICE} D-Bus service: ${SPECIAL_DBUS_SERVICE} Gtk: ${have_gtk} + prefix: ${prefix} + root dir: ${with_rootdir} udev rules dir: ${with_udevrulesdir} " @@ -64,6 +64,8 @@ * tcpwrap +* use setproctitle() when forking, before exec() (waiting for (PR_SET_PROCTITLE_AREA to enter the kernel) + Regularly: * look for close() vs. close_nointr() vs. close_nointr_nofail() diff --git a/man/systemd.special.xml.in b/man/systemd.special.xml.in index 1d9c1326b4..a2e1bb2cbd 100644 --- a/man/systemd.special.xml.in +++ b/man/systemd.special.xml.in @@ -80,6 +80,7 @@ <filename>sigpwr.target</filename>, <filename>sockets.target</filename>, <filename>swap.target</filename>, + <filename>sysinit.target</filename>, <filename>syslog.target</filename>, <filename>@SPECIAL_SYSLOG_SERVICE@</filename>, <filename>systemd-initctl.service</filename>, @@ -111,16 +112,15 @@ target unit to all SysV service units configured for runlevel 1 to 5.</para> - <para>systemd automatically - adds dependencies of the types - Wants and After for all - SysV service units configured - for runlevels that are not 0 - to 6 to this target unit. - This covers the special - boot-up runlevels some - distributions have, such as S - or b.</para> + <para>Usually this should pull + in all sockets, mount points, + swap devices and other basic + initialization necessary for + the general purpose + daemons. Most normal daemon + should have dependencies of + type After and Requires on + this unit.</para> </listitem> </varlistentry> <varlistentry> @@ -587,6 +587,23 @@ </listitem> </varlistentry> <varlistentry> + <term><filename>sysinit.target</filename></term> + <listitem> + <para>A special target unit + covering early boot-up scripts.</para> + <para>systemd automatically + adds dependencies of the types + Wants and After for all + SysV service units configured + for runlevels that are not 0 + to 6 to this target unit. + This covers the special + boot-up runlevels some + distributions have, such as S + or b.</para> + </listitem> + </varlistentry> + <varlistentry> <term><filename>@SPECIAL_SYSLOG_SERVICE@</filename></term> <listitem> <para>A special unit for the diff --git a/src/dbus-manager.c b/src/dbus-manager.c index 6a323019fe..c80b22b9e6 100644 --- a/src/dbus-manager.c +++ b/src/dbus-manager.c @@ -36,6 +36,26 @@ " <arg name=\"name\" type=\"s\" direction=\"in\"/>\n" \ " <arg name=\"unit\" type=\"o\" direction=\"out\"/>\n" \ " </method>\n" \ + " <method name=\"StartUnit\">\n" \ + " <arg name=\"name\" type=\"s\" direction=\"in\"/>\n" \ + " <arg name=\"mode\" type=\"s\" direction=\"in\"/>\n" \ + " <arg name=\"job\" type=\"o\" direction=\"out\"/>\n" \ + " </method>\n" \ + " <method name=\"StopUnit\">\n" \ + " <arg name=\"name\" type=\"s\" direction=\"in\"/>\n" \ + " <arg name=\"mode\" type=\"s\" direction=\"in\"/>\n" \ + " <arg name=\"job\" type=\"o\" direction=\"out\"/>\n" \ + " </method>\n" \ + " <method name=\"ReloadUnit\">\n" \ + " <arg name=\"name\" type=\"s\" direction=\"in\"/>\n" \ + " <arg name=\"mode\" type=\"s\" direction=\"in\"/>\n" \ + " <arg name=\"job\" type=\"o\" direction=\"out\"/>\n" \ + " </method>\n" \ + " <method name=\"RestartUnit\">\n" \ + " <arg name=\"name\" type=\"s\" direction=\"in\"/>\n" \ + " <arg name=\"mode\" type=\"s\" direction=\"in\"/>\n" \ + " <arg name=\"job\" type=\"o\" direction=\"out\"/>\n" \ + " </method>\n" \ " <method name=\"GetJob\">\n" \ " <arg name=\"id\" type=\"u\" direction=\"in\"/>\n" \ " <arg name=\"job\" type=\"o\" direction=\"out\"/>\n" \ @@ -184,6 +204,7 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection DBusError error; DBusMessage *reply = NULL; char * path = NULL; + JobType job_type = _JOB_TYPE_INVALID; assert(connection); assert(message); @@ -248,7 +269,15 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection DBUS_TYPE_INVALID)) goto oom; - } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "GetJob")) { + } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "StartUnit")) + job_type = JOB_START; + else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "StopUnit")) + job_type = JOB_STOP; + else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "ReloadUnit")) + job_type = JOB_RELOAD; + else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "RestartUnit")) + job_type = JOB_RESTART; + else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "GetJob")) { uint32_t id; Job *j; @@ -297,7 +326,7 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection HASHMAP_FOREACH_KEY(u, k, m->units, i) { char *u_path, *j_path; - const char *description, *load_state, *active_state, *sub_state, *job_type; + const char *description, *load_state, *active_state, *sub_state, *sjob_type; DBusMessageIter sub2; uint32_t job_id; @@ -323,11 +352,11 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection goto oom; } - job_type = job_type_to_string(u->meta.job->type); + sjob_type = job_type_to_string(u->meta.job->type); } else { job_id = 0; j_path = u_path; - job_type = ""; + sjob_type = ""; } if (!dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &u->meta.id) || @@ -337,7 +366,7 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &sub_state) || !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_OBJECT_PATH, &u_path) || !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_UINT32, &job_id) || - !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &job_type) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &sjob_type) || !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_OBJECT_PATH, &j_path)) { free(u_path); if (u->meta.job) @@ -636,6 +665,46 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection } else return bus_default_message_handler(m, message, NULL, properties); + + if (job_type != _JOB_TYPE_INVALID) { + const char *name, *smode; + JobMode mode; + Job *j; + Unit *u; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_STRING, &smode, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(m, message, &error, -EINVAL); + + if ((mode = job_mode_from_string(smode)) == _JOB_MODE_INVALID) + return bus_send_error_reply(m, message, NULL, -EINVAL); + + if ((r = manager_load_unit(m, name, NULL, &u)) < 0) + return bus_send_error_reply(m, message, NULL, r); + + if (job_type == JOB_START && u->meta.only_by_dependency) + return bus_send_error_reply(m, message, NULL, -EPERM); + + if ((r = manager_add_job(m, job_type, u, mode, true, &j)) < 0) + return bus_send_error_reply(m, message, NULL, r); + + if (!(reply = dbus_message_new_method_return(message))) + goto oom; + + if (!(path = job_dbus_path(j))) + goto oom; + + if (!dbus_message_append_args( + reply, + DBUS_TYPE_OBJECT_PATH, &path, + DBUS_TYPE_INVALID)) + goto oom; + } + free(path); if (reply) { diff --git a/src/dbus-unit.c b/src/dbus-unit.c index 87218cd2ee..8e35377dc5 100644 --- a/src/dbus-unit.c +++ b/src/dbus-unit.c @@ -260,6 +260,7 @@ static DBusHandlerResult bus_unit_message_dispatch(Unit *u, DBusMessage *message Manager *m = u->meta.manager; DBusError error; JobType job_type = _JOB_TYPE_INVALID; + char *path = NULL; dbus_error_init(&error); @@ -281,7 +282,6 @@ static DBusHandlerResult bus_unit_message_dispatch(Unit *u, DBusMessage *message JobMode mode; Job *j; int r; - char *path; if (job_type == JOB_START && u->meta.only_by_dependency) return bus_send_error_reply(m, message, NULL, -EPERM); @@ -312,6 +312,8 @@ static DBusHandlerResult bus_unit_message_dispatch(Unit *u, DBusMessage *message goto oom; } + free(path); + if (reply) { if (!dbus_connection_send(m->api_bus, reply, NULL)) goto oom; @@ -322,6 +324,8 @@ static DBusHandlerResult bus_unit_message_dispatch(Unit *u, DBusMessage *message return DBUS_HANDLER_RESULT_HANDLED; oom: + free(path); + if (reply) dbus_message_unref(reply); diff --git a/src/dbus.c b/src/dbus.c index f5bbc5815a..7e6d65e2c8 100644 --- a/src/dbus.c +++ b/src/dbus.c @@ -65,6 +65,8 @@ const char *const bus_interface_table[] = { NULL }; +static const char *error_to_dbus(int error); + static void api_bus_dispatch_status(DBusConnection *bus, DBusDispatchStatus status, void *data) { Manager *m = data; @@ -333,6 +335,7 @@ static void bus_toggle_timeout(DBusTimeout *timeout, void *data) { static DBusHandlerResult api_bus_message_filter(DBusConnection *connection, DBusMessage *message, void *data) { Manager *m = data; DBusError error; + DBusMessage *reply = NULL; assert(connection); assert(message); @@ -370,10 +373,67 @@ static DBusHandlerResult api_bus_message_filter(DBusConnection *connection, DBu manager_dispatch_bus_name_owner_changed(m, name, old_owner, new_owner); } + } else if (dbus_message_is_signal(message, "org.freedesktop.systemd1.Activator", "ActivationRequest")) { + const char *name; + + if (!dbus_message_get_args(message, &error, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_INVALID)) + log_error("Failed to parse ActivationRequest message: %s", error.message); + else { + int r; + Unit *u; + + log_debug("Got D-Bus activation request for %s", name); + + r = manager_load_unit(m, name, NULL, &u); + + if (r >= 0 && u->meta.only_by_dependency) + r = -EPERM; + + if (r >= 0) + r = manager_add_job(m, JOB_START, u, JOB_REPLACE, true, NULL); + + if (r < 0) { + const char *id, *text; + + if (!(reply = dbus_message_new_signal("/org/freedesktop/systemd1", "org.freedesktop.systemd1.Activator", "ActivationFailure"))) + goto oom; + + id = error_to_dbus(r); + text = strerror(-r); + + if (!dbus_message_set_destination(reply, DBUS_SERVICE_DBUS) || + !dbus_message_append_args(reply, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_STRING, &id, + DBUS_TYPE_STRING, &text, + DBUS_TYPE_INVALID)) + goto oom; + } + + /* On success we don't do anything, the service will be spwaned now */ + } } dbus_error_free(&error); + + if (reply) { + if (!dbus_connection_send(connection, reply, NULL)) + goto oom; + + dbus_message_unref(reply); + } + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + +oom: + if (reply) + dbus_message_unref(reply); + + dbus_error_free(&error); + + return DBUS_HANDLER_RESULT_NEED_MEMORY; } static DBusHandlerResult system_bus_message_filter(DBusConnection *connection, DBusMessage *message, void *data) { @@ -531,6 +591,95 @@ oom: return -ENOMEM; } +static void query_name_list_pending_cb(DBusPendingCall *pending, void *userdata) { + DBusMessage *reply; + DBusError error; + Manager *m = userdata; + + assert(m); + + dbus_error_init(&error); + + assert_se(reply = dbus_pending_call_steal_reply(pending)); + + switch (dbus_message_get_type(reply)) { + + case DBUS_MESSAGE_TYPE_ERROR: + + assert_se(dbus_set_error_from_message(&error, reply)); + log_warning("ListNames() failed: %s", error.message); + break; + + case DBUS_MESSAGE_TYPE_METHOD_RETURN: { + int r; + char **l; + + if ((r = bus_parse_strv(reply, &l)) < 0) + log_warning("Failed to parse ListNames() reply: %s", strerror(-r)); + else { + char **t; + + STRV_FOREACH(t, l) + /* This is a bit hacky, we say the + * owner of the name is the name + * itself, because we don't want the + * extra traffic to figure out the + * real owner. */ + manager_dispatch_bus_name_owner_changed(m, *t, NULL, *t); + + strv_free(l); + } + + break; + } + + default: + assert_not_reached("Invalid reply message"); + } + + dbus_message_unref(reply); + dbus_error_free(&error); +} + +static int query_name_list(Manager *m) { + DBusMessage *message = NULL; + DBusPendingCall *pending = NULL; + + /* Asks for the currently installed bus names */ + + if (!(message = dbus_message_new_method_call( + DBUS_SERVICE_DBUS, + DBUS_PATH_DBUS, + DBUS_INTERFACE_DBUS, + "ListNames"))) + goto oom; + + if (!dbus_connection_send_with_reply(m->api_bus, message, &pending, -1)) + goto oom; + + if (!dbus_pending_call_set_notify(pending, query_name_list_pending_cb, m, NULL)) + goto oom; + + dbus_message_unref(message); + dbus_pending_call_unref(pending); + + /* We simple ask for the list and don't wait for it. Sooner or + * later we'll get it. */ + + return 0; + +oom: + if (pending) { + dbus_pending_call_cancel(pending); + dbus_pending_call_unref(pending); + } + + if (message) + dbus_message_unref(message); + + return -ENOMEM; +} + static int bus_setup_loop(Manager *m, DBusConnection *bus) { assert(m); assert(bus); @@ -642,6 +791,7 @@ int bus_init_api(Manager *m) { return -ENOMEM; } + /* Get NameOwnerChange messages */ dbus_bus_add_match(m->api_bus, "type='signal'," "sender='"DBUS_SERVICE_DBUS"'," @@ -656,11 +806,31 @@ int bus_init_api(Manager *m) { return -ENOMEM; } + /* Get activation requests */ + dbus_bus_add_match(m->api_bus, + "type='signal'," + "sender='"DBUS_SERVICE_DBUS"'," + "interface='org.freedesktop.systemd1.Activator'," + "path='"DBUS_PATH_DBUS"'", + &error); + + if (dbus_error_is_set(&error)) { + log_error("Failed to register match: %s", error.message); + dbus_error_free(&error); + bus_done_api(m); + return -ENOMEM; + } + if ((r = request_name(m)) < 0) { bus_done_api(m); return r; } + if ((r = query_name_list(m)) < 0) { + bus_done_api(m); + return r; + } + log_debug("Successfully connected to API D-Bus bus %s as %s", strnull((id = dbus_connection_get_server_id(m->api_bus))), strnull(dbus_bus_get_unique_name(m->api_bus))); diff --git a/src/hostname-setup.c b/src/hostname-setup.c index 3b988d4c8b..e9f722e622 100644 --- a/src/hostname-setup.c +++ b/src/hostname-setup.c @@ -52,7 +52,8 @@ static char* strip_bad_chars(char *s) { (*p >= 'A' && *p <= 'Z') || (*p >= '0' && *p <= '9') || *p == '-' || - *p == '_') + *p == '_' || + *p == '.') *(d++) = *p; *d = 0; diff --git a/src/initctl.c b/src/initctl.c index 407d32d93f..9872437aa9 100644 --- a/src/initctl.c +++ b/src/initctl.c @@ -96,7 +96,7 @@ static void change_runlevel(Server *s, int runlevel) { const char *target; DBusMessage *m = NULL, *reply = NULL; DBusError error; - const char *path, *replace = "isolate"; + const char *replace = "replace"; assert(s); @@ -109,44 +109,19 @@ static void change_runlevel(Server *s, int runlevel) { log_debug("Running request %s", target); - if (!(m = dbus_message_new_method_call("org.freedesktop.systemd1", "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "LoadUnit"))) { + if (!(m = dbus_message_new_method_call("org.freedesktop.systemd1", "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "StartUnit"))) { log_error("Could not allocate message."); goto finish; } if (!dbus_message_append_args(m, DBUS_TYPE_STRING, &target, - DBUS_TYPE_INVALID)) { - log_error("Could not attach group information to signal message."); - goto finish; - } - - if (!(reply = dbus_connection_send_with_reply_and_block(s->bus, m, -1, &error))) { - log_error("Failed to get unit path: %s", error.message); - goto finish; - } - - if (!dbus_message_get_args(reply, &error, - DBUS_TYPE_OBJECT_PATH, &path, - DBUS_TYPE_INVALID)) { - log_error("Failed to parse unit path: %s", error.message); - goto finish; - } - - dbus_message_unref(m); - if (!(m = dbus_message_new_method_call("org.freedesktop.systemd1", path, "org.freedesktop.systemd1.Unit", "Start"))) { - log_error("Could not allocate message."); - goto finish; - } - - if (!dbus_message_append_args(m, DBUS_TYPE_STRING, &replace, DBUS_TYPE_INVALID)) { - log_error("Could not attach group information to signal message."); + log_error("Could not attach target and flag information to signal message."); goto finish; } - dbus_message_unref(reply); if (!(reply = dbus_connection_send_with_reply_and_block(s->bus, m, -1, &error))) { log_error("Failed to start unit: %s", error.message); goto finish; diff --git a/src/load-fragment.c b/src/load-fragment.c index a706880b9a..5f5e37397b 100644 --- a/src/load-fragment.c +++ b/src/load-fragment.c @@ -1366,7 +1366,7 @@ static int load_from_path(Unit *u, const char *path) { { "Environment", config_parse_strv, &(context).environment, section }, \ { "StandardInput", config_parse_input, &(context).std_input, section }, \ { "StandardOutput", config_parse_output, &(context).std_output, section }, \ - { "StandardError", config_parse_output, &(context).std_output, section }, \ + { "StandardError", config_parse_output, &(context).std_error, section }, \ { "TTYPath", config_parse_path, &(context).tty_path, section }, \ { "SyslogIdentifier", config_parse_string, &(context).syslog_identifier, section }, \ { "SyslogFacility", config_parse_facility, &(context).syslog_priority, section }, \ @@ -357,6 +357,27 @@ static int log_dispatch( return r; } +int log_dump_internal( + int level, + const char*file, + int line, + const char *func, + char *buffer) { + + int saved_errno, r; + + /* This modifies the buffer... */ + + if (_likely_(LOG_PRI(level) > log_max_level)) + return 0; + + saved_errno = errno; + r = log_dispatch(level, file, line, func, buffer); + errno = saved_errno; + + return r; +} + int log_meta( int level, const char*file, @@ -368,7 +389,7 @@ int log_meta( int saved_errno, r; va_list ap; - if (_likely(LOG_PRI(level) > log_max_level)) + if (_likely_(LOG_PRI(level) > log_max_level)) return 0; saved_errno = errno; @@ -59,13 +59,21 @@ int log_meta( const char*file, int line, const char *func, - const char *format, ...) _printf_attr(5,6); + const char *format, ...) _printf_attr_(5,6); -_noreturn void log_assert( +_noreturn_ void log_assert( const char*file, int line, const char *func, - const char *format, ...) _printf_attr(4,5); + const char *format, ...) _printf_attr_(4,5); + +/* This modifies the buffer passed! */ +int log_dump_internal( + int level, + const char*file, + int line, + const char *func, + char *buffer); #define log_debug(...) log_meta(LOG_DEBUG, __FILE__, __LINE__, __func__, __VA_ARGS__) #define log_info(...) log_meta(LOG_INFO, __FILE__, __LINE__, __func__, __VA_ARGS__) @@ -73,6 +81,9 @@ _noreturn void log_assert( #define log_warning(...) log_meta(LOG_WARNING, __FILE__, __LINE__, __func__, __VA_ARGS__) #define log_error(...) log_meta(LOG_ERR, __FILE__, __LINE__, __func__, __VA_ARGS__) +/* This modifies the buffer passed! */ +#define log_dump(level, buffer) log_dump_internal(level, __FILE__, __LINE__, __func__, buffer) + const char *log_target_to_string(LogTarget target); LogTarget log_target_from_string(const char *s); diff --git a/src/macro.h b/src/macro.h index 622c08eeda..763a4de27a 100644 --- a/src/macro.h +++ b/src/macro.h @@ -25,19 +25,19 @@ #include <assert.h> #include <sys/types.h> -#define _printf_attr(a,b) __attribute__ ((format (printf, a, b))) -#define _sentinel __attribute__ ((sentinel)) -#define _noreturn __attribute__((noreturn)) -#define _unused __attribute__ ((unused)) -#define _destructor __attribute__ ((destructor)) -#define _pure __attribute__ ((pure)) -#define _const __attribute__ ((const)) -#define _deprecated __attribute__ ((deprecated)) -#define _packed __attribute__ ((packed)) -#define _malloc __attribute__ ((malloc)) -#define _weak __attribute__ ((weak)) -#define _likely(x) (__builtin_expect(!!(x),1)) -#define _unlikely(x) (__builtin_expect(!!(x),0)) +#define _printf_attr_(a,b) __attribute__ ((format (printf, a, b))) +#define _sentinel_ __attribute__ ((sentinel)) +#define _noreturn_ __attribute__((noreturn)) +#define _unused_ __attribute__ ((unused)) +#define _destructor_ __attribute__ ((destructor)) +#define _pure_ __attribute__ ((pure)) +#define _const_ __attribute__ ((const)) +#define _deprecated_ __attribute__ ((deprecated)) +#define _packed_ __attribute__ ((packed)) +#define _malloc_ __attribute__ ((malloc)) +#define _weak_ __attribute__ ((weak)) +#define _likely_(x) (__builtin_expect(!!(x),1)) +#define _unlikely_(x) (__builtin_expect(!!(x),0)) /* Rounds up */ static inline size_t ALIGN(size_t l) { @@ -70,7 +70,7 @@ static inline size_t ALIGN(size_t l) { #define assert_se(expr) \ do { \ - if (_unlikely(!(expr))) \ + if (_unlikely_(!(expr))) \ log_assert(__FILE__, __LINE__, __PRETTY_FUNCTION__, \ "Assertion '%s' failed at %s:%u, function %s(). Aborting.", \ #expr , __FILE__, __LINE__, __PRETTY_FUNCTION__); \ diff --git a/src/main.c b/src/main.c index 7a829cea5c..7c93f6d9c7 100644 --- a/src/main.c +++ b/src/main.c @@ -58,7 +58,7 @@ static int crash_chvt = -1; static bool confirm_spawn = false; static FILE* serialization = NULL; -_noreturn static void freeze(void) { +_noreturn_ static void freeze(void) { for (;;) pause(); } @@ -66,7 +66,7 @@ _noreturn static void freeze(void) { static void nop_handler(int sig) { } -_noreturn static void crash(int sig) { +_noreturn_ static void crash(int sig) { if (!dump_core) log_error("Caught <%s>, not dumping core.", strsignal(sig)); diff --git a/src/manager.c b/src/manager.c index 933dd5064f..38964939c3 100644 --- a/src/manager.c +++ b/src/manager.c @@ -548,6 +548,19 @@ static void manager_clear_jobs_and_units(Manager *m) { while ((u = hashmap_first(m->units))) unit_free(u); + + manager_dispatch_cleanup_queue(m); + + assert(!m->load_queue); + assert(!m->run_queue); + assert(!m->dbus_unit_queue); + assert(!m->dbus_job_queue); + assert(!m->cleanup_queue); + assert(!m->gc_queue); + + assert(hashmap_isempty(m->transaction_jobs)); + assert(hashmap_isempty(m->jobs)); + assert(hashmap_isempty(m->units)); } void manager_free(Manager *m) { @@ -555,7 +568,6 @@ void manager_free(Manager *m) { assert(m); - manager_dispatch_cleanup_queue(m); manager_clear_jobs_and_units(m); for (c = 0; c < _UNIT_TYPE_MAX; c++) @@ -625,9 +637,8 @@ int manager_coldplug(Manager *m) { if (u->meta.id != k) continue; - if (UNIT_VTABLE(u)->coldplug) - if ((q = UNIT_VTABLE(u)->coldplug(u)) < 0) - r = q; + if ((q = unit_coldplug(u)) < 0) + r = q; } return r; @@ -964,20 +975,25 @@ static int transaction_verify_order_one(Manager *m, Job *j, Job *from, unsigned /* Does a recursive sweep through the ordering graph, looking * for a cycle. If we find cycle we try to break it. */ - /* Did we find a cycle? */ - if (j->marker && j->generation == generation) { + /* Have we seen this before? */ + if (j->generation == generation) { Job *k; - /* So, we already have been here. We have a - * cycle. Let's try to break it. We go backwards in - * our path and try to find a suitable job to - * remove. We use the marker to find our way back, - * since smart how we are we stored our way back in - * there. */ + /* If the marker is NULL we have been here already and + * decided the job was loop-free from here. Hence + * shortcut things and return right-away. */ + if (!j->marker) + return 0; + /* So, the marker is not NULL and we already have been + * here. We have a cycle. Let's try to break it. We go + * backwards in our path and try to find a suitable + * job to remove. We use the marker to find our way + * back, since smart how we are we stored our way back + * in there. */ log_debug("Found ordering cycle on %s/%s", j->unit->meta.id, job_type_to_string(j->type)); - for (k = from; k; k = (k->generation == generation ? k->marker : NULL)) { + for (k = from; k; k = ((k->generation == generation && k->marker != k) ? k->marker : NULL)) { log_debug("Walked on cycle path to %s/%s", k->unit->meta.id, job_type_to_string(k->type)); @@ -1002,8 +1018,10 @@ static int transaction_verify_order_one(Manager *m, Job *j, Job *from, unsigned } /* Make the marker point to where we come from, so that we can - * find our way backwards if we want to break a cycle */ - j->marker = from; + * find our way backwards if we want to break a cycle. We use + * a special marker for the beginning: we point to + * ourselves. */ + j->marker = from ? from : j; j->generation = generation; /* We assume that the the dependencies are bidirectional, and @@ -1035,6 +1053,7 @@ static int transaction_verify_order(Manager *m, unsigned *generation) { Job *j; int r; Iterator i; + unsigned g; assert(m); assert(generation); @@ -1042,8 +1061,10 @@ static int transaction_verify_order(Manager *m, unsigned *generation) { /* Check if the ordering graph is cyclic. If it is, try to fix * that up by dropping one of the jobs. */ + g = (*generation)++; + HASHMAP_FOREACH(j, m->transaction_jobs, i) - if ((r = transaction_verify_order_one(m, j, NULL, (*generation)++)) < 0) + if ((r = transaction_verify_order_one(m, j, NULL, g)) < 0) return r; return 0; @@ -1882,10 +1903,32 @@ static int manager_process_signal_fd(Manager *m) { break; } - case SIGUSR2: - manager_dump_units(m, stdout, "\t"); - manager_dump_jobs(m, stdout, "\t"); + case SIGUSR2: { + FILE *f; + char *dump = NULL; + size_t size; + + if (!(f = open_memstream(&dump, &size))) { + log_warning("Failed to allocate memory stream."); + break; + } + + manager_dump_units(m, f, "\t"); + manager_dump_jobs(m, f, "\t"); + + if (ferror(f)) { + fclose(f); + free(dump); + log_warning("Failed to write status stream"); + break; + } + + fclose(f); + log_dump(LOG_INFO, dump); + free(dump); + break; + } case SIGHUP: m->exit_code = MANAGER_RELOAD; diff --git a/src/manager.h b/src/manager.h index 210e66053c..a2084e924b 100644 --- a/src/manager.h +++ b/src/manager.h @@ -108,6 +108,7 @@ struct Watch { #define SPECIAL_DISPLAY_MANAGER_SERVICE "display-manager.service" /* Debian's $x-display-manager */ #define SPECIAL_MAIL_TRANSFER_AGENT_TARGET "mail-transfer-agent.target" /* Debian's $mail-{transport|transfer-agent */ #define SPECIAL_BASIC_TARGET "basic.target" +#define SPECIAL_SYSINIT_TARGET "sysinit.target" #define SPECIAL_RESCUE_TARGET "rescue.target" #define SPECIAL_EXIT_SERVICE "exit.service" diff --git a/src/mount-setup.c b/src/mount-setup.c index 889cf67eb5..33e6f4fa0e 100644 --- a/src/mount-setup.c +++ b/src/mount-setup.c @@ -42,12 +42,13 @@ typedef struct MountPoint { } MountPoint; static const MountPoint mount_table[] = { - { "proc", "/proc", "proc", NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV, true }, - { "sysfs", "/sys", "sysfs", NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV, true }, - { "devtmps", "/dev", "devtmpfs", "mode=755", MS_NOSUID, true }, - { "tmpfs", "/dev/shm", "tmpfs", "mode=1777", MS_NOSUID|MS_NOEXEC|MS_NODEV, true }, - { "devpts", "/dev/pts", "devpts", NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV, false }, - { "cgroup", "/cgroup/systemd", "cgroup", "none,name=systemd", MS_NOSUID|MS_NOEXEC|MS_NODEV, true }, + { "proc", "/proc", "proc", NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV, true }, + { "sysfs", "/sys", "sysfs", NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV, true }, + { "devtmpfs", "/dev", "devtmpfs", "mode=755", MS_NOSUID, true }, + { "tmpfs", "/dev/shm", "tmpfs", "mode=1777", MS_NOSUID|MS_NOEXEC|MS_NODEV, true }, + { "devpts", "/dev/pts", "devpts", NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV, false }, + { "tmpfs", "/cgroup", "tmpfs", "mode=755", MS_NOSUID|MS_NOEXEC|MS_NODEV, true }, + { "cgroup", "/cgroup/systemd", "cgroup", "none,name=systemd", MS_NOSUID|MS_NOEXEC|MS_NODEV, true }, }; bool mount_point_is_api(const char *path) { diff --git a/src/mount.c b/src/mount.c index dfe4f875e1..5577f16dfd 100644 --- a/src/mount.c +++ b/src/mount.c @@ -1262,7 +1262,7 @@ finish: static int mount_load_proc_self_mountinfo(Manager *m, bool set_flags) { int r; - char *device, *path, *options, *fstype, *d, *p; + char *device, *path, *options, *options2, *fstype, *d, *p, *o; assert(m); @@ -1271,7 +1271,7 @@ static int mount_load_proc_self_mountinfo(Manager *m, bool set_flags) { for (;;) { int k; - device = path = options = fstype = d = p = NULL; + device = path = options = options2 = fstype = d = p = o = NULL; if ((k = fscanf(m->proc_self_mountinfo, "%*s " /* (1) mount id */ @@ -1284,11 +1284,13 @@ static int mount_load_proc_self_mountinfo(Manager *m, bool set_flags) { "- " /* (8) seperator */ "%ms " /* (9) file system type */ "%ms" /* (10) mount source */ + "%ms" /* (11) mount options 2 */ "%*[^\n]", /* some rubbish at the end */ &path, &options, &fstype, - &device)) != 4) { + &device, + &options2)) != 5) { if (k == EOF) break; @@ -1297,21 +1299,28 @@ static int mount_load_proc_self_mountinfo(Manager *m, bool set_flags) { goto finish; } + if (asprintf(&o, "%s,%s", options, options2) < 0) { + r = -ENOMEM; + goto finish; + } + if (!(d = cunescape(device)) || !(p = cunescape(path))) { r = -ENOMEM; goto finish; } - if ((r = mount_add_one(m, d, p, options, fstype, true, set_flags)) < 0) + if ((r = mount_add_one(m, d, p, o, fstype, true, set_flags)) < 0) goto finish; free(device); free(path); free(options); + free(options2); free(fstype); free(d); free(p); + free(o); } r = 0; @@ -1320,9 +1329,11 @@ finish: free(device); free(path); free(options); + free(options2); free(fstype); free(d); free(p); + free(o); return r; } diff --git a/src/sd-daemon.c b/src/sd-daemon.c index 2e1bf3213c..29bd204680 100644 --- a/src/sd-daemon.c +++ b/src/sd-daemon.c @@ -89,7 +89,6 @@ int sd_listen_fds(int unset_environment) { goto finish; } - for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + (int) l; fd ++) { int flags; diff --git a/src/sd-daemon.h b/src/sd-daemon.h index e209af6489..0d8de45b72 100644 --- a/src/sd-daemon.h +++ b/src/sd-daemon.h @@ -30,10 +30,11 @@ #include <inttypes.h> /* Reference implementation of a few systemd related interfaces for - * writing daemons. These interfaces are trivial to implement, however - * to simplify porting we provide this reference - * implementation. Applications are free to reimplement the algorithms - * described here. */ + * writing daemons. These interfaces are trivial to implement. To + * simplify porting we provide this reference + * implementation. Applications are welcome to reimplement the + * algorithms described here, if they do not want to include these two + * source files. */ /* Log levels for usage on stderr: @@ -56,12 +57,16 @@ #define SD_LISTEN_FDS_START 3 /* Returns how many file descriptors have been passed, or a negative - * errno code on failure. Optionally removes the $LISTEN_FDS and - * $LISTEN_PID file descriptors from the environment - * (recommended). You'll find the file descriptors passed as fds - * SD_LISTEN_FDS_START to SD_LISTEN_FDS_START+r-1 if r is the return - * value of this functioin. Returns a negative errno style error code - * on failure. */ + * errno code on failure. Optionally, removes the $LISTEN_FDS and + * $LISTEN_PID file descriptors from the environment (recommended, but + * problematic in threaded environments). If r is the return value of + * this function you'll find the file descriptors passed as fds + * SD_LISTEN_FDS_START to SD_LISTEN_FDS_START+r-1. Returns a negative + * errno style error code on failure. This function call ensures that + * the FD_CLOEXEC flag is set for the passed file descriptors, to make + * sure they are not passed on to child processes. If FD_CLOEXEC shall + * not be set, the caller needs to unset it after this call for all file + * descriptors that are used.*/ int sd_listen_fds(int unset_environment); /* Helper call for identifying a passed file descriptor. Returns 1 if @@ -86,7 +91,7 @@ int sd_is_socket(int fd, int family, int type, int listening); /* Helper call for identifying a passed file descriptor. Returns 1 if * the file descriptor is an Internet socket, of the specified family - * (either AF_INET or AF_INET6) of the specified type (SOCK_DGRAM, + * (either AF_INET or AF_INET6) and the specified type (SOCK_DGRAM, * SOCK_STREAM, ...), 0 otherwise. If version is 0 a protocol version * check is not done. If type is 0 a socket type check will not be * done. If port is 0 a socket port check will not be done. The diff --git a/src/service.c b/src/service.c index 8ff7b73138..8b1fab785a 100644 --- a/src/service.c +++ b/src/service.c @@ -58,10 +58,10 @@ static const struct { { "rc6.d", SPECIAL_RUNLEVEL6_TARGET, RUNLEVEL_DOWN }, /* SUSE style boot.d */ - { "boot.d", SPECIAL_BASIC_TARGET, RUNLEVEL_BASIC }, + { "boot.d", SPECIAL_SYSINIT_TARGET, RUNLEVEL_BASIC }, /* Debian style rcS.d */ - { "rcS.d", SPECIAL_BASIC_TARGET, RUNLEVEL_BASIC }, + { "rcS.d", SPECIAL_SYSINIT_TARGET, RUNLEVEL_BASIC }, }; #define RUNLEVELS_UP "12345" @@ -340,9 +340,6 @@ static int service_load_sysv_path(Service *s, const char *path) { goto finish; } - s->type = SERVICE_FORKING; - s->restart = SERVICE_ONCE; - free(s->sysv_path); if (!(s->sysv_path = strdup(path))) { r = -ENOMEM; @@ -650,8 +647,10 @@ static int service_load_sysv_path(Service *s, const char *path) { s->timeout_usec = 0; /* Special setting for all SysV services */ + s->type = SERVICE_FORKING; s->valid_no_process = true; s->kill_mode = KILL_PROCESS_GROUP; + s->restart = SERVICE_ONCE; u->meta.load_state = UNIT_LOADED; r = 0; @@ -1964,14 +1963,18 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) { break; case SERVICE_START: - assert(s->type == SERVICE_FINISH); + if (s->type == SERVICE_FINISH) { + /* This was our main goal, so let's go on */ + if (success) + service_enter_start_post(s); + else + service_enter_signal(s, SERVICE_FINAL_SIGTERM, false); + break; + } else { + assert(s->type == SERVICE_DBUS); - /* This was our main goal, so let's go on */ - if (success) - service_enter_start_post(s); - else - service_enter_signal(s, SERVICE_FINAL_SIGTERM, false); - break; + /* Fall through */ + } case SERVICE_RUNNING: service_enter_running(s, success); diff --git a/src/service.h b/src/service.h index 40bd57e256..5242de58fa 100644 --- a/src/service.h +++ b/src/service.h @@ -56,8 +56,8 @@ typedef enum ServiceRestart { } ServiceRestart; typedef enum ServiceType { - SERVICE_FORKING, /* forks by itself (i.e. traditional daemons) */ SERVICE_SIMPLE, /* we fork and go on right-away (i.e. modern socket activated daemons) */ + SERVICE_FORKING, /* forks by itself (i.e. traditional daemons) */ SERVICE_FINISH, /* we fork and wait until the program finishes (i.e. programs like fsck which run and need to finish before we continue) */ SERVICE_DBUS, /* we fork and wait until a specific D-Bus name appears on the bus */ _SERVICE_TYPE_MAX, diff --git a/src/socket-util.c b/src/socket-util.c index 0c9fc9f999..4a1b3d8b51 100644 --- a/src/socket-util.c +++ b/src/socket-util.c @@ -443,7 +443,7 @@ bool socket_address_equal(const SocketAddress *a, const SocketAddress *b) { return true; } -bool socket_address_is(const SocketAddress *a, const char *s) { +bool socket_address_is(const SocketAddress *a, const char *s, int type) { struct SocketAddress b; assert(a); @@ -452,6 +452,8 @@ bool socket_address_is(const SocketAddress *a, const char *s) { if (socket_address_parse(&b, s) < 0) return false; + b.type = type; + return socket_address_equal(a, &b); } diff --git a/src/socket-util.h b/src/socket-util.h index 993972c458..ffcc86882f 100644 --- a/src/socket-util.h +++ b/src/socket-util.h @@ -72,7 +72,7 @@ int socket_address_listen( mode_t socket_mode, int *ret); -bool socket_address_is(const SocketAddress *a, const char *s); +bool socket_address_is(const SocketAddress *a, const char *s, int type); bool socket_address_equal(const SocketAddress *a, const SocketAddress *b); diff --git a/src/socket.c b/src/socket.c index 909151752c..19f1d22097 100644 --- a/src/socket.c +++ b/src/socket.c @@ -1067,7 +1067,7 @@ static int socket_serialize(Unit *u, FILE *f, FDSet *fds) { if ((r = socket_address_print(&p->address, &t)) < 0) return r; - unit_serialize_item_format(u, f, "socket", "%i %s", copy, t); + unit_serialize_item_format(u, f, "socket", "%i %i %s", copy, p->address.type, t); free(t); } else { assert(p->type == SOCKET_FIFO); @@ -1145,15 +1145,15 @@ static int socket_deserialize_item(Unit *u, const char *key, const char *value, } } else if (streq(key, "socket")) { - int fd, skip = 0; + int fd, type, skip = 0; SocketPort *p; - if (sscanf(value, "%i %n", &fd, &skip) < 1 || fd < 0 || !fdset_contains(fds, fd)) + if (sscanf(value, "%i %i %n", &fd, &type, &skip) < 2 || fd < 0 || type < 0 || !fdset_contains(fds, fd)) log_debug("Failed to parse socket value %s", value); else { LIST_FOREACH(port, p, s->ports) - if (socket_address_is(&p->address, value+skip)) + if (socket_address_is(&p->address, value+skip, type)) break; if (p) { diff --git a/src/strv.h b/src/strv.h index f0be83dd59..11d2ea1207 100644 --- a/src/strv.h +++ b/src/strv.h @@ -29,7 +29,7 @@ char *strv_find(char **l, const char *name); void strv_free(char **l); -char **strv_copy(char **l) _malloc; +char **strv_copy(char **l) _malloc_; unsigned strv_length(char **l); char **strv_merge(char **a, char **b); @@ -41,20 +41,20 @@ char **strv_uniq(char **l); #define strv_contains(l, s) (!!strv_find((l), (s))) -char **strv_new(const char *x, ...) _sentinel _malloc; -char **strv_new_ap(const char *x, va_list ap) _malloc; +char **strv_new(const char *x, ...) _sentinel_ _malloc_; +char **strv_new_ap(const char *x, va_list ap) _malloc_; static inline bool strv_isempty(char **l) { return !l || !*l; } -char **strv_split(const char *s, const char *separator) _malloc; -char **strv_split_quoted(const char *s) _malloc; +char **strv_split(const char *s, const char *separator) _malloc_; +char **strv_split_quoted(const char *s) _malloc_; -char *strv_join(char **l, const char *separator) _malloc; +char *strv_join(char **l, const char *separator) _malloc_; -char **strv_env_merge(char **x, ...) _sentinel; -char **strv_env_delete(char **x, ...) _sentinel; +char **strv_env_merge(char **x, ...) _sentinel_; +char **strv_env_delete(char **x, ...) _sentinel_; #define STRV_FOREACH(s, l) \ for ((s) = (l); (s) && *(s); (s)++) diff --git a/src/swap.c b/src/swap.c index 2c7e4924d6..c35a8e785a 100644 --- a/src/swap.c +++ b/src/swap.c @@ -246,7 +246,7 @@ int swap_add_one( bool from_proc_swaps) { Unit *u = NULL; char *e = NULL, *w = NULL; - bool delete; + bool delete = false; int r; SwapParameters *p; diff --git a/src/systemctl.vala b/src/systemctl.vala index e3e675f479..6cce93bec6 100644 --- a/src/systemctl.vala +++ b/src/systemctl.vala @@ -252,25 +252,17 @@ int main (string[] args) { for (int i = 2; i < args.length; i++) { - ObjectPath p = manager.load_unit(args[i]); - - Unit u = bus.get_object( - "org.freedesktop.systemd1", - p, - "org.freedesktop.systemd1.Unit") as Unit; - string mode = replace ? "replace" : "fail"; - ObjectPath j = null; if (args[1] == "start") - j = u.start(mode); + j = manager.start_unit(args[i], mode); else if (args[1] == "stop") - j = u.stop(mode); + j = manager.stop_unit(args[i], mode); else if (args[1] == "restart") - j = u.restart(mode); + j = manager.restart_unit(args[i], mode); else if (args[1] == "reload") - j = u.reload(mode); + j = manager.reload_unit(args[i], mode); if (block) jobs.append(j); @@ -283,14 +275,7 @@ int main (string[] args) { return 1; } - ObjectPath p = manager.load_unit(args[2]); - - Unit u = bus.get_object( - "org.freedesktop.systemd1", - p, - "org.freedesktop.systemd1.Unit") as Unit; - - ObjectPath j = u.start("isolate"); + ObjectPath j = manager.start_unit(args[2], "isolate"); if (block) { manager.subscribe(); diff --git a/src/systemd-interfaces.vala b/src/systemd-interfaces.vala index a8aeb75579..7445479911 100644 --- a/src/systemd-interfaces.vala +++ b/src/systemd-interfaces.vala @@ -52,6 +52,11 @@ public interface Manager : DBus.Object { public abstract ObjectPath load_unit(string name) throws DBus.Error; public abstract ObjectPath get_job(uint32 id) throws DBus.Error; + public abstract ObjectPath start_unit(string name, string mode) throws DBus.Error; + public abstract ObjectPath stop_unit(string name, string mode) throws DBus.Error; + public abstract ObjectPath reload_unit(string name, string mode) throws DBus.Error; + public abstract ObjectPath restart_unit(string name, string mode) throws DBus.Error; + public abstract void clear_jobs() throws DBus.Error; public abstract void subscribe() throws DBus.Error; diff --git a/src/test-engine.c b/src/test-engine.c index 27e16f3484..eb17f580e2 100644 --- a/src/test-engine.c +++ b/src/test-engine.c @@ -36,9 +36,9 @@ int main(int argc, char *argv[]) { assert_se(manager_new(MANAGER_INIT, false, &m) >= 0); printf("Load1:\n"); - assert_se(manager_load_unit(m, "a.service", NULL, &a) == 0); - assert_se(manager_load_unit(m, "b.service", NULL, &b) == 0); - assert_se(manager_load_unit(m, "c.service", NULL, &c) == 0); + assert_se(manager_load_unit(m, "a.service", NULL, &a) >= 0); + assert_se(manager_load_unit(m, "b.service", NULL, &b) >= 0); + assert_se(manager_load_unit(m, "c.service", NULL, &c) >= 0); manager_dump_units(m, stdout, "\t"); printf("Test1: (Trivial)\n"); @@ -47,8 +47,8 @@ int main(int argc, char *argv[]) { printf("Load2:\n"); manager_clear_jobs(m); - assert_se(manager_load_unit(m, "d.service", NULL, &d) == 0); - assert_se(manager_load_unit(m, "e.service", NULL, &e) == 0); + assert_se(manager_load_unit(m, "d.service", NULL, &d) >= 0); + assert_se(manager_load_unit(m, "e.service", NULL, &e) >= 0); manager_dump_units(m, stdout, "\t"); printf("Test2: (Cyclic Order, Unfixable)\n"); @@ -64,7 +64,7 @@ int main(int argc, char *argv[]) { manager_dump_jobs(m, stdout, "\t"); printf("Load3:\n"); - assert_se(manager_load_unit(m, "g.service", NULL, &g) == 0); + assert_se(manager_load_unit(m, "g.service", NULL, &g) >= 0); manager_dump_units(m, stdout, "\t"); printf("Test5: (Colliding transaction, fail)\n"); @@ -86,7 +86,7 @@ int main(int argc, char *argv[]) { manager_dump_jobs(m, stdout, "\t"); printf("Load4:\n"); - assert_se(manager_load_unit(m, "h.service", NULL, &h) == 0); + assert_se(manager_load_unit(m, "h.service", NULL, &h) >= 0); manager_dump_units(m, stdout, "\t"); printf("Test10: (Unmeargable job type of auxiliary job, fail)\n"); diff --git a/src/unit.c b/src/unit.c index 57b3b77954..3bb41a4239 100644 --- a/src/unit.c +++ b/src/unit.c @@ -67,6 +67,7 @@ Unit *unit_new(Manager *m) { u->meta.manager = m; u->meta.type = _UNIT_TYPE_INVALID; + u->meta.deserialized_job = _JOB_TYPE_INVALID; return u; } @@ -318,10 +319,19 @@ void unit_free(Unit *u) { bus_unit_send_removed_signal(u); - /* Detach from next 'bigger' objects */ + if (u->meta.load_state != UNIT_STUB) + if (UNIT_VTABLE(u)->done) + UNIT_VTABLE(u)->done(u); + SET_FOREACH(t, u->meta.names, i) hashmap_remove_value(u->meta.manager->units, t, u); + if (u->meta.job) + job_free(u->meta.job); + + for (d = 0; d < _UNIT_DEPENDENCY_MAX; d++) + bidi_set_free(u, u->meta.dependencies[d]); + if (u->meta.type != _UNIT_TYPE_INVALID) LIST_REMOVE(Meta, units_per_type, u->meta.manager->units_per_type[u->meta.type], &u->meta); @@ -339,19 +349,8 @@ void unit_free(Unit *u) { u->meta.manager->n_in_gc_queue--; } - /* Free data and next 'smaller' objects */ - if (u->meta.job) - job_free(u->meta.job); - - if (u->meta.load_state != UNIT_STUB) - if (UNIT_VTABLE(u)->done) - UNIT_VTABLE(u)->done(u); - cgroup_bonding_free_list(u->meta.cgroup_bondings); - for (d = 0; d < _UNIT_DEPENDENCY_MAX; d++) - bidi_set_free(u, u->meta.dependencies[d]); - free(u->meta.description); free(u->meta.fragment_path); @@ -968,56 +967,54 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns) { * failed previously due to EAGAIN. */ job_add_to_run_queue(u->meta.job); - else { - assert(u->meta.job->state == JOB_RUNNING); - /* Let's check whether this state change - * constitutes a finished job, or maybe - * cotradicts a running job and hence needs to - * invalidate jobs. */ + /* Let's check whether this state change constitutes a + * finished job, or maybe cotradicts a running job and + * hence needs to invalidate jobs. */ - switch (u->meta.job->type) { + switch (u->meta.job->type) { - case JOB_START: - case JOB_VERIFY_ACTIVE: + case JOB_START: + case JOB_VERIFY_ACTIVE: - if (UNIT_IS_ACTIVE_OR_RELOADING(ns)) - job_finish_and_invalidate(u->meta.job, true); - else if (ns != UNIT_ACTIVATING) { - unexpected = true; - job_finish_and_invalidate(u->meta.job, false); - } + if (UNIT_IS_ACTIVE_OR_RELOADING(ns)) + job_finish_and_invalidate(u->meta.job, true); + else if (u->meta.job->state == JOB_RUNNING && ns != UNIT_ACTIVATING) { + unexpected = true; + job_finish_and_invalidate(u->meta.job, false); + } - break; + break; - case JOB_RELOAD: - case JOB_RELOAD_OR_START: + case JOB_RELOAD: + case JOB_RELOAD_OR_START: + if (u->meta.job->state == JOB_RUNNING) { if (ns == UNIT_ACTIVE) job_finish_and_invalidate(u->meta.job, true); else if (ns != UNIT_ACTIVATING && ns != UNIT_ACTIVE_RELOADING) { unexpected = true; job_finish_and_invalidate(u->meta.job, false); } + } - break; + break; - case JOB_STOP: - case JOB_RESTART: - case JOB_TRY_RESTART: + case JOB_STOP: + case JOB_RESTART: + case JOB_TRY_RESTART: - if (ns == UNIT_INACTIVE) - job_finish_and_invalidate(u->meta.job, true); - else if (ns != UNIT_DEACTIVATING) { - unexpected = true; - job_finish_and_invalidate(u->meta.job, false); - } + if (ns == UNIT_INACTIVE) + job_finish_and_invalidate(u->meta.job, true); + else if (u->meta.job->state == JOB_RUNNING && ns != UNIT_DEACTIVATING) { + unexpected = true; + job_finish_and_invalidate(u->meta.job, false); + } - break; + break; - default: - assert_not_reached("Job type unknown"); - } + default: + assert_not_reached("Job type unknown"); } } @@ -1794,6 +1791,9 @@ int unit_serialize(Unit *u, FILE *f, FDSet *fds) { if ((r = UNIT_VTABLE(u)->serialize(u, f, fds)) < 0) return r; + if (u->meta.job) + unit_serialize_item(u, f, "job", job_type_to_string(u->meta.job->type)); + /* End marker */ fputc('\n', f); return 0; @@ -1860,6 +1860,17 @@ int unit_deserialize(Unit *u, FILE *f, FDSet *fds) { } else v = l+k; + if (streq(l, "job")) { + JobType type; + + if ((type = job_type_from_string(v)) < 0) + log_debug("Failed to parse job type value %s", v); + else + u->meta.deserialized_job = type; + + continue; + } + if ((r = UNIT_VTABLE(u)->deserialize_item(u, l, v, fds)) < 0) return r; } @@ -1902,6 +1913,25 @@ int unit_add_node_link(Unit *u, const char *what, bool wants) { return 0; } +int unit_coldplug(Unit *u) { + int r; + + assert(u); + + if (UNIT_VTABLE(u)->coldplug) + if ((r = UNIT_VTABLE(u)->coldplug(u)) < 0) + return r; + + if (u->meta.deserialized_job >= 0) { + if ((r = manager_add_job(u->meta.manager, u->meta.deserialized_job, u, JOB_FAIL, false, NULL)) < 0) + return r; + + u->meta.deserialized_job = _JOB_TYPE_INVALID; + } + + return 0; +} + static const char* const unit_type_table[_UNIT_TYPE_MAX] = { [UNIT_SERVICE] = "service", [UNIT_TIMER] = "timer", diff --git a/src/unit.h b/src/unit.h index f585fa6238..5e61f7c027 100644 --- a/src/unit.h +++ b/src/unit.h @@ -40,7 +40,7 @@ typedef enum UnitDependency UnitDependency; #include "execute.h" #define UNIT_NAME_MAX 128 -#define DEFAULT_TIMEOUT_USEC (20*USEC_PER_SEC) +#define DEFAULT_TIMEOUT_USEC (60*USEC_PER_SEC) #define DEFAULT_RESTART_USEC (100*USEC_PER_MSEC) typedef enum KillMode { @@ -185,6 +185,10 @@ struct Meta { /* Garbage collect us we nobody wants or requires us anymore */ bool stop_when_unneeded; + /* When deserializing, temporarily store the job type for this + * unit here, if there was a job scheduled */ + int deserialized_job; /* This is actually of type JobType */ + bool in_load_queue:1; bool in_dbus_queue:1; bool in_cleanup_queue:1; @@ -431,12 +435,14 @@ char **unit_full_printf_strv(Unit *u, char **l); bool unit_can_serialize(Unit *u); int unit_serialize(Unit *u, FILE *f, FDSet *fds); -void unit_serialize_item_format(Unit *u, FILE *f, const char *key, const char *value, ...) _printf_attr(4,5); +void unit_serialize_item_format(Unit *u, FILE *f, const char *key, const char *value, ...) _printf_attr_(4,5); void unit_serialize_item(Unit *u, FILE *f, const char *key, const char *value); int unit_deserialize(Unit *u, FILE *f, FDSet *fds); int unit_add_node_link(Unit *u, const char *what, bool wants); +int unit_coldplug(Unit *u); + const char *unit_type_to_string(UnitType i); UnitType unit_type_from_string(const char *s); diff --git a/test2/a.service b/test2/a.service index 4ddb8b4622..4168d2d051 100644 --- a/test2/a.service +++ b/test2/a.service @@ -1,4 +1,7 @@ -[Meta] +[Unit] Description=A Requires=b.service Before=b.service + +[Service] +ExecStart=/bin/true diff --git a/test2/b.service b/test2/b.service index ca946073d3..e03bae36be 100644 --- a/test2/b.service +++ b/test2/b.service @@ -1,3 +1,6 @@ -[Meta] +[Unit] Description=B Wants=f.service + +[Service] +ExecStart=/bin/true diff --git a/test2/c.service b/test2/c.service index 8800ff70c7..e2f60a8fbf 100644 --- a/test2/c.service +++ b/test2/c.service @@ -1,3 +1,6 @@ -[Meta] +[Unit] Description=C Requires=a.service + +[Service] +ExecStart=/bin/true diff --git a/test2/d.service b/test2/d.service index 279c1716c2..921fd2ee1b 100644 --- a/test2/d.service +++ b/test2/d.service @@ -1,5 +1,8 @@ -[Meta] +[Unit] Description=D:Cyclic After=b.service Before=a.service Requires=a.service + +[Service] +ExecStart=/bin/true diff --git a/test2/e.service b/test2/e.service index 2e86e33daf..5ba98c7c43 100644 --- a/test2/e.service +++ b/test2/e.service @@ -1,5 +1,8 @@ -[Meta] +[Unit] Description=E:Cyclic After=b.service Before=a.service Wants=a.service + +[Service] +ExecStart=/bin/true diff --git a/test2/f.service b/test2/f.service index d0b30effd7..7dde681c17 100644 --- a/test2/f.service +++ b/test2/f.service @@ -1,2 +1,5 @@ -[Meta] +[Unit] Description=F + +[Service] +ExecStart=/bin/true diff --git a/test2/g.service b/test2/g.service index e811e6083d..cbfa82a454 100644 --- a/test2/g.service +++ b/test2/g.service @@ -1,3 +1,6 @@ -[Meta] +[Unit] Description=G Conflicts=e.service + +[Service] +ExecStart=/bin/true diff --git a/test2/h.service b/test2/h.service index 4b9ffa3e83..74a7751cad 100644 --- a/test2/h.service +++ b/test2/h.service @@ -1,3 +1,6 @@ -[Meta] +[Unit] Description=H Wants=g.service + +[Service] +ExecStart=/bin/true diff --git a/units/.gitignore b/units/.gitignore index 7e61543864..ea85dc081e 100644 --- a/units/.gitignore +++ b/units/.gitignore @@ -1,7 +1,7 @@ systemd-initctl.service systemd-logger.service syslog.target -basic.target +sysinit.target graphical.target multi-user.target getty@.service diff --git a/units/sys-fs-fuse-connections.automount b/units/basic.target index db1316277f..aa94b94ad6 100644 --- a/units/sys-fs-fuse-connections.automount +++ b/units/basic.target @@ -5,9 +5,10 @@ # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. -[Unit] -Description=FUSE Control File System Automount Point -Before=basic.target +# See systemd.special(7) for details -[Automount] -Where=/sys/fs/fuse/connections +[Unit] +Description=Basic System +Requires=sysinit.target local-fs.target swap.target sockets.target +After=sysinit.target local-fs.target swap.target sockets.target +OnlyByDependency=yes diff --git a/units/dev-hugepages.automount b/units/dev-hugepages.automount index 9fef9eeb37..4e7f8ff5a9 100644 --- a/units/dev-hugepages.automount +++ b/units/dev-hugepages.automount @@ -7,7 +7,7 @@ [Unit] Description=Huge Pages File System Automount Point -Before=basic.target +Before=sysinit.target [Automount] Where=/dev/hugepages diff --git a/units/dev-mqueue.automount b/units/dev-mqueue.automount index a24ffe68f5..4df53dcaa4 100644 --- a/units/dev-mqueue.automount +++ b/units/dev-mqueue.automount @@ -7,7 +7,7 @@ [Unit] Description=POSIX Message Queue File System Automount Point -Before=basic.target +Before=sysinit.target [Automount] Where=/dev/mqueue diff --git a/units/emergency.service b/units/emergency.service index 3cbca3d012..924723fefe 100644 --- a/units/emergency.service +++ b/units/emergency.service @@ -12,8 +12,7 @@ Description=Emergency Shell [Service] ExecStart=/bin/sh -Type=simple StandardInput=tty Restart=restart-always RestartSec=0 -KillMode=process +KillMode=process-group diff --git a/units/fedora/halt.service b/units/fedora/halt.service index ff498e4375..50373d48b6 100644 --- a/units/fedora/halt.service +++ b/units/fedora/halt.service @@ -9,7 +9,7 @@ Description=Halt Requires=shutdown.target killall.service After=shutdown.target killall.service -Conflicts=dev-hugepages.automount dev-mqueue.automount proc-sys-fs-binfmt_misc.automount sys-kernel-debug.automount +Conflicts=dev-hugepages.automount dev-mqueue.automount proc-sys-fs-binfmt_misc.automount sys-kernel-debug.automount sys-kernel-security.automount [Service] Type=finish diff --git a/units/fedora/poweroff.service b/units/fedora/poweroff.service index 07af6c62c3..f237e32719 100644 --- a/units/fedora/poweroff.service +++ b/units/fedora/poweroff.service @@ -9,7 +9,7 @@ Description=Power-Off Requires=shutdown.target killall.service After=shutdown.target killall.service -Conflicts=dev-hugepages.automount dev-mqueue.automount proc-sys-fs-binfmt_misc.automount sys-kernel-debug.automount +Conflicts=dev-hugepages.automount dev-mqueue.automount proc-sys-fs-binfmt_misc.automount sys-kernel-debug.automount sys-kernel-security.automount [Service] Type=finish diff --git a/units/fedora/prefdm.service b/units/fedora/prefdm.service index 291910239f..3428026c54 100644 --- a/units/fedora/prefdm.service +++ b/units/fedora/prefdm.service @@ -14,4 +14,3 @@ Conflicts=shutdown.target [Service] ExecStart=/etc/X11/prefdm -nodaemon -Type=simple diff --git a/units/fedora/rc-local.service b/units/fedora/rc-local.service index cb0700700b..58b59820e2 100644 --- a/units/fedora/rc-local.service +++ b/units/fedora/rc-local.service @@ -10,6 +10,7 @@ Description=/etc/rc.local Compatibility Requires=basic.target After=basic.target Conflicts=shutdown.target +Before=getty@tty1.service # The rcN.d symlink uses the name "local" while the script itself is # called "rc.local", hence carry both names here. @@ -17,7 +18,6 @@ Names=rc-local.service local.service [Service] ExecStart=/etc/rc.local start -Type=simple TimeoutSec=0 StandardInput=tty ValidNoProcess=yes diff --git a/units/fedora/reboot.service b/units/fedora/reboot.service index 77f5cb3f53..b99dfdc8ac 100644 --- a/units/fedora/reboot.service +++ b/units/fedora/reboot.service @@ -9,7 +9,7 @@ Description=Reboot Requires=shutdown.target killall.service After=shutdown.target killall.service -Conflicts=dev-hugepages.automount dev-mqueue.automount proc-sys-fs-binfmt_misc.automount sys-kernel-debug.automount +Conflicts=dev-hugepages.automount dev-mqueue.automount proc-sys-fs-binfmt_misc.automount sys-kernel-debug.automount sys-kernel-security.automount [Service] Type=finish diff --git a/units/gentoo/Makefile b/units/gentoo/Makefile new file mode 120000 index 0000000000..50be21181f --- /dev/null +++ b/units/gentoo/Makefile @@ -0,0 +1 @@ +../../src/Makefile
\ No newline at end of file diff --git a/units/gentoo/halt.service b/units/gentoo/halt.service index 8762a7827b..c5d96043c0 100644 --- a/units/gentoo/halt.service +++ b/units/gentoo/halt.service @@ -9,7 +9,7 @@ Description=Halt Requires=shutdown.target killall.service After=shutdown.target killall.service -Conflicts=dev-hugepages.automount dev-mqueue.automount proc-sys-fs-binfmt_misc.automount sys-kernel-debug.automount +Conflicts=dev-hugepages.automount dev-mqueue.automount proc-sys-fs-binfmt_misc.automount sys-kernel-debug.automount sys-kernel-security.automount [Service] Type=finish diff --git a/units/gentoo/killall.service b/units/gentoo/killall.service index a02062f815..626e9d1f68 100644 --- a/units/gentoo/killall.service +++ b/units/gentoo/killall.service @@ -8,6 +8,7 @@ [Unit] Description=Kill All Processes After=shutdown.target +OnlyByDependency=yes [Service] Type=finish diff --git a/units/gentoo/poweroff.service b/units/gentoo/poweroff.service index 1a0a6a44f8..2cc645ec53 100644 --- a/units/gentoo/poweroff.service +++ b/units/gentoo/poweroff.service @@ -9,7 +9,7 @@ Description=Power-Off Requires=shutdown.target killall.service After=shutdown.target killall.service -Conflicts=dev-hugepages.automount dev-mqueue.automount proc-sys-fs-binfmt_misc.automount sys-kernel-debug.automount +Conflicts=dev-hugepages.automount dev-mqueue.automount proc-sys-fs-binfmt_misc.automount sys-kernel-debug.automount sys-kernel-security.automount [Service] Type=finish diff --git a/units/gentoo/reboot.service b/units/gentoo/reboot.service index 080a084c75..fdca6f866e 100644 --- a/units/gentoo/reboot.service +++ b/units/gentoo/reboot.service @@ -9,7 +9,7 @@ Description=Reboot Requires=shutdown.target killall.service After=shutdown.target killall.service -Conflicts=dev-hugepages.automount dev-mqueue.automount proc-sys-fs-binfmt_misc.automount sys-kernel-debug.automount +Conflicts=dev-hugepages.automount dev-mqueue.automount proc-sys-fs-binfmt_misc.automount sys-kernel-debug.automount sys-kernel-security.automount [Service] Type=finish diff --git a/units/gentoo/xdm.service b/units/gentoo/xdm.service index 8370ef24f8..ac1df75722 100644 --- a/units/gentoo/xdm.service +++ b/units/gentoo/xdm.service @@ -14,4 +14,3 @@ Conflicts=shutdown.target [Service] ExecStart=/etc/init.d/xdm start -Type=simple diff --git a/units/getty@.service.m4 b/units/getty@.service.m4 index d330fdf32b..a302bf9722 100644 --- a/units/getty@.service.m4 +++ b/units/getty@.service.m4 @@ -17,7 +17,8 @@ After=basic.target Conflicts=shutdown.target [Service] -Type=simple +Environment=TERM=linux ExecStart=GETTY %I Restart=restart-always RestartSec=0 +KillMode=process-group diff --git a/units/proc-sys-fs-binfmt_misc.automount b/units/proc-sys-fs-binfmt_misc.automount index 4e9b23b938..82369c56b3 100644 --- a/units/proc-sys-fs-binfmt_misc.automount +++ b/units/proc-sys-fs-binfmt_misc.automount @@ -7,7 +7,7 @@ [Unit] Description=Arbitrary Executable File Formats File System Automount Point -Before=basic.target +Before=sysinit.target [Automount] Where=/proc/sys/fs/binfmt_misc diff --git a/units/suse/Makefile b/units/suse/Makefile new file mode 120000 index 0000000000..50be21181f --- /dev/null +++ b/units/suse/Makefile @@ -0,0 +1 @@ +../../src/Makefile
\ No newline at end of file diff --git a/units/suse/halt.service b/units/suse/halt.service new file mode 100644 index 0000000000..bc237f02f0 --- /dev/null +++ b/units/suse/halt.service @@ -0,0 +1,19 @@ +# This file is part of systemd. +# +# systemd is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. + +[Unit] +Description=Halt +Requires=shutdown.target +After=shutdown.target +Conflicts=dev-hugepages.automount dev-mqueue.automount proc-sys-fs-binfmt_misc.automount sys-kernel-debug.automount sys-kernel-security.automount + +[Service] +Type=finish +ValidNoProcess=yes +Environment=INIT_HALT=HALT +Environment=RUNLEVEL=0 +ExecStart=/etc/init.d/halt start diff --git a/units/suse/poweroff.service b/units/suse/poweroff.service new file mode 100644 index 0000000000..a68c10cfd3 --- /dev/null +++ b/units/suse/poweroff.service @@ -0,0 +1,17 @@ +# This file is part of systemd. +# +# systemd is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. + +[Unit] +Description=Power-Off +Requires=shutdown.target +After=shutdown.target +Conflicts=dev-hugepages.automount dev-mqueue.automount proc-sys-fs-binfmt_misc.automount sys-kernel-debug.automount sys-kernel-security.automount + +[Service] +Type=finish +ValidNoProcess=yes +ExecStart=/etc/init.d/halt start diff --git a/units/sys-fs-fuse-connections.mount b/units/suse/reboot.service index 0a0a4e8ccb..3dbb469117 100644 --- a/units/sys-fs-fuse-connections.mount +++ b/units/suse/reboot.service @@ -6,9 +6,12 @@ # (at your option) any later version. [Unit] -Description=FUSE Control File System +Description=Reboot +Requires=shutdown.target +After=shutdown.target +Conflicts=dev-hugepages.automount dev-mqueue.automount proc-sys-fs-binfmt_misc.automount sys-kernel-debug.automount sys-kernel-security.automount -[Mount] -What=fusectl -Where=/sys/fs/fuse/connections -Type=fusectl +[Service] +Type=finish +ValidNoProcess=yes +ExecStart=/etc/init.d/reboot start diff --git a/units/sys-kernel-debug.automount b/units/sys-kernel-debug.automount index 3d5b52d049..4da3f20531 100644 --- a/units/sys-kernel-debug.automount +++ b/units/sys-kernel-debug.automount @@ -7,7 +7,7 @@ [Unit] Description=Debug File System Automount Point -Before=basic.target +Before=sysinit.target [Automount] Where=/sys/kernel/debug diff --git a/units/sys-kernel-security.automount b/units/sys-kernel-security.automount index 061a5a23ad..5d8356e513 100644 --- a/units/sys-kernel-security.automount +++ b/units/sys-kernel-security.automount @@ -7,7 +7,7 @@ [Unit] Description=Security File System Automount Point -Before=basic.target +Before=sysinit.target [Automount] Where=/sys/kernel/security diff --git a/units/basic.target.m4 b/units/sysinit.target.m4 index 537ad8daf7..68c661ef02 100644 --- a/units/basic.target.m4 +++ b/units/sysinit.target.m4 @@ -8,9 +8,7 @@ # See systemd.special(7) for details [Unit] -Description=Basic System -Requires=local-fs.target swap.target sockets.target -After=local-fs.target swap.target sockets.target +Description=Systemd Initialization Conflicts=emergency.service OnlyByDependency=yes m4_dnl diff --git a/units/systemd-initctl.service.in b/units/systemd-initctl.service.in index 283c057cf4..7450e07e61 100644 --- a/units/systemd-initctl.service.in +++ b/units/systemd-initctl.service.in @@ -11,5 +11,4 @@ Description=systemd /dev/initctl Compatibility Daemon [Service] -ExecStart=@pkglibexecdir@/systemd-initctl -Type=simple +ExecStart=@rootlibexecdir@/systemd-initctl diff --git a/units/systemd-initctl.socket b/units/systemd-initctl.socket index fdb95deddd..26b526cdcb 100644 --- a/units/systemd-initctl.socket +++ b/units/systemd-initctl.socket @@ -9,6 +9,8 @@ [Unit] Description=systemd /dev/initctl Compatibility Socket +After=sysinit.target +Before=sockets.target [Socket] ListenFIFO=/dev/initctl diff --git a/units/systemd-logger.service.in b/units/systemd-logger.service.in index 39a20013b4..2004438971 100644 --- a/units/systemd-logger.service.in +++ b/units/systemd-logger.service.in @@ -12,5 +12,4 @@ Description=systemd Logging Daemon After=@SPECIAL_SYSLOG_SERVICE@ [Service] -ExecStart=@pkglibexecdir@/systemd-logger -Type=simple +ExecStart=@rootlibexecdir@/systemd-logger diff --git a/units/systemd-logger.socket b/units/systemd-logger.socket index f62b582d3e..44684ce1d0 100644 --- a/units/systemd-logger.socket +++ b/units/systemd-logger.socket @@ -9,6 +9,8 @@ [Unit] Description=systemd Logging Socket +After=sysinit.target +Before=sockets.target [Socket] ListenStream=@/org/freedesktop/systemd1/logger |