+void manager_dispatch_bus_name_owner_changed(
+ Manager *m,
+ const char *name,
+ const char* old_owner,
+ const char *new_owner) {
+
+ Unit *u;
+
+ assert(m);
+ assert(name);
+
+ if (!(u = hashmap_get(m->watch_bus, name)))
+ return;
+
+ UNIT_VTABLE(u)->bus_name_owner_change(u, name, old_owner, new_owner);
+}
+
+void manager_dispatch_bus_query_pid_done(
+ Manager *m,
+ const char *name,
+ pid_t pid) {
+
+ Unit *u;
+
+ assert(m);
+ assert(name);
+ assert(pid >= 1);
+
+ if (!(u = hashmap_get(m->watch_bus, name)))
+ return;
+
+ UNIT_VTABLE(u)->bus_query_pid_done(u, name, pid);
+}
+
+int manager_open_serialization(FILE **_f) {
+ char *path;
+ mode_t saved_umask;
+ int fd;
+ FILE *f;
+
+ assert(_f);
+
+ if (asprintf(&path, "/dev/shm/systemd-%u.dump-XXXXXX", (unsigned) getpid()) < 0)
+ return -ENOMEM;
+
+ saved_umask = umask(0077);
+ fd = mkostemp(path, O_RDWR|O_CLOEXEC);
+ umask(saved_umask);
+
+ if (fd < 0) {
+ free(path);
+ return -errno;
+ }
+
+ unlink(path);
+
+ log_debug("Serializing state to %s", path);
+ free(path);
+
+ if (!(f = fdopen(fd, "w+")) < 0)
+ return -errno;
+
+ *_f = f;
+
+ return 0;
+}
+
+int manager_serialize(Manager *m, FILE *f, FDSet *fds) {
+ Iterator i;
+ Unit *u;
+ const char *t;
+ int r;
+
+ assert(m);
+ assert(f);
+ assert(fds);
+
+ HASHMAP_FOREACH_KEY(u, t, m->units, i) {
+ if (u->meta.id != t)
+ continue;
+
+ if (!unit_can_serialize(u))
+ continue;
+
+ /* Start marker */
+ fputs(u->meta.id, f);
+ fputc('\n', f);
+
+ if ((r = unit_serialize(u, f, fds)) < 0)
+ return r;
+ }
+
+ if (ferror(f))
+ return -EIO;
+
+ return 0;
+}
+
+int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
+ int r = 0;
+
+ assert(m);
+ assert(f);
+
+ log_debug("Deserializing state...");
+
+ for (;;) {
+ Unit *u;
+ char name[UNIT_NAME_MAX+2];
+
+ /* Start marker */
+ if (!fgets(name, sizeof(name), f)) {
+ if (feof(f))
+ break;
+
+ return -errno;
+ }
+
+ char_array_0(name);
+
+ if ((r = manager_load_unit(m, strstrip(name), NULL, &u)) < 0)
+ return r;
+
+ if ((r = unit_deserialize(u, f, fds)) < 0)
+ return r;
+ }
+
+ if (ferror(f))
+ return -EIO;
+
+ return 0;
+}
+
+int manager_reload(Manager *m) {
+ int r, q;
+ FILE *f;
+ FDSet *fds;
+
+ assert(m);
+
+ if ((r = manager_open_serialization(&f)) < 0)
+ return r;
+
+ if (!(fds = fdset_new())) {
+ r = -ENOMEM;
+ goto finish;
+ }
+
+ if ((r = manager_serialize(m, f, fds)) < 0)
+ goto finish;
+
+ if (fseeko(f, 0, SEEK_SET) < 0) {
+ r = -errno;
+ goto finish;
+ }
+
+ /* From here on there is no way back. */
+ manager_clear_jobs_and_units(m);
+
+ /* First, enumerate what we can from all config files */
+ if ((q = manager_enumerate(m)) < 0)
+ r = q;
+
+ /* Second, deserialize our stored data */
+ if ((q = manager_deserialize(m, f, fds)) < 0)
+ r = q;
+
+ fclose(f);
+ f = NULL;
+
+ /* Third, fire things up! */
+ if ((q = manager_coldplug(m)) < 0)
+ r = q;
+
+finish:
+ if (f)
+ fclose(f);
+
+ if (fds)
+ fdset_free(fds);
+
+ return r;
+}
+