aports

Custom Alpine Linux aports

git clone git://git.lin.moe/aports.git

  1#!/bin/sh
  2# Copyright (c) 2012, Piotr Karbowski <piotr.karbowski@gmail.com>
  3# All rights reserved.
  4#
  5# Redistribution and use in source and binary forms, with or without modification, are
  6# permitted provided that the following conditions are met:
  7#
  8#    * Redistributions of source code must retain the above copyright notice, this list
  9#      of conditions and the following disclaimer.
 10#    * Redistributions in binary form must reproduce the above copyright notice, this list
 11#      of conditions and the following disclaimer in the documentation and/or other
 12#      materials provided with the distribution.
 13#    * Neither the name of the Piotr Karbowski nor the names of its contributors may be
 14#      used to endorse or promote products derived from this software without specific
 15#      prior written permission.
 16#
 17# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
 18# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 19# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
 20# THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 21# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
 22# OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 23# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 24# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE US
 25# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 26
 27# This script suppose to preserve interfaces names.
 28# First it will run nameif to rename interfaces if configured in /etc/mactab
 29# Then it will dump known interfaces to new mactab file.
 30# Next it will parse old /etc/mactab and copy all interfaces which wasnt added in step two.
 31# On the end, it will replace /etc/mactab with the new one.
 32
 33# Info: Step two will only care about eth*, wlan*, ath*, wifi* and ra* interfaces.
 34
 35umask 077
 36
 37if [ -n "${USER}" ] && [ "${USER}" != 'root' ]; then
 38	echo "You need root to run it." >&2
 39	exit 1
 40fi
 41
 42command_exists() {
 43	command -v "${1}" >/dev/null 2>&1
 44}
 45
 46in_comma_list() {
 47	# Check whatever $1 is in the comma separated list $2.
 48	local x
 49	local check_for="$1"
 50	case ",$2," in
 51		*,"${check_for}",*)
 52			return 0
 53		;;
 54	esac
 55	return 1
 56}
 57
 58get_nic_macaddr() {
 59	# Try to get real mac address from nic $1.
 60	local nic="$1"
 61	local macaddr
 62	if command_exists ethtool; then
 63		macaddr="$(ethtool -P ${nic} 2>/dev/null)"
 64		macaddr="${macaddr##*: }"
 65		if [ -n "${macaddr}" ] && [ "${macaddr}" != 'not set' ]; then
 66			echo "${macaddr}"
 67			return 0
 68		fi
 69	fi
 70	if command_exists ip; then
 71		macaddr="$(ip link show dev ${nic} |grep permaddr)"
 72		macaddr="${macaddr##*permaddr }"
 73		if [ -n "${macaddr}" ]; then
 74			echo "${macaddr}"
 75			return 0
 76		fi
 77	fi
 78	# Fallback to get mac address from sysfs.
 79	cat "/sys/class/net/${nic}/address"
 80}
 81
 82lockfile='/etc/mactab.settle-nics_lockfile'
 83while : ; do
 84	if ! test -f "${lockfile}" && ( set -o noclobber; echo "$$" > "${lockfile}") 2> /dev/null; then
 85		break
 86	else
 87		sleep 1
 88	fi	
 89done
 90
 91case "$1" in
 92	--write-mactab)
 93		write_mactab='true'
 94		tmpfile="/etc/mactab.settle-nics_tmpfile.$$"
 95		rm -f "${tmpfile}"
 96	;;
 97	'')
 98		tmpfile='/dev/null'
 99	;;
100	*)
101		echo "Wrong argument!" >&2
102		exit 1
103	;;
104	
105esac
106
107trap 'status="$?"; rm -f "${lockfile}"; test -f "${tmpfile}" && rm -f "${tmpfile}"; exit "${status}"' INT TERM EXIT
108
109# If we do have configured nics but the configured names are already used by something else, rename it to temp name.
110# I wish nameif or ifrename could be smart enough to do it itself...
111inconf_nics=""
112inconf_macs=""
113if [ -f '/etc/mactab' ]; then
114	while read nic macaddr _; do
115		case "${nic}" in
116			'#'*)
117			;;
118			*)
119				inconf_nics="${inconf_nics},${nic}"
120				inconf_macs="${inconf_macs},${macaddr}"
121				if [ -e "/sys/class/net/${nic}" ]; then
122					curr_macaddr="$(get_nic_macaddr ${nic})"
123					if [ "${curr_macaddr}" != "${macaddr}" ]; then
124						# Okey, so kernel added another NIC with name which we preserved for other NIC.
125						echo "Looks like '${nic}' is preserved. renaming current '${nic}' to '${nic}_tmp' ..." >&2
126						ip link set dev "${nic}" name "${nic}_tmp"
127					fi
128				fi
129			;;
130		esac
131	done < '/etc/mactab'
132fi
133
134# Run nameif so all interfaces will be renamed to specified names.
135if command_exists nameif && test -f /etc/mactab; then
136	nameif
137fi
138
139# Arrr rite. by now nemaif should put nics in right order, if there is still any *_tmp nic, we shall assign proper, free device name to it.
140for nic in /sys/class/net/*_tmp; do
141	nic="${nic##*/}"
142	if [ "${nic}" = '*_tmp' ]; then break; fi
143	nic_basename="${nic%%_tmp}"
144	nic_basename="${nic_basename%%[0-9]*}"
145	i=0
146	while [ "${i}" -le "128" ]; do
147		if ! [ -e "/sys/class/net/${nic_basename}${i}" ] && ! in_comma_list "${nic_basename}${i}" "${inconf_nics}"; then
148			echo "Renaming '${nic}' to '${nic_basename}${i}' ..." >&2
149			ip link set dev "${nic}" name "${nic_basename}${i}"
150			break
151		fi
152		i="$(($i+1))"
153	done
154done
155
156if [ "${write_mactab}" != 'true' ]; then
157	# We don't want write mactab thus there is no reason to check the network interfaces' mac addresses and so on...
158	exit 0
159fi
160
161printf '%s\n' "# Generated by settle-nics from mdev-like-a-boss." >> "${tmpfile}"
162
163# First get all the macs of current accessable nics
164detected_nics=""
165detected_macs=""
166for i in /sys/class/net/*; do
167	unset device macaddr
168	device="${i##*/}"
169	case "${device}" in
170		*_tmp)
171		;;
172		eth[0-9]*|wlan[0-9]*|ath[0-9]*|wifi[0-9]*|ra[0-9]*)
173			macaddr="$(get_nic_macaddr ${device} 2>/dev/null)"
174			if [ -n "${macaddr}" ] && ! in_comma_list "${macaddr}" "${inconf_macs}" && ! in_comma_list "${device}" "${inconf_nics}"; then
175				detected_nics="${detected_nics},${device}"
176				detected_macs="${detected_macs},${macaddr}"
177				printf '%-15s %s\n' "${device}" "${macaddr}" >> "${tmpfile}"
178			fi
179		;;
180	esac
181done
182
183# Now lets parse current /etc/mactab so we no loose any configured but not available at this moment interface.
184if [ -f '/etc/mactab' ]; then
185	unset device macaddr
186	while read device macaddr; do
187		case "${device}" in
188			'#'*)
189			;;
190			*)
191				if [ -n "${macaddr}" ] && ! in_comma_list "${macaddr}" "${detected_macs}" && ! in_comma_list "${device}" "${detected_nics}"; then
192					printf '%-15s %s\n' "${device}" "${macaddr}" >> "${tmpfile}"
193				fi
194			;;
195		esac
196	done < '/etc/mactab'
197fi
198
199mv "${tmpfile}" '/etc/mactab'