summaryrefslogtreecommitdiff
blob: ba5b25f1827c69bb94f83df53bcb112d1d513384 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
#!/sbin/runscript
# Copyright 1999-2010 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2

command=/usr/lib/systemd/systemd-udevd
command_args="--daemon ${udev_opts}"
description="udev manages device permissions and symbolic links in /dev"

rc_coldplug=${rc_coldplug:-${RC_COLDPLUG:-YES}}
udev_debug="${udev_debug:-no}"
udev_monitor="${udev_monitor:-no}"
udev_monitor_keep_running="${udev_monitor_keep_running:-no}"
udev_settle_timeout="${udev_settle_timeout:-60}"
kv_min="${kv_min:-2.6.34}"

depend()
{
	provide dev
	need sysfs udev-mount
	before checkfs fsck

	# udev does not work inside vservers
	keyword -vserver -lxc
}

KV_to_int()
{
	[ -z $1 ] && return 1

	local x=${1%%[!0-9.]*} y= z=
	local KV_MAJOR=${x%%.*}
	y=${x#*.}
	[ "$x" = "$y" ] && y=0.0
	local KV_MINOR=${y%%.*}
	z=${y#*.}
	[ "$y" = "$z" ] && z=0
	local KV_MICRO=${z%%.*}
	local KV_int=$((${KV_MAJOR} * 65536 + ${KV_MINOR} * 256 + ${KV_MICRO} ))

	# We make version 2.2.0 the minimum version we will handle as
	# a sanity check ... if its less, we fail ...
	[ "${KV_int}" -lt 131584 ] && return 1
	
	echo "${KV_int}"
}

_RC_GET_KV_CACHE=""
get_KV()
{
	if [ -z "${_RC_GET_KV_CACHE}" ] ; then
		_RC_GET_KV_CACHE="$(uname -r)"
	fi
	echo "$(KV_to_int "${_RC_GET_KV_CACHE}")"
	return $?
}

# FIXME
# Instead of this script testing kernel version, udev itself should
# Maybe something like udevd --test || exit $?
check_kernel()
{
	if [ $(get_KV) -lt $(KV_to_int ${kv_min}) ]; then
		eerror "Your kernel is too old to work with this version of udev."
		eerror "Current udev only supports Linux kernel ${kv_min} and newer."
		return 1
	fi
	return 0
}

_RC_GET_RUNDIR_CACHE=
get_rundir()
{
	if [ -z "$_RC_GET_RUNDIR_CACHE" ]; then
		_RC_GET_RUNDIR_CACHE="$(udevadm info --run)"
	fi
	echo "$_RC_GET_RUNDIR_CACHE"
	return 0
}

is_service_enabled()
{
	local svc="$1"

	[ ! -e "/etc/init.d/${svc}" ] && return 1

	[ -e "/etc/runlevels/${RC_BOOTLEVEL}/${svc}" ] && return 0
	[ -e "/etc/runlevels/${RC_DEFAULTLEVEL}/${svc}" ] && return 0
	return 1
}

start_pre()
{
	if is_service_enabled network; then
		# disable network hotplugging
		local f="$(get_rundir)/rules.d/90-network.rules"
		echo "# This file disables network hotplug events calling" >> "${f}"
		echo "# old-style openrc net scripts" >> "${f}"
		echo "# as we use /etc/init.d/network to set up our network" >> "${f}"
	fi

	if [ -e /proc/sys/kernel/hotplug ]; then
		echo "" >/proc/sys/kernel/hotplug
	fi

	# load unix domain sockets if built as module, Bug #221253
	# and not yet loaded, Bug #363549
	if [ ! -e /proc/net/unix ]; then
		if ! modprobe unix; then
			eerror "Cannot load the unix domain socket module"
		fi
	fi

	if yesno "${udev_debug}"; then
		command_args="${command_args} --debug 2> $(get_rundir)/udev.log"
	fi
}

start_udevmonitor()
{
	yesno "${udev_monitor}" || return 0

	udevmonitor_log="$(get_rundir)/udevmonitor.log"
	udevmonitor_pid="$(get_rundir)/udevmonitor.pid"

	einfo "udev: Running udevadm monitor ${udev_monitor_opts} to log all events"
	start-stop-daemon --start --stdout "${udevmonitor_log}" \
		--make-pidfile --pidfile "${udevmonitor_pid}" \
		--background --exec /sbin/udevadm -- monitor ${udev_monitor_opts}
}

populate_dev()
{
	if get_bootparam "nocoldplug" ; then
		rc_coldplug="NO"
		ewarn "Skipping udev coldplug as requested in kernel cmdline"
	fi

	ebegin "Populating /dev with existing devices through uevents"
	if ! yesno "${rc_coldplug}"; then
		# Do not run any init-scripts, Bug #206518
		udevadm control --property=do_not_run_plug_service=1
	fi
	udevadm trigger --type=subsystems --action=add
	udevadm trigger --type=devices --action=add
	eend $?

	# we can speed up booting under these conditions:
	#  * using devtmpfs so kernel creates device nodes for us
	#  * only using kernel created device nodes at boot
	# (in /etc/fstab and elsewhere)
	#
	ebegin "Waiting for uevents to be processed"
	udevadm settle --timeout=${udev_settle_timeout}
	eend $?

	udevadm control --property=do_not_run_plug_service=
	return 0
}

stop_udevmonitor()
{
	yesno "${udev_monitor}" || return 0

	if yesno "${udev_monitor_keep_running}"; then
		ewarn "udev: udevmonitor is still running and writing into ${udevmonitor_log}"
	else
		einfo "udev: Stopping udevmonitor: Log is in ${udevmonitor_log}"
		start-stop-daemon --stop --pidfile "${udevmonitor_pid}" --exec /sbin/udevadm
	fi
}

display_hotplugged_services()
{
	local svcfile= svc= services=
	for svcfile in "${RC_SVCDIR}"/hotplugged/*; do
		svc="${svcfile##*/}"
		[ -x "${svcfile}" ] || continue

		services="${services} ${svc}"
	done
	[ -n "${services}" ] && einfo "Device initiated services:${HILITE}${services}${NORMAL}"
}

start_post()
{
	start_udevmonitor
	populate_dev
	stop_udevmonitor
	display_hotplugged_services
	return 0
}