]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/network/generator/main.c
network-generator: rename generated unit files
[thirdparty/systemd.git] / src / network / generator / main.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
2
3 #include <getopt.h>
4
5 #include "fd-util.h"
6 #include "generator.h"
7 #include "macro.h"
8 #include "main-func.h"
9 #include "mkdir.h"
10 #include "network-generator.h"
11 #include "path-util.h"
12 #include "proc-cmdline.h"
13
14 #define NETWORKD_UNIT_DIRECTORY "/run/systemd/network"
15
16 static const char *arg_root = NULL;
17
18 static int network_save(Network *network, const char *dest_dir) {
19 _cleanup_free_ char *filename = NULL;
20 _cleanup_fclose_ FILE *f = NULL;
21 int r;
22
23 assert(network);
24
25 r = asprintf(&filename, "%s-%s.network",
26 isempty(network->ifname) ? "91" : "90",
27 isempty(network->ifname) ? "default" : network->ifname);
28 if (r < 0)
29 return log_oom();
30
31 r = generator_open_unit_file(dest_dir, "kernel command line", filename, &f);
32 if (r < 0)
33 return r;
34
35 network_dump(network, f);
36
37 return 0;
38 }
39
40 static int netdev_save(NetDev *netdev, const char *dest_dir) {
41 _cleanup_free_ char *filename = NULL;
42 _cleanup_fclose_ FILE *f = NULL;
43 int r;
44
45 assert(netdev);
46
47 r = asprintf(&filename, "90-%s.netdev",
48 netdev->ifname);
49 if (r < 0)
50 return log_oom();
51
52 r = generator_open_unit_file(dest_dir, "kernel command line", filename, &f);
53 if (r < 0)
54 return r;
55
56 netdev_dump(netdev, f);
57
58 return 0;
59 }
60
61 static int link_save(Link *link, const char *dest_dir) {
62 _cleanup_free_ char *filename = NULL;
63 _cleanup_fclose_ FILE *f = NULL;
64 int r;
65
66 assert(link);
67
68 r = asprintf(&filename, "90-%s.link",
69 link->ifname);
70 if (r < 0)
71 return log_oom();
72
73 r = generator_open_unit_file(dest_dir, "kernel command line", filename, &f);
74 if (r < 0)
75 return r;
76
77 link_dump(link, f);
78
79 return 0;
80 }
81
82 static int context_save(Context *context) {
83 Network *network;
84 NetDev *netdev;
85 Link *link;
86 Iterator i;
87 int k, r = 0;
88 const char *p;
89
90 p = prefix_roota(arg_root, NETWORKD_UNIT_DIRECTORY);
91
92 r = mkdir_p(p, 0755);
93 if (r < 0)
94 return log_error_errno(r, "Failed to create directory " NETWORKD_UNIT_DIRECTORY ": %m");
95
96 HASHMAP_FOREACH(network, context->networks_by_name, i) {
97 k = network_save(network, p);
98 if (k < 0 && r >= 0)
99 r = k;
100 }
101
102 HASHMAP_FOREACH(netdev, context->netdevs_by_name, i) {
103 k = netdev_save(netdev, p);
104 if (k < 0 && r >= 0)
105 r = k;
106 }
107
108 HASHMAP_FOREACH(link, context->links_by_name, i) {
109 k = link_save(link, p);
110 if (k < 0 && r >= 0)
111 r = k;
112 }
113
114 return r;
115 }
116
117 static int help(void) {
118 printf("%s [OPTIONS...] [-- KERNEL_CMDLINE]\n"
119 " -h --help Show this help\n"
120 " --version Show package version\n"
121 , program_invocation_short_name
122 );
123
124 return 0;
125 }
126
127 static int parse_argv(int argc, char *argv[]) {
128 enum {
129 ARG_VERSION = 0x100,
130 ARG_ROOT,
131 };
132 static const struct option options[] = {
133 { "help", no_argument, NULL, 'h' },
134 { "version", no_argument, NULL, ARG_VERSION },
135 { "root", required_argument, NULL, ARG_ROOT },
136 {},
137 };
138 int c;
139
140 assert(argc >= 0);
141 assert(argv);
142
143 while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0)
144
145 switch (c) {
146
147 case 'h':
148 return help();
149
150 case ARG_VERSION:
151 return version();
152
153 case ARG_ROOT:
154 arg_root = optarg;
155 break;
156
157 case '?':
158 return -EINVAL;
159
160 default:
161 assert_not_reached("Unhandled option");
162 }
163
164 return 1;
165 }
166
167 static int run(int argc, char *argv[]) {
168 _cleanup_(context_clear) Context context = {};
169 int i, r;
170
171 r = parse_argv(argc, argv);
172 if (r <= 0)
173 return r;
174
175 if (optind >= argc) {
176 r = proc_cmdline_parse(parse_cmdline_item, &context, 0);
177 if (r < 0)
178 return log_warning_errno(r, "Failed to parse kernel command line: %m");
179 } else {
180 for (i = optind; i < argc; i++) {
181 _cleanup_free_ char *word = NULL;
182 char *value;
183
184 word = strdup(argv[i]);
185 if (!word)
186 return log_oom();
187
188 value = strchr(word, '=');
189 if (value)
190 *(value++) = 0;
191
192 r = parse_cmdline_item(word, value, &context);
193 if (r < 0)
194 return log_warning_errno(r, "Failed to parse command line \"%s%s%s\": %m",
195 word, value ? "=" : "", strempty(value));
196 }
197 }
198
199 r = context_merge_networks(&context);
200 if (r < 0)
201 return log_warning_errno(r, "Failed to merge multiple command line options: %m");
202
203 return context_save(&context);
204 }
205
206 DEFINE_MAIN_FUNCTION(run);