[node-patches] Change in ovirt-node[master]: Add initramfs re-generation during installation
fabiand at redhat.com
fabiand at redhat.com
Fri Jun 26 10:48:28 UTC 2015
Fabian Deutsch has uploaded a new change for review.
Change subject: Add initramfs re-generation during installation
......................................................................
Add initramfs re-generation during installation
Previously Node's initramfs was created at build time and never got
changed. This lead to problems in situations where some configuration
(i.e. a multipath configuration) was required in initramfs.
With this patch, the initramfs will be generated at installation time.
Change-Id: I209a82ff6bf10edf0857e362584bc6370081c320
Signed-off-by: Fabian Deutsch <fabiand at fedoraproject.org>
---
M ovirt-node.spec.in
M scripts/Makefile.am
A scripts/ovirt-node-update-initramfs
M src/ovirt/node/utils/system.py
M src/ovirtnode/install.py
5 files changed, 122 insertions(+), 40 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/ovirt-node refs/changes/12/42912/1
diff --git a/ovirt-node.spec.in b/ovirt-node.spec.in
index 5867ec7..5b39f18 100644
--- a/ovirt-node.spec.in
+++ b/ovirt-node.spec.in
@@ -1043,6 +1043,7 @@
%{_sbindir}/persist
%{_sbindir}/unpersist
%{_sbindir}/ovirt-node-upgrade
+%{_sbindir}/ovirt-node-update-initramfs
%{python_sitelib}/ovirt_config_setup
%exclude %{python_sitelib}/ovirt_config_setup/cim.py*
%exclude %{python_sitelib}/ovirt_config_setup/snmp.py*
diff --git a/scripts/Makefile.am b/scripts/Makefile.am
index 9facb20..7e3f257 100644
--- a/scripts/Makefile.am
+++ b/scripts/Makefile.am
@@ -21,7 +21,8 @@
dist_sbin_SCRIPTS = \
persist \
unpersist \
- ovirt-node-upgrade.py
+ ovirt-node-upgrade.py \
+ ovirt-node-update-initramfs
dist_bin_SCRIPTS = \
ovirt-node-setup \
diff --git a/scripts/ovirt-node-update-initramfs b/scripts/ovirt-node-update-initramfs
new file mode 100755
index 0000000..ec724e7
--- /dev/null
+++ b/scripts/ovirt-node-update-initramfs
@@ -0,0 +1,31 @@
+#!/bin/env python
+"""
+The bash logic is:
+mount -oremount,rw /run/initramfs/live
+mount -obind /run/initramfs/live /boot
+
+dracut -f
+
+pushd /boot
+ mv -v initrd0.img initrd0.img.orig
+ mv -v initramfs-* initrd0.img
+popd
+
+umount /boot
+mount -oremount,ro /run/initramfs/live
+"""
+
+import logging
+from ovirt.node.utils import system
+
+
+log = logging.getLogger()
+
+
+if __name__ == "__main__":
+ stdout = logging.StreamHandler()
+ log.addHandler(stdout)
+ initramfs = system.Initramfs()
+ initramfs.rebuild()
+
+# vim: set sts=4 et:
diff --git a/src/ovirt/node/utils/system.py b/src/ovirt/node/utils/system.py
index 3c99967..74a9860 100644
--- a/src/ovirt/node/utils/system.py
+++ b/src/ovirt/node/utils/system.py
@@ -30,6 +30,7 @@
import subprocess
import sys
import time
+from contextlib import contextmanager
import rpm
import system_config_keyboard.keyboard
@@ -37,6 +38,7 @@
from ovirt.node import base, utils
from ovirt.node.utils import process, parse_varfile
from ovirt.node.utils.fs import File
+from ovirt.node.utils.process import check_output, check_call
LOGGER = logging.getLogger(__name__)
@@ -351,6 +353,32 @@
else:
copy_dir_if_not_exist("%s/%s" % (orig, f), "%s/%s" % (target,
f))
+
+
+ at contextmanager
+def mounted_boot():
+ LOGGER.info("Mounting /liveos and /boot")
+ import ovirtnode.ovirtfunctions as ofunc
+
+ ofunc.mount_liveos()
+ if not os.path.ismount("/liveos"):
+ raise RuntimeError("Failed to mount /liveos")
+
+ liveos = Mount("/liveos")
+ boot = Mount(device="/liveos", path="/boot")
+
+ liveos.remount(rw=True)
+ boot.mount("bind")
+
+ if not os.path.ismount("/boot"):
+ raise RuntimeError("Failed to mount /boot")
+
+ # Now run something in this context
+ yield
+
+ boot.umount()
+ liveos.umount()
+ LOGGER.info("Successfully unmounted /liveos and /boot")
class NVR(object):
@@ -915,17 +943,18 @@
LOGGER.exception("Can't remount %s on %s!" % (device,
self.path))
- def mount(self):
+ def mount(self, options=""):
if not self.device:
LOGGER.exception("Can't mount without a device specified")
raise RuntimeError("No device was specified when Mount() "
"was initialized")
fstype = self.fstype if self.fstype else "auto"
+ options = ["-o" + options] if options else []
try:
- utils.process.check_call(["mount", "-t", fstype,
- self.device, self.path])
+ utils.process.check_call(["mount", "-t", fstype] + options +
+ [self.device, self.path])
except:
LOGGER.exception("Can't mount %s on %s" % (self.device,
self.path))
@@ -1196,3 +1225,57 @@
vgs = [x.strip() for x in out.split("\n")]
return vgs
+
+
+class Initramfs(base.Base):
+ """This class shallw rap the logic needed to rebuild the initramfs
+
+ The main obstacle is mounting the correct paths.
+ Furthermore we are taking care that now orphans are left over.
+ """
+ def _regenerate_initramfs(self):
+ pri_initrd = "/boot/initrd0.img"
+ new_initrd = pri_initrd + ".new"
+ backup_initrd = pri_initrd + ".old"
+
+ LOGGER.info("Regenerating initramfs "
+ "'%s' (this can take a while)" % pri_initrd)
+
+ rd_stdout = ""
+ try:
+ rd_stdout = check_output(["dracut", new_initrd],
+ stderr=process.PIPE)
+ except:
+ LOGGER.warn("dracut failed to regenerate the initramfs")
+ LOGGER.warn("dracut output: %s" % rd_stdout)
+ raise
+
+ try:
+ check_call(["mv", pri_initrd, backup_initrd])
+ check_call(["mv", new_initrd, pri_initrd])
+ except:
+ LOGGER.warn("Failed to put new initrd in place")
+ if not os.path.exists(pri_initrd):
+ check_call(["mv", backup_initrd, pri_initrd])
+ raise
+ finally:
+ for orph in [backup_initrd, new_initrd]:
+ try:
+ os.unlink(orph)
+ LOGGER.debug("Removed orphan: %s" % orph)
+ except:
+ pass
+
+ def rebuild(self):
+ LOGGER.info("Preparing to regenerate the initramfs")
+ LOGGER.info("The regenreation is performed in-place, "
+ "the existing initrd will be overwritten")
+ try:
+ with mounted_boot():
+ self._regenerate_initramfs()
+ LOGGER.info("Initramfs regenration completed successfully")
+ except:
+ LOGGER.info("Initramfs regenration failed")
+ raise
+
+# vim: set sts=4 et:
diff --git a/src/ovirtnode/install.py b/src/ovirtnode/install.py
index e125daa..c2b808f 100755
--- a/src/ovirtnode/install.py
+++ b/src/ovirtnode/install.py
@@ -594,42 +594,8 @@
"rd_NO_MULTIPATH",
"")
- is_mpath_root = self.disk and self.disk.startswith("/dev/mapper")
- has_mpath_wwid = "mpath.wwid=" in self.bootparams
- if is_mpath_root and not has_mpath_wwid:
- """We need to specify the wwid of the root device if it
- is using multiple paths to prevent races within dracut.
- Basically there are two options:
- 1. bake wwid of root device into initrd
- 2. pass wwid of root device on kernel cmdline
- I choose 2 because it seems to be less invasive.
- https://bugzilla.redhat.com/show_bug.cgi?id=1152948
- """
- lsblkcmd = "lsblk -inls %s | awk 'FNR==2 {print $1}'" % self.disk
- lsblkproc = _functions.subprocess_closefds(lsblkcmd, shell=True,
- stdout=subprocess.PIPE,
- stderr=subprocess.STDOUT)
- lsblkout, lsblkerr = lsblkproc.communicate()
- logger.debug("lsblk returned: %s -- %s" % (lsblkout, lsblkerr))
- if not lsblkout.strip():
- raise RuntimeError("Failed to determin parent of partition: %s" % self.disk)
- part_parent = "/dev/mapper/" + lsblkout.strip()
- logger.debug("lsblk found parent for partition %s: %s" % (self.disk, part_parent))
-
- wwidcmd = "multipath -ll %s | egrep -o '^.*dm-[0-9]' | cut -d' ' -f1" % part_parent
- logger.debug("Checking device for multipath: %s" % wwidcmd)
- wwidproc = _functions.subprocess_closefds(wwidcmd, shell=True,
- stdout=subprocess.PIPE,
- stderr=subprocess.STDOUT)
- wwidout, wwiderr = wwidproc.communicate()
- logger.debug("multipath returned: %s -- %s" % (wwidout, wwiderr))
- wwid = wwidout.strip()
- if wwid:
- logger.debug("Using multipath wwid: %s" % wwid)
- self.bootparams += " mpath.wwid=%s" % wwid
- logger.debug("Cmdline with mpath: %s" % self.bootparams)
- else:
- logger.debug("Got NO multipath wwid, not using any")
+ # Update initramfs to pickup multipath wwids
+ _system.Initramfs().rebuild()
if " " in self.disk:
# workaround for grub setup failing with spaces in dev.name:
--
To view, visit https://gerrit.ovirt.org/42912
To unsubscribe, visit https://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I209a82ff6bf10edf0857e362584bc6370081c320
Gerrit-PatchSet: 1
Gerrit-Project: ovirt-node
Gerrit-Branch: master
Gerrit-Owner: Fabian Deutsch <fabiand at redhat.com>
More information about the node-patches
mailing list