1#!/bin/sh
2# SPDX-License-Identifier: GPL-2.0+
3#
4# Create an awk script that takes as input numbers of CPUs and outputs
5# lists of CPUs, one per line in both cases.
6#
7# Usage: kvm-get-cpus-script.sh /path/to/cpu/arrays /path/to/put/script [ /path/to/state ]
8#
9# The CPU arrays are output by kvm-assign-cpus.sh, and are valid awk
10# statements initializing the variables describing the system's topology.
11#
12# The optional state is input by this script (if the file exists and is
13# non-empty), and can also be output by this script.
14
15cpuarrays="${1-/sys/devices/system/node}"
16scriptfile="${2}"
17statefile="${3}"
18
19if ! test -f "$cpuarrays"
20then
21	echo "File not found: $cpuarrays" 1>&2
22	exit 1
23fi
24scriptdir="`dirname "$scriptfile"`"
25if ! test -d "$scriptdir" || ! test -x "$scriptdir" || ! test -w "$scriptdir"
26then
27	echo "Directory not usable for script output: $scriptdir"
28	exit 1
29fi
30
31cat << '___EOF___' > "$scriptfile"
32BEGIN {
33___EOF___
34cat "$cpuarrays" >> "$scriptfile"
35if test -r "$statefile"
36then
37	cat "$statefile" >> "$scriptfile"
38fi
39cat << '___EOF___' >> "$scriptfile"
40}
41
42# Do we have the system architecture to guide CPU affinity?
43function gotcpus()
44{
45	return numnodes != "";
46}
47
48# Return a comma-separated list of the next n CPUs.
49function nextcpus(n,  i, s)
50{
51	for (i = 0; i < n; i++) {
52		if (nodecpus[curnode] == "")
53			curnode = 0;
54		if (cpu[curnode][curcpu[curnode]] == "")
55			curcpu[curnode] = 0;
56		if (s != "")
57			s = s ",";
58		s = s cpu[curnode][curcpu[curnode]];
59		curcpu[curnode]++;
60		curnode++
61	}
62	return s;
63}
64
65# Dump out the current node/CPU state so that a later invocation of this
66# script can continue where this one left off.  Of course, this only works
67# when a state file was specified and where there was valid sysfs state.
68# Returns 1 if the state was dumped, 0 otherwise.
69#
70# Dumping the state for one system configuration and loading it into
71# another isn't likely to do what you want, whatever that might be.
72function dumpcpustate(  i, fn)
73{
74___EOF___
75echo '	fn = "'"$statefile"'";' >> $scriptfile
76cat << '___EOF___' >> "$scriptfile"
77	if (fn != "" && gotcpus()) {
78		print "curnode = " curnode ";" > fn;
79		for (i = 0; i < numnodes; i++)
80			if (curcpu[i] != "")
81				print "curcpu[" i "] = " curcpu[i] ";" >> fn;
82		return 1;
83	}
84	if (fn != "")
85		print "# No CPU state to dump." > fn;
86	return 0;
87}
88___EOF___
89