]> git.ipfire.org Git - people/ms/network.git/commitdiff
Fix hotplugging with udev.
authorMichael Tremer <michael.tremer@ipfire.org>
Fri, 25 May 2012 09:02:08 +0000 (09:02 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Fri, 25 May 2012 09:02:08 +0000 (09:02 +0000)
New devices will now be correctly named
and brought up after plugging them in.

functions.constants
functions.device
functions.lock [new file with mode: 0644]
functions.logging
functions.util
hooks/ports/ethernet
udev/network-hotplug
udev/network-hotplug-rename
udev/rules.d/60-net.rules

index 04da262fe4931c64ce28e36b3159384f1e9a8860..40f306df2593e04ae75e737a319d3f71ca315a7a 100644 (file)
@@ -79,4 +79,4 @@ TIMEOUT_RESTART=2
 
 DEVICE_PRINT_LINE1="    %-24s %s\n"
 
-PORT_PATTERN=portN
+PORT_PATTERN="pN"
index ff1412708d53c4e6cbc5bc5dfa9c25bed6edc9c3..238cb06aab7978372fd01d212b7344adfc612e94 100644 (file)
@@ -560,13 +560,18 @@ function device_hotplug() {
        shift
 
        assert isset device
-       #assert device_exists ${device}
+       assert device_exists ${device}
 
        if ! device_is_free ${device}; then
                log ERROR "The device '${device}' is in use."
                return ${EXIT_ERROR}
        fi
 
+       if ! device_is_real ${device}; then
+               log DEBUG "Don't rename any virtual devices."
+               return ${EXIT_OK}
+       fi
+
        for port in $(ports_get_all); do
                port_cmd hotplug ${port} ${device}
                if [ $? -eq ${EXIT_OK} ]; then
@@ -575,6 +580,13 @@ function device_hotplug() {
                fi
        done
 
-       port_find_free ${PORT_PATTERN}
-       return $?
+       # If no port configuration could be found, we search for the next
+       # unused name and return that.
+       local port=$(port_find_free ${PORT_PATTERN})
+
+       log DEBUG "Could not find an existing port configuration for '${device}'."
+       log DEBUG "${device} --> ${port}"
+
+       echo "${port}"
+       return ${EXIT_OK}
 }
diff --git a/functions.lock b/functions.lock
new file mode 100644 (file)
index 0000000..7241405
--- /dev/null
@@ -0,0 +1,58 @@
+#!/bin/bash
+###############################################################################
+#                                                                             #
+# IPFire.org - A linux based firewall                                         #
+# Copyright (C) 2012  Michael Tremer & Christian Schmidt                      #
+#                                                                             #
+# This program is free software: you can redistribute it and/or modify        #
+# it under the terms of the GNU General Public License as published by        #
+# the Free Software Foundation, either version 3 of the License, or           #
+# (at your option) any later version.                                         #
+#                                                                             #
+# This program is distributed in the hope that it will be useful,             #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of              #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               #
+# GNU General Public License for more details.                                #
+#                                                                             #
+# You should have received a copy of the GNU General Public License           #
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.       #
+#                                                                             #
+###############################################################################
+
+function lock_acquire() {
+       local lockfile="${1}"
+       assert isset lockfile
+
+       # timeout value in seconds
+       local timeout=60
+       timeout=$(( ${timeout} * 10 ))
+
+       log DEBUG "Acquiring lock '${lockfile}'."
+
+       local free="false"
+       while [ ${timeout} -gt 0 ]; do
+               if [ ! -e "${lockfile}" ]; then
+                       free="true"
+                       break
+               fi
+
+               timeout=$(( ${timeout} - 1 ))
+               sleep 0.1
+       done
+
+       assert ${free} "Could not acquire lock '${lockfile}'."
+
+       # Write out pid to the lockfile and make sure that
+       # nobody else can access it.
+       echo "$$" > ${lockfile}
+       chmod 600 ${lockfile}
+}
+
+function lock_release() {
+       local lockfile="${1}"
+
+       log DEBUG "Releasing lock '${lockfile}'."
+
+       # Remove the lockfile (okay if it does not exist).
+       rm -f ${lockfile}
+}
index 76b3bdc732be5cd84a76a74681c8478ce5ef2263..6cb827815b4ef02ef998045754e114859b506f00 100644 (file)
 #                                                                             #
 ###############################################################################
 
-LOG_FACILITY="network"
+if [ -z "${LOG_FACILITY}" ]; then
+       LOG_FACILITY="network"
+fi
+
 LOG_LEVEL="DEBUG"
 
+if [ -z "${LOG_DISABLE_STDOUT}" ]; then
+       LOG_DISABLE_STDOUT=false
+fi
+
 function log() {
        local level=${1}
        shift
@@ -38,6 +45,9 @@ function log() {
 
        logger -t ${LOG_FACILITY} "${message}"
 
+       # Leave here, when there should be no output on the console.
+       [ "${LOG_DISABLE_STDOUT}" = "true" ] && return 0
+
        case "${level}" in
                DEBUG|INFO|WARNING|ERROR)
                        message="${COLOUR_LOG[${level}]}${message}${COLOUR_NORMAL}"
index 953df22a50905ce35aa1687d616993ea48fc700d..f990362f7e2b351336de6d7af9de669e9c271ae0 100644 (file)
@@ -314,6 +314,8 @@ function exec_cmd() {
        log DEBUG "Running command: ${cmd}"
 
        DEBUG=${DEBUG} \
+       LOG_DISABLE_STDOUT="${LOG_DISABLE_STDOUT}" \
+       LOG_FACILITY="${LOG_FACILITY}" \
                ${SHELL} ${cmd}
        local ret=$?
 
index cf37aa05cf78d25ee9970172f5b38efc69d464c2..499889adc84e66f3646f7965dfe0962e68f27352 100755 (executable)
@@ -19,7 +19,7 @@
 #                                                                             #
 ###############################################################################
 
-. /lib/network/header-port
+. /usr/lib/network/header-port
 
 HOOK_SETTINGS="HOOK DEVICE_MAC"
 
@@ -70,9 +70,11 @@ function _hotplug() {
        config_read $(port_file ${port})
 
        if [ "${DEVICE_MAC}" = "$(device_get_address ${device})" ]; then
+               log DEBUG "Device '${device}' equals port '${port}'."
                exit ${EXIT_OK}
        fi
 
+       log DEBUG "Device '${device}' does not equal port '${port}'."
        exit ${EXIT_ERROR}
 }
 
index d4a76cb91ff9c8bd81398d2fa1d86599d9374f6c..63fd3795e7787df79e1c8f54eebb45c472f43f58 100755 (executable)
 #                                                                             #
 ###############################################################################
 
-. /lib/network/functions
+. /usr/lib/network/functions
+
+# Setup logging.
+LOG_FACILITY="network-hotplug"
+
+log DEBUG "Called with ACTION='${ACTION}', INTERFACE='${INTERFACE}'."
 
 # Do nothing, if the network isn't running.
 # That happens for example on boot time.
 if ! network_is_running; then
+       log DEBUG "network has not been started, yet. Exiting."
        exit 0
 fi
 
@@ -33,23 +39,30 @@ assert isset INTERFACE
 
 # Check, if the device is a physical network interface and
 # if we can handle it.
-if ! device_is_real ${INTERFACE}; then
-       exit ${EXIT_OK}
-fi
-
-# Check, if there is a configuration for that device.
-if port_exists ${INTERFACE}; then
-       port=${INTERFACE}
-
-else
-       # If the given device was not configured,
-       # we create an initial configuration.
-       port_create ethernet ${INTERFACE}
-       exit ${EXIT_OK}
+if device_exists ${INTERFACE}; then
+       if ! device_is_real ${INTERFACE}; then
+               log DEBUG "Called for interface '${INTERFACE}' which is a virtual interface. Exiting."
+               exit ${EXIT_OK}
+       fi
 fi
 
 case "${ACTION}" in
        add|register)
+               # Check, if there is a configuration for that device.
+               if port_exists ${INTERFACE}; then
+                       port=${INTERFACE}
+
+               # Create new configuration for _real_ network devices.
+               elif device_is_real ${INTERFACE}; then
+                       # If the given device was not configured,
+                       # we create an initial configuration.
+                       port_create ethernet ${INTERFACE}
+
+               # Dunno what to do in any other case.
+               else
+                       exit 0
+               fi
+
                zone=$(port_zone ${port})
 
                # Check, if the device is configured in a zone.
@@ -63,7 +76,7 @@ case "${ACTION}" in
                ;;
 
        remove|unregister)
-               port_down ${port}
+               # Do nothing.
                ;;
 esac
 
index 3879d0295ec6d93ca57d9b9ce793345d1d5d55f0..1678deb61dfb8e7cc7e38e66807e555f1e55c863 100755 (executable)
 #                                                                             #
 ###############################################################################
 
-. /lib/network/functions
+# Setup logging.
+LOG_FACILITY="network-hotplug-rename"
+LOG_DISABLE_STDOUT="true"
+
+. /usr/lib/network/functions
+
+# Setup the locking.
+LOCKFILE="${RUN_DIR}/.rename_lock"
+function cleanup() {
+       lock_release ${LOCKFILE}
+}
+trap cleanup EXIT TERM KILL
 
 # Check if the INTERFACE variable is properly set.
 assert isset INTERFACE
 
+# Log what we are doing here.
+log DEBUG "Called for interface '${INTERFACE}'."
+
+# Acquiring lock for this operation.
+lock_acquire ${LOCKFILE}
+
 # Get the name of that device from the configuration
 # or return a new one if it is unknown.
 device_hotplug ${INTERFACE}
index 6d7bc0b3290327b2ecb288c5e4fc4da34c25d968..ab1779b34800e563bfc9d9993f459023e9a7e752 100644 (file)
@@ -2,7 +2,7 @@
 # Call a script that checks for the right name of the new device.
 # It is either renamed to match an existing configuration or gets
 # a new name.
-ACTION=="add", SUBSYSTEM=="net", PROGRAM="/lib/udev/network-hotplug-rename", RESULT=="?*", ENV{INTERFACE_NAME}="$result"
+ACTION=="add", SUBSYSTEM=="net", PROGRAM="/usr/lib/udev/network-hotplug-rename", RESULT=="?*", NAME="$result"
 
 # Handle all plugged-in devices.
-SUBSYSTEM=="net", RUN+="/lib/udev/network-hotplug"
+SUBSYSTEM=="net", RUN+="/usr/lib/udev/network-hotplug"