diff options
-rw-r--r-- | fixme | 8 | ||||
-rw-r--r-- | man/systemctl.xml | 8 | ||||
-rw-r--r-- | man/systemd.unit.xml | 17 | ||||
-rw-r--r-- | src/bus-errors.h | 1 | ||||
-rw-r--r-- | src/dbus-unit.c | 18 | ||||
-rw-r--r-- | src/dbus-unit.h | 4 | ||||
-rw-r--r-- | src/load-fragment.c | 1 | ||||
-rw-r--r-- | src/manager.c | 5 | ||||
-rw-r--r-- | src/unit.c | 7 | ||||
-rw-r--r-- | src/unit.h | 6 | ||||
-rw-r--r-- | units/emergency.target | 1 | ||||
-rw-r--r-- | units/graphical.target.m4 | 1 | ||||
-rw-r--r-- | units/halt.target | 1 | ||||
-rw-r--r-- | units/multi-user.target.m4 | 1 | ||||
-rw-r--r-- | units/poweroff.target | 1 | ||||
-rw-r--r-- | units/reboot.target | 1 | ||||
-rw-r--r-- | units/rescue.target | 1 |
17 files changed, 73 insertions, 9 deletions
@@ -72,10 +72,6 @@ * auditd service files -* auto-serial-getty vs. isolate - -* add RefuseManualIsolate= (default on?) - * add systemctl switch to dump transaction without executing it * shell wenn fsck im arsch is @@ -90,9 +86,9 @@ * o_ndelay ausschalten für stdin/stderr/stdout auf socket -External: +* kexec, suspend, resume -* make sure MountOnPlug und MountAuto und SwapOnPlug is off in Fedora +External: * place /etc/inittab with explaining blurb. diff --git a/man/systemctl.xml b/man/systemctl.xml index 1c5c884f8c..6af8e61d06 100644 --- a/man/systemctl.xml +++ b/man/systemctl.xml @@ -341,8 +341,12 @@ <listitem><para>Start the unit specified on the command line and its - dependencies and stop all - others.</para></listitem> + dependencies and stop all others. Note + that this works only on units where + <option>AllowIsolate=</option> is + enabled. See + <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry> + for details.</para></listitem> </varlistentry> <varlistentry> <term><command>is-active [NAME...]</command></term> diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml index bb11682fc6..250989fe0f 100644 --- a/man/systemd.unit.xml +++ b/man/systemd.unit.xml @@ -485,6 +485,23 @@ </varlistentry> <varlistentry> + <term><varname>AllowIsolate=</varname></term> + + <listitem><para>Takes a boolean + argument. If <option>true</option> + this unit may be used with the + <command>systemctl isolate</command> + command. Otherwise this will be + refused. It probably is a good idea to + leave this disabled except for target + units that shall be used similar to + runlevels in SysV init systems, just + as a precaution to avoid unusable + system states. This option defaults to + <option>false</option>.</para></listitem> + </varlistentry> + + <varlistentry> <term><varname>DefaultDependencies=</varname></term> <listitem><para>Takes a boolean diff --git a/src/bus-errors.h b/src/bus-errors.h index 7bff75019c..a63350cc23 100644 --- a/src/bus-errors.h +++ b/src/bus-errors.h @@ -35,6 +35,7 @@ #define BUS_ERROR_NOT_SUPPORTED "org.freedesktop.systemd1.NotSupported" #define BUS_ERROR_INVALID_JOB_MODE "org.freedesktop.systemd1.InvalidJobMode" #define BUS_ERROR_ONLY_BY_DEPENDENCY "org.freedesktop.systemd1.OnlyByDependency" +#define BUS_ERROR_NO_ISOLATION "org.freedesktop.systemd1.NoIsolation" #define BUS_ERROR_LOAD_FAILED "org.freedesktop.systemd1.LoadFailed" #define BUS_ERROR_JOB_TYPE_NOT_APPLICABLE "org.freedesktop.systemd1.JobTypeNotApplicable" #define BUS_ERROR_TRANSACTION_IS_DESTRUCTIVE "org.freedesktop.systemd1.TransactionIsDestructive" diff --git a/src/dbus-unit.c b/src/dbus-unit.c index 519aa5c3e8..eab816ac93 100644 --- a/src/dbus-unit.c +++ b/src/dbus-unit.c @@ -205,6 +205,24 @@ int bus_unit_append_can_reload(Manager *m, DBusMessageIter *i, const char *prope return 0; } +int bus_unit_append_can_isolate(Manager *m, DBusMessageIter *i, const char *property, void *data) { + Unit *u = data; + dbus_bool_t b; + + assert(m); + assert(i); + assert(property); + assert(u); + + b = unit_can_isolate(u) && + !u->meta.refuse_manual_start; + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_BOOLEAN, &b)) + return -ENOMEM; + + return 0; +} + int bus_unit_append_job(Manager *m, DBusMessageIter *i, const char *property, void *data) { Unit *u = data; DBusMessageIter sub; diff --git a/src/dbus-unit.h b/src/dbus-unit.h index cc55ad7cf9..6e3726d73f 100644 --- a/src/dbus-unit.h +++ b/src/dbus-unit.h @@ -85,6 +85,7 @@ " <property name=\"CanReload\" type=\"b\" access=\"read\"/>\n" \ " <property name=\"CanStart\" type=\"b\" access=\"read\"/>\n" \ " <property name=\"CanStop\" type=\"b\" access=\"read\"/>\n" \ + " <property name=\"CanIsolate\" type=\"b\" access=\"read\"/>\n" \ " <property name=\"Job\" type=\"(uo)\" access=\"read\"/>\n" \ " <property name=\"RecursiveStop\" type=\"b\" access=\"read\"/>\n" \ " <property name=\"StopWhenUneeded\" type=\"b\" access=\"read\"/>\n" \ @@ -126,11 +127,13 @@ { "org.freedesktop.systemd1.Unit", "CanStart", bus_unit_append_can_start, "b", u }, \ { "org.freedesktop.systemd1.Unit", "CanStop", bus_unit_append_can_stop, "b", u }, \ { "org.freedesktop.systemd1.Unit", "CanReload", bus_unit_append_can_reload, "b", u }, \ + { "org.freedesktop.systemd1.Unit", "CanIsolate", bus_unit_append_can_isolate, "b", u }, \ { "org.freedesktop.systemd1.Unit", "Job", bus_unit_append_job, "(uo)", u }, \ { "org.freedesktop.systemd1.Unit", "RecursiveStop", bus_property_append_bool, "b", &u->meta.recursive_stop }, \ { "org.freedesktop.systemd1.Unit", "StopWhenUneeded", bus_property_append_bool, "b", &u->meta.stop_when_unneeded }, \ { "org.freedesktop.systemd1.Unit", "RefuseManualStart", bus_property_append_bool, "b", &u->meta.refuse_manual_start }, \ { "org.freedesktop.systemd1.Unit", "RefuseManualStop", bus_property_append_bool, "b", &u->meta.refuse_manual_stop }, \ + { "org.freedesktop.systemd1.Unit", "AllowIsolate", bus_property_append_bool, "b", &u->meta.allow_isolate }, \ { "org.freedesktop.systemd1.Unit", "DefaultDependencies", bus_property_append_bool, "b", &u->meta.default_dependencies }, \ { "org.freedesktop.systemd1.Unit", "DefaultControlGroup", bus_unit_append_default_cgroup, "s", u }, \ { "org.freedesktop.systemd1.Unit", "ControlGroups", bus_unit_append_cgroups, "as", u }, \ @@ -147,6 +150,7 @@ int bus_unit_append_sub_state(Manager *m, DBusMessageIter *i, const char *proper int bus_unit_append_can_start(Manager *m, DBusMessageIter *i, const char *property, void *data); int bus_unit_append_can_stop(Manager *m, DBusMessageIter *i, const char *property, void *data); int bus_unit_append_can_reload(Manager *m, DBusMessageIter *i, const char *property, void *data); +int bus_unit_append_can_isolate(Manager *m, DBusMessageIter *i, const char *property, void *data); int bus_unit_append_job(Manager *m, DBusMessageIter *i, const char *property, void *data); int bus_unit_append_default_cgroup(Manager *m, DBusMessageIter *i, const char *property, void *data); int bus_unit_append_cgroups(Manager *m, DBusMessageIter *i, const char *property, void *data); diff --git a/src/load-fragment.c b/src/load-fragment.c index 103e056961..c9ed6798ae 100644 --- a/src/load-fragment.c +++ b/src/load-fragment.c @@ -1580,6 +1580,7 @@ static int load_from_path(Unit *u, const char *path) { { "StopWhenUnneeded", config_parse_bool, &u->meta.stop_when_unneeded, "Unit" }, { "RefuseManualStart", config_parse_bool, &u->meta.refuse_manual_start, "Unit" }, { "RefuseManualStop", config_parse_bool, &u->meta.refuse_manual_stop, "Unit" }, + { "AllowIsolate", config_parse_bool, &u->meta.allow_isolate, "Unit" }, { "DefaultDependencies", config_parse_bool, &u->meta.default_dependencies, "Unit" }, { "IgnoreDependencyFailure",config_parse_bool, &u->meta.ignore_dependency_failure, "Unit" }, { "JobTimeoutSec", config_parse_usec, &u->meta.job_timeout, "Unit" }, diff --git a/src/manager.c b/src/manager.c index 0afc99243e..f542883b34 100644 --- a/src/manager.c +++ b/src/manager.c @@ -1523,6 +1523,11 @@ int manager_add_job(Manager *m, JobType type, Unit *unit, JobMode mode, bool ove return -EINVAL; } + if (mode == JOB_ISOLATE && !unit->meta.allow_isolate) { + dbus_set_error(e, BUS_ERROR_NO_ISOLATION, "Operation refused, unit may not be isolated."); + return -EPERM; + } + log_debug("Trying to enqueue job %s/%s", unit->meta.id, job_type_to_string(type)); if ((r = transaction_add_job_and_dependencies(m, type, unit, NULL, true, override, false, e, &ret)) < 0) { diff --git a/src/unit.c b/src/unit.c index 34bfd3f64c..33696477a9 100644 --- a/src/unit.c +++ b/src/unit.c @@ -812,6 +812,13 @@ bool unit_can_start(Unit *u) { return !!UNIT_VTABLE(u)->start; } +bool unit_can_isolate(Unit *u) { + assert(u); + + return unit_can_start(u) && + u->meta.allow_isolate; +} + /* Errors: * -EBADR: This unit type does not support stopping. * -EALREADY: Unit is already stopped. diff --git a/src/unit.h b/src/unit.h index 0362602fa1..e3c0c0f060 100644 --- a/src/unit.h +++ b/src/unit.h @@ -205,6 +205,9 @@ struct Meta { /* Don't allow the user to stop this unit manually, allow stopping only indirectly via dependency. */ bool refuse_manual_stop; + /* Allow isolation requests */ + bool allow_isolate; + bool in_load_queue:1; bool in_dbus_queue:1; bool in_cleanup_queue:1; @@ -359,7 +362,7 @@ struct UnitVTable { /* Exclude from automatic gc */ bool no_gc:1; - /* Exclude from isolation requests */ + /* Exclude from stopping on isolation requests */ bool no_isolate:1; /* Show status updates on the console */ @@ -445,6 +448,7 @@ void unit_dump(Unit *u, FILE *f, const char *prefix); bool unit_can_reload(Unit *u); bool unit_can_start(Unit *u); +bool unit_can_isolate(Unit *u); int unit_start(Unit *u); int unit_stop(Unit *u); diff --git a/units/emergency.target b/units/emergency.target index 5bf2ae236b..6a99e05f03 100644 --- a/units/emergency.target +++ b/units/emergency.target @@ -11,3 +11,4 @@ Description=Emergency Mode Requires=emergency.service After=emergency.service +AllowIsolate=yes diff --git a/units/graphical.target.m4 b/units/graphical.target.m4 index a80fecfc63..97c01ce1ec 100644 --- a/units/graphical.target.m4 +++ b/units/graphical.target.m4 @@ -20,6 +20,7 @@ Names=runlevel5.target m4_ifdef(`TARGET_SUSE', Names=runlevel5.target )m4_dnl +AllowIsolate=yes [Install] Alias=default.target diff --git a/units/halt.target b/units/halt.target index 77b4044229..70e90fedde 100644 --- a/units/halt.target +++ b/units/halt.target @@ -11,6 +11,7 @@ Description=Halt Requires=halt.service After=halt.service +AllowIsolate=yes [Install] Alias=ctrl-alt-del.target diff --git a/units/multi-user.target.m4 b/units/multi-user.target.m4 index 6f384fe165..48c21d23f9 100644 --- a/units/multi-user.target.m4 +++ b/units/multi-user.target.m4 @@ -20,6 +20,7 @@ Names=runlevel3.target m4_ifdef(`TARGET_SUSE', Names=runlevel3.target )m4_dnl +AllowIsolate=yes [Install] Alias=default.target diff --git a/units/poweroff.target b/units/poweroff.target index b2b56b2893..cb9460639f 100644 --- a/units/poweroff.target +++ b/units/poweroff.target @@ -12,6 +12,7 @@ Description=Power-Off Names=runlevel0.target Requires=poweroff.service After=poweroff.service +AllowIsolate=yes [Install] Alias=ctrl-alt-del.target diff --git a/units/reboot.target b/units/reboot.target index b3be52ff90..855751306d 100644 --- a/units/reboot.target +++ b/units/reboot.target @@ -12,6 +12,7 @@ Description=Reboot Names=runlevel6.target Requires=reboot.service After=reboot.service +AllowIsolate=yes [Install] Alias=ctrl-alt-del.target diff --git a/units/rescue.target b/units/rescue.target index 2694856c66..810fa14da7 100644 --- a/units/rescue.target +++ b/units/rescue.target @@ -12,6 +12,7 @@ Description=Rescue Mode Requires=sysinit.target local-fs.target swap.target After=sysinit.target local-fs.target swap.target Names=runlevel1.target +AllowIsolate=yes [Install] Alias=kbrequest.target |