* write utmp record a la upstart for processes
-* follow property change dbus spec
-
* selinux policy loading
* place /etc/inittab with explaining blurb.
* bash completion a la gdbus
+* fstab mit tüdelchen
+
+* api mounts gegen fstab mergen und remounten
+
External:
* procps, psmisc, sysvinit-tools, hostname → util-linux-ng
.reset_maintenance = automount_reset_maintenance,
+ .bus_interface = "org.freedesktop.systemd1.Automount",
.bus_message_handler = bus_automount_message_handler,
.shutdown = automount_shutdown
BUS_UNIT_INTERFACE \
BUS_AUTOMOUNT_INTERFACE \
BUS_PROPERTIES_INTERFACE \
+ BUS_PEER_INTERFACE \
BUS_INTROSPECTABLE_INTERFACE \
"</node>\n"
BUS_UNIT_INTERFACE \
BUS_DEVICE_INTERFACE \
BUS_PROPERTIES_INTERFACE \
+ BUS_PEER_INTERFACE \
BUS_INTROSPECTABLE_INTERFACE \
"</node>\n"
const char bus_device_interface[] = BUS_DEVICE_INTERFACE;
+const char bus_device_invalidating_properties[] =
+ "SysFSPath\0"
+ "\0";
+
DBusHandlerResult bus_device_message_handler(Unit *u, DBusConnection *c, DBusMessage *message) {
const BusProperty properties[] = {
BUS_UNIT_PROPERTIES,
DBusHandlerResult bus_device_message_handler(Unit *u, DBusConnection *c, DBusMessage *message);
extern const char bus_device_interface[];
+extern const char bus_device_invalidating_properties[];
#endif
#define BUS_JOB_INTERFACE \
" <interface name=\"org.freedesktop.systemd1.Job\">\n" \
" <method name=\"Cancel\"/>\n" \
- " <signal name=\"Changed\"/>\n" \
" <property name=\"Id\" type=\"u\" access=\"read\"/>\n" \
" <property name=\"Unit\" type=\"(so)\" access=\"read\"/>\n" \
" <property name=\"JobType\" type=\"s\" access=\"read\"/>\n" \
"<node>\n" \
BUS_JOB_INTERFACE \
BUS_PROPERTIES_INTERFACE \
+ BUS_PEER_INTERFACE \
BUS_INTROSPECTABLE_INTERFACE \
"</node>\n"
const char bus_job_interface[] = BUS_JOB_INTERFACE;
+#define INVALIDATING_PROPERTIES \
+ "State\0" \
+ "\0" \
+
static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_job_append_state, job_state, JobState);
static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_job_append_type, job_type, JobType);
goto oom;
if (j->sent_dbus_new_signal) {
- /* Send a change signal */
+ /* Send a properties changed signal */
- if (!(m = dbus_message_new_signal(p, "org.freedesktop.systemd1.Job", "Changed")))
+ if (!(m = bus_properties_changed_new(p, "org.freedesktop.systemd1.Job", INVALIDATING_PROPERTIES)))
goto oom;
+
} else {
/* Send a new signal */
"<node>\n" \
BUS_MANAGER_INTERFACE \
BUS_PROPERTIES_INTERFACE \
+ BUS_PEER_INTERFACE \
BUS_INTROSPECTABLE_INTERFACE
#define INTROSPECTION_END \
BUS_UNIT_INTERFACE \
BUS_MOUNT_INTERFACE \
BUS_PROPERTIES_INTERFACE \
+ BUS_PEER_INTERFACE \
BUS_INTROSPECTABLE_INTERFACE \
"</node>\n"
const char bus_mount_interface[] = BUS_MOUNT_INTERFACE;
+const char bus_mount_invalidating_properties[] =
+ "What\0"
+ "Options\0"
+ "Type\0"
+ "ExecMount\0"
+ "ExecUnmount\0"
+ "ExecRemount\0"
+ "ControlPID\0"
+ "\0";
+
static int bus_mount_append_what(Manager *n, DBusMessageIter *i, const char *property, void *data) {
Mount *m = data;
const char *d;
DBusHandlerResult bus_mount_message_handler(Unit *u, DBusConnection *c, DBusMessage *message);
extern const char bus_mount_interface[];
+extern const char bus_mount_invalidating_properties[];
#endif
BUS_UNIT_INTERFACE \
BUS_PATH_INTERFACE \
BUS_PROPERTIES_INTERFACE \
+ BUS_PEER_INTERFACE \
BUS_INTROSPECTABLE_INTERFACE \
"</node>\n"
BUS_UNIT_INTERFACE \
BUS_SERVICE_INTERFACE \
BUS_PROPERTIES_INTERFACE \
+ BUS_PEER_INTERFACE \
BUS_INTROSPECTABLE_INTERFACE \
"</node>\n"
const char bus_service_interface[] = BUS_SERVICE_INTERFACE;
+const char bus_service_invalidating_properties[] =
+ "ExecStartPre\0"
+ "ExecStart\0"
+ "ExecStartPost\0"
+ "ExecReload\0"
+ "ExecStop\0"
+ "ExecStopPost\0"
+ "ExecMain\0"
+ "MainPID\0"
+ "ControlPID\0"
+ "StatusText\0"
+ "\0";
+
static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_service_append_type, service_type, ServiceType);
static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_service_append_restart, service_restart, ServiceRestart);
static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_service_append_notify_access, notify_access, NotifyAccess);
DBusHandlerResult bus_service_message_handler(Unit *u, DBusConnection *c, DBusMessage *message);
extern const char bus_service_interface[];
+extern const char bus_service_invalidating_properties[];
#endif
BUS_UNIT_INTERFACE \
BUS_SNAPSHOT_INTERFACE \
BUS_PROPERTIES_INTERFACE \
+ BUS_PEER_INTERFACE \
BUS_INTROSPECTABLE_INTERFACE \
"</node>\n"
BUS_UNIT_INTERFACE \
BUS_SOCKET_INTERFACE \
BUS_PROPERTIES_INTERFACE \
+ BUS_PEER_INTERFACE \
BUS_INTROSPECTABLE_INTERFACE \
"</node>\n"
const char bus_socket_interface[] = BUS_SOCKET_INTERFACE;
+const char bus_socket_invalidating_properties[] =
+ "ExecStartPre\0"
+ "ExecStartPost\0"
+ "ExecStopPre\0"
+ "ExecStopPost\0"
+ "ControlPID\0"
+ "NAccepted\0"
+ "NConnections\0"
+ "\0";
+
static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_socket_append_bind_ipv6_only, socket_address_bind_ipv6_only, SocketAddressBindIPv6Only);
DBusHandlerResult bus_socket_message_handler(Unit *u, DBusConnection *c, DBusMessage *message) {
DBusHandlerResult bus_socket_message_handler(Unit *u, DBusConnection *c, DBusMessage *message);
extern const char bus_socket_interface[];
+extern const char bus_socket_invalidating_properties[];
#endif
BUS_UNIT_INTERFACE \
BUS_SWAP_INTERFACE \
BUS_PROPERTIES_INTERFACE \
+ BUS_PEER_INTERFACE \
BUS_INTROSPECTABLE_INTERFACE \
"</node>\n"
const char bus_swap_interface[] = BUS_SWAP_INTERFACE;
+const char bus_swap_invalidating_properties[] =
+ "What\0"
+ "Priority\0"
+ "\0";
+
static int bus_swap_append_priority(Manager *m, DBusMessageIter *i, const char *property, void *data) {
Swap *s = data;
dbus_int32_t j;
DBusHandlerResult bus_swap_message_handler(Unit *u, DBusConnection *c, DBusMessage *message);
extern const char bus_swap_interface[];
+extern const char bus_swap_invalidating_properties[];
#endif
BUS_UNIT_INTERFACE \
BUS_TARGET_INTERFACE \
BUS_PROPERTIES_INTERFACE \
+ BUS_PEER_INTERFACE \
BUS_INTROSPECTABLE_INTERFACE \
"</node>\n"
BUS_UNIT_INTERFACE \
BUS_TIMER_INTERFACE \
BUS_PROPERTIES_INTERFACE \
+ BUS_PEER_INTERFACE \
BUS_INTROSPECTABLE_INTERFACE \
"</node>\n"
const char bus_timer_interface[] = BUS_TIMER_INTERFACE;
+const char bus_timer_invalidating_properties[] =
+ "Timers\0"
+ "NextElapseUSec\0"
+ "\0";
+
static int bus_timer_append_timers(Manager *m, DBusMessageIter *i, const char *property, void *data) {
Timer *p = data;
DBusMessageIter sub, sub2;
DBusHandlerResult bus_timer_message_handler(Unit *u, DBusConnection *c, DBusMessage *message);
extern const char bus_timer_interface[];
+extern const char bus_timer_invalidating_properties[];
#endif
const char bus_unit_interface[] = BUS_UNIT_INTERFACE;
+#define INVALIDATING_PROPERTIES \
+ "LoadState\0" \
+ "ActiveState\0" \
+ "SubState\0" \
+ "InactiveExitTimestamp\0" \
+ "ActiveEnterTimestamp\0" \
+ "ActiveExitTimestamp\0" \
+ "InactiveEnterTimestamp\0" \
+ "Job\0" \
+ "NeedDaemonReload\0" \
+ "\0"
+
int bus_unit_append_names(Manager *m, DBusMessageIter *i, const char *property, void *data) {
char *t;
Iterator j;
goto oom;
if (u->meta.sent_dbus_new_signal) {
- /* Send a change signal */
+ /* Send a properties changed signal. First for the
+ * specific type, then for the generic unit. The
+ * clients may rely on this order to get atomic
+ * behaviour if needed. */
+
+ if (UNIT_VTABLE(u)->bus_invalidating_properties) {
+
+ if (!(m = bus_properties_changed_new(p,
+ UNIT_VTABLE(u)->bus_interface,
+ UNIT_VTABLE(u)->bus_invalidating_properties)))
+ goto oom;
+
+ if (bus_broadcast(u->meta.manager, m) < 0)
+ goto oom;
- if (!(m = dbus_message_new_signal(p, "org.freedesktop.systemd1.Unit", "Changed")))
+ dbus_message_unref(m);
+ }
+
+ if (!(m = bus_properties_changed_new(p, "org.freedesktop.systemd1.Unit", INVALIDATING_PROPERTIES)))
goto oom;
+
} else {
/* Send a new signal */
" <arg name=\"job\" type=\"o\" direction=\"out\"/>\n" \
" </method>\n" \
" <method name=\"ResetMaintenance\"/>\n" \
- " <signal name=\"Changed\"/>\n" \
" <property name=\"Id\" type=\"s\" access=\"read\"/>\n" \
" <property name=\"Names\" type=\"as\" access=\"read\"/>\n" \
" <property name=\"Following\" type=\"s\" access=\"read\"/>\n" \
if (!dbus_message_iter_close_container(&iter, &sub))
goto oom;
}
+
} else if (dbus_message_is_method_call(message, "org.freedesktop.DBus.Properties", "GetAll") && properties) {
const char *interface;
const BusProperty *p;
return !set_isempty(BUS_CONNECTION_SUBSCRIBED(m, c));
}
+
+DBusMessage* bus_properties_changed_new(const char *path, const char *interface, const char *properties) {
+ DBusMessage *m;
+ DBusMessageIter iter, sub;
+ const char *i;
+
+ assert(interface);
+ assert(properties);
+
+ if (!(m = dbus_message_new_signal(path, "org.freedesktop.DBus.Properties", "PropertiesChanged")))
+ goto oom;
+
+ dbus_message_iter_init_append(m, &iter);
+
+ /* We won't send any property values, since they might be
+ * large and sometimes not cheap to generated */
+
+ if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &interface) ||
+ !dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "{sv}", &sub) ||
+ !dbus_message_iter_close_container(&iter, &sub) ||
+ !dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "s", &sub))
+ goto oom;
+
+ NULSTR_FOREACH(i, properties)
+ if (!dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, &i))
+ goto oom;
+
+ if (!dbus_message_iter_close_container(&iter, &sub))
+ goto oom;
+
+ return m;
+
+oom:
+ if (m)
+ dbus_message_unref(m);
+
+ return NULL;
+}
" <arg name=\"interface\" direction=\"in\" type=\"s\"/>\n" \
" <arg name=\"properties\" direction=\"out\" type=\"a{sv}\"/>\n" \
" </method>\n" \
+ " <signal name=\"PropertiesChanged\">\n" \
+ " <arg type=\"s\" name=\"interface\"/>\n" \
+ " <arg type=\"a{sv}\" name=\"changed_properties\"/>\n" \
+ " <arg type=\"as\" name=\"invalidated_properties\"/>\n" \
+ " </signal>\n" \
" </interface>\n"
#define BUS_INTROSPECTABLE_INTERFACE \
" </method>\n" \
" </interface>\n"
+#define BUS_PEER_INTERFACE \
+ "<interface name=\"org.freedesktop.DBus.Peer\">\n" \
+ " <method name=\"Ping\"/>\n" \
+ " <method name=\"GetMachineId\">\n" \
+ " <arg type=\"s\" name=\"machine_uuid\" direction=\"out\"/>\n" \
+ " </method>\n" \
+ "</interface>\n"
+
int bus_init(Manager *m);
void bus_done(Manager *m);
bool bus_has_subscriber(Manager *m);
bool bus_connection_has_subscriber(Manager *m, DBusConnection *c);
+DBusMessage* bus_properties_changed_new(const char *path, const char *interface, const char *properties);
+
#define BUS_CONNECTION_SUBSCRIBED(m, c) dbus_connection_get_data((c), (m)->subscribed_data_slot)
#define BUS_PENDING_CALL_NAME(m, p) dbus_pending_call_get_data((p), (m)->name_data_slot)
.active_state = device_active_state,
.sub_state_to_string = device_sub_state_to_string,
+ .bus_interface = "org.freedesktop.systemd1.Device",
.bus_message_handler = bus_device_message_handler,
+ .bus_invalidating_properties = bus_device_invalidating_properties,
.following = device_following,
default:
assert_not_reached("Uh, control process died at wrong time.");
}
+
+ /* Notify clients about changed exit status */
+ unit_add_to_dbus_queue(u);
}
static void mount_timer_event(Unit *u, uint64_t elapsed, Watch *w) {
.reset_maintenance = mount_reset_maintenance,
+ .bus_interface = "org.freedesktop.systemd1.Mount",
.bus_message_handler = bus_mount_message_handler,
+ .bus_invalidating_properties = bus_mount_invalidating_properties,
.enumerate = mount_enumerate,
.shutdown = mount_shutdown
.reset_maintenance = path_reset_maintenance,
+ .bus_interface = "org.freedesktop.systemd1.Path",
.bus_message_handler = bus_path_message_handler
};
}
}
}
+
+ /* Notify clients about changed exit status */
+ unit_add_to_dbus_queue(u);
}
static void service_timer_event(Unit *u, uint64_t elapsed, Watch* w) {
}
}
+
+ /* Notify clients about changed status or main pid */
+ unit_add_to_dbus_queue(u);
}
static int service_enumerate(Manager *m) {
.bus_name_owner_change = service_bus_name_owner_change,
.bus_query_pid_done = service_bus_query_pid_done,
+ .bus_interface = "org.freedesktop.systemd1.Service",
.bus_message_handler = bus_service_message_handler,
+ .bus_invalidating_properties = bus_service_invalidating_properties,
.enumerate = service_enumerate
};
.active_state = snapshot_active_state,
.sub_state_to_string = snapshot_sub_state_to_string,
+ .bus_interface = "org.freedesktop.systemd1.Snapshot",
.bus_message_handler = bus_snapshot_message_handler
};
const char *path,
mode_t directory_mode,
mode_t socket_mode,
- const char *label,
int *_fd) {
int fd = -1, r = 0;
mkdir_parents(path, directory_mode);
- if ((r = label_fifofile_set(label, path)) < 0)
+ if ((r = label_fifofile_set(path)) < 0)
goto fail;
/* Enforce the right access mode for the fifo */
if ((r = manager_add_job(s->meta.manager, JOB_START, UNIT(service), JOB_REPLACE, true, &error, NULL)) < 0)
goto fail;
+
+ /* Notify clients about changed counters */
+ unit_add_to_dbus_queue(UNIT(s));
}
return;
assert_not_reached("Uh, control process died at wrong time.");
}
}
+
+ /* Notify clients about changed exit status */
+ unit_add_to_dbus_queue(u);
}
static void socket_timer_event(Unit *u, uint64_t elapsed, Watch *w) {
.reset_maintenance = socket_reset_maintenance,
- .bus_message_handler = bus_socket_message_handler
+ .bus_interface = "org.freedesktop.systemd1.Socket",
+ .bus_message_handler = bus_socket_message_handler,
+ .bus_invalidating_properties = bus_socket_invalidating_properties
};
.check_gc = swap_check_gc,
+ .bus_interface = "org.freedesktop.systemd1.Swap",
.bus_message_handler = bus_swap_message_handler,
+ .bus_invalidating_properties = bus_swap_invalidating_properties,
.reset_maintenance = swap_reset_maintenance,
foreach (var i in list) {
TreeIter iter;
+ Properties p = bus.get_object(
+ "org.freedesktop.systemd1",
+ i.unit_path,
+ "org.freedesktop.DBus.Properties") as Properties;
+
+
+ p.properties_changed.connect(on_unit_changed);
+
Unit u = bus.get_object(
"org.freedesktop.systemd1",
i.unit_path,
"org.freedesktop.systemd1.Unit") as Unit;
- u.changed.connect(on_unit_changed);
-
unit_model.append(out iter);
unit_model.set(iter,
0, i.id,
foreach (var i in list) {
TreeIter iter;
+ Properties p = bus.get_object(
+ "org.freedesktop.systemd1",
+ i.job_path,
+ "org.freedesktop.DBus.Properties") as Properties;
+
+ p.properties_changed.connect(on_job_changed);
+
Job j = bus.get_object(
"org.freedesktop.systemd1",
i.job_path,
"org.freedesktop.systemd1.Job") as Job;
- j.changed.connect(on_job_changed);
-
job_model.append(out iter);
job_model.set(iter,
0, "%u".printf(i.id),
}
public void on_unit_new(string id, ObjectPath path) {
- Unit u = bus.get_object(
+ Properties p = bus.get_object(
"org.freedesktop.systemd1",
path,
- "org.freedesktop.systemd1.Unit") as Unit;
+ "org.freedesktop.DBus.Properties") as Properties;
- u.changed.connect(on_unit_changed);
+ p.properties_changed.connect(on_unit_changed);
TreeIter iter;
unit_model.append(out iter);
+
+ Unit u = bus.get_object(
+ "org.freedesktop.systemd1",
+ path,
+ "org.freedesktop.systemd1.Unit") as Unit;
+
update_unit_iter(iter, id, u);
}
}
public void on_job_new(uint32 id, ObjectPath path) {
- Job j = bus.get_object(
+
+ Properties p = bus.get_object(
"org.freedesktop.systemd1",
path,
- "org.freedesktop.systemd1.Job") as Job;
+ "org.freedesktop.DBus.Properties") as Properties;
- j.changed.connect(on_job_changed);
+ p.properties_changed.connect(on_job_changed);
TreeIter iter;
job_model.append(out iter);
+
+ Job j = bus.get_object(
+ "org.freedesktop.systemd1",
+ path,
+ "org.freedesktop.systemd1.Job") as Job;
+
update_job_iter(iter, id, j);
}
} while (job_model.iter_next(ref iter));
}
- public void on_unit_changed(Unit u) {
+ public void on_unit_changed(Properties p, string iface, HashTable<string, Value?> changed_properties, string[] invalidated_properties) {
TreeIter iter;
string id;
+ Unit u = bus.get_object(
+ p.get_bus_name(),
+ p.get_path(),
+ "org.freedesktop.systemd1.Unit") as Unit;
+
if (!(unit_model.get_iter_first(out iter)))
return;
} while (unit_model.iter_next(ref iter));
}
- public void on_job_changed(Job j) {
+ public void on_job_changed(Properties p, string iface, HashTable<string, Value?> changed_properties, string[] invalidated_properties) {
TreeIter iter;
uint32 id;
+ Job j = bus.get_object(
+ p.get_bus_name(),
+ p.get_path(),
+ "org.freedesktop.systemd1.Job") as Job;
+
if (!(job_model.get_iter_first(out iter)))
return;
printf("Job %u removed.\n", id);
- } else if (dbus_message_is_signal(message, "org.freedesktop.systemd1.Unit", "Changed") ||
- dbus_message_is_signal(message, "org.freedesktop.systemd1.Job", "Changed")) {
+ } else if (dbus_message_is_signal(message, "org.freedesktop.DBus.Properties", "PropertiesChanged")) {
const char *path, *interface, *property = "Id";
DBusMessageIter iter, sub;
path = dbus_message_get_path(message);
- interface = dbus_message_get_interface(message);
+
+ if (!dbus_message_get_args(message, &error,
+ DBUS_TYPE_STRING, &interface,
+ DBUS_TYPE_INVALID)) {
+ log_error("Failed to parse message: %s", error.message);
+ goto finish;
+ }
+
+ if (!streq(interface, "org.freedesktop.systemd1.Job") &&
+ !streq(interface, "org.freedesktop.systemd1.Unit"))
+ goto finish;
if (!(m = dbus_message_new_method_call(
"org.freedesktop.systemd1",
dbus_bus_add_match(bus,
"type='signal',"
"sender='org.freedesktop.systemd1',"
- "interface='org.freedesktop.systemd1.Unit',"
- "member='Changed'",
- &error);
-
- if (dbus_error_is_set(&error)) {
- log_error("Failed to add match: %s", error.message);
- r = -EIO;
- goto finish;
- }
-
- dbus_bus_add_match(bus,
- "type='signal',"
- "sender='org.freedesktop.systemd1',"
- "interface='org.freedesktop.systemd1.Job',"
- "member='Changed'",
+ "interface='org.freedesktop.DBus.Properties',"
+ "member='PropertiesChanged'",
&error);
if (dbus_error_is_set(&error)) {
public abstract JobInfo[] list_jobs() throws DBus.Error;
public abstract ObjectPath get_unit(string name) throws DBus.Error;
+ public abstract ObjectPath get_unit_by_pid(uint32 pid) throws DBus.Error;
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 ObjectPath start_unit(string name, string mode = "replace") throws DBus.Error;
+ public abstract ObjectPath stop_unit(string name, string mode = "replace") throws DBus.Error;
+ public abstract ObjectPath reload_unit(string name, string mode = "replace") throws DBus.Error;
+ public abstract ObjectPath restart_unit(string name, string mode = "replace") throws DBus.Error;
+ public abstract ObjectPath try_restart_unit(string name, string mode = "replace") throws DBus.Error;
+ public abstract ObjectPath reload_or_restart_unit(string name, string mode = "replace") throws DBus.Error;
+ public abstract ObjectPath reload_or_try_restart_unit(string name, string mode = "replace") throws DBus.Error;
+
+ public abstract void reset_maintenance_unit(string name = "") throws DBus.Error;
public abstract void clear_jobs() throws DBus.Error;
public abstract string id { owned get; }
public abstract string[] names { owned get; }
+ public abstract string following { owned get; }
public abstract string[] requires { owned get; }
public abstract string[] requires_overridable { owned get; }
public abstract string[] requisite { owned get; }
public abstract string[] required_by_overridable { owned get; }
public abstract string[] wanted_by { owned get; }
public abstract string[] conflicts { owned get; }
+ public abstract string[] conflicted_by { owned get; }
public abstract string[] before { owned get; }
public abstract string[] after { owned get; }
+ public abstract string[] on_failure { owned get; }
public abstract string description { owned get; }
public abstract string load_state { owned get; }
public abstract string active_state { owned get; }
public abstract uint64 active_exit_timestamp { owned get; }
public abstract uint64 inactive_enter_timestamp { owned get; }
public abstract bool can_start { owned get; }
+ public abstract bool can_stop { owned get; }
public abstract bool can_reload { owned get; }
public abstract JobLink job { owned get; }
public abstract bool recursive_stop { owned get; }
public abstract bool stop_when_unneeded { owned get; }
+ public abstract bool refuse_manual_start { owned get; }
+ public abstract bool refuse_manual_stop { owned get; }
+ public abstract bool default_dependencies { owned get; }
public abstract string default_control_group { owned get; }
public abstract string[] control_groups { owned get; }
-
- public abstract ObjectPath start(string mode) throws DBus.Error;
- public abstract ObjectPath stop(string mode) throws DBus.Error;
- public abstract ObjectPath restart(string mode) throws DBus.Error;
- public abstract ObjectPath reload(string mode) throws DBus.Error;
-
- public abstract signal void changed();
+ public abstract bool need_daemon_reload { owned get; }
+ public abstract uint64 job_timeout_usec { owned get; }
+
+ public abstract ObjectPath start(string mode = "replace") throws DBus.Error;
+ public abstract ObjectPath stop(string mode = "replace") throws DBus.Error;
+ public abstract ObjectPath reload(string mode = "replace") throws DBus.Error;
+ public abstract ObjectPath restart(string mode = "replace") throws DBus.Error;
+ public abstract ObjectPath try_restart(string mode = "replace") throws DBus.Error;
+ public abstract ObjectPath reload_or_restart(string mode = "replace") throws DBus.Error;
+ public abstract ObjectPath reload_or_try_restart(string mode = "replace") throws DBus.Error;
+
+ public abstract void reset_maintenance() throws DBus.Error;
}
[DBus (name = "org.freedesktop.systemd1.Job")]
public abstract UnitLink unit { owned get; }
public abstract void cancel() throws DBus.Error;
+}
- public abstract signal void changed();
+[DBus (name = "org.freedesktop.DBus.Properties")]
+public interface Properties : DBus.Object {
+ public abstract Value? get(string iface, string property) throws DBus.Error;
+ public abstract signal void properties_changed(string iface, HashTable<string, Value?> changed_properties, string[] invalidated_properties);
}
.active_state = target_active_state,
.sub_state_to_string = target_sub_state_to_string,
+ .bus_interface = "org.freedesktop.systemd1.Target",
.bus_message_handler = bus_target_message_handler
};
.reset_maintenance = timer_reset_maintenance,
- .bus_message_handler = bus_timer_message_handler
+ .bus_interface = "org.freedesktop.systemd1.Timer",
+ .bus_message_handler = bus_timer_message_handler,
+ .bus_invalidating_properties = bus_timer_invalidating_properties
};
/* Type specific cleanups. */
void (*shutdown)(Manager *m);
+ /* When sending out PropertiesChanged signal, which properties
+ * shall be invalidated? This is a NUL seperated list of
+ * strings, to minimize relocations a little. */
+ const char *bus_invalidating_properties;
+
+ /* The interface name */
+ const char *bus_interface;
+
/* Can units of this type have multiple names? */
bool no_alias:1;
int touch(const char *path);
+#define NULSTR_FOREACH(i, l) \
+ for ((i) = (l); (i) && *(i); (i) = strchr((i), 0)+1)
+
const char *ioprio_class_to_string(int i);
int ioprio_class_from_string(const char *s);