Add errors=panic to rootfs

* Add errors=panic to rootfs in order to panic and
not to go to 'ro' when there are any errors on the disk
* Set parameter kernel.panic in sysctl to 60 (By default,
the kernel will not reboot after a panic, but this option
will cause a kernel reboot after 60 seconds.)

Doc-Impact

Change-Id: Ib24f13d3cbbf792e7ee81a9b4054e084f4ec1b5e
Closes-Bug: 1371689
This commit is contained in:
Oleksiy Molchanov 2015-07-14 18:48:30 +03:00
parent 21f4b55f16
commit fca0ea6535
4 changed files with 110 additions and 2 deletions

View File

@ -50,10 +50,12 @@ cloud-init-per instance conntrack_ipv4 /bin/sh -c 'echo nf_conntrack_ipv4 | tee
cloud-init-per instance conntrack_ipv6 /bin/sh -c 'echo nf_conntrack_ipv6 | tee -a /etc/rc.modules'
cloud-init-per instance chmod_rc_modules chmod +x /etc/rc.modules
cloud-init-per instance conntrack_max /bin/sh -c 'echo "net.nf_conntrack_max=1048576" | tee -a /etc/sysctl.conf'
cloud-init-per instance kernel_panic /bin/sh -c 'echo "kernel.panic=60" | tee -a /etc/sysctl.conf'
cloud-init-per instance conntrack_ipv4_load modprobe nf_conntrack_ipv4
cloud-init-per instance conntrack_ipv6_load modprobe nf_conntrack_ipv6
cloud-init-per instance conntrack_max_set sysctl -w "net.nf_conntrack_max=1048576"
cloud-init-per instance kernel_panic_set sysctl -w "kernel.panic=60"
cloud-init-per instance mkdir_coredump mkdir -p /var/log/coredump
cloud-init-per instance set_coredump /bin/sh -c 'echo -e "kernel.core_pattern=/var/log/coredump/core.%e.%p.%h.%t" | tee -a /etc/sysctl.conf'

View File

@ -56,10 +56,12 @@ fi
cloud-init-per instance conntrack_ipv4 /bin/sh -c 'echo nf_conntrack_ipv4 | tee -a /etc/modules'
cloud-init-per instance conntrack_ipv6 /bin/sh -c 'echo nf_conntrack_ipv6 | tee -a /etc/modules'
cloud-init-per instance conntrack_max /bin/sh -c 'echo "net.nf_conntrack_max=1048576" | tee -a /etc/sysctl.conf'
cloud-init-per instance kernel_panic /bin/sh -c 'echo "kernel.panic=60" | tee -a /etc/sysctl.conf'
cloud-init-per instance conntrack_ipv4_load modprobe nf_conntrack_ipv4
cloud-init-per instance conntrack_ipv6_load modprobe nf_conntrack_ipv6
cloud-init-per instance conntrack_max_set sysctl -w "net.nf_conntrack_max=1048576"
cloud-init-per instance kernel_panic_set sysctl -w "kernel.panic=60"
cloud-init-per instance dhclient /bin/sh -c 'echo "supersede routers 0;" | tee /etc/dhcp/dhclient.conf'

View File

@ -454,8 +454,12 @@ class Manager(object):
# at fstab line. Currently we set it into 0 which means
# a corresponding file system will never be checked. We assume
# puppet or other configuration tool will care of it.
f.write('UUID=%s %s %s defaults 0 0\n' %
(mount2uuid[fs.mount], fs.mount, fs.type))
if fs.mount == '/':
f.write('UUID=%s %s %s defaults,errors=panic 0 0\n' %
(mount2uuid[fs.mount], fs.mount, fs.type))
else:
f.write('UUID=%s %s %s defaults 0 0\n' %
(mount2uuid[fs.mount], fs.mount, fs.type))
self.umount_target(chroot)

View File

@ -45,6 +45,106 @@ class TestManager(test_base.BaseTestCase):
mock_lbd.return_value = test_nailgun.LIST_BLOCK_DEVICES_SAMPLE
self.mgr = manager.Manager(test_nailgun.PROVISION_SAMPLE_DATA)
@mock.patch('fuel_agent.manager.open',
create=True, new_callable=mock.mock_open)
@mock.patch('fuel_agent.manager.gu', create=True)
@mock.patch('fuel_agent.manager.utils', create=True)
@mock.patch.object(manager.Manager, 'mount_target')
@mock.patch.object(manager.Manager, 'umount_target')
def test_do_bootloader_grub1(self, mock_umount, mock_mount, mock_utils,
mock_gu, mock_open):
# actually covers only grub1 related logic
mock_utils.execute.return_value = ('fake_UUID\n', None)
mock_gu.guess_initrd.return_value = 'guessed_initrd'
mock_gu.guess_kernel.return_value = 'guessed_kernel'
mock_gu.guess_grub_version.return_value = 1
self.mgr.do_bootloader()
mock_gu.guess_grub_version.assert_called_once_with(
chroot='/tmp/target')
mock_gu.grub1_cfg.assert_called_once_with(
kernel_params=' console=ttyS0,9600 console=tty0 rootdelay=90 '
'nomodeset root=UUID=fake_UUID ',
initrd='guessed_initrd',
chroot='/tmp/target',
kernel='guessed_kernel')
mock_gu.grub1_install.assert_called_once_with(
['/dev/sda', '/dev/sdb', '/dev/sdc'],
'/dev/sda3', chroot='/tmp/target')
self.assertFalse(mock_gu.grub2_cfg.called)
self.assertFalse(mock_gu.grub2_install.called)
@mock.patch('fuel_agent.manager.open',
create=True, new_callable=mock.mock_open)
@mock.patch('fuel_agent.manager.gu', create=True)
@mock.patch('fuel_agent.manager.utils', create=True)
@mock.patch.object(manager.Manager, 'mount_target')
@mock.patch.object(manager.Manager, 'umount_target')
def test_do_bootloader_grub2(self, mock_umount, mock_mount, mock_utils,
mock_gu, mock_open):
# actually covers only grub2 related logic
mock_utils.execute.return_value = ('fake_UUID\n', None)
mock_gu.guess_grub_version.return_value = 2
self.mgr.do_bootloader()
mock_gu.guess_grub_version.assert_called_once_with(
chroot='/tmp/target')
mock_gu.grub2_cfg.assert_called_once_with(
kernel_params=' console=ttyS0,9600 console=tty0 rootdelay=90 '
'nomodeset root=UUID=fake_UUID ',
chroot='/tmp/target')
mock_gu.grub2_install.assert_called_once_with(
['/dev/sda', '/dev/sdb', '/dev/sdc'],
chroot='/tmp/target')
self.assertFalse(mock_gu.grub1_cfg.called)
self.assertFalse(mock_gu.grub1_install.called)
@mock.patch('fuel_agent.manager.gu', create=True)
@mock.patch('fuel_agent.manager.utils', create=True)
@mock.patch.object(manager.Manager, 'mount_target')
@mock.patch.object(manager.Manager, 'umount_target')
def test_do_bootloader_writes(self, mock_umount, mock_mount, mock_utils,
mock_gu):
# actually covers only write() calls
mock_utils.execute.return_value = ('fake_UUID\n', None)
with mock.patch('fuel_agent.manager.open', create=True) as mock_open:
file_handle_mock = mock_open.return_value.__enter__.return_value
self.mgr.do_bootloader()
expected_open_calls = [
mock.call('/tmp/target/etc/udev/rules.d/70-persistent-net.'
'rules', 'w'),
mock.call('/tmp/target/etc/udev/rules.d/75-persistent-net-'
'generator.rules', 'w'),
mock.call('/tmp/target/etc/nailgun-agent/nodiscover', 'w'),
mock.call('/tmp/target/etc/fstab', 'wb')]
self.assertEqual(expected_open_calls, mock_open.call_args_list)
expected_write_calls = [
mock.call('# Generated by fuel-agent during provisioning: '
'BEGIN\n'),
mock.call('SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", '
'ATTR{address}=="08:00:27:79:da:80", ATTR{type}=="1"'
', KERNEL=="eth*", NAME="eth0"\n'),
mock.call('SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", '
'ATTR{address}=="08:00:27:46:43:60", ATTR{type}=="1"'
', KERNEL=="eth*", NAME="eth1"\n'),
mock.call('SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", '
'ATTR{address}=="08:00:27:b1:d7:15", ATTR{type}=="1"'
', KERNEL=="eth*", NAME="eth2"\n'),
mock.call('# Generated by fuel-agent during provisioning: '
'END\n'),
mock.call('# Generated by fuel-agent during provisioning:\n# '
'DO NOT DELETE. It is needed to disable '
'net-generator\n'),
mock.call('UUID=fake_UUID /boot ext2 defaults 0 0\n'),
mock.call('UUID=fake_UUID /tmp ext2 defaults 0 0\n'),
mock.call('UUID=fake_UUID / ext4 defaults,errors=panic 0 0\n'),
mock.call('UUID=fake_UUID swap swap defaults 0 0\n'),
mock.call('UUID=fake_UUID /var/lib/glance xfs defaults 0 0\n')]
self.assertEqual(expected_write_calls,
file_handle_mock.write.call_args_list)
mock_umount.assert_called_once_with('/tmp/target')
mock_mount.assert_called_once_with('/tmp/target')
mock_utils.makedirs_if_not_exists.assert_called_once_with(
'/tmp/target/etc/nailgun-agent')
@mock.patch('six.moves.builtins.open')
@mock.patch.object(os, 'symlink')
@mock.patch.object(os, 'remove')