]> git.ipfire.org Git - people/ms/network.git/commitdiff
networkd: Implement smarter handling of the configuration file hierarchy
authorMichael Tremer <michael.tremer@ipfire.org>
Sun, 11 Jun 2023 13:02:35 +0000 (13:02 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Sun, 11 Jun 2023 13:05:33 +0000 (13:05 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/networkd/config.c
src/networkd/config.h
src/networkd/daemon.c
src/networkd/daemon.h
src/networkd/port.c
src/networkd/port.h
src/networkd/ports.c
src/networkd/zone.c
src/networkd/zone.h
src/networkd/zones.c

index c6281cb249021a4c1d25111b75f2d5af58d4d008..53fd8e30894bdbcb12d3a8cb013ca7749e5718cb 100644 (file)
 #                                                                             #
 #############################################################################*/
 
+#include <dirent.h>
 #include <errno.h>
+#include <fcntl.h>
 #include <limits.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <sys/queue.h>
+#include <sys/types.h>
+#include <sys/stat.h>
 #include <unistd.h>
 
 #include "address.h"
@@ -161,7 +165,6 @@ int nw_config_open(nw_config** config, const char* path) {
        // Create a new configuration
        r = nw_config_create(config, f);
 
-ERROR:
        if (f)
                fclose(f);
 
@@ -419,6 +422,208 @@ int nw_config_set_bool(nw_config* config, const char* key, const int value) {
        return nw_config_set(config, key, value ? "true" : "false");
 }
 
+/*
+       Directory
+*/
+
+struct nw_configd {
+       int nrefs;
+
+       char path[PATH_MAX];
+       int fd;
+};
+
+static void nw_configd_free(nw_configd* dir) {
+       if (dir->fd >= 0)
+               close(dir->fd);
+
+       free(dir);
+}
+
+static int __nw_configd_create(nw_configd** dir, int fd, const char* path) {
+       nw_configd* d = NULL;
+       int r;
+
+       // Allocate a new object
+       d = calloc(1, sizeof(*d));
+       if (!d)
+               return -errno;
+
+       // Initialize the reference counter
+       d->nrefs = 1;
+
+       // Store the file descriptor
+       d->fd = dup(fd);
+       if (d->fd < 0) {
+               r = -errno;
+               goto ERROR;
+       }
+
+       // Store path
+       if (path) {
+               r = nw_string_set(d->path, path);
+               if (r < 0)
+                       goto ERROR;
+       }
+
+       *dir = d;
+       return 0;
+
+ERROR:
+       nw_configd_free(d);
+       return r;
+}
+
+int nw_configd_create(nw_configd** dir, const char* path) {
+       int fd;
+
+       // Open the directory
+       fd = open(path, O_DIRECTORY);
+       if (fd < 0) {
+               ERROR("Could not open %s: %m\n", path);
+               return -errno;
+       }
+
+       return __nw_configd_create(dir, fd, path);
+}
+
+nw_configd* nw_configd_ref(nw_configd* dir) {
+       dir->nrefs++;
+
+       return dir;
+}
+
+nw_configd* nw_configd_unref(nw_configd* dir) {
+       if (--dir->nrefs > 0)
+               return dir;
+
+       nw_configd_free(dir);
+       return NULL;
+}
+
+static int nw_configd_open(nw_configd* dir, const char* path, int flags) {
+       return openat(dir->fd, path, flags);
+}
+
+FILE* nw_configd_fopen(nw_configd* dir, const char* path, const char* mode) {
+       int fd;
+
+       // Open file
+       fd = nw_configd_open(dir, path, 0);
+       if (fd < 0)
+               return NULL;
+
+       // Return a file handle
+       return fdopen(fd, mode);
+}
+
+int nw_configd_open_config(nw_config** config, nw_configd* dir, const char* path) {
+       FILE* f = NULL;
+       int r;
+
+       // Open the file
+       f = nw_configd_fopen(dir, path, "r");
+       if (!f)
+               return -errno;
+
+       // Create configuration
+       r = nw_config_create(config, f);
+       if (r < 0)
+               goto ERROR;
+
+ERROR:
+       if (f)
+               fclose(f);
+
+       return r;
+}
+
+int nw_configd_unlink(nw_configd* dir, const char* path, int flags) {
+       return unlinkat(dir->fd, path, flags);
+}
+
+nw_configd* nw_configd_descend(nw_configd* dir, const char* path) {
+       nw_configd* d = NULL;
+       char p[PATH_MAX];
+       int fd = -1;
+       int r;
+
+       // Join paths
+       r = nw_path_join(p, dir->path, path);
+       if (r < 0)
+               goto ERROR;
+
+       // Open directory
+       fd = nw_configd_open(dir, path, O_DIRECTORY);
+       if (fd < 0) {
+               ERROR("Could not open %s: %m\n", p);
+               goto ERROR;
+       }
+
+       // Create a new config directory object
+       r = __nw_configd_create(&d, fd, p);
+       if (r < 0)
+               goto ERROR;
+
+ERROR:
+       if (fd >= 0)
+               close(fd);
+
+       return d;
+}
+
+int nw_configd_walk(nw_configd* dir, nw_configd_walk_callback callback, void* data) {
+       FILE* f = NULL;
+       DIR* d = NULL;
+       struct dirent* e = NULL;
+       int r;
+
+       // Re-open the directory
+       d = fdopendir(dir->fd);
+       if (!d) {
+               r = -errno;
+               goto ERROR;
+       }
+
+       // Walk trough everything
+       for (;;) {
+               // Read the next entry
+               e = readdir(d);
+               if (!e)
+                       break;
+
+               // Skip anything that is not a regular file
+               if (e->d_type != DT_REG)
+                       continue;
+
+               // Skip hidden files
+               if (e->d_name[0] == '.')
+                       continue;
+
+               // Open the file
+               f = nw_configd_fopen(dir, e->d_name, "r");
+               if (!f) {
+                       r = -errno;
+                       goto ERROR;
+               }
+
+               // Call the callback
+               r = callback(e, f, data);
+               fclose(f);
+
+               if (r < 0)
+                       goto ERROR;
+       }
+
+       r = 0;
+
+ERROR:
+       if (d)
+               closedir(d);
+
+       return r;
+}
+
 /*
        Options
 */
index 4b8bc01fb9570688d9977444a8bdc2b39d46d782..3e7c097729e8784d38bc36577018ebdbc9a2481f 100644 (file)
@@ -21,6 +21,7 @@
 #ifndef NETWORKD_CONFIG_H
 #define NETWORKD_CONFIG_H
 
+#include <dirent.h>
 #include <stdio.h>
 
 #define NETWORK_CONFIG_KEY_MAX_LENGTH          128
@@ -52,6 +53,27 @@ int nw_config_set_int(nw_config* config, const char* key, const int value);
 int nw_config_get_bool(nw_config* config, const char* key);
 int nw_config_set_bool(nw_config* config, const char* key, const int value);
 
+/*
+       Directory
+*/
+
+typedef struct nw_configd nw_configd;
+
+int nw_configd_create(nw_configd** dir, const char* path);
+
+nw_configd* nw_configd_ref(nw_configd* dir);
+nw_configd* nw_configd_unref(nw_configd* dir);
+
+FILE* nw_configd_fopen(nw_configd* dir, const char* path, const char* mode);
+int nw_configd_open_config(nw_config** config, nw_configd* dir, const char* path);
+int nw_configd_unlink(nw_configd* dir, const char* path, int flags);
+
+nw_configd* nw_configd_descend(nw_configd* dir, const char* path);
+
+typedef int (*nw_configd_walk_callback)(struct dirent* entry, FILE* f, void* data);
+
+int nw_configd_walk(nw_configd* dir, nw_configd_walk_callback callback, void* data);
+
 /*
        Options
 */
index a62e343fdef1318f07c7a9e69e2714ef236a77a2..dfbcc151d72cd1a4e2bd29897c2b5f95c9dac7c2 100644 (file)
@@ -51,7 +51,7 @@ struct nw_daemon {
        int nrefs;
 
        // Configuration
-       int configfd;
+       nw_configd* configd;
        nw_config* config;
 
        // Event Loop
@@ -103,36 +103,14 @@ static int __nw_daemon_reload(sd_event_source* source, const struct signalfd_sig
 */
 
 static int nw_daemon_config_open(nw_daemon* daemon, const char* path) {
-       // Open the directory
-       daemon->configfd = open(path, O_DIRECTORY);
-       if (daemon->configfd < 0) {
-               ERROR("Could not open %s: %m\n", path);
-               return -errno;
-       }
-
-       return 0;
-}
-
-FILE* nw_daemon_config_fopen(nw_daemon* daemon, const char* path, const char* mode) {
-       // Open the file
-       int fd = openat(daemon->configfd, path, 0);
-       if (fd < 0) {
-               ERROR("Could not open configuration file %s: %m\n", path);
-               return NULL;
-       }
-
-       // Return a file handle
-       return fdopen(fd, mode);
-}
+       int r;
 
-DIR* nw_daemon_config_opendir(nw_daemon* daemon, const char* path) {
-       int fd = openat(daemon->configfd, path, O_DIRECTORY);
-       if (fd < 0) {
-               ERROR("Could not open configuration directory %s: %m\n", path);
-               return NULL;
-       }
+       // Open the configuration directory
+       r = nw_configd_create(&daemon->configd, path);
+       if (r < 0)
+               return r;
 
-       return fdopendir(fd);
+       return 0;
 }
 
 static int nw_daemon_parse_argv(nw_daemon* daemon, int argc, char* argv[]) {
@@ -213,33 +191,17 @@ static int nw_daemon_setup_loop(nw_daemon* daemon) {
 }
 
 static int nw_daemon_load_config(nw_daemon* daemon) {
-       FILE* f = NULL;
        int r;
 
        // If no configuration path has been opened yet, we will open something
-       if (!daemon->configfd) {
+       if (!daemon->configd) {
                r = nw_daemon_config_open(daemon, CONFIG_DIR);
                if (r < 0)
-                       goto ERROR;
+                       return r;
        }
 
        // Open the configuration file
-       f = nw_daemon_config_fopen(daemon, "settings", "r");
-       if (!f) {
-               r = -errno;
-               goto ERROR;
-       }
-
-       // Create configuration
-       r = nw_config_create(&daemon->config, f);
-       if (r < 0)
-               goto ERROR;
-
-ERROR:
-       if (f)
-               fclose(f);
-
-       return r;
+       return nw_configd_open_config(&daemon->config, daemon->configd, "settings");
 }
 
 static int nw_start_device_monitor(nw_daemon* daemon) {
@@ -540,8 +502,8 @@ static void nw_daemon_free(nw_daemon* daemon) {
        // Cleanup common objects
        nw_daemon_cleanup(daemon);
 
-       if (daemon->configfd > 0)
-               close(daemon->configfd);
+       if (daemon->configd)
+               nw_configd_unref(daemon->configd);
        if (daemon->stats_collector_event)
                sd_event_source_unref(daemon->stats_collector_event);
        if (daemon->bus)
@@ -640,6 +602,16 @@ int nw_daemon_save(nw_daemon* daemon) {
        return 0;
 }
 
+nw_configd* nw_daemon_configd(nw_daemon* daemon, const char* path) {
+       if (!daemon->configd)
+               return NULL;
+
+       if (path)
+               return nw_configd_descend(daemon->configd, path);
+
+       return nw_configd_ref(daemon->configd);
+}
+
 /*
        Bus
 */
index b03086c873b5f0ae7a6468040091cd326ecde1a7..2d56d7971f9fb0d634af9677f0849a720966daef 100644 (file)
@@ -29,6 +29,7 @@
 
 typedef struct nw_daemon nw_daemon;
 
+#include "config.h"
 #include "link.h"
 #include "links.h"
 #include "port.h"
@@ -47,11 +48,7 @@ int nw_daemon_reload(nw_daemon* daemon);
 
 int nw_daemon_save(nw_daemon* daemon);
 
-/*
-       Configuration
-*/
-FILE* nw_daemon_config_fopen(nw_daemon* daemon, const char* path, const char* mode);
-DIR* nw_daemon_config_opendir(nw_daemon* daemon, const char* path);
+nw_configd* nw_daemon_configd(nw_daemon* daemon, const char* path);
 
 /*
        Bus
index f54795694640bed6d584afc6fc18cc785b954518..141bba59024d285f6a70349178296a4f91faa307 100644 (file)
@@ -222,24 +222,10 @@ ERROR:
        return r;
 }
 
-int nw_port_open(nw_port** port, nw_daemon* daemon, const char* name) {
+int nw_port_open(nw_port** port, nw_daemon* daemon, const char* name, FILE* f) {
        nw_config* config = NULL;
-       FILE* f = NULL;
-       char path[PATH_MAX];
        int r;
 
-       // Make path
-       r = nw_string_format(path, "ports/%s", name);
-       if (r < 0)
-               goto ERROR;
-
-       // Open the configuration file
-       f = nw_daemon_config_fopen(daemon, path, "r");
-       if (!f) {
-               r = -errno;
-               goto ERROR;
-       }
-
        // Initialize the configuration
        r = nw_config_create(&config, f);
        if (r < 0)
@@ -248,7 +234,7 @@ int nw_port_open(nw_port** port, nw_daemon* daemon, const char* name) {
        // Fetch the type
        const char* type = nw_config_get(config, "TYPE");
        if (!type) {
-               ERROR("Port configuration %s has no TYPE\n", path);
+               ERROR("Port %s has no TYPE\n", name);
                r = -ENOTSUP;
                goto ERROR;
        }
@@ -261,8 +247,6 @@ int nw_port_open(nw_port** port, nw_daemon* daemon, const char* name) {
 ERROR:
        if (config)
                nw_config_unref(config);
-       if (f)
-               fclose(f);
 
        return r;
 }
@@ -292,6 +276,7 @@ static void __nw_port_unref(void* data) {
 }
 
 int nw_port_destroy(nw_port* port) {
+       nw_configd* configd = NULL;
        int r;
 
        DEBUG("Destroying port %s\n", port->name);
@@ -299,26 +284,33 @@ int nw_port_destroy(nw_port* port) {
        // Destroy the physical link (if exists)
        if (port->link) {
                r = nw_link_destroy(port->link);
-               if (r)
-                       return r;
+               if (r < 0)
+                       goto ERROR;
        }
 
        // Dereference the port from other ports
        r = nw_daemon_ports_walk(port->daemon, __nw_port_drop_port, port);
-       if (r)
-               return r;
+       if (r < 0)
+               goto ERROR;
 
        // Dereference the port from other zones
        r = nw_daemon_zones_walk(port->daemon, __nw_zone_drop_port, port);
-       if (r)
-               return r;
+       if (r < 0)
+               goto ERROR;
 
-       // Destroy the configuration
-       r = nw_config_destroy(port->config);
-       if (r)
-               return r;
+       // Fetch the configuration directory
+       configd = nw_daemon_configd(port->daemon, "ports");
+       if (configd) {
+               r = nw_configd_unlink(configd, port->name, 0);
+               if (r < 0)
+                       goto ERROR;
+       }
 
-       return 0;
+ERROR:
+       if (configd)
+               nw_configd_unref(configd);
+
+       return r;
 }
 
 int __nw_port_drop_port(nw_daemon* daemon, nw_port* port, void* data) {
@@ -345,17 +337,19 @@ int __nw_port_drop_port(nw_daemon* daemon, nw_port* port, void* data) {
 }
 
 int nw_port_save(nw_port* port) {
-       char path[PATH_MAX];
+       nw_configd* configd = NULL;
        FILE* f = NULL;
        int r;
 
-       // Compose path
-       r = nw_string_format(path, "ports/%s", port->name);
-       if (r < 0)
-               return r;
+       // Fetch configuration directory
+       configd = nw_daemon_configd(port->daemon, "ports");
+       if (!configd) {
+               r = -errno;
+               goto ERROR;
+       }
 
        // Open file
-       f = nw_daemon_config_fopen(port->daemon, path, "w");
+       f = nw_configd_fopen(configd, port->name, "w");
        if (!f) {
                r = -errno;
                goto ERROR;
@@ -372,6 +366,8 @@ int nw_port_save(nw_port* port) {
                goto ERROR;
 
 ERROR:
+       if (configd)
+               nw_configd_unref(configd);
        if (f)
                fclose(f);
        if (r)
index f1cb3d289c8e46bdc4d5cf3548b263661cf8da26..3cbe4b0918f071812626ef768f791c1c274ae86f 100644 (file)
@@ -105,7 +105,7 @@ struct nw_port {
 
 int nw_port_create(nw_port** port, nw_daemon* daemon,
        const nw_port_type_id_t type, const char* name, nw_config* config);
-int nw_port_open(nw_port** port, nw_daemon* daemon, const char* name);
+int nw_port_open(nw_port** port, nw_daemon* daemon, const char* name, FILE* f);
 
 nw_port* nw_port_ref(nw_port* port);
 nw_port* nw_port_unref(nw_port* port);
index 761e564a53b30c7fa7109ac4f889311c0f3bde4d..95a13e37a06ba1d467c59828566d587d178419aa 100644 (file)
@@ -130,12 +130,14 @@ static int nw_ports_add_port(nw_ports* ports, nw_port* port) {
        return 0;
 }
 
-static int nw_ports_enumerate_port(nw_ports* ports, const char* name) {
+static int __nw_ports_enumerate(struct dirent* entry, FILE* f, void* data) {
        nw_port* port = NULL;
        int r;
 
+       nw_ports* ports = (nw_ports*)data;
+
        // Create a new port
-       r = nw_port_open(&port, ports->daemon, name);
+       r = nw_port_open(&port, ports->daemon, entry->d_name, f);
        if (r < 0 || r == 1)
                goto ERROR;
 
@@ -152,45 +154,19 @@ ERROR:
 }
 
 int nw_ports_enumerate(nw_ports* ports) {
-       DIR* d = NULL;
-       struct dirent* entry = NULL;
+       nw_configd* configd = NULL;
        int r;
 
-       // Open the ports directory
-       d = nw_daemon_config_opendir(ports->daemon, "ports");
-       if (!d) {
-               switch (errno) {
-                       case ENOENT:
-                               return 0;
-
-                       default:
-                               return -errno;
-               }
-       }
-
-       for (;;) {
-               // Read the next entry
-               entry = readdir(d);
-               if (!entry)
-                       break;
-
-               // Skip anything that is not a regular file
-               if (entry->d_type != DT_REG)
-                       continue;
+       // Fetch ports configuration directory
+       configd = nw_daemon_configd(ports->daemon, "ports");
+       if (!configd)
+               return 0;
 
-               // Skip hidden files
-               if (entry->d_name[0] == '.')
-                       continue;
+       // Walk through all files
+       r = nw_configd_walk(configd, __nw_ports_enumerate, ports);
 
-               // Enumerate the port
-               r = nw_ports_enumerate_port(ports, entry->d_name);
-               if (r < 0)
-                       goto ERROR;
-       }
-
-ERROR:
-       if (d)
-               closedir(d);
+       // Cleanup
+       nw_configd_unref(configd);
 
        return r;
 }
index cc5fdaf5bdcc903334529495ead9c4df68847290..19d221fbb720138d1c4f09934c81f0c1ec1a48d6 100644 (file)
 #include "string.h"
 #include "zone.h"
 
+static const nw_string_table_t nw_zone_type_id[] = {
+       { -1, NULL },
+};
+
+NW_STRING_TABLE_LOOKUP(nw_zone_type_id_t, nw_zone_type_id)
+
 struct nw_zone {
        nw_daemon* daemon;
        int nrefs;
@@ -45,32 +51,6 @@ struct nw_zone {
        nw_config *config;
 };
 
-#define nw_zone_path(zone, path, format, ...) \
-       __nw_zone_path(zone, path, sizeof(path), format, __VA_ARGS__)
-
-static int __nw_zone_path(nw_zone* zone, char* p, const size_t length,
-               const char* format, ...) {
-       char prefix[NAME_MAX];
-       char suffix[NAME_MAX];
-       va_list args;
-       int r;
-
-       // Format the prefix
-       r = nw_string_format(prefix, "%s/zones/%s", CONFIG_DIR, zone->name);
-       if (r)
-               return r;
-
-       // Format the suffix
-       va_start(args, format);
-       r = nw_string_vformat(suffix, format, args);
-       va_end(args);
-       if (r)
-               return r;
-
-       // Join the two parts together
-       return __nw_path_join(p, length, prefix, suffix);
-}
-
 static void nw_zone_free(nw_zone* zone) {
        if (zone->link)
                nw_link_unref(zone->link);
@@ -109,8 +89,7 @@ static int nw_zone_set_link(nw_zone* zone, nw_link* link) {
 
 static int nw_zone_setup(nw_zone* zone) {
        nw_link* link = NULL;
-       char path[PATH_MAX];
-       int r;
+       int r = 0;
 
        // Find the link
        link = nw_daemon_get_link_by_name(zone->daemon, zone->name);
@@ -120,18 +99,6 @@ static int nw_zone_setup(nw_zone* zone) {
                        goto ERROR;
        }
 
-#if 0
-       // Compose the path to the main configuration file
-       r = nw_zone_path(zone, path, "%s", "settings");
-       if (r)
-               goto ERROR;
-
-       // Initialize the configuration
-       r = nw_config_create(&zone->config, path);
-       if (r)
-               goto ERROR;
-#endif
-
 ERROR:
        if (link)
                nw_link_unref(link);
@@ -139,13 +106,15 @@ ERROR:
        return r;
 }
 
-int nw_zone_create(nw_zone** zone, nw_daemon* daemon, const char* name) {
+int nw_zone_create(nw_zone** zone, nw_daemon* daemon, const nw_zone_type_id_t type,
+               const char* name, nw_config* config) {
+       nw_zone* z = NULL;
        int r;
 
        // Allocate a new object
-       nw_zone* z = calloc(1, sizeof(*z));
+       z = calloc(1, sizeof(*z));
        if (!z)
-               return 1;
+               return -errno;
 
        // Store a reference to the daemon
        z->daemon = nw_daemon_ref(daemon);
@@ -158,6 +127,11 @@ int nw_zone_create(nw_zone** zone, nw_daemon* daemon, const char* name) {
        if (r)
                goto ERROR;
 
+       // Copy the configuration
+       r = nw_config_copy(config, &z->config);
+       if (r < 0)
+               goto ERROR;
+
        // Setup the zone
        r = nw_zone_setup(z);
        if (r)
@@ -171,6 +145,35 @@ ERROR:
        return r;
 }
 
+int nw_zone_open(nw_zone** zone, nw_daemon* daemon, const char* name, FILE* f) {
+       nw_config* config = NULL;
+       int r;
+
+       // Initialize the configuration
+       r = nw_config_create(&config, f);
+       if (r < 0)
+               goto ERROR;
+
+       // Fetch the type
+       const char* type = nw_config_get(config, "TYPE");
+       if (!type) {
+               ERROR("Zone %s has no TYPE\n", name);
+               r = -ENOTSUP;
+               goto ERROR;
+       }
+
+       // Create a new zone
+       r = nw_zone_create(zone, daemon, nw_zone_type_id_from_string(type), name, config);
+       if (r < 0)
+               goto ERROR;
+
+ERROR:
+       if (config)
+               nw_config_unref(config);
+
+       return r;
+}
+
 nw_zone* nw_zone_ref(nw_zone* zone) {
        zone->nrefs++;
 
@@ -195,30 +198,41 @@ int __nw_zone_drop_port(nw_daemon* daemon, nw_zone* zone, void* data) {
 }
 
 int nw_zone_save(nw_zone* zone) {
-       char path[PATH_MAX];
+       nw_configd* configd = NULL;
        FILE* f = NULL;
        int r;
 
-       // Compose path
-       r = nw_string_format(path, "zones/%s/settings", zone->name);
-       if (r < 0)
+       // Fetch configuration directory
+       configd = nw_daemon_configd(zone->daemon, "zones");
+       if (!configd) {
+               r = -errno;
                goto ERROR;
+       }
 
        // Open file
-       f = nw_daemon_config_fopen(zone->daemon, path, "w");
+       f = nw_configd_fopen(configd, zone->name, "w");
        if (!f) {
                r = -errno;
                goto ERROR;
        }
 
+       // Write out the configuration
+       r = nw_config_options_write(zone->config);
+       if (r < 0)
+               goto ERROR;
+
        // Write the configuration
        r = nw_config_write(zone->config, f);
-       if (r)
+       if (r < 0)
                goto ERROR;
 
 ERROR:
+       if (configd)
+               nw_configd_unref(configd);
        if (f)
                fclose(f);
+       if (r)
+               ERROR("Could not save configuration for zone %s: %s\n", zone->name, strerror(-r));
 
        return r;
 }
index 480440fbda58ae87cf47fd94ab58d26a42964eb9..6ab951b4a6243906e94d4f544e0e79b2b3f9663a 100644 (file)
 
 typedef struct nw_zone nw_zone;
 
+typedef enum nw_zone_type_id {
+       __EMPTY
+} nw_zone_type_id_t;
+
 #include <linux/if_link.h>
 
+#include "config.h"
 #include "daemon.h"
 
-int nw_zone_create(nw_zone** zone, nw_daemon* daemon, const char* name);
+int nw_zone_create(nw_zone** zone, nw_daemon* daemon, const nw_zone_type_id_t type,
+       const char* name, nw_config* config);
+int nw_zone_open(nw_zone** zone, nw_daemon* daemon, const char* name, FILE* f);
 
 nw_zone* nw_zone_ref(nw_zone* zone);
 nw_zone* nw_zone_unref(nw_zone* zone);
index 84a6673e8ef19cb18c17907cddf33d1b8f03547b..654e637e16af9b586a53eaf7027149a13906641a 100644 (file)
@@ -135,30 +135,15 @@ static int nw_zones_add_zone(nw_zones* zones, nw_zone* zone) {
        return 0;
 }
 
-static int __nw_zones_enumerate(const char* path, const struct stat* s, void* data) {
+static int __nw_zones_enumerate(struct dirent* entry, FILE* f, void* data) {
        nw_zone* zone = NULL;
        int r;
 
        nw_zones* zones = (nw_zones*)data;
 
-       // Skip anything that isn't a directory
-       if (!S_ISDIR(s->st_mode))
-               return 0;
-
-       // Find the basename of the file
-       const char* name = nw_path_basename(path);
-
-       // Break on invalid paths
-       if (!name)
-               return 0;
-
-       // Skip any hidden files
-       if (*name == '.')
-               return 0;
-
        // Create a new zone
-       r = nw_zone_create(&zone, zones->daemon, name);
-       if (r)
+       r = nw_zone_open(&zone, zones->daemon, entry->d_name, f);
+       if (r < 0 || r == 1)
                goto ERROR;
 
        // Add the zone to the list
@@ -174,7 +159,21 @@ ERROR:
 }
 
 int nw_zones_enumerate(nw_zones* zones) {
-       return nw_ftw(ZONE_CONFIG_DIR, ZONE_CONFIG_DIR "/*", __nw_zones_enumerate, zones);
+       nw_configd* configd = NULL;
+       int r;
+
+       // Fetch zones configuration directory
+       configd = nw_daemon_configd(zones->daemon, "zones");
+       if (!configd)
+               return 0;
+
+       // Walk through all files
+       r = nw_configd_walk(configd, __nw_zones_enumerate, zones);
+
+       // Cleanup
+       nw_configd_unref(configd);
+
+       return r;
 }
 
 size_t nw_zones_num(nw_zones* zones) {