...

Text file src/github.com/opencontainers/runc/script/check-config.sh

Documentation: github.com/opencontainers/runc/script

     1#!/usr/bin/env bash
     2set -e
     3
     4# bits of this were adapted from check_config.sh in docker
     5# see also https://github.com/docker/docker/blob/master/contrib/check-config.sh
     6
     7possibleConfigs=(
     8	'/proc/config.gz'
     9	"/boot/config-$(uname -r)"
    10	"/usr/src/linux-$(uname -r)/.config"
    11	'/usr/src/linux/.config'
    12)
    13possibleConfigFiles=(
    14	'config.gz'
    15	"config-$(uname -r)"
    16	'.config'
    17)
    18
    19if ! command -v zgrep &>/dev/null; then
    20	zgrep() {
    21		zcat "$2" | grep "$1"
    22	}
    23fi
    24
    25kernelVersion="$(uname -r)"
    26kernelMajor="${kernelVersion%%.*}"
    27kernelMinor="${kernelVersion#"$kernelMajor".}"
    28kernelMinor="${kernelMinor%%.*}"
    29
    30kernel_lt() {
    31	[ "$kernelMajor" -lt "$1" ] && return
    32	[ "$kernelMajor" -eq "$1" ] && [ "$kernelMinor" -le "$2" ]
    33}
    34
    35is_set() {
    36	zgrep "CONFIG_$1=[y|m]" "$CONFIG" >/dev/null
    37}
    38is_set_in_kernel() {
    39	zgrep "CONFIG_$1=y" "$CONFIG" >/dev/null
    40}
    41is_set_as_module() {
    42	zgrep "CONFIG_$1=m" "$CONFIG" >/dev/null
    43}
    44
    45color() {
    46	local codes=()
    47	if [ "$1" = 'bold' ]; then
    48		codes=("${codes[@]}" '1')
    49		shift
    50	fi
    51	if [ "$#" -gt 0 ]; then
    52		local code
    53		case "$1" in
    54		# see https://en.wikipedia.org/wiki/ANSI_escape_code#Colors
    55		black) code=30 ;;
    56		red) code=31 ;;
    57		green) code=32 ;;
    58		yellow) code=33 ;;
    59		blue) code=34 ;;
    60		magenta) code=35 ;;
    61		cyan) code=36 ;;
    62		white) code=37 ;;
    63		esac
    64		if [ "$code" ]; then
    65			codes=("${codes[@]}" "$code")
    66		fi
    67	fi
    68	local IFS=';'
    69	echo -en '\033['"${codes[*]}"'m'
    70}
    71wrap_color() {
    72	text="$1"
    73	shift
    74	color "$@"
    75	echo -n "$text"
    76	color reset
    77	echo
    78}
    79
    80wrap_good() {
    81	local name="$1"
    82	shift
    83	local val="$1"
    84	shift
    85	echo "$(wrap_color "$name" white): $(wrap_color "$val" green)" "$@"
    86}
    87
    88wrap_bad() {
    89	local name="$1"
    90	shift
    91	local val="$1"
    92	shift
    93	echo "$(wrap_color "$name" bold): $(wrap_color "$val" bold red)" "$@"
    94}
    95wrap_warning() {
    96	wrap_color >&2 "$*" red
    97}
    98
    99check_flag() {
   100	if is_set_in_kernel "$1"; then
   101		wrap_good "CONFIG_$1" 'enabled'
   102	elif is_set_as_module "$1"; then
   103		wrap_good "CONFIG_$1" 'enabled (as module)'
   104	else
   105		wrap_bad "CONFIG_$1" 'missing'
   106	fi
   107}
   108
   109check_flags() {
   110	for flag in "$@"; do
   111		echo "- $(check_flag "$flag")"
   112	done
   113}
   114
   115check_distro_userns() {
   116	[ -r /etc/os-release ] || return 0
   117	# shellcheck source=/dev/null
   118	. /etc/os-release 2>/dev/null || return 0
   119	if [[ "${ID}" =~ ^(centos|rhel)$ && "${VERSION_ID}" =~ ^7 ]]; then
   120		# this is a CentOS7 or RHEL7 system
   121		grep -q "user_namespace.enable=1" /proc/cmdline || {
   122			# no user namespace support enabled
   123			wrap_bad "  (RHEL7/CentOS7" "User namespaces disabled; add 'user_namespace.enable=1' to boot command line)"
   124		}
   125	fi
   126}
   127
   128is_config() {
   129	local config="$1"
   130
   131	# Todo: more check
   132	[[ -f "$config" ]] && return 0
   133	return 1
   134}
   135
   136search_config() {
   137	local target_dir="$1"
   138	[[ "$target_dir" ]] || target_dir=("${possibleConfigs[@]}")
   139
   140	local tryConfig
   141	for tryConfig in "${target_dir[@]}"; do
   142		is_config "$tryConfig" && {
   143			CONFIG="$tryConfig"
   144			return
   145		}
   146		[[ -d "$tryConfig" ]] && {
   147			for tryFile in "${possibleConfigFiles[@]}"; do
   148				is_config "$tryConfig/$tryFile" && {
   149					CONFIG="$tryConfig/$tryFile"
   150					return
   151				}
   152			done
   153		}
   154	done
   155
   156	wrap_warning "error: cannot find kernel config"
   157	wrap_warning "  try running this script again, specifying the kernel config:"
   158	wrap_warning "    CONFIG=/path/to/kernel/.config $0 or $0 /path/to/kernel/.config"
   159	exit 1
   160}
   161
   162CONFIG="$1"
   163
   164is_config "$CONFIG" || {
   165	if [[ ! "$CONFIG" ]]; then
   166		wrap_color "info: no config specified, searching for kernel config ..." white
   167		search_config
   168	elif [[ -d "$CONFIG" ]]; then
   169		wrap_color "info: input is a directory, searching for kernel config in this directory..." white
   170		search_config "$CONFIG"
   171	else
   172		wrap_warning "warning: $CONFIG seems not a kernel config, searching other paths for kernel config ..."
   173		search_config
   174	fi
   175}
   176
   177wrap_color "info: reading kernel config from $CONFIG ..." white
   178echo
   179
   180echo 'Generally Necessary:'
   181
   182echo -n '- '
   183if [ "$(stat -f -c %t /sys/fs/cgroup 2>/dev/null)" = "63677270" ]; then
   184	wrap_good 'cgroup hierarchy' 'cgroupv2'
   185else
   186	cgroupSubsystemDir="$(awk '/[, ](cpu|cpuacct|cpuset|devices|freezer|memory)[, ]/ && $3 == "cgroup" { print $2 }' /proc/mounts | head -n1)"
   187	cgroupDir="$(dirname "$cgroupSubsystemDir")"
   188	if [ -d "$cgroupDir/cpu" ] || [ -d "$cgroupDir/cpuacct" ] || [ -d "$cgroupDir/cpuset" ] || [ -d "$cgroupDir/devices" ] || [ -d "$cgroupDir/freezer" ] || [ -d "$cgroupDir/memory" ]; then
   189		wrap_good 'cgroup hierarchy' 'properly mounted' "[$cgroupDir]"
   190	else
   191		if [ "$cgroupSubsystemDir" ]; then
   192			wrap_bad 'cgroup hierarchy' 'single mountpoint!' "[$cgroupSubsystemDir]"
   193		else
   194			wrap_bad 'cgroup hierarchy' 'nonexistent??'
   195		fi
   196		wrap_color '    (see https://github.com/tianon/cgroupfs-mount)' yellow
   197	fi
   198fi
   199
   200if [ "$(cat /sys/module/apparmor/parameters/enabled 2>/dev/null)" = 'Y' ]; then
   201	echo -n '- '
   202	if command -v apparmor_parser &>/dev/null; then
   203		wrap_good 'apparmor' 'enabled and tools installed'
   204	else
   205		wrap_bad 'apparmor' 'enabled, but apparmor_parser missing'
   206		echo -n '    '
   207		if command -v apt-get &>/dev/null; then
   208			wrap_color '(use "apt-get install apparmor" to fix this)' yellow
   209		elif command -v yum &>/dev/null; then
   210			wrap_color '(your best bet is "yum install apparmor-parser")' yellow
   211		else
   212			wrap_color '(look for an "apparmor" package for your distribution)' yellow
   213		fi
   214	fi
   215fi
   216
   217flags=(
   218	NAMESPACES {NET,PID,IPC,UTS}_NS
   219	CGROUPS CGROUP_CPUACCT CGROUP_DEVICE CGROUP_FREEZER CGROUP_SCHED CPUSETS MEMCG
   220	KEYS
   221	VETH BRIDGE BRIDGE_NETFILTER
   222	IP_NF_FILTER IP_NF_TARGET_MASQUERADE
   223	NETFILTER_XT_MATCH_{ADDRTYPE,CONNTRACK,IPVS}
   224	IP_NF_NAT NF_NAT
   225
   226	# required for bind-mounting /dev/mqueue into containers
   227	POSIX_MQUEUE
   228)
   229check_flags "${flags[@]}"
   230
   231if kernel_lt 5 1; then
   232	check_flags NF_NAT_IPV4
   233fi
   234
   235if kernel_lt 5 2; then
   236	check_flags NF_NAT_NEEDED
   237fi
   238
   239echo
   240
   241echo 'Optional Features:'
   242{
   243	check_flags USER_NS
   244	check_distro_userns
   245
   246	check_flags SECCOMP
   247	check_flags SECCOMP_FILTER
   248	check_flags CGROUP_PIDS
   249
   250	check_flags MEMCG_SWAP
   251
   252	if kernel_lt 5 8; then
   253		check_flags MEMCG_SWAP_ENABLED
   254		if is_set MEMCG_SWAP && ! is_set MEMCG_SWAP_ENABLED; then
   255			wrap_color '    (note that cgroup swap accounting is not enabled in your kernel config, you can enable it by setting boot option "swapaccount=1")' bold black
   256		fi
   257	fi
   258}
   259
   260if kernel_lt 4 5; then
   261	check_flags MEMCG_KMEM
   262fi
   263
   264if kernel_lt 3 18; then
   265	check_flags RESOURCE_COUNTERS
   266fi
   267
   268if kernel_lt 3 13; then
   269	netprio=NETPRIO_CGROUP
   270else
   271	netprio=CGROUP_NET_PRIO
   272fi
   273
   274if kernel_lt 5 0; then
   275	check_flags IOSCHED_CFQ CFQ_GROUP_IOSCHED
   276fi
   277
   278flags=(
   279	BLK_CGROUP BLK_DEV_THROTTLING
   280	CGROUP_PERF
   281	CGROUP_HUGETLB
   282	NET_CLS_CGROUP "$netprio"
   283	CFS_BANDWIDTH FAIR_GROUP_SCHED RT_GROUP_SCHED
   284	IP_NF_TARGET_REDIRECT
   285	IP_VS
   286	IP_VS_NFCT
   287	IP_VS_PROTO_TCP
   288	IP_VS_PROTO_UDP
   289	IP_VS_RR
   290	SECURITY_SELINUX
   291	SECURITY_APPARMOR
   292)
   293check_flags "${flags[@]}"

View as plain text