Parcourir la source

netconsole remote kernel logger

To configure:

 * set system.netconsole.enabled to true
 * create system.netconsole.target dict
 * set a record with IP address and MAC and interface as subdict

It works with both static and DHCP interfaces, and applies online.
You could use bash-scripting in netconsole.conf.
You could override the MAC.

See tests/pillar/system.sls for further information.

Change-Id: I1cbde47575eb5d32a34cd6d79a063f42dbea7643
tags/2017.4.1
Vladimir Eremin il y a 7 ans
Parent
révision
ccf28849b0
Aucun compte lié à l'adresse e-mail de l'auteur
7 fichiers modifiés avec 254 ajouts et 0 suppressions
  1. +26
    -0
      README.rst
  2. +136
    -0
      linux/files/netconsole
  3. +22
    -0
      linux/files/netconsole.conf
  4. +3
    -0
      linux/system/init.sls
  5. +43
    -0
      linux/system/netconsole.sls
  6. +14
    -0
      tests/integration/system/netconsole_spec.rb
  7. +10
    -0
      tests/pillar/system.sls

+ 26
- 0
README.rst Voir le fichier

@@ -1184,6 +1184,32 @@ config files for external use, eg. docker, etc.
username: test
password: test

Netconsole Remote Kernel Logging
--------------------------------

Netconsole logger could be configured for configfs-enabled kernels
(`CONFIG_NETCONSOLE_DYNAMIC` should be enabled). Configuration applies both in
runtime (if network is already configured), and on-boot after interface
initialization. Notes:

* receiver could be located only in same L3 domain
(or you need to configure gateway MAC manually)
* receiver's MAC is detected only on configuration time
* using broadcast MAC is not recommended

.. code-block:: yaml

parameters:
linux:
system:
netconsole:
enabled: true
port: 514 (optional)
loglevel: debug (optional)
target:
192.168.0.1:
interface: bond0
mac: "ff:ff:ff:ff:ff:ff" (optional)

Usage
=====

+ 136
- 0
linux/files/netconsole Voir le fichier

@@ -0,0 +1,136 @@
#!/bin/sh
SYSFS_NETCONSOLE="/sys/kernel/config/netconsole"
NETCONSOLE_CONF="/etc/default/netconsole.conf"
NETCONSOLE_PORT="514"

netconsole_remove() {
for sysfsnc in "${SYSFS_NETCONSOLE}/${interface:-}-"*
do
if [ -e "${sysfsnc}" ]
then
logger -t netconsole "remove ${sysfsnc}"
rmdir "${sysfsnc}"
fi
done
}

netconsole_remote_mac()
{
neigh()
{
ip -4 -o neigh show to "${remote_ip}" dev "${interface}" | cut -d\ -f3
}
remote_mac="$(neigh)"
if [ -n "${remote_mac:-}" ] && [ "${remote_mac:-}" != "INCOMPLETE" ]
then
if [ "${remote_mac:-}" != "FAILED" ]
then
echo "${remote_mac:-}"
return 0
fi
else
if ping -n -q -c 1 -w 1 -I "${interface}" "${remote_ip}" >/dev/null && remote_mac="$(neigh)" && [ -n "${remote_mac:-}" ]
then
echo "${remote_mac:-}"
return 0
fi
fi
return 1
}

netconsole_add() {
netconsole() {
iface="${1:-}"
remote_ip="${2:-}"
remote_mac="${3:-}"

if [ "${iface:-}" = "${interface:-}" ] && [ -n "${remote_ip:-}" ]
then
logger -t netconsole "from ${new_ip_address:-}@${interface:-}"
else
return 1
fi
if [ -n "${remote_mac}" ] || remote_mac="$(netconsole_remote_mac)"
then
logger -t netconsole "to ${remote_ip} ${remote_mac}"
else
return 1
fi

sysfsnc="${SYSFS_NETCONSOLE}/${interface}-${remote_ip}"

if [ -e "${sysfsnc}" ] && [ -z "${old_ip_address:-}" ]
then
old_ip_address="$(cat "${sysfsnc}/local_ip")"
fi

if [ "${old_ip_address:-}" != "${new_ip_address:-}" ] || ! [ -e "${sysfsnc}" ]
then
logger -t netconsole "setup netconsole"
else
return 1
fi

mkdir -p "${sysfsnc}"
if [ "$(cat "${sysfsnc}/enabled")" != "0" ]
then
echo "0" > "${sysfsnc}/enabled"
fi

if [ -n "${new_ip_address:-}" ]
then
echo "${new_ip_address}" > "${sysfsnc}/local_ip"
fi
echo "${interface}" > "${sysfsnc}/dev_name"
echo "${remote_mac}" > "${sysfsnc}/remote_mac"
echo "${remote_ip}" > "${sysfsnc}/remote_ip"
echo "${PORT:-${NETCONSOLE_PORT}}" > "${sysfsnc}/remote_port"
echo "1" > "${sysfsnc}/enabled"
return 0
}

if [ -f "${NETCONSOLE_CONF}" ]
then
modprobe netconsole
mountpoint -q /sys/kernel/config || mount none -t configfs /sys/kernel/config

if [ -e "${SYSFS_NETCONSOLE}" ]
then
(
set -x
set +e
. "${NETCONSOLE_CONF}"
) ||:
fi
fi
}

netconsole_setup() {
case ${reason:-} in
BOUND|RENEW|REBIND|REBOOT)
netconsole_add
;;
EXPIRE|FAIL|RELEASE|STOP)
netconsole_remove
;;
PREINIT) : ;;
*)
if [ "${ADDRFAM:-}" = "inet" ] && [ "${METHOD:-}" = "static" ]
then
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
interface="${IFACE:-}"
new_ip_address="${IF_ADDRESS:-}"
case ${MODE:-} in
start)
netconsole_add
;;
stop)
netconsole_remove
;;
*) : ;;
esac
fi
esac
}

netconsole_setup

+ 22
- 0
linux/files/netconsole.conf Voir le fichier

@@ -0,0 +1,22 @@
{%- from "linux/map.jinja" import system with context %}
# default port is 514
#PORT=6666
{%- if system.netconsole is mapping and system.netconsole.port is defined %}
PORT="{{ system.netconsole.port }}"
{%- endif %}

# unicast, could be multiline
#netconsole ens3 192.168.1.32 fa:16:3e:8d:f6:d0
{%- if system.netconsole is mapping and system.netconsole.target is mapping %}
{%- for target, data in system.netconsole.target.iteritems() %}
{%- if data is mapping %}
netconsole "{{ data.get('interface', '${interface}') }}" "{{ target }}" "{{ data.get('mac', '') }}"
{%- endif %}
{%- endfor %}
{%- endif %}

# set up dmesg log level
# dmesg -n info
{%- if system.netconsole is mapping and system.netconsole.loglevel is defined %}
dmesg -n "{{ system.netconsole.loglevel }}"
{%- endif %}

+ 3
- 0
linux/system/init.sls Voir le fichier

@@ -80,3 +80,6 @@ include:
{%- if system.sudo is defined %}
- linux.system.sudo
{%- endif %}
{%- if system.netconsole is defined %}
- linux.system.netconsole
{%- endif %}

+ 43
- 0
linux/system/netconsole.sls Voir le fichier

@@ -0,0 +1,43 @@
{% from "linux/map.jinja" import system with context %}
{% if system.enabled and system.netconsole is mapping and system.netconsole.enabled %}

/etc/dhcp/dhclient-exit-hooks.d/netconsole:
file.managed:
- source: salt://linux/files/netconsole
- makedirs: True

/etc/network/if-up.d/netconsole:
file.managed:
- source: salt://linux/files/netconsole
- mode: 755

/etc/network/if-down.d/netconsole:
file.managed:
- source: salt://linux/files/netconsole
- mode: 755

/etc/default/netconsole.conf:
file.managed:
- source: salt://linux/files/netconsole.conf
- template: jinja

{% if system.netconsole is mapping and system.netconsole.target is mapping %}
{% for target, data in system.netconsole.target.iteritems() %}
{% if data is mapping and data.interface is defined %}
/etc/network/if-up.d/netconsole {{ target }} {{ data.interface }}:
cmd.run:
- name: /etc/network/if-up.d/netconsole
- env:
- IFACE: {{ data.interface }}
- METHOD: static
- ADDRFAM: inet
- MODE: start
- onchanges:
- file: /etc/default/netconsole.conf
- require:
- file: /etc/network/if-up.d/netconsole
{% endif %}
{% endfor %}
{% endif %}

{% endif %}

+ 14
- 0
tests/integration/system/netconsole_spec.rb Voir le fichier

@@ -0,0 +1,14 @@

## NETCONSOLE
#
describe file('/etc/default/netconsole.conf') do
it('should exist')
its('content') { should match /^PORT="514"/}
its('content') { should match /^netconsole "bond0" "192.168.0.1" "ff:ff:ff:ff:ff:ff"/}
its('content') { should match /^dmesg -n "debug"/}
end

describe file('/etc/dhcp/dhclient-exit-hooks.d/netconsole') do
it('should exist')
its('content') { should match /netconsole_setup/}
end

+ 10
- 0
tests/pillar/system.sls Voir le fichier

@@ -265,3 +265,13 @@ linux:
- host1
- host2
- .local

# pillars for netconsole setup
netconsole:
enabled: true
port: 514
loglevel: debug
target:
192.168.0.1:
mac: "ff:ff:ff:ff:ff:ff"
interface: bond0

Chargement…
Annuler
Enregistrer