networkctl: introduce "persistent-storage" command
authorYu Watanabe <watanabe.yu+github@gmail.com>
Mon, 26 Feb 2024 01:33:20 +0000 (10:33 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Mon, 11 Mar 2024 16:57:16 +0000 (01:57 +0900)
Then, this introduces systemd-networkd-persistent-storage.service.

systemd-networkd.service is an early starting service. So, at the time
it is started, the persistent storage for the service may not be ready,
and we cannot use StateDirectory=systemd/network in
systemd-networkd.service.

The newly added systemd-networkd-persistent-storage.service creates the
state directory for networkd, and notify systemd-networkd that the
directory is usable.

man/networkctl.xml
src/network/networkctl.c
tmpfiles.d/systemd-network.conf
units/meson.build
units/systemd-networkd-persistent-storage.service [new file with mode: 0644]
units/systemd-networkd.service.in

index e85718269a5e07ccfacf2c39562b99e7474b4f03..8370e72cf9ba663a40a92fd09d4b6d768551b1d3 100644 (file)
@@ -495,6 +495,21 @@ s - Service VLAN, m - Two-port MAC Relay (TPMR)
 
         <xi:include href="version-info.xml" xpointer="v256"/></listitem>
       </varlistentry>
+
+      <varlistentry>
+        <term>
+          <command>persistent-storage</command>
+          <replaceable>BOOL</replaceable>
+        </term>
+        <listitem>
+          <para>Notify <filename>systemd-networkd.service</filename> that the persistent storage for the
+          service is ready. This is called by
+          <filename>systemd-networkd-persistent-storage.service</filename>. Usually, this command should not
+          be called manually by users or administrators.</para>
+
+          <xi:include href="version-info.xml" xpointer="v256"/>
+        </listitem>
+      </varlistentry>
     </variablelist>
   </refsect1>
 
index 686d83b06b4da39921bd7cf365ab9eb7d924e455..88e5b5ec9ea1272bad76adea9b0bc767535ff256 100644 (file)
@@ -2929,6 +2929,24 @@ static int verb_reconfigure(int argc, char *argv[], void *userdata) {
         return 0;
 }
 
+static int verb_persistent_storage(int argc, char *argv[], void *userdata) {
+        _cleanup_(varlink_unrefp) Varlink *vl = NULL;
+        bool ready;
+        int r;
+
+        r = parse_boolean(argv[1]);
+        if (r < 0)
+                return log_error_errno(r, "Failed to parse argument: %s", argv[1]);
+        ready = r;
+
+        r = varlink_connect_networkd(&vl);
+        if (r < 0)
+                return r;
+
+        return varlink_callb_and_log(vl, "io.systemd.Network.SetPersistentStorage", /* reply = */ NULL,
+                                     JSON_BUILD_OBJECT(JSON_BUILD_PAIR_BOOLEAN("Ready", ready)));
+}
+
 static int help(void) {
         _cleanup_free_ char *link = NULL;
         int r;
@@ -2955,6 +2973,8 @@ static int help(void) {
                "  cat FILES|DEVICES...   Show network configuration files\n"
                "  mask FILES...          Mask network configuration files\n"
                "  unmask FILES...        Unmask network configuration files\n"
+               "  persistent-storage BOOL\n"
+               "                         Notify systemd-networkd if persistent storage is ready\n"
                "\nOptions:\n"
                "  -h --help              Show this help\n"
                "     --version           Show package version\n"
@@ -3098,21 +3118,22 @@ static int parse_argv(int argc, char *argv[]) {
 
 static int networkctl_main(int argc, char *argv[]) {
         static const Verb verbs[] = {
-                { "list",        VERB_ANY, VERB_ANY, VERB_DEFAULT|VERB_ONLINE_ONLY, list_links          },
-                { "status",      VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY,              link_status         },
-                { "lldp",        VERB_ANY, VERB_ANY, 0,                             link_lldp_status    },
-                { "label",       1,        1,        0,                             list_address_labels },
-                { "delete",      2,        VERB_ANY, 0,                             link_delete         },
-                { "up",          2,        VERB_ANY, 0,                             link_up_down        },
-                { "down",        2,        VERB_ANY, 0,                             link_up_down        },
-                { "renew",       2,        VERB_ANY, VERB_ONLINE_ONLY,              link_renew          },
-                { "forcerenew",  2,        VERB_ANY, VERB_ONLINE_ONLY,              link_force_renew    },
-                { "reconfigure", 2,        VERB_ANY, VERB_ONLINE_ONLY,              verb_reconfigure    },
-                { "reload",      1,        1,        VERB_ONLINE_ONLY,              verb_reload         },
-                { "edit",        2,        VERB_ANY, 0,                             verb_edit           },
-                { "cat",         2,        VERB_ANY, 0,                             verb_cat            },
-                { "mask",        2,        VERB_ANY, 0,                             verb_mask           },
-                { "unmask",      2,        VERB_ANY, 0,                             verb_unmask         },
+                { "list",               VERB_ANY, VERB_ANY, VERB_DEFAULT|VERB_ONLINE_ONLY, list_links              },
+                { "status",             VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY,              link_status             },
+                { "lldp",               VERB_ANY, VERB_ANY, 0,                             link_lldp_status        },
+                { "label",              1,        1,        0,                             list_address_labels     },
+                { "delete",             2,        VERB_ANY, 0,                             link_delete             },
+                { "up",                 2,        VERB_ANY, 0,                             link_up_down            },
+                { "down",               2,        VERB_ANY, 0,                             link_up_down            },
+                { "renew",              2,        VERB_ANY, VERB_ONLINE_ONLY,              link_renew              },
+                { "forcerenew",         2,        VERB_ANY, VERB_ONLINE_ONLY,              link_force_renew        },
+                { "reconfigure",        2,        VERB_ANY, VERB_ONLINE_ONLY,              verb_reconfigure        },
+                { "reload",             1,        1,        VERB_ONLINE_ONLY,              verb_reload             },
+                { "edit",               2,        VERB_ANY, 0,                             verb_edit               },
+                { "cat",                2,        VERB_ANY, 0,                             verb_cat                },
+                { "mask",               2,        VERB_ANY, 0,                             verb_mask               },
+                { "unmask",             2,        VERB_ANY, 0,                             verb_unmask             },
+                { "persistent-storage", 2,        2,        0,                             verb_persistent_storage },
                 {}
         };
 
index 24197555ee8d025f7869bd36a0a41f942daa455a..323beca59c521f51f16e91735a8f53faac25957a 100644 (file)
@@ -7,6 +7,7 @@
 
 # See tmpfiles.d(5) for details
 
-d /run/systemd/netif 0755 systemd-network systemd-network -
-d /run/systemd/netif/links 0755 systemd-network systemd-network -
+d /run/systemd/netif        0755 systemd-network systemd-network -
+d /run/systemd/netif/links  0755 systemd-network systemd-network -
 d /run/systemd/netif/leases 0755 systemd-network systemd-network -
+d /var/lib/systemd/network  0755 systemd-network systemd-network -
index afe9ec7d1d9043977df8f5628f8f495c4b5e4027..1458cc5986765a91bc6e464b4dc4a953e9b62285 100644 (file)
@@ -432,6 +432,10 @@ units = [
           'symlinks' : ['sysinit.target.wants/'],
         },
         { 'file' : 'systemd-network-generator.service.in' },
+        {
+          'file' : 'systemd-networkd-persistent-storage.service',
+          'conditions' : ['ENABLE_NETWORKD'],
+        },
         {
           'file' : 'systemd-networkd-wait-online.service.in',
           'conditions' : ['ENABLE_NETWORKD'],
diff --git a/units/systemd-networkd-persistent-storage.service b/units/systemd-networkd-persistent-storage.service
new file mode 100644 (file)
index 0000000..c151d36
--- /dev/null
@@ -0,0 +1,27 @@
+#  SPDX-License-Identifier: LGPL-2.1-or-later
+#
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Enable Persistent Storage in systemd-networkd
+Documentation=man:networkctl(1)
+ConditionCapability=CAP_NET_ADMIN
+DefaultDependencies=no
+After=systemd-remount-fs.service systemd-networkd.service
+BindsTo=systemd-networkd.service
+Conflicts=shutdown.target
+RequiresMountsFor=/var/lib/systemd/network
+ConditionPathExists=!/etc/initrd-release
+
+[Service]
+Type=oneshot
+User=systemd-network
+ExecStart=networkctl persistent-storage yes
+ExecStop=networkctl persistent-storage no
+StateDirectory=systemd/network
+RemainAfterExit=yes
index 3dcaa55aac32c7509ea26dd4f1e194864314f045..200b126faa99343bb35c9510be7eca41e31a975a 100644 (file)
@@ -17,7 +17,7 @@ DefaultDependencies=no
 After=systemd-networkd.socket systemd-udevd.service network-pre.target systemd-sysusers.service systemd-sysctl.service
 Before=network.target multi-user.target shutdown.target initrd-switch-root.target
 Conflicts=shutdown.target initrd-switch-root.target
-Wants=systemd-networkd.socket network.target
+Wants=systemd-networkd.socket network.target systemd-networkd-persistent-storage.service
 
 [Service]
 AmbientCapabilities=CAP_NET_ADMIN CAP_NET_BIND_SERVICE CAP_NET_BROADCAST CAP_NET_RAW