summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2023-04-26 14:55:41 +0200
committerGitHub <noreply@github.com>2023-04-26 14:55:41 +0200
commitd21d71fb285ebd4726536159c4ccaa08b7046215 (patch)
tree03c8202c726881e003229aed98bf94ffeac7cb41 /src
parent914f280d0c0f1555ff94d5490dc4f264af7f331f (diff)
parentf3e4d04298bb73b836dd7ca90f7c7b09de1e776b (diff)
downloadsystemd-d21d71fb285ebd4726536159c4ccaa08b7046215.tar.gz
Merge pull request #26944 from aafeijoo-suse/systemd-network-generator-initrd-fix
network-generator: do not parse kernel command line more than once
Diffstat (limited to 'src')
-rw-r--r--src/basic/fs-util.c2
-rw-r--r--src/network/generator/main.c55
-rw-r--r--src/shared/generator.c46
-rw-r--r--src/shared/generator.h10
4 files changed, 80 insertions, 33 deletions
diff --git a/src/basic/fs-util.c b/src/basic/fs-util.c
index f8cd93800d..1e1413dc80 100644
--- a/src/basic/fs-util.c
+++ b/src/basic/fs-util.c
@@ -820,7 +820,7 @@ int conservative_renameat(
_cleanup_close_ int old_fd = -EBADF, new_fd = -EBADF;
struct stat old_stat, new_stat;
- /* Renames the old path to thew new path, much like renameat() — except if both are regular files and
+ /* Renames the old path to the new path, much like renameat() — except if both are regular files and
* have the exact same contents and basic file attributes already. In that case remove the new file
* instead. This call is useful for reducing inotify wakeups on files that are updated but don't
* actually change. This function is written in a style that we rather rename too often than suppress
diff --git a/src/network/generator/main.c b/src/network/generator/main.c
index a0af0b831b..492980249b 100644
--- a/src/network/generator/main.c
+++ b/src/network/generator/main.c
@@ -4,6 +4,7 @@
#include "build.h"
#include "fd-util.h"
+#include "fs-util.h"
#include "generator.h"
#include "macro.h"
#include "main-func.h"
@@ -17,67 +18,97 @@
static const char *arg_root = NULL;
static int network_save(Network *network, const char *dest_dir) {
- _cleanup_free_ char *filename = NULL;
+ _cleanup_free_ char *filename = NULL, *p = NULL;
+ _cleanup_(unlink_and_freep) char *temp_path = NULL;
_cleanup_fclose_ FILE *f = NULL;
int r;
assert(network);
+ r = generator_open_unit_file_full(dest_dir, NULL, NULL, &f, &temp_path);
+ if (r < 0)
+ return r;
+
+ network_dump(network, f);
+
r = asprintf(&filename, "%s-%s.network",
isempty(network->ifname) ? "91" : "90",
isempty(network->ifname) ? "default" : network->ifname);
if (r < 0)
return log_oom();
- r = generator_open_unit_file(dest_dir, "kernel command line", filename, &f);
+ p = path_join(dest_dir, filename);
+ if (!p)
+ return log_oom();
+
+ r = conservative_rename(temp_path, p);
if (r < 0)
return r;
- network_dump(network, f);
-
+ temp_path = mfree(temp_path);
return 0;
}
static int netdev_save(NetDev *netdev, const char *dest_dir) {
- _cleanup_free_ char *filename = NULL;
+ _cleanup_free_ char *filename = NULL, *p = NULL;
+ _cleanup_(unlink_and_freep) char *temp_path = NULL;
_cleanup_fclose_ FILE *f = NULL;
int r;
assert(netdev);
+ r = generator_open_unit_file_full(dest_dir, NULL, NULL, &f, &temp_path);
+ if (r < 0)
+ return r;
+
+ netdev_dump(netdev, f);
+
r = asprintf(&filename, "90-%s.netdev",
netdev->ifname);
if (r < 0)
return log_oom();
- r = generator_open_unit_file(dest_dir, "kernel command line", filename, &f);
+ p = path_join(dest_dir, filename);
+ if (!p)
+ return log_oom();
+
+ r = conservative_rename(temp_path, p);
if (r < 0)
return r;
- netdev_dump(netdev, f);
-
+ temp_path = mfree(temp_path);
return 0;
}
static int link_save(Link *link, const char *dest_dir) {
- _cleanup_free_ char *filename = NULL;
+ _cleanup_free_ char *filename = NULL, *p = NULL;
+ _cleanup_(unlink_and_freep) char *temp_path = NULL;
_cleanup_fclose_ FILE *f = NULL;
int r;
assert(link);
+ r = generator_open_unit_file_full(dest_dir, NULL, NULL, &f, &temp_path);
+ if (r < 0)
+ return r;
+
+ link_dump(link, f);
+
filename = strjoin(!isempty(link->ifname) ? "90" :
!hw_addr_is_null(&link->mac) ? "91" : "92",
"-", link->filename, ".link");
if (!filename)
return log_oom();
- r = generator_open_unit_file(dest_dir, "kernel command line", filename, &f);
+ p = path_join(dest_dir, filename);
+ if (!p)
+ return log_oom();
+
+ r = conservative_rename(temp_path, p);
if (r < 0)
return r;
- link_dump(link, f);
-
+ temp_path = mfree(temp_path);
return 0;
}
diff --git a/src/shared/generator.c b/src/shared/generator.c
index 2ed4be2bf3..b16d0a0ef2 100644
--- a/src/shared/generator.c
+++ b/src/shared/generator.c
@@ -21,41 +21,57 @@
#include "specifier.h"
#include "string-util.h"
#include "time-util.h"
+#include "tmpfile-util.h"
#include "unit-name.h"
-int generator_open_unit_file(
+int generator_open_unit_file_full(
const char *dir,
const char *source,
const char *fn,
- FILE **ret) {
+ FILE **ret_file,
+ char **ret_temp_path) {
_cleanup_free_ char *p = NULL;
FILE *f;
int r;
assert(dir);
- assert(fn);
- assert(ret);
+ assert(ret_file);
- p = path_join(dir, fn);
- if (!p)
- return log_oom();
+ /* If <ret_temp_path> is specified, it creates a temporary unit file and also returns its
+ * temporary path. */
- r = fopen_unlocked(p, "wxe", &f);
- if (r < 0) {
- if (source && r == -EEXIST)
- return log_error_errno(r,
- "Failed to create unit file '%s', as it already exists. Duplicate entry in '%s'?",
- p, source);
+ if (ret_temp_path) {
+ r = fopen_temporary(dir, &f, &p);
+ if (r < 0)
+ return log_error_errno(r, "Failed to create temporary unit file in '%s': %m", dir);
+
+ (void) fchmod(fileno(f), 0644);
- return log_error_errno(r, "Failed to create unit file '%s': %m", p);
+ *ret_temp_path = TAKE_PTR(p);
+ } else {
+ assert(fn);
+
+ p = path_join(dir, fn);
+ if (!p)
+ return log_oom();
+
+ r = fopen_unlocked(p, "wxe", &f);
+ if (r < 0) {
+ if (source && r == -EEXIST)
+ return log_error_errno(r,
+ "Failed to create unit file '%s', as it already exists. Duplicate entry in '%s'?",
+ p, source);
+
+ return log_error_errno(r, "Failed to create unit file '%s': %m", p);
+ }
}
fprintf(f,
"# Automatically generated by %s\n\n",
program_invocation_short_name);
- *ret = f;
+ *ret_file = f;
return 0;
}
diff --git a/src/shared/generator.h b/src/shared/generator.h
index 111900fd45..d97d6edc67 100644
--- a/src/shared/generator.h
+++ b/src/shared/generator.h
@@ -6,11 +6,11 @@
#include "macro.h"
#include "main-func.h"
-int generator_open_unit_file(
- const char *dest,
- const char *source,
- const char *name,
- FILE **file);
+int generator_open_unit_file_full(const char *dest, const char *source, const char *name, FILE **ret_file, char **ret_temp_path);
+
+static inline int generator_open_unit_file(const char *dest, const char *source, const char *name, FILE **ret_file) {
+ return generator_open_unit_file_full(dest, source, name, ret_file, NULL);
+}
int generator_add_symlink_full(const char *dir, const char *dst, const char *dep_type, const char *src, const char *instance);