summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fixme8
-rw-r--r--man/systemctl.xml8
-rw-r--r--man/systemd.unit.xml17
-rw-r--r--src/bus-errors.h1
-rw-r--r--src/dbus-unit.c18
-rw-r--r--src/dbus-unit.h4
-rw-r--r--src/load-fragment.c1
-rw-r--r--src/manager.c5
-rw-r--r--src/unit.c7
-rw-r--r--src/unit.h6
-rw-r--r--units/emergency.target1
-rw-r--r--units/graphical.target.m41
-rw-r--r--units/halt.target1
-rw-r--r--units/multi-user.target.m41
-rw-r--r--units/poweroff.target1
-rw-r--r--units/reboot.target1
-rw-r--r--units/rescue.target1
17 files changed, 73 insertions, 9 deletions
diff --git a/fixme b/fixme
index d5bca0c429..e5d17a060e 100644
--- a/fixme
+++ b/fixme
@@ -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