How can I start usb_modeswitch before the network-configuration?

1

I'm using a Huawei E3531 to connect a Raspberry Zero running on vanilla Raspbian 8.0 (jessie) to the internet. As this is for a remote standalone application, it needs to be able to automatically get back online after a power-blackout.

I've configured usb_modeswitch to switch the USB-mode to cdc_ether, which reliably brings up an eth0 after the modeswitch. Unfortunately usb_modeswitch is started after the network devices are configured, therefore the network-link is not brought up on a cold boot (It works nicely on a reboot, where the mode is already correctly set).

According to https://www.freedesktop.org/wiki/Software/systemd/NetworkTarget/ it should be possible to add network-pre.target-directives to a service to get it to run before the network is configured:

network-pre.target is a target that may be used to order services before any network interface is configured. It's primary purpose is for usage with firewall services that want to establish a firewall before any network interface is up.

It's a passive unit: you cannot start it directly and it is not pulled in by the the network management service, but by the service that wants to run before it. [..] Services that want to be run before the network is configured should place Before=network-pre.target and also set Wants=network-pre.target to pull it in. This way, unless there's actually a service that needs to be ordered before the network is up the target is not pulled in, hence avoiding any unnecessary synchronization point.

I've modified /var/lib/systemd/system/usb_modeswitch@.service and added Before-/Wants-directives accordingly:

[Unit]
Description=USB_ModeSwitch
Before=network-pre.target
Wants=network-pre.target

[Service]
Type=oneshot
ExecStart=/usr/sbin/usb_modeswitch_dispatcher --switch-systemd %I
Environment="TMPDIR=/run"

Which now leads to a "Ordering cycle" error on booting:

[..]
[  OK  ] Started Trigger Flushing of Journal to Persistent Storage.
[ SKIP ] Ordering cycle found, skipping LSB: Raise network interfaces.
[ SKIP ] Ordering cycle found, skipping Network (Pre)
[  OK  ] Created slice system-usb_modeswitch.slice.
[..]

Here's the output of systemctl show ..:

root@raspberrypi:/lib/systemd/system# systemctl show -p Requires,Wants,Requisite,BindsTo,PartOf,Before,After usb_modeswitch@.
Requires=basic.target
Requisite=
Wants=network-pre.target system-usb_modeswitch.slice
BindsTo=
PartOf=
Before=network-pre.target shutdown.target
After=systemd-journald.socket basic.target system-usb_modeswitch.slice

root@raspberrypi:/lib/systemd/system# systemctl show -p Requires,Wants,Requisite,BindsTo,PartOf,Before,After usb_modeswitch@.service
Failed to get properties: Unit name usb_modeswitch@.service is not valid.
root@raspberrypi:/lib/systemd/system#

I'm also wondering why systemctl show works with usb_modeswitch@. but not with usb_modeswitch@.service

Removing the two lines in the service-file restores the old behaviour without SKIP-errors.

Is there any other way to bring up the network-interfaces after the usb_modeswitch? Do I need to adapt anything else in the systemd-configuration to make this work?

Christian Benke

Posted 2017-05-18T13:39:06.943

Reputation: 121

Answers

1

I've been able to fix the issue using the following configuration:

[Unit]
Description=USB_ModeSwitch
DefaultDependencies=no
After=local-fs.target systemd-sysctl.service
Before=network-pre.target shutdown.target
Wants=network-pre.target
Conflicts=shutdown.target

[Service]
Type=oneshot
ExecStart=/usr/sbin/usb_modeswitch_dispatcher --switch-systemd %I
Environment="TMPDIR=/run"

I found the solution via this comment on an Ubuntu-bugreport, which refers to a similar problem with shorewall instead of usb_modeswitch.

DefaultDependencies is defined as:

will implicitly complement all configured dependencies of type Wants= or Requires= with dependencies of type After=

I have not tested if this setting is a key part of the configuration or if it can be left out.

--

Here's the full explanation from the aforementioned bug-report (For shorewall instead of usb_modeswitch):

Shorewall does not come with a systemd native service unit description. Such description is being generated at boot by /lib/systemd/system-generators/systemd-sysv-generator based on /etc/init.d/shorewall. I have noticed, however, that the LSB header of /etc/init.d/shorewall wants the service to be started from /etc/rcS.d, which is pretty early, and at the same time it has Required-Start: $network $remote_fs, which is a pretty strong requirement. In fact, this is the only script in /etc/rcS.d that requires $network (well, except shorewall6, which exhibits exactly the same problem). Looking into the auto-generated unit in /run/systemd/generator.late/shorewall.service shows:

DefaultDependencies=no
Before=sysinit.target shutdown.target
After=network-online.target remote-fs.target
Wants=network-online.target
Conflicts=shutdown.target

This looks problematic: sysinit.target is a very early target, most higher level services are started after it, and on many systems (including mine) various dependencies will make network-online.target available only after sysinit.target.

Whatever the exact cause was, this configuration works for me and doesn't seem to have any undesired effects.

Christian Benke

Posted 2017-05-18T13:39:06.943

Reputation: 121