From: Michael Tremer Date: Fri, 9 Jun 2023 09:29:01 +0000 (+0000) Subject: ports: Refactor enumerating ports X-Git-Url: http://git.ipfire.org/?p=people%2Fms%2Fnetwork.git;a=commitdiff_plain;h=8edf3da1c28feb4e2af80786c5e41e52f07b0f73 ports: Refactor enumerating ports This entails a little rewrite how we deal with where configuration files are stored. Signed-off-by: Michael Tremer --- diff --git a/src/networkd/config.c b/src/networkd/config.c index b7f3f722..3d444c41 100644 --- a/src/networkd/config.c +++ b/src/networkd/config.c @@ -53,9 +53,6 @@ struct nw_config_option { struct nw_config { int nrefs; - // The path to the configuration file - char path[PATH_MAX]; - STAILQ_HEAD(config_entries, nw_config_entry) entries; // Options @@ -118,7 +115,7 @@ static void nw_config_free(nw_config* config) { free(config); } -int nw_config_create(nw_config** config, const char* path) { +int nw_config_create(nw_config** config, FILE* f) { int r; nw_config* c = calloc(1, sizeof(*c)); @@ -134,15 +131,10 @@ int nw_config_create(nw_config** config, const char* path) { // Initialise options STAILQ_INIT(&c->options); - // Store the path - if (path) { - r = nw_string_set(c->path, path); - if (r) - goto ERROR; - - // Try to read the configuration from path - r = nw_config_read(c); - if (r) + // Read configuration + if (f) { + r = nw_config_read(c, f); + if (r < 0) goto ERROR; } @@ -156,6 +148,25 @@ ERROR: return r; } +int nw_config_open(nw_config** config, const char* path) { + FILE* f = NULL; + int r; + + // Open path + f = fopen(path, "r"); + if (!f) + return -errno; + + // Create a new configuration + r = nw_config_create(config, f); + +ERROR: + if (f) + fclose(f); + + return r; +} + nw_config* nw_config_ref(nw_config* config) { config->nrefs++; @@ -170,17 +181,6 @@ nw_config* nw_config_unref(nw_config* config) { return NULL; } -int nw_config_destroy(nw_config* config) { - int r; - - // Drop all entries - r = nw_config_flush(config); - if (r) - return r; - - return unlink(config->path); -} - int nw_config_copy(nw_config* config, nw_config** copy) { struct nw_config_entry* entry = NULL; nw_config* c = NULL; @@ -208,13 +208,6 @@ ERROR: return r; } -const char* nw_config_path(nw_config* config) { - if (*config->path) - return config->path; - - return NULL; -} - int nw_config_flush(nw_config* config) { struct nw_config_entry* entry = NULL; @@ -229,7 +222,7 @@ int nw_config_flush(nw_config* config) { return 0; } -int nw_config_readf(nw_config* config, FILE* f) { +int nw_config_read(nw_config* config, FILE* f) { char* line = NULL; size_t length = 0; int r; @@ -275,39 +268,7 @@ int nw_config_readf(nw_config* config, FILE* f) { return r; } -int nw_config_read(nw_config* config) { - FILE* f = NULL; - int r; - - // We cannot read if path is not set - if (!*config->path) { - errno = ENOTSUP; - return 1; - } - - // Open the file - f = fopen(config->path, "r"); - if (!f) { - // Silently ignore if the file does not exist - if (errno == ENOENT) - return 0; - - ERROR("Could not read configuration file %s: %m\n", config->path); - r = 1; - goto ERROR; - } - - // Read from file - r = nw_config_readf(config, f); - -ERROR: - if (f) - fclose(f); - - return r; -} - -static int nw_config_writef(nw_config* config, FILE* f) { +int nw_config_write(nw_config* config, FILE* f) { struct nw_config_entry* entry = NULL; int r; @@ -327,32 +288,6 @@ static int nw_config_writef(nw_config* config, FILE* f) { return 0; } -int nw_config_write(nw_config* config) { - int r; - - // We cannot write if path is not set - if (!*config->path) { - errno = ENOTSUP; - return 1; - } - - FILE* f = fopen(config->path, "w"); - if (!f) { - ERROR("Failed to open %s for writing: %m\n", config->path); - r = 1; - goto ERROR; - } - - // Write configuration - r = nw_config_writef(config, f); - -ERROR: - if (f) - fclose(f); - - return r; -} - static struct nw_config_entry* nw_config_find(nw_config* config, const char* key) { struct nw_config_entry* entry = NULL; diff --git a/src/networkd/config.h b/src/networkd/config.h index d532da33..b25d05e6 100644 --- a/src/networkd/config.h +++ b/src/networkd/config.h @@ -28,21 +28,18 @@ typedef struct nw_config nw_config; -int nw_config_create(nw_config** config, const char* path); +int nw_config_create(nw_config** config, FILE* f); +int nw_config_open(nw_config** config, const char* path); nw_config* nw_config_ref(nw_config* config); nw_config* nw_config_unref(nw_config* config); -int nw_config_destroy(nw_config* config); int nw_config_copy(nw_config* config, nw_config** copy); -const char* nw_config_path(nw_config* config); - int nw_config_flush(nw_config* config); -int nw_config_readf(nw_config* config, FILE* f); -int nw_config_read(nw_config* config); -int nw_config_write(nw_config* config); +int nw_config_read(nw_config* config, FILE* f); +int nw_config_write(nw_config* config, FILE* f); int nw_config_del(nw_config* config, const char* key); diff --git a/src/networkd/daemon.c b/src/networkd/daemon.c index f0ef4aa3..a62e343f 100644 --- a/src/networkd/daemon.c +++ b/src/networkd/daemon.c @@ -113,7 +113,7 @@ static int nw_daemon_config_open(nw_daemon* daemon, const char* path) { return 0; } -static FILE* nw_daemon_config_fopen(nw_daemon* daemon, const char* path, const char* mode) { +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) { @@ -125,6 +125,16 @@ static FILE* nw_daemon_config_fopen(nw_daemon* daemon, const char* path, const c return fdopen(fd, mode); } +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; + } + + return fdopendir(fd); +} + static int nw_daemon_parse_argv(nw_daemon* daemon, int argc, char* argv[]) { enum { ARG_CONFIG, @@ -221,12 +231,7 @@ static int nw_daemon_load_config(nw_daemon* daemon) { } // Create configuration - r = nw_config_create(&daemon->config, NULL); - if (r < 0) - goto ERROR; - - // Parse configuration - r = nw_config_readf(daemon->config, f); + r = nw_config_create(&daemon->config, f); if (r < 0) goto ERROR; @@ -615,10 +620,12 @@ int nw_daemon_save(nw_daemon* daemon) { DEBUG("Saving configuration...\n"); +#if 0 // Save settings - r = nw_config_write(daemon->config); + r = nw_config_write(daemon->config, f); if (r) return r; +#endif // Save ports r = nw_ports_save(daemon->ports); diff --git a/src/networkd/daemon.h b/src/networkd/daemon.h index 8653af38..b03086c8 100644 --- a/src/networkd/daemon.h +++ b/src/networkd/daemon.h @@ -21,6 +21,9 @@ #ifndef NETWORKD_DAEMON_H #define NETWORKD_DAEMON_H +#include +#include + #include #include @@ -44,6 +47,12 @@ 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); + /* Bus */ diff --git a/src/networkd/port.c b/src/networkd/port.c index fb5d4189..7d654e3c 100644 --- a/src/networkd/port.c +++ b/src/networkd/port.c @@ -147,7 +147,7 @@ int nw_port_create(nw_port** port, nw_daemon* daemon, // Allocate a new object nw_port* p = calloc(1, sizeof(*p)); if (!p) - return 1; + return -errno; // Store a reference to the daemon p->daemon = nw_daemon_ref(daemon); @@ -172,17 +172,17 @@ int nw_port_create(nw_port** port, nw_daemon* daemon, // Store the name r = nw_string_set(p->name, name); - if (r) + if (r < 0) goto ERROR; // Copy the configuration r = nw_config_copy(config, &p->config); - if (r) + if (r < 0) goto ERROR; // Setup the port r = nw_port_setup(p); - if (r) + if (r < 0) goto ERROR; // Validate the configuration @@ -210,32 +210,47 @@ ERROR: return r; } -int nw_port_create_from_config(nw_port** port, nw_daemon* daemon, - const char* name, const char* path) { +int nw_port_open(nw_port** port, nw_daemon* daemon, const char* name) { 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, path); - if (r) + 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("Port configuration %s has no TYPE\n", path); - r = 1; + r = -ENOTSUP; goto ERROR; } // Create a new port r = nw_port_create(port, daemon, nw_port_type_id_from_string(type), name, config); - if (r) + if (r < 0) goto ERROR; ERROR: if (config) nw_config_unref(config); + if (f) + fclose(f); return r; } @@ -316,24 +331,39 @@ int __nw_port_drop_port(nw_daemon* daemon, nw_port* port, void* data) { } int nw_port_save(nw_port* port) { + char path[PATH_MAX]; + FILE* f = NULL; int r; + // Compose path + r = nw_string_format(path, "ports/%s", port->name); + if (r < 0) + return r; + + // Open file + f = nw_daemon_config_fopen(port->daemon, path, "w"); + if (!f) { + r = -errno; + goto ERROR; + } + // Write out the configuration r = nw_config_options_write(port->config); if (r < 0) goto ERROR; // Write the configuration - r = nw_config_write(port->config); - if (r) - return r; - - return 0; + r = nw_config_write(port->config, f); + if (r < 0) + goto ERROR; ERROR: - ERROR("Could not save configuration for port %s: %s\n", port->name, strerror(-r)); + if (f) + fclose(f); + if (r) + ERROR("Could not save configuration for port %s: %s\n", port->name, strerror(-r)); - return 1; + return r; } const char* nw_port_name(nw_port* port) { diff --git a/src/networkd/port.h b/src/networkd/port.h index 7c2e4366..efa2fdbe 100644 --- a/src/networkd/port.h +++ b/src/networkd/port.h @@ -95,8 +95,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_create_from_config(nw_port** port, nw_daemon* daemon, - const char* name, const char* path); +int nw_port_open(nw_port** port, nw_daemon* daemon, const char* name); nw_port* nw_port_ref(nw_port* port); nw_port* nw_port_unref(nw_port* port); diff --git a/src/networkd/ports.c b/src/networkd/ports.c index 65545e81..761e564a 100644 --- a/src/networkd/ports.c +++ b/src/networkd/ports.c @@ -18,6 +18,7 @@ # # #############################################################################*/ +#include #include #include #include @@ -129,43 +130,14 @@ static int nw_ports_add_port(nw_ports* ports, nw_port* port) { return 0; } -static int __nw_ports_enumerate(const char* path, const struct stat* s, void* data) { +static int nw_ports_enumerate_port(nw_ports* ports, const char* name) { nw_port* port = NULL; int r; - nw_ports* ports = (nw_ports*)data; - - // Skip anything that isn't a regular file - if (!S_ISREG(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 port - r = nw_port_create_from_config(&port, ports->daemon, name, path); - switch (r) { - // All okay - case 0: - break; - - // Invalid configuration - case 1: - ERROR("Could not open port %s\n", name); - r = 0; - goto ERROR; - - default: - goto ERROR; - } + r = nw_port_open(&port, ports->daemon, name); + if (r < 0 || r == 1) + goto ERROR; // Add the port to the list r = nw_ports_add_port(ports, port); @@ -180,7 +152,47 @@ ERROR: } int nw_ports_enumerate(nw_ports* ports) { - return nw_ftw(PORT_CONFIG_DIR, PORT_CONFIG_DIR "/*", __nw_ports_enumerate, ports); + DIR* d = NULL; + struct dirent* entry = 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; + + // Skip hidden files + if (entry->d_name[0] == '.') + continue; + + // Enumerate the port + r = nw_ports_enumerate_port(ports, entry->d_name); + if (r < 0) + goto ERROR; + } + +ERROR: + if (d) + closedir(d); + + return r; } nw_port* nw_ports_get_by_name(nw_ports* ports, const char* name) { diff --git a/src/networkd/zone.c b/src/networkd/zone.c index 9f5b7f8c..cc5fdaf5 100644 --- a/src/networkd/zone.c +++ b/src/networkd/zone.c @@ -120,6 +120,7 @@ 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) @@ -129,6 +130,7 @@ static int nw_zone_setup(nw_zone* zone) { r = nw_config_create(&zone->config, path); if (r) goto ERROR; +#endif ERROR: if (link) @@ -193,13 +195,32 @@ int __nw_zone_drop_port(nw_daemon* daemon, nw_zone* zone, void* data) { } int nw_zone_save(nw_zone* zone) { + char path[PATH_MAX]; + FILE* f = NULL; int r; - r = nw_config_write(zone->config); + // Compose path + r = nw_string_format(path, "zones/%s/settings", zone->name); + if (r < 0) + goto ERROR; + + // Open file + f = nw_daemon_config_fopen(zone->daemon, path, "w"); + if (!f) { + r = -errno; + goto ERROR; + } + + // Write the configuration + r = nw_config_write(zone->config, f); if (r) - return r; + goto ERROR; - return 0; +ERROR: + if (f) + fclose(f); + + return r; } const char* nw_zone_name(nw_zone* zone) {