return n;
}
+/* FIXME: Does not rollback on failure! */
+int name_link_names(Name *n, bool replace) {
+ char *t;
+ void *state;
+ int r;
+
+ assert(n);
+
+ if (!n->meta.linked)
+ return 0;
+
+ /* Link all names that aren't linked yet. */
+
+ SET_FOREACH(t, n->meta.names, state)
+ if (replace) {
+ if ((r = hashmap_replace(n->meta.manager->names, t, n)) < 0)
+ return r;
+ } else {
+ if ((r = hashmap_put(n->meta.manager->names, t, n)) < 0)
+ return r;
+ }
+
+ return 0;
+}
+
int name_link(Name *n) {
- char **t;
int r;
- void *state;
assert(n);
assert(!set_isempty(n->meta.names));
assert(!n->meta.linked);
- SET_FOREACH(t, n->meta.names, state)
- if ((r = hashmap_put(n->meta.manager->names, t, n)) < 0)
- goto fail;
+ n->meta.linked = true;
- if (n->meta.state == NAME_STUB)
- LIST_PREPEND(Meta, n->meta.manager->load_queue, &n->meta);
+ if ((r = name_link_names(n, false) < 0)) {
+ char *t;
+ void *state;
- n->meta.linked = true;
+ /* Rollback the registered names */
+ SET_FOREACH(t, n->meta.names, state)
+ hashmap_remove_value(n->meta.manager->names, t, n);
- return 0;
+ n->meta.linked = false;
+ return r;
+ }
-fail:
- SET_FOREACH(t, n->meta.names, state)
- assert_se(hashmap_remove(n->meta.manager->names, t) == n);
+ if (n->meta.state == NAME_STUB)
+ LIST_PREPEND(Meta, n->meta.manager->load_queue, &n->meta);
- return r;
+ return 0;
}
static void bidi_set_free(Name *name, Set *s) {
/* Detach from next 'bigger' objects */
if (name->meta.linked) {
- char **t;
+ char *t;
void *state;
SET_FOREACH(t, name->meta.names, state)
- assert_se(hashmap_remove(name->meta.manager->names, t) == name);
+ hashmap_remove_value(name->meta.manager->names, t, name);
if (name->meta.state == NAME_STUB)
LIST_REMOVE(Meta, name->meta.manager->load_queue, &name->meta);
Socket *s = SOCKET(name);
for (i = 0; i < s->n_fds; i++)
- nointr_close(s->fds[i]);
+ close_nointr(s->fds[i]);
break;
}
return 0;
}
+/* FIXME: Does not rollback on failure! */
int name_augment(Name *n) {
int r;
void* state;
assert(n);
- /* Adds in the missing links to make all dependencies bidirectional */
+ /* Adds in the missing links to make all dependencies
+ * bidirectional. */
SET_FOREACH(other, n->meta.dependencies[NAME_BEFORE], state)
if ((r = ensure_in_set(&other->meta.dependencies[NAME_AFTER], n) < 0))
return 0;
}
+/* FIXME: Does not rollback on failure! */
int name_merge(Name *name, Name *other) {
int r;
NameDependency d;
assert(name);
assert(other);
-
assert(name->meta.manager == other->meta.manager);
+ /* This merges 'other' into 'name'. FIXME: This does not
+ * rollback on failure. */
+
if (name->meta.type != other->meta.type)
return -EINVAL;
if ((r = ensure_merge(&name->meta.dependencies[d], other->meta.dependencies[d])) < 0)
return r;
+ /* Hookup new deps and names */
+ if (name->meta.linked) {
+ if ((r = name_augment(name)) < 0)
+ return r;
+
+ if ((r = name_link_names(name, true)) < 0)
+ return r;
+ }
+
return 0;
}
return set_first(n->meta.names);
}
-void name_dump(Name *n, FILE *f) {
+void name_dump(Name *n, FILE *f, const char *prefix) {
static const char* const state_table[_NAME_STATE_MAX] = {
- [NAME_STUB] = "STUB",
- [NAME_LOADED] = "LOADED",
- [NAME_FAILED] = "FAILED"
+ [NAME_STUB] = "stub",
+ [NAME_LOADED] = "loaded",
+ [NAME_FAILED] = "failed"
};
+ static const char* const socket_state_table[_SOCKET_STATE_MAX] = {
+ [SOCKET_DEAD] = "dead",
+ [SOCKET_BEFORE] = "before",
+ [SOCKET_START_PRE] = "start-pre",
+ [SOCKET_START] = "start",
+ [SOCKET_START_POST] = "start-post",
+ [SOCKET_LISTENING] = "listening",
+ [SOCKET_RUNNING] = "running",
+ [SOCKET_STOP_PRE] = "stop-pre",
+ [SOCKET_STOP] = "stop",
+ [SOCKET_STOP_POST] = "stop-post",
+ [SOCKET_MAINTAINANCE] = "maintainance"
+ };
+
+ void *state;
+ char *t;
+
assert(n);
- fprintf(stderr,
- "Name %s (%s), state %s\n",
- name_id(n),
- n->meta.description ? n->meta.description : name_id(n),
- state_table[n->meta.state]);
+ if (!prefix)
+ prefix = "";
+
+ fprintf(f,
+ "%sName %s:\n"
+ "%s\tDescription: %s\n"
+ "%s\tName State: %s\n",
+ prefix, name_id(n),
+ prefix, n->meta.description ? n->meta.description : name_id(n),
+ prefix, state_table[n->meta.state]);
+
+ fprintf(f, "%s\tNames: ", prefix);
+ SET_FOREACH(t, n->meta.names, state)
+ fprintf(f, "%s ", t);
+ fprintf(f, "\n");
+
+ switch (n->meta.type) {
+ case NAME_SOCKET: {
+ int r;
+ char *s = NULL;
+ const char *t;
+
+ if ((r = address_print(&n->socket.address, &s)) < 0)
+ t = strerror(-r);
+ else
+ t = s;
+
+ fprintf(f,
+ "%s\tAddress: %s\n"
+ "%s\tSocket State: %s\n",
+ prefix, t,
+ prefix, socket_state_table[n->socket.state]);
+
+ free(s);
+ break;
+ }
+
+ default:
+ ;
+ }
if (n->meta.job) {
- fprintf(f, "\tâ–¶ ");
- job_dump(n->meta.job, f);
+ char *p;
+
+ if (asprintf(&p, "%s\t", prefix) >= 0)
+ prefix = p;
+ else
+ p = NULL;
+
+ job_dump(n->meta.job, f, prefix);
+ free(p);
}
}