Gentoo Archives: gentoo-dev

From: "Michał Górny" <mgorny@g.o>
To: gentoo-dev@l.g.o
Subject: Re: [gentoo-dev] [PATCH] mount-boot.eclass: Check if /boot is sane, but don't try to mount it.
Date: Fri, 06 Dec 2019 14:03:53
Message-Id: f519f9d2926045b498642fc2ba7fa77f18a34991.camel@gentoo.org
In Reply to: [gentoo-dev] [PATCH] mount-boot.eclass: Check if /boot is sane, but don't try to mount it. by "Ulrich Müller"
1 On Fri, 2019-12-06 at 14:11 +0100, Ulrich Müller wrote:
2 > The eclass failed to remount a read-only mounted /boot, because package
3 > collision sanity checks in recent Portage versions prevented it from
4 > reaching pkg_pretend() at all. Furthermore, with the "mount-sandbox"
5
6 Did you mean: pkg_preinst?
7
8 > feature enabled, the mount won't be propagated past pkg_preinst() and
9 > installed files would end up under the (shadowed) mount point.
10 >
11 > Therefore don't even attempt to mount /boot ourselves, but error out
12 > if it isn't mounted read/write and ask the user to mount /boot.
13 >
14 > Also clean up and simplify. (For example, awk is a grown-up program
15 > which doesn't need any help from egrep or sed. :-)
16 >
17 > Closes: https://bugs.gentoo.org/532264
18 > Signed-off-by: Ulrich Müller <ulm@g.o>
19 > ---
20 > eclass/mount-boot.eclass | 137 ++++++++++++---------------------------
21 > 1 file changed, 43 insertions(+), 94 deletions(-)
22 >
23 > diff --git a/eclass/mount-boot.eclass b/eclass/mount-boot.eclass
24 > index 938df6732f4..1d7eb8bfc29 100644
25 > --- a/eclass/mount-boot.eclass
26 > +++ b/eclass/mount-boot.eclass
27 > @@ -1,156 +1,105 @@
28 > -# Copyright 1999-2015 Gentoo Foundation
29 > +# Copyright 1999-2019 Gentoo Authors
30 > # Distributed under the terms of the GNU General Public License v2
31 >
32 > # @ECLASS: mount-boot.eclass
33 > # @MAINTAINER:
34 > # base-system@g.o
35 > # @BLURB: functions for packages that install files into /boot
36 > # @DESCRIPTION:
37 > # This eclass is really only useful for bootloaders.
38 > #
39 > # If the live system has a separate /boot partition configured, then this
40 > # function tries to ensure that it's mounted in rw mode, exiting with an
41 > -# error if it can't. It does nothing if /boot isn't a separate partition.
42 > +# error if it can't. It does nothing if /boot isn't a separate partition.
43 > +
44 > +case ${EAPI:-0} in
45 > + 4|5|6|7) ;;
46 > + *) die "${ECLASS}: EAPI ${EAPI:-0} not supported" ;;
47 > +esac
48 >
49 > EXPORT_FUNCTIONS pkg_pretend pkg_preinst pkg_postinst pkg_prerm pkg_postrm
50 >
51 > # @FUNCTION: mount-boot_disabled
52 > # @INTERNAL
53 > # @DESCRIPTION:
54 > # Detect whether the current environment/build settings are such that we do not
55 > # want to mess with any mounts.
56 > mount-boot_is_disabled() {
57 > # Since this eclass only deals with /boot, skip things when ROOT is active.
58 > - if [[ "${ROOT:-/}" != "/" ]] ; then
59 > + if [[ ${ROOT:-/} != "/" ]] ; then
60
61 I suppose you can unquote RHS too since it doesn't contain any pattern
62 characters, if you are already touching quoting.
63
64 > return 0
65 > fi
66 >
67 > # If we're only building a package, then there's no need to check things.
68 > - if [[ "${MERGE_TYPE}" == "buildonly" ]] ; then
69 > + if [[ ${MERGE_TYPE} == "buildonly" ]] ; then
70 > return 0
71 > fi
72 >
73 > # The user wants us to leave things be.
74 > - if [[ -n ${DONT_MOUNT_BOOT} ]] ; then
75 > + if [[ -n ${I_KNOW_WHAT_I_AM_DOING} ]] ; then
76 > return 0
77 > fi
78 >
79 > # OK, we want to handle things ourselves.
80 > return 1
81 > }
82 >
83 > # @FUNCTION: mount-boot_check_status
84 > # @INTERNAL
85 > # @DESCRIPTION:
86 > -# Figure out what kind of work we need to do in order to have /boot be sane.
87 > -# Return values are:
88 > -# 0 - Do nothing at all!
89 > -# 1 - It's mounted, but is currently ro, so need to remount rw.
90 > -# 2 - It's not mounted, so need to mount it rw.
91 > +# Check if /boot is sane, i.e., mounted read/write if on a separate
92 > +# partition. Return 0 if conditions are fulfilled, otherwise die.
93
94 I don't think there's a point in explicitly defining the return value
95 if there is no alternative.
96
97 > mount-boot_check_status() {
98 > # Get out fast if possible.
99 > mount-boot_is_disabled && return 0
100 >
101 > # note that /dev/BOOT is in the Gentoo default /etc/fstab file
102 > - local fstabstate=$(awk '!/^#|^[[:blank:]]+#|^\/dev\/BOOT/ {print $2}' /etc/fstab | egrep "^/boot$" )
103 > - local procstate=$(awk '$2 ~ /^\/boot$/ {print $2}' /proc/mounts)
104 > - local proc_ro=$(awk '{ print $2 " ," $4 "," }' /proc/mounts | sed -n '/^\/boot .*,ro,/p')
105 > -
106 > - if [ -n "${fstabstate}" ] && [ -n "${procstate}" ] ; then
107 > - if [ -n "${proc_ro}" ] ; then
108 > - echo
109 > - einfo "Your boot partition, detected as being mounted at /boot, is read-only."
110 > - einfo "It will be remounted in read-write mode temporarily."
111 > - return 1
112 > - else
113 > - echo
114 > - einfo "Your boot partition was detected as being mounted at /boot."
115 > - einfo "Files will be installed there for ${PN} to function correctly."
116 > - return 0
117 > - fi
118 > - elif [ -n "${fstabstate}" ] && [ -z "${procstate}" ] ; then
119 > - echo
120 > - einfo "Your boot partition was not mounted at /boot, so it will be automounted for you."
121 > - einfo "Files will be installed there for ${PN} to function correctly."
122 > - return 2
123 > - else
124 > - echo
125 > + local fstabstate=$(awk '!/^[[:blank:]]*#|^\/dev\/BOOT/ && $2 == "/boot" \
126 > + {print $2}' /etc/fstab)
127
128 The 'print' here is used as a boolean... why not use a boolean output
129 instead?
130
131 > +
132 > + if [[ -z ${fstabstate} ]] ; then
133 > einfo "Assuming you do not have a separate /boot partition."
134 > return 0
135 > fi
136 > -}
137 >
138 > -mount-boot_pkg_pretend() {
139 > - # Get out fast if possible.
140 > - mount-boot_is_disabled && return 0
141 > + local procstate=$(awk '$2 == "/boot" \
142 > + {print gensub(/^(.*,)?(ro|rw)(,.*)?$/, "\\2", 1, $4)}' /proc/mounts)
143
144 Shouldn't this use /proc/self/mounts?
145
146 >
147 > - elog "To avoid automounting and auto(un)installing with /boot,"
148 > - elog "just export the DONT_MOUNT_BOOT variable."
149 > - mount-boot_check_status
150 > + if [[ -z ${procstate} ]] ; then
151 > + eerror "Your boot partition is not mounted at /boot."
152 > + eerror "Please mount it and retry."
153 > + die "/boot not mounted"
154 > + fi
155 > +
156 > + if [[ ${procstate} == "ro" ]] ; then
157 > + eerror "Your boot partition, detected as being mounted at /boot," \
158 > + "is read-only."
159 > + eerror "Please remount it read/write and retry."
160 > + die "/boot mounted read-only"
161 > + fi
162 > +
163 > + einfo "Your boot partition was detected as being mounted at /boot."
164 > + einfo "Files will be installed there for ${PN} to function correctly."
165 > + return 0
166 > }
167 >
168 > -mount-boot_mount_boot_partition() {
169 > +mount-boot_pkg_pretend() {
170 > mount-boot_check_status
171 > - case $? in
172 > - 0) # Nothing to do.
173 > - ;;
174 > - 1) # Remount it rw.
175 > - mount -o remount,rw /boot
176 > - if [ $? -ne 0 ] ; then
177 > - echo
178 > - eerror "Unable to remount in rw mode. Please do it manually!"
179 > - die "Can't remount in rw mode. Please do it manually!"
180 > - fi
181 > - touch /boot/.e.remount
182 > - ;;
183 > - 2) # Mount it rw.
184 > - mount /boot -o rw
185 > - if [ $? -ne 0 ] ; then
186 > - echo
187 > - eerror "Cannot automatically mount your /boot partition."
188 > - eerror "Your boot partition has to be mounted rw before the installation"
189 > - eerror "can continue. ${PN} needs to install important files there."
190 > - die "Please mount your /boot partition manually!"
191 > - fi
192 > - touch /boot/.e.mount
193 > - ;;
194 > - esac
195 > }
196 >
197 > mount-boot_pkg_preinst() {
198 > - # Handle older EAPIs.
199 > - case ${EAPI:-0} in
200 > - [0-3]) mount-boot_pkg_pretend ;;
201 > - esac
202 > -
203 > - mount-boot_mount_boot_partition
204 > + mount-boot_check_status
205 > }
206 >
207 > mount-boot_pkg_prerm() {
208 > - touch "${ROOT}"/boot/.keep 2>/dev/null
209 > - mount-boot_mount_boot_partition
210 > - touch "${ROOT}"/boot/.keep 2>/dev/null
211 > -}
212 > -
213 > -mount-boot_umount_boot_partition() {
214 > - # Get out fast if possible.
215 > - mount-boot_is_disabled && return 0
216 > -
217 > - if [ -e /boot/.e.remount ] ; then
218 > - einfo "Automatically remounting /boot as ro as it was previously."
219 > - rm -f /boot/.e.remount
220 > - mount -o remount,ro /boot
221 > - elif [ -e /boot/.e.mount ] ; then
222 > - einfo "Automatically unmounting /boot as it was previously."
223 > - rm -f /boot/.e.mount
224 > - umount /boot
225 > + mount-boot_check_status
226 > + if ! ( shopt -s failglob; : "${ROOT}"/boot/.keep* ) 2>/dev/null ; then
227
228 EROOT?
229
230 > + # Create a .keep file, in case it is shadowed at the mount point
231 > + touch "${ROOT}"/boot/.keep 2>/dev/null
232 > fi
233 > }
234 >
235 > -mount-boot_pkg_postinst() {
236 > - mount-boot_umount_boot_partition
237 > -}
238 > +# No-op phases for backwards compatibility
239 > +mount-boot_pkg_postinst() { :; }
240 >
241 > -mount-boot_pkg_postrm() {
242 > - mount-boot_umount_boot_partition
243 > -}
244 > +mount-boot_pkg_postrm() { :; }
245
246 --
247 Best regards,
248 Michał Górny

Attachments

File name MIME type
signature.asc application/pgp-signature

Replies