unit: rename OnlyByDependency= to RefuseManualStart= and introduce RefuseManualStop=

Some unit shall never be start on user request (e.g. shutdown.target)
others never be stopped on user request (e.g. auditd.servce), hence
offer options for both.
This commit is contained in:
Lennart Poettering 2010-08-10 20:57:21 +02:00
parent 77d98d666a
commit b5e9dba8d6
15 changed files with 85 additions and 29 deletions

12
fixme
View File

@ -81,6 +81,10 @@
* hide plymouth in multi-user mode
* audit
* env vars must be replaced by ""
External:
* sysv functions should color when stdout is tty, not stdin
@ -105,6 +109,14 @@ https://bugs.freedesktop.org/show_bug.cgi?id=29194 -- ConsoleKit
https://bugs.freedesktop.org/show_bug.cgi?id=29205 -- udisks
http://article.gmane.org/gmane.linux.bluez.kernel/6479 -- bluez
http://www.spinics.net/lists/linux-nfs/msg14371.html -- rpcbind
https://bugzilla.redhat.com/show_bug.cgi?id=617328 -- ntp
https://bugzilla.redhat.com/show_bug.cgi?id=617320 -- at
https://bugzilla.redhat.com/show_bug.cgi?id=617326 -- fprintd
https://bugzilla.redhat.com/show_bug.cgi?id=617333 -- yum
https://bugzilla.redhat.com/show_bug.cgi?id=617317 -- acpid
https://bugzilla.redhat.com/show_bug.cgi?id=617327 -- gpm
https://bugzilla.redhat.com/show_bug.cgi?id=617330 -- pcsc-lite
https://bugzilla.redhat.com/show_bug.cgi?id=617321 -- audit
Regularly:

View File

@ -461,20 +461,26 @@
</varlistentry>
<varlistentry>
<term><varname>OnlyByDependency=</varname></term>
<term><varname>RefuseManualStart=</varname></term>
<term><varname>RefuseManualStop=</varname></term>
<listitem><para>Takes a boolean
argument. If <option>true</option>
this unit can only be activated
indirectly. In this case explicit
start-up requested by the user is
denied, however if it is started as a
(resp. deactivated) indirectly. In
this case explicit start-up
(resp. termination) requested by the
user is denied, however if it is
started (resp. stopped) as a
dependency of another unit, start-up
will succeed. This is mostly a safety
feature to ensure that the user does
not accidentally activate units that are
not intended to be activated
explicitly. This option defaults to
(resp. termination) will succeed. This
is mostly a safety feature to ensure
that the user does not accidentally
activate units that are not intended
to be activated explicitly, and not
accidentally deactivate units that are
not intended to be deactivated.
These options default to
<option>false</option>.</para></listitem>
</varlistentry>

View File

@ -801,8 +801,11 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection,
job_type = JOB_RELOAD;
}
if (job_type == JOB_START && u->meta.only_by_dependency) {
dbus_set_error(&error, BUS_ERROR_ONLY_BY_DEPENDENCY, "Unit may be activated by dependency only.");
if ((job_type == JOB_START && u->meta.refuse_manual_start) ||
(job_type == JOB_STOP && u->meta.refuse_manual_stop) ||
((job_type == JOB_RESTART || job_type == JOB_TRY_RESTART) &&
(u->meta.refuse_manual_start || u->meta.refuse_manual_stop))) {
dbus_set_error(&error, BUS_ERROR_ONLY_BY_DEPENDENCY, "Operation refused, may be requested by dependency only.");
return bus_send_error_reply(m, connection, message, &error, -EPERM);
}

View File

@ -147,7 +147,28 @@ int bus_unit_append_can_start(Manager *m, DBusMessageIter *i, const char *proper
assert(u);
b = unit_can_start(u) &&
!u->meta.only_by_dependency;
!u->meta.refuse_manual_start;
if (!dbus_message_iter_append_basic(i, DBUS_TYPE_BOOLEAN, &b))
return -ENOMEM;
return 0;
}
int bus_unit_append_can_stop(Manager *m, DBusMessageIter *i, const char *property, void *data) {
Unit *u = data;
dbus_bool_t b;
assert(m);
assert(i);
assert(property);
assert(u);
/* On the lower levels we assume that every unit we can start
* we can also stop */
b = unit_can_start(u) &&
!u->meta.refuse_manual_stop;
if (!dbus_message_iter_append_basic(i, DBUS_TYPE_BOOLEAN, &b))
return -ENOMEM;
@ -334,8 +355,11 @@ static DBusHandlerResult bus_unit_message_dispatch(Unit *u, DBusConnection *conn
Job *j;
int r;
if (job_type == JOB_START && u->meta.only_by_dependency) {
dbus_set_error(&error, BUS_ERROR_ONLY_BY_DEPENDENCY, "Unit may be activated by dependency only.");
if ((job_type == JOB_START && u->meta.refuse_manual_start) ||
(job_type == JOB_STOP && u->meta.refuse_manual_stop) ||
((job_type == JOB_RESTART || job_type == JOB_TRY_RESTART) &&
(u->meta.refuse_manual_start || u->meta.refuse_manual_stop))) {
dbus_set_error(&error, BUS_ERROR_ONLY_BY_DEPENDENCY, "Operation refused, may be requested by dependency only.");
return bus_send_error_reply(m, connection, message, &error, -EPERM);
}

View File

@ -85,10 +85,12 @@
" <property name=\"InactiveEnterTimestamp\" type=\"t\" access=\"read\"/>\n" \
" <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=\"Job\" type=\"(uo)\" access=\"read\"/>\n" \
" <property name=\"RecursiveStop\" type=\"b\" access=\"read\"/>\n" \
" <property name=\"StopWhenUneeded\" type=\"b\" access=\"read\"/>\n" \
" <property name=\"OnlyByDependency\" type=\"b\" access=\"read\"/>\n" \
" <property name=\"RefuseManualStart\" type=\"b\" access=\"read\"/>\n" \
" <property name=\"RefuseManualStop\" type=\"b\" access=\"read\"/>\n" \
" <property name=\"DefaultDependencies\" type=\"b\" access=\"read\"/>\n" \
" <property name=\"DefaultControlGroup\" type=\"s\" access=\"read\"/>\n" \
" <property name=\"ControlGroups\" type=\"as\" access=\"read\"/>\n" \
@ -123,11 +125,13 @@
{ "org.freedesktop.systemd1.Unit", "ActiveExitTimestamp", bus_property_append_uint64, "t", &u->meta.active_exit_timestamp.realtime }, \
{ "org.freedesktop.systemd1.Unit", "InactiveEnterTimestamp",bus_property_append_uint64, "t", &u->meta.inactive_enter_timestamp.realtime }, \
{ "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", "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", "OnlyByDependency", bus_property_append_bool, "b", &u->meta.only_by_dependency }, \
{ "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", "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 }, \
@ -142,6 +146,7 @@ int bus_unit_append_load_state(Manager *m, DBusMessageIter *i, const char *prope
int bus_unit_append_active_state(Manager *m, DBusMessageIter *i, const char *property, void *data);
int bus_unit_append_sub_state(Manager *m, DBusMessageIter *i, const char *property, void *data);
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_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);

View File

@ -385,7 +385,7 @@ static DBusHandlerResult api_bus_message_filter(DBusConnection *connection, DBus
r = manager_load_unit(m, name, NULL, &error, &u);
if (r >= 0 && u->meta.only_by_dependency)
if (r >= 0 && u->meta.refuse_manual_start)
r = -EPERM;
if (r >= 0)

View File

@ -1566,7 +1566,8 @@ static int load_from_path(Unit *u, const char *path) {
{ "OnFailure", config_parse_deps, UINT_TO_PTR(UNIT_ON_FAILURE), "Unit" },
{ "RecursiveStop", config_parse_bool, &u->meta.recursive_stop, "Unit" },
{ "StopWhenUnneeded", config_parse_bool, &u->meta.stop_when_unneeded, "Unit" },
{ "OnlyByDependency", config_parse_bool, &u->meta.only_by_dependency, "Unit" },
{ "RefuseManualStart", config_parse_bool, &u->meta.refuse_manual_start, "Unit" },
{ "RefuseManualStop", config_parse_bool, &u->meta.refuse_manual_stop, "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" },

View File

@ -646,12 +646,14 @@ void unit_dump(Unit *u, FILE *f, const char *prefix) {
fprintf(f,
"%s\tRecursive Stop: %s\n"
"%s\tStopWhenUnneeded: %s\n"
"%s\tOnlyByDependency: %s\n"
"%s\tRefuseManualStart: %s\n"
"%s\tRefuseManualStop: %s\n"
"%s\tDefaultDependencies: %s\n"
"%s\tIgnoreDependencyFailure: %s\n",
prefix, yes_no(u->meta.recursive_stop),
prefix, yes_no(u->meta.stop_when_unneeded),
prefix, yes_no(u->meta.only_by_dependency),
prefix, yes_no(u->meta.refuse_manual_start),
prefix, yes_no(u->meta.refuse_manual_stop),
prefix, yes_no(u->meta.default_dependencies),
prefix, yes_no(u->meta.ignore_dependency_failure));

View File

@ -186,15 +186,18 @@ struct Meta {
/* Garbage collect us we nobody wants or requires us anymore */
bool stop_when_unneeded;
/* Refuse manual starting, allow starting only indirectly via dependency. */
bool only_by_dependency;
/* Create default depedencies */
bool default_dependencies;
/* Bring up this unit even if a dependency fails to start */
bool ignore_dependency_failure;
/* Refuse manual starting, allow starting only indirectly via dependency. */
bool refuse_manual_start;
/* Don't allow the user to stop this unit manually, allow stopping only indirectly via dependency. */
bool refuse_manual_stop;
/* 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 */

View File

@ -11,4 +11,4 @@
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
RefuseManualStart=yes

View File

@ -9,7 +9,7 @@
Description=Kill All Processes
DefaultDependencies=no
After=shutdown.target
OnlyByDependency=yes
RefuseManualStart=yes
[Service]
Type=finish

View File

@ -9,7 +9,7 @@
Description=Kill All Processes
DefaultDependencies=no
After=shutdown.target
OnlyByDependency=yes
RefuseManualStart=yes
[Service]
Type=finish

View File

@ -9,5 +9,5 @@
[Unit]
Description=Shutdown
OnlyByDependency=yes
RefuseManualStart=yes
IgnoreDependencyFailure=yes

View File

@ -11,7 +11,7 @@
Description=System Initialization
Conflicts=emergency.service emergency.target
After=emergency.service emergency.target
OnlyByDependency=yes
RefuseManualStart=yes
m4_dnl
m4_ifdef(`TARGET_FEDORA',
m4_dnl Hook in Fedora's /etc/rc.d/rc.sysinit

View File

@ -9,5 +9,5 @@
[Unit]
Description=Unmount All Filesystems
OnlyByDependency=yes
RefuseManualStart=yes
IgnoreDependencyFailure=yes