summaryrefslogtreecommitdiff
blob: 59c52af2ae1218ef4a5270dd35edf0ad9b341001 (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
# Copyright 1999-2005 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2

udev_version() {
	local version=0

	if [[ -x /sbin/udev ]] ; then
		version=$(/sbin/udev -V)
		# We need it without a leading '0', else bash do the wrong thing
		version=${version##0}
		# Older udev's will print nothing
		[[ -z ${version} ]] && version=0
	fi

	echo "${version}"
}

# This works for 2.6.15 kernels or greater
trigger_events() {
	list=""
	# if you want real coldplug (with all modules being loaded for all
	# devices in the system), uncomment out the next line.
	#list="$list $(echo /sys/bus/*/devices/*/uevent)"
	list="$list $(echo /sys/class/*/*/uevent)"
	list="$list $(echo /sys/block/*/uevent /sys/block/*/*/uevent)"
	for i in $list; do
		case "$i" in
			*/device/uevent)
				# skip followed device symlinks
				continue
				;;
			*/class/mem/*|*/class/tty/*)
				first="$first $i"
				;;
			*/block/md*)
				last="$last $i"
				;;
			*/*)
				default="$default $i"
				;;
		esac
	done

	# trigger the sorted events
	for i in $first $default $last; do
		echo "add" > "$i"
	done
}

populate_udev() {
	# populate /dev with devices already found by the kernel
	if [ "$(get_KV)" -gt "$(KV_to_int '2.6.14')" ] ; then
		ebegin "Populating /dev with existing devices through uevents"
		trigger_events
		eend 0
	else
		ebegin "Populating /dev with existing devices with udevstart"
		/sbin/udevstart
		eend 0
	fi

	# loop until everything is finished
	# there's gotta be a better way...
	ebegin "Letting udev process events"
	loop=0
	while test -d /dev/.udev/queue; do
		sleep 0.1;
		test "$loop" -gt 300 && break
		loop=$(($loop + 1))
	done
	#einfo "loop = $loop"
	eend 0

	ebegin "Finalizing udev configuration"

	# Not provided by sysfs but needed
	ln -snf /proc/self/fd /dev/fd
	ln -snf fd/0 /dev/stdin
	ln -snf fd/1 /dev/stdout
	ln -snf fd/2 /dev/stderr
	[[ -e /proc/kcore ]] && ln -snf /proc/kcore /dev/core

	# Create nodes that udev can't
	[[ -x /sbin/dmsetup ]] && /sbin/dmsetup mknodes &>/dev/null
	[[ -x /sbin/lvm ]] && \
		/sbin/lvm vgscan -P --mknodes --ignorelockingfailure &>/dev/null
	[[ -x /sbin/evms_activate ]] && /sbin/evms_activate -q &>/dev/null

	# Create problematic directories
	mkdir -p /dev/{pts,shm}

	# copy over any persistant things
	cp --preserve=all --recursive --update /lib/udev/devices/* /dev

	# Same thing as /dev/.devfsd
	touch /dev/.udev
	eend 0

	return 0
}

main() {
		# Setup temporary storage for /dev
		ebegin "Mounting /dev for udev"
		if [[ ${RC_USE_FSTAB} == "yes" ]] ; then
			mntcmd=$(get_mount_fstab /dev)
		else
			unset mntcmd
		fi
		if [[ -n ${mntcmd} ]] ; then
			try mount -n ${mntcmd}
		else
			if egrep -qs tmpfs /proc/filesystems ; then
				mntcmd="tmpfs"
			else
				mntcmd="ramfs"
			fi
			# many video drivers require exec access in /dev #92921
			try mount -n -t ${mntcmd} udev /dev -o exec,nosuid,mode=0755
		fi
		eend $?

		# Selinux lovin; /selinux should be mounted by selinux-patched init
		if [[ -x /sbin/restorecon && -c /selinux/null ]] ; then
			restorecon /dev &> /selinux/null
		fi

		# Actually get udev rolling
		if [[ ${RC_DEVICE_TARBALL} == "yes" && \
		      -s /lib/udev-state/devices.tar.bz2 ]] ; then
			ebegin "Populating /dev with saved device nodes"
			try tar -jxpf /lib/udev-state/devices.tar.bz2 -C /dev
			eend $?
		fi

		# Setup hotplugging (if possible)
		ebegin "Setting up proper hotplug agent"
		if [[ -e /proc/sys/kernel/hotplug ]] ; then
			if [ "$(get_KV)" -gt "$(KV_to_int '2.6.14')" ] ; then
				einfo "  Using netlink for hotplug events..."
				echo "" > /proc/sys/kernel/hotplug
			elif [[ $(udev_version) -ge "48" ]] ; then
				einfo "  Setting /sbin/udevsend as hotplug agent ..."
				echo "/sbin/udevsend" > /proc/sys/kernel/hotplug
			elif [[ -x /sbin/hotplug ]] ; then
				einfo "  Using /sbin/hotplug as hotplug agent ..."
			else
				einfo "  Setting /sbin/udev as hotplug agent ..."
				echo "/sbin/udev" > /proc/sys/kernel/hotplug
			fi
		fi
		eend 0

		ebegin "Starting udevd"
		/sbin/udevd --daemon
		eend $?

		populate_udev
}

main


# vim:ts=4