aboutsummaryrefslogtreecommitdiff
blob: 3e6f98b940a371d90ad85991fb3981b934d2195d (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
# $Id$

set_bootloader() {
	case "${BOOTLOADER}" in
		grub)
			set_bootloader_grub
			;;
		*)
			print_warning "Bootloader ${BOOTLOADER} is not currently supported"
			;;
	esac
}

set_bootloader_read_fstab() {
	local ROOTFS=$(awk 'BEGIN{RS="((#[^\n]*)?\n)"}( $2 == "/" ) { print $1; exit }' /etc/fstab)
	local BOOTFS=$(awk 'BEGIN{RS="((#[^\n]*)?\n)"}( $2 == "'${BOOTDIR}'") { print $1; exit }' /etc/fstab)

	# If ${BOOTDIR} is not defined in /etc/fstab, it must be the same as /
	[ -z "${BOOTFS}" ] && BOOTFS=${ROOTFS}

	echo "${ROOTFS} ${BOOTFS}"
}

set_bootloader_grub_read_device_map() {
	# Read GRUB device map
	[ ! -d ${TEMP} ] && mkdir ${TEMP}
	echo "quit" | grub --batch --device-map=${TEMP}/grub.map &>/dev/null
	echo "${TEMP}/grub.map"
}

set_bootloader_grub() {
	local GRUB_CONF="${BOOTDIR}/grub/grub.conf"

	print_info 1 "Adding kernel to ${GRUB_CONF}..."

	if [ ! -e ${GRUB_CONF} ]
	then
		local GRUB_BOOTFS
		if [ -n "${BOOTFS}" ]
		then
			GRUB_BOOTFS=$BOOTFS
		else
			GRUB_BOOTFS=$(set_bootloader_read_fstab | cut -d' ' -f2)
		fi

		# Get the GRUB mapping for our device
		local GRUB_BOOT_DISK1=$(echo ${GRUB_BOOTFS} | sed -e 's#\(/dev/.\+\)[[:digit:]]\+#\1#')
		local GRUB_BOOT_DISK=$(awk '{if ($2 == "'${GRUB_BOOT_DISK1}'") {gsub(/(\(|\))/, "", $1); print $1;}}' ${TEMP}/grub.map)
		local GRUB_BOOT_PARTITION=$(($(echo ${GRUB_BOOTFS} | sed -e 's#/dev/.\+\([[:digit:]]?*\)#\1#') - 1))

		if [ -n "${GRUB_BOOT_DISK}" -a -n "${GRUB_BOOT_PARTITION}" ]
		then

			# Create grub configuration directory and file if it doesn't exist.
			[ ! -d `dirname ${GRUB_CONF}` ] && mkdir -p `dirname ${GRUB_CONF}`

			touch ${GRUB_CONF}
			echo 'default 0' >> ${GRUB_CONF}
			echo 'timeout 5' >> ${GRUB_CONF}
			echo "root (${GRUB_BOOT_DISK},${GRUB_BOOT_PARTITION})" >> ${GRUB_CONF}
			echo >> ${GRUB_CONF}

			# Add grub configuration to grub.conf	
			echo "# Genkernel generated entry, see GRUB documentation for details" >> ${GRUB_CONF}
			echo "title=Gentoo Linux ($KV)" >> ${GRUB_CONF}
			if [ "${BUILD_INITRD}" = '0' ]
			then
				echo -e "\tkernel /kernel-${KNAME}-${ARCH}-${KV} root=${GRUB_ROOTFS}" >> ${GRUB_CONF}
			else
				echo -e "\tkernel /kernel-${KNAME}-${ARCH}-${KV} root=/dev/ram0 init=/linuxrc real_root=${GRUB_ROOTFS}" >> ${GRUB_CONF}
				if [ "${PAT}" -gt '4' ]
				then
				    echo -e "\tinitrd /initramfs-${KNAME}-${ARCH}-${KV}" >> ${GRUB_CONF}
				fi
			fi
			echo >> ${GRUB_CONF}
		else
			print_error 1 "Error! ${BOOTDIR}/grub/grub.conf does not exist and the correct settings can not be automatically detected."
			print_error 1 "Please manually create your ${BOOTDIR}/grub/grub.conf file."
		fi

	else
		# The grub.conf already exists, so let's try to duplicate the default entry
		if set_bootloader_grub_check_for_existing_entry "${GRUB_CONF}"; then
			print_warning 1 "An entry was already found for a kernel/initramfs with this name...skipping update"
			return 0
		fi

		set_bootloader_grub_duplicate_default "${GRUB_CONF}"
	fi

}

set_bootloader_grub_duplicate_default_replace_kernel_initrd() {
	sed -r -e "/^[[:space:]]*kernel/s/kernel-[[:alnum:][:punct:]]+/kernel-${KNAME}-${ARCH}-${KV}/" - |
	sed -r -e "/^[[:space:]]*initrd/s/init(rd|ramfs)-[[:alnum:][:punct:]]+/init\1-${KNAME}-${ARCH}-${KV}/"
}

set_bootloader_grub_check_for_existing_entry() {
	local GRUB_CONF=$1
	if grep -q "^[[:space:]]*kernel[[:space:]=]*.*/kernel-${KNAME}-${ARCH}-${KV}\([[:space:]]\|$\)" "${GRUB_CONF}" &&
		grep -q "^[[:space:]]*initrd[[:space:]=]*.*/initramfs-${KNAME}-${ARCH}-${KV}\([[:space:]]\|$\)" "${GRUB_CONF}"
	then
		return 0
	fi
	return 1
}

set_bootloader_grub_duplicate_default() {
	local GRUB_CONF=$1
	local GRUB_CONF_TMP="${GRUB_CONF}.tmp"
	
	line_count=$(wc -l < "${GRUB_CONF}")
	line_nums="$(grep -n "^title" "${GRUB_CONF}" | cut -d: -f1)"
	if [ -z "${line_nums}" ]; then
		print_error 1 "No current 'title' entries found in your grub.conf...skipping update"
		return 0
	fi
	line_nums="${line_nums} $((${line_count}+1))"

	# Find default entry
	default=$(sed -rn '/^[[:space:]]*default[[:space:]=]/s/^.*default[[:space:]=]+([[:alnum:]]+).*$/\1/p' "${GRUB_CONF}")
    if [ -z "${default}" ]; then
		print_warning 1 "No default entry found...assuming 0"
		default=0
	fi
	if ! echo ${default} | grep -q '^[0-9]\+$'; then
		print_error 1 "We don't support non-numeric (such as 'saved') default values...skipping update"
		return 0
	fi

	# Grub defaults are 0 based, cut is 1 based
	# Figure out where the default entry lives
	startstop=$(echo ${line_nums} | cut -d" " -f$((${default}+1))-$((${default}+2)))
	startline=$(echo ${startstop} | cut -d" " -f1)
	stopline=$(echo ${startstop} | cut -d" " -f2)

	# Write out the bits before the default entry
	sed -n 1,$((${startline}-1))p "${GRUB_CONF}" > "${GRUB_CONF_TMP}"

	# Put in our title
	echo "title=Gentoo Linux (${KV})" >> "${GRUB_CONF_TMP}"

	# Pass the default entry (minus the title) through to the replacement function and pipe the output to GRUB_CONF_TMP
	sed -n $((${startline}+1)),$((${stopline}-1))p "${GRUB_CONF}" | set_bootloader_grub_duplicate_default_replace_kernel_initrd >> "${GRUB_CONF_TMP}"

	# Finish off with everything including the previous default entry
	sed -n ${startline},${line_count}p "${GRUB_CONF}" >> "${GRUB_CONF_TMP}"

	cp "${GRUB_CONF}" "${GRUB_CONF}.bak"
	cp "${GRUB_CONF_TMP}" "${GRUB_CONF}"
	rm "${GRUB_CONF_TMP}"
}