1 /* SPDX-License-Identifier: LGPL-2.1+ */
10 #include "network-generator.h"
11 #include "path-util.h"
12 #include "proc-cmdline.h"
14 #define NETWORKD_UNIT_DIRECTORY "/run/systemd/network"
16 static const char *arg_root
= NULL
;
18 static int network_save(Network
*network
, const char *dest_dir
) {
19 _cleanup_free_
char *filename
= NULL
;
20 _cleanup_fclose_
FILE *f
= NULL
;
25 r
= asprintf(&filename
, "%s-initrd-%s.network",
26 isempty(network
->ifname
) ? "99" : "98",
27 isempty(network
->ifname
) ? "default" : network
->ifname
);
31 r
= generator_open_unit_file(dest_dir
, "kernel command line", filename
, &f
);
35 network_dump(network
, f
);
40 static int netdev_save(NetDev
*netdev
, const char *dest_dir
) {
41 _cleanup_free_
char *filename
= NULL
;
42 _cleanup_fclose_
FILE *f
= NULL
;
47 r
= asprintf(&filename
, "98-initrd-%s.netdev",
52 r
= generator_open_unit_file(dest_dir
, "kernel command line", filename
, &f
);
56 netdev_dump(netdev
, f
);
61 static int link_save(Link
*link
, const char *dest_dir
) {
62 _cleanup_free_
char *filename
= NULL
;
63 _cleanup_fclose_
FILE *f
= NULL
;
68 r
= asprintf(&filename
, "98-initrd-%s.link",
73 r
= generator_open_unit_file(dest_dir
, "kernel command line", filename
, &f
);
82 static int context_save(Context
*context
) {
90 p
= prefix_roota(arg_root
, NETWORKD_UNIT_DIRECTORY
);
94 return log_error_errno(r
, "Failed to create directory " NETWORKD_UNIT_DIRECTORY
": %m");
96 HASHMAP_FOREACH(network
, context
->networks_by_name
, i
) {
97 k
= network_save(network
, p
);
102 HASHMAP_FOREACH(netdev
, context
->netdevs_by_name
, i
) {
103 k
= netdev_save(netdev
, p
);
108 HASHMAP_FOREACH(link
, context
->links_by_name
, i
) {
109 k
= link_save(link
, p
);
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
127 static int parse_argv(int argc
, char *argv
[]) {
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
},
143 while ((c
= getopt_long(argc
, argv
, "h", options
, NULL
)) >= 0)
161 assert_not_reached("Unhandled option");
167 static int run(int argc
, char *argv
[]) {
168 _cleanup_(context_clear
) Context context
= {};
171 r
= parse_argv(argc
, argv
);
175 if (optind
>= argc
) {
176 r
= proc_cmdline_parse(parse_cmdline_item
, &context
, 0);
178 return log_warning_errno(r
, "Failed to parse kernel command line: %m");
180 for (i
= optind
; i
< argc
; i
++) {
181 _cleanup_free_
char *word
= NULL
;
184 word
= strdup(argv
[i
]);
188 value
= strchr(word
, '=');
192 r
= parse_cmdline_item(word
, value
, &context
);
194 return log_warning_errno(r
, "Failed to parse command line \"%s%s%s\": %m",
195 word
, value
? "=" : "", strempty(value
));
199 r
= context_merge_networks(&context
);
201 return log_warning_errno(r
, "Failed to merge multiple command line options: %m");
203 return context_save(&context
);
206 DEFINE_MAIN_FUNCTION(run
);