FS#35715 - [netctl] fails to start network inside Linux Container
Attached to Project:
Arch Linux
Opened by John Lane (starfry) - Saturday, 08 June 2013, 10:54 GMT
Last edited by Jouke Witteveen (jouke) - Saturday, 17 November 2018, 12:03 GMT
Opened by John Lane (starfry) - Saturday, 08 June 2013, 10:54 GMT
Last edited by Jouke Witteveen (jouke) - Saturday, 17 November 2018, 12:03 GMT
|
Details
Description:
Starting a netctl profile inside an LXC container fails because the unit file generated by netctl contains a dependency on a udev unit which will never exist because udev cannot run inside a Linux Container. The solution is to for netctl to not add the dependency to the unit file that it writes if it is running inside LXC. A patch file is attached that uses systemd-detect-virt to make this decision. Additionally, the network interface inside the container is UP when the container starts and netctl will refuse to start if the interface is already up. The solution that I found to this problem was to add "ForceConnect=yes" to the profile (I could not find this option documented on the man page for netctl.profile so I don't know whether using it is the right thing to do). Additional info: * package version(s) netctl 1.1-1 * config and/or log files etc. Steps to reproduce: Create a container with a netctl profile. Use netctl to start the profile. It won't start. Attempting to start directly with "/usr/lib/network/network start profile" will highlight the issue with the interface being up preventing start-up. This can be remedied with a "ip link set dev eth0 down" and then retrying. Also after bringing the interface down "netctl start profile" or "systemctl start netctl@profile" will also work. Add "ForceConnect=yes" to the profile to prevent this issue. |
This task depends upon
Closed by Jouke Witteveen (jouke)
Saturday, 17 November 2018, 12:03 GMT
Reason for closing: None
Additional comments about closing: Please reopen if this is still an issue.
Saturday, 17 November 2018, 12:03 GMT
Reason for closing: None
Additional comments about closing: Please reopen if this is still an issue.
I also think the need to not depend on the udev interface covers more scenarios than lxc (e.g. running in a chroot, systemd-nspawn, etc) so rather than checking for systemd-detect-virt returning "lxc" I think it might be more approoriate to check when it does not return "none". I have attached a modified netctl patch for that.
netctl.patch (0.6 KiB)
if [[ $(systemd-detect-virt) != none ]]; then
BindsToInterfaces=()
ForceConnect=yes
fi
These values can then still be overridden in profile files.
[code]
if is_interface "$Interface"; then
report_error "Interface '$Interface' already exists"
return 1
else
bring_interface_up "$BindsToInterfaces"
ip link add link "$BindsToInterfaces" name "$Interface" type vlan id "$VLANID"
fi
[/code]
So, I've simply get "No unique physical device for VLAN interface 'eth0.2500' specified" error.
About the usage of ForceConnect, this bug indeed indicates a valid use-case for it. It is documented in netctl >= 1.2.
Have you tried to modify lxc configuration (/var/lib/lxc/[name]/config) and to remove "lxc.network.flags = up"?
Re the suggestion of a hook
if [[ $(systemd-detect-virt) != none ]]; then
BindsToInterfaces=()
ForceConnect=yes
fi
This is executed and does what it says - it empties the BindsToInterfaces array. But it doesn't solve the problem because line 114 in netctl:
[[ -v BindsToInterfaces ]] || BindsToInterfaces=$Interface
which sets it to the named interface in the config.
The use of "ForceConnect" does work, however. But as per the suggestion above, isn't necessary if "lxc.network.flags = up" is removed from the container config.
I have also tried a systemd "drop-in" to unset the BindsTo but I can't get it to work either...
# cat /etc/systemd/system/netctl@.service.d/without_udev.conf
[Unit]
BindsTo=
After=
My main issue is that test -v does not distinguish between an undefined BindsToInterfaces and an empty array.
Following patch solves it for me (unit_enable)
--- a/src/netctl.in
+++ b/src/netctl.in
@@ -111,7 +111,8 @@ unit_enable() {
echo ".include @systemdsystemunitdir@/netctl@.service" > "$unit"
echo -e "\n[Unit]" >> "$unit"
[[ -n $Description ]] && echo "Description=$Description" >> "$unit"
- [[ -v BindsToInterfaces ]] || BindsToInterfaces=$Interface
+ declare -p BindsToInterfaces >/dev/null 2>/dev/null
+ [[ $? -eq 1 ]] && BindsToInterfaces=$Interface
if (( ${#BindsToInterfaces[@]} )); then
: ${InterfaceRoot=sys/subsystem/net/devices/}
printf "BindsTo=$(sd_escape "$InterfaceRoot")%s.device\n" \