a->tokens = NULL;
}
+int automount_add_one_mount_link(Automount *a, Mount *m) {
+ int r;
+
+ assert(a);
+ assert(m);
+
+ if (a->meta.load_state != UNIT_LOADED ||
+ m->meta.load_state != UNIT_LOADED)
+ return 0;
+
+ if (!path_startswith(a->where, m->where))
+ return 0;
+
+ if ((r = unit_add_dependency(UNIT(m), UNIT_BEFORE, UNIT(a), true)) < 0)
+ return r;
+
+ if ((r = unit_add_dependency(UNIT(a), UNIT_REQUIRES, UNIT(m), true)) < 0)
+ return r;
+
+ return 0;
+}
+
+static int automount_add_mount_links(Automount *a) {
+ Meta *other;
+ int r;
+
+ assert(a);
+
+ LIST_FOREACH(units_per_type, other, a->meta.manager->units_per_type[UNIT_MOUNT])
+ if ((r = automount_add_one_mount_link(a, (Mount*) other)) < 0)
+ return r;
+
+ return 0;
+}
+
static int automount_verify(Automount *a) {
bool b;
char *e;
path_kill_slashes(a->where);
+ if ((r = automount_add_mount_links(a)) < 0)
+ return r;
+
if ((r = unit_load_related_unit(u, ".mount", (Unit**) &a->mount)) < 0)
return r;
int automount_send_ready(Automount *a, int status);
+int automount_add_one_mount_link(Automount *a, Mount *m);
+
const char* automount_state_to_string(AutomountState i);
AutomountState automount_state_from_string(const char *s);
" <arg name=\"names\" type=\"as\" direction=\"in\"/>" \
" </method>" \
" <method name=\"UnsetEnvironment\">" \
- " <arg name=\"names\" type=\"as\" direction=\"in\"/>" \
+ " <arg name=\"names\" type=\"as\" direction=\"in\"/>" \
" </method>" \
" <signal name=\"UnitNew\">" \
" <arg name=\"id\" type=\"s\"/>" \
for ((i) = ITERATOR_FIRST, (e) = hashmap_iterate((h), &(i), (const void**) &(k)); (e); (e) = hashmap_iterate((h), &(i), (const void**) &(k)))
#define HASHMAP_FOREACH_BACKWARDS(e, h, i) \
- for ((i) = ITERATE_LAST, (e) = hashmap_iterate_backwards((h), &(i), NULL); (e); (e) = hashmap_iterate_backwards((h), &(i), NULL))
+ for ((i) = ITERATOR_LAST, (e) = hashmap_iterate_backwards((h), &(i), NULL); (e); (e) = hashmap_iterate_backwards((h), &(i), NULL))
#endif
}
if ((r = manager_startup(m, serialization, fds)) < 0)
- log_error("Failed to fully startup daemon: %s", strerror(-r));
+ log_error("Failed to fully start up daemon: %s", strerror(-r));
if (fds) {
/* This will close all file descriptors that were opened, but
}
if (m->running_as == MANAGER_INIT) {
- /* /etc/init.d/ compativility does not matter to users */
+ /* /etc/init.d/ compatibility does not matter to users */
if ((e = getenv("SYSTEMD_SYSVINIT_PATH")))
if (!(m->sysvinit_path = split_path_and_make_absolute(e)))
unit_unwatch_timer(u, &m->timer_watch);
}
-int mount_add_node_links(Unit *u, const char *what) {
- Unit *device;
- char *e;
+static int mount_add_mount_links(Mount *m) {
+ Meta *other;
int r;
- assert(u);
+ assert(m);
- if (!what)
- /* We observe kernel mounts only while they are live,
- * hence don't create any links for them */
- return 0;
+ /* Adds in links to other mount points that might lie below or
+ * above us in the hierarchy */
- /* Adds in links to the device that this node is based on */
+ LIST_FOREACH(units_per_type, other, m->meta.manager->units_per_type[UNIT_MOUNT]) {
+ Mount *n = (Mount*) other;
- if (!path_startswith(what, "/dev/"))
- return 0;
+ if (n == m)
+ continue;
- if (!(e = unit_name_build_escape(what+1, NULL, ".device")))
- return -ENOMEM;
+ if (n->meta.load_state != UNIT_LOADED)
+ continue;
- r = manager_load_unit(u->meta.manager, e, NULL, &device);
- free(e);
+ if (path_startswith(m->where, n->where)) {
- if (r < 0)
- return r;
+ if ((r = unit_add_dependency(UNIT(m), UNIT_AFTER, UNIT(n), true)) < 0)
+ return r;
- if ((r = unit_add_dependency(u, UNIT_AFTER, device, true)) < 0)
- return r;
+ if (n->from_etc_fstab || n->from_fragment)
+ if ((r = unit_add_dependency(UNIT(m), UNIT_REQUIRES, UNIT(n), true)) < 0)
+ return r;
- if ((r = unit_add_dependency(u, UNIT_REQUIRES, device, true)) < 0)
- return r;
+ } else if (path_startswith(n->where, m->where)) {
- if (u->meta.manager->running_as == MANAGER_INIT ||
- u->meta.manager->running_as == MANAGER_SYSTEM)
- if ((r = unit_add_dependency(device, UNIT_WANTS, u, false)) < 0)
- return r;
+ if ((r = unit_add_dependency(UNIT(m), UNIT_BEFORE, UNIT(n), true)) < 0)
+ return r;
+
+ if (m->from_etc_fstab || m->from_fragment)
+ if ((r = unit_add_dependency(UNIT(n), UNIT_REQUIRES, UNIT(m), true)) < 0)
+ return r;
+ }
+ }
return 0;
}
-int mount_add_path_links(Unit *u, const char *where, bool requires) {
+static int mount_add_swap_links(Mount *m) {
Meta *other;
int r;
- assert(u);
-
- /* Adds in link to other mount points, that might lie below or
- * above us in the hierarchy */
-
- LIST_FOREACH(units_per_type, other, u->meta.manager->units_per_type[UNIT_MOUNT]) {
- Mount *n;
+ assert(m);
- n = (Mount*) other;
+ LIST_FOREACH(units_per_type, other, m->meta.manager->units_per_type[UNIT_SWAP])
+ if ((r = swap_add_one_mount_link((Swap*) other, m)) < 0)
+ return r;
- if (UNIT(n) == u)
- continue;
+ return 0;
+}
- if (u->meta.load_state != UNIT_LOADED)
- continue;
+static int mount_add_automount_links(Mount *m) {
+ Meta *other;
+ int r;
- if (path_startswith(where, n->where)) {
+ assert(m);
- if ((r = unit_add_dependency(u, UNIT_AFTER, UNIT(other), true)) < 0)
- return r;
+ LIST_FOREACH(units_per_type, other, m->meta.manager->units_per_type[UNIT_AUTOMOUNT])
+ if ((r = automount_add_one_mount_link((Automount*) other, m)) < 0)
+ return r;
- if (requires)
- if ((r = unit_add_dependency(u, UNIT_REQUIRES, UNIT(other), true)) < 0)
- return r;
+ return 0;
+}
- } else if (path_startswith(n->where, where)) {
+static int mount_add_socket_links(Mount *m) {
+ Meta *other;
+ int r;
- if ((r = unit_add_dependency(u, UNIT_BEFORE, UNIT(other), true)) < 0)
- return r;
+ assert(m);
- if (requires)
- if ((r = unit_add_dependency(UNIT(other), UNIT_REQUIRES, u, true)) < 0)
- return r;
- }
- }
+ LIST_FOREACH(units_per_type, other, m->meta.manager->units_per_type[UNIT_SOCKET])
+ if ((r = socket_add_one_mount_link((Socket*) other, m)) < 0)
+ return r;
return 0;
}
/* This is a new unit? Then let's add in some extras */
if (u->meta.load_state == UNIT_LOADED) {
const char *what = m->parameters_fragment.what;
+
if (!what)
what = m->parameters_etc_fstab.what;
if (m->parameters_fragment.what)
m->from_fragment = true;
- if ((r = mount_add_node_links(u, what)) < 0)
+ if ((r = unit_add_node_link(u, what,
+ (u->meta.manager->running_as == MANAGER_INIT ||
+ u->meta.manager->running_as == MANAGER_SYSTEM))) < 0)
+ return r;
+
+ if ((r = mount_add_mount_links(m)) < 0)
+ return r;
+
+ if ((r = mount_add_socket_links(m)) < 0)
+ return r;
+
+ if ((r = mount_add_swap_links(m)) < 0)
return r;
- if ((r = mount_add_path_links(u, m->where, m->from_etc_fstab || m->from_fragment)) < 0)
+ if ((r = mount_add_automount_links(m)) < 0)
return r;
- if ((r = mount_add_target_links(MOUNT(u))) < 0)
+ if ((r = mount_add_target_links(m)) < 0)
return r;
if ((r = unit_add_default_cgroup(u)) < 0)
void mount_fd_event(Manager *m, int events);
int mount_path_is_mounted(Manager *m, const char* path);
-int mount_add_node_links(Unit *m, const char *what);
-int mount_add_path_links(Unit *m, const char *where, bool requires);
const char* mount_state_to_string(MountState i);
MountState mount_state_from_string(const char *s);
return false;
return socket_address_equal(a, &b);
+}
+
+bool socket_address_needs_mount(const SocketAddress *a, const char *prefix) {
+ assert(a);
+
+ if (socket_address_family(a) != AF_UNIX)
+ return false;
+
+ if (a->sockaddr.un.sun_path[0] == 0)
+ return false;
+ return path_startswith(a->sockaddr.un.sun_path, prefix);
}
bool socket_address_equal(const SocketAddress *a, const SocketAddress *b);
+bool socket_address_needs_mount(const SocketAddress *a, const char *prefix);
+
#endif
return 0;
}
+static bool socket_needs_mount(Socket *s, const char *prefix) {
+ SocketPort *p;
+
+ assert(s);
+
+ LIST_FOREACH(port, p, s->ports) {
+
+ if (p->type == SOCKET_SOCKET) {
+ if (socket_address_needs_mount(&p->address, prefix))
+ return true;
+ } else {
+ assert(p->type == SOCKET_FIFO);
+ if (path_startswith(p->path, prefix))
+ return true;
+ }
+ }
+
+ return false;
+}
+
+int socket_add_one_mount_link(Socket *s, Mount *m) {
+ int r;
+
+ assert(s);
+ assert(m);
+
+ if (s->meta.load_state != UNIT_LOADED ||
+ m->meta.load_state != UNIT_LOADED)
+ return 0;
+
+ if (!socket_needs_mount(s, m->where))
+ return 0;
+
+ if ((r = unit_add_dependency(UNIT(m), UNIT_BEFORE, UNIT(s), true)) < 0)
+ return r;
+
+ if ((r = unit_add_dependency(UNIT(s), UNIT_REQUIRES, UNIT(m), true)) < 0)
+ return r;
+
+ return 0;
+}
+
+static int socket_add_mount_links(Socket *s) {
+ Meta *other;
+ int r;
+
+ assert(s);
+
+ LIST_FOREACH(units_per_type, other, s->meta.manager->units_per_type[UNIT_MOUNT])
+ if ((r = socket_add_one_mount_link(s, (Mount*) other)) < 0)
+ return r;
+
+ return 0;
+}
+
+static int socket_add_device_link(Socket *s) {
+ char *t;
+ int r;
+
+ assert(s);
+
+ if (!s->bind_to_device)
+ return 0;
+
+ if (asprintf(&t, "/sys/subsystem/net/devices/%s", s->bind_to_device) < 0)
+ return -ENOMEM;
+
+ r = unit_add_node_link(UNIT(s), t, false);
+ free(t);
+
+ return r;
+}
+
static int socket_load(Unit *u) {
Socket *s = SOCKET(u);
int r;
return r;
}
+ if ((r = socket_add_mount_links(s)) < 0)
+ return r;
+
+ if ((r = socket_add_device_link(s)) < 0)
+ return r;
+
if ((r = unit_add_exec_dependencies(u, &s->exec_context)) < 0)
return r;
#include "manager.h"
#include "unit.h"
#include "socket-util.h"
+#include "mount.h"
typedef enum SocketState {
SOCKET_DEAD,
/* Called from the service when it shut down */
void socket_notify_service_dead(Socket *s);
+/* Called from the mount code figure out if a mount is a dependency of
+ * any of the sockets of this socket */
+int socket_add_one_mount_link(Socket *s, Mount *m);
+
extern const UnitVTable socket_vtable;
const char* socket_state_to_string(SocketState i);
return 0;
}
+int swap_add_one_mount_link(Swap *s, Mount *m) {
+ int r;
+
+ assert(s);
+ assert(m);
+
+ if (s->meta.load_state != UNIT_LOADED ||
+ m->meta.load_state != UNIT_LOADED)
+ return 0;
+
+ if (!path_startswith(s->what, m->where))
+ return 0;
+
+ if ((r = unit_add_dependency(UNIT(m), UNIT_BEFORE, UNIT(s), true)) < 0)
+ return r;
+
+ if ((r = unit_add_dependency(UNIT(s), UNIT_REQUIRES, UNIT(m), true)) < 0)
+ return r;
+
+ return 0;
+}
+
+static int swap_add_mount_links(Swap *s) {
+ Meta *other;
+ int r;
+
+ assert(s);
+
+ LIST_FOREACH(units_per_type, other, s->meta.manager->units_per_type[UNIT_MOUNT])
+ if ((r = swap_add_one_mount_link(s, (Mount*) other)) < 0)
+ return r;
+
+ return 0;
+}
+
static int swap_add_target_links(Swap *s) {
Manager *m = s->meta.manager;
Unit *tu;
int r;
- r = manager_load_unit(m, SPECIAL_SWAP_TARGET, NULL, &tu);
- if (r < 0)
+ if ((r = manager_load_unit(m, SPECIAL_SWAP_TARGET, NULL, &tu)) < 0)
return r;
- if (!s->no_auto && (r = unit_add_dependency(tu, UNIT_WANTS, UNIT(s), true)) < 0)
- return r;
+ if (!s->no_auto)
+ if ((r = unit_add_dependency(tu, UNIT_WANTS, UNIT(s), true)) < 0)
+ return r;
return unit_add_dependency(UNIT(s), UNIT_BEFORE, tu, true);
}
path_kill_slashes(s->what);
- if ((r = mount_add_node_links(u, s->what)) < 0)
+ if ((r = unit_add_node_link(u, s->what,
+ (u->meta.manager->running_as == MANAGER_INIT ||
+ u->meta.manager->running_as == MANAGER_SYSTEM))) < 0)
return r;
- if (!path_startswith(s->what, "/dev/"))
- if ((r = mount_add_path_links(u, s->what, true)) < 0)
- return r;
+ if ((r = swap_add_mount_links(s)) < 0)
+ return r;
if ((r = swap_add_target_links(s)) < 0)
return r;
bool from_proc_swaps_only:1;
bool found_in_proc_swaps:1;
- MountState state, deserialized_state;
+ SwapState state, deserialized_state;
};
extern const UnitVTable swap_vtable;
+int swap_add_one(Manager *m, const char *what, bool no_auto, int prio, bool from_proc_swap);
+
+int swap_add_one_mount_link(Swap *s, Mount *m);
+
const char* swap_state_to_string(SwapState i);
SwapState swap_state_from_string(const char *s);
-extern int swap_add_one(Manager *m, const char *what, bool no_auto, int prio, bool from_proc_swap);
#endif
}
}
+int unit_add_node_link(Unit *u, const char *what, bool wants) {
+ Unit *device;
+ char *e;
+ int r;
+
+ assert(u);
+
+ if (!what)
+ return 0;
+
+ /* Adds in links to the device node that this unit is based on */
+
+ if (!path_startswith(what, "/dev/") && !path_startswith(what, "/sys/"))
+ return 0;
+
+ if (!(e = unit_name_build_escape(what+1, NULL, ".device")))
+ return -ENOMEM;
+
+ r = manager_load_unit(u->meta.manager, e, NULL, &device);
+ free(e);
+
+ if (r < 0)
+ return r;
+
+ if ((r = unit_add_dependency(u, UNIT_AFTER, device, true)) < 0)
+ return r;
+
+ if ((r = unit_add_dependency(u, UNIT_REQUIRES, device, true)) < 0)
+ return r;
+
+ if (wants)
+ if ((r = unit_add_dependency(device, UNIT_WANTS, u, false)) < 0)
+ return r;
+
+ return 0;
+}
static const char* const unit_type_table[_UNIT_TYPE_MAX] = {
[UNIT_SERVICE] = "service",
void unit_serialize_item(Unit *u, FILE *f, const char *key, const char *value);
int unit_deserialize(Unit *u, FILE *f, FDSet *fds);
+int unit_add_node_link(Unit *u, const char *what, bool wants);
+
const char *unit_type_to_string(UnitType i);
UnitType unit_type_from_string(const char *s);