2
0
mirror of https://github.com/xcat2/xcat-core.git synced 2026-09-08 12:40:45 +00:00

feat(genesis): report IBM Z identity

This commit is contained in:
Vinícius Ferrão
2026-09-04 00:54:04 -03:00
parent e08804d0e8
commit cb09b5033d
4 changed files with 117 additions and 6 deletions
@@ -107,6 +107,7 @@ void xcat_set_text(char *destination, size_t size, const char *format, ...);
char *xcat_read_allocated_line(const char *path);
bool xcat_read_line(const char *path, char *value, size_t size);
bool xcat_read_key(const char *path, const char *key, char *value, size_t size);
bool xcat_read_colon_key(const char *path, const char *key, char *value, size_t size);
bool xcat_safe_name(const char *value);
bool xcat_cmdline_value(const char *cmdline, const char *key, char *value, size_t size);
unsigned long long xcat_read_uptime(void);
@@ -201,6 +201,8 @@ static void set_boot_loader(const char *cmdline, char *loader, size_t size) {
xcat_set_text(loader, size, "PXELINUX");
else if (strcmp(value, "elilo") == 0)
xcat_set_text(loader, size, "ELILO");
else if (strcmp(value, "s390-ccw") == 0)
xcat_set_text(loader, size, "QEMU TFTP loader");
else
xcat_set_text(loader, size, "unrecognized");
} else if (xcat_cmdline_value(cmdline, "BOOTIF", value, sizeof(value))) {
@@ -216,6 +218,15 @@ static bool useful_identity(const char *value) {
strcmp(value, "unknown") != 0;
}
static void set_s390_identity(const char *proc_root, struct console_state *state) {
char path[VALUE_SIZE * 2];
snprintf(path, sizeof(path), "%s/sysinfo", proc_root);
if (!useful_identity(state->uuid) &&
!xcat_read_colon_key(path, "VM00 UUID", state->uuid, sizeof(state->uuid)))
xcat_read_colon_key(path, "LPAR UUID", state->uuid, sizeof(state->uuid));
}
static void split_action(const char *destiny, char *action, size_t action_size, char *target,
size_t target_size) {
const char *separator = strchr(destiny, '=');
@@ -291,8 +302,12 @@ void xcat_load_console_state(struct console_state *state) {
char path[VALUE_SIZE * 2];
char release_name[64] = "xCAT Genesis";
char release_version[32] = "";
#ifdef XCAT_CONSOLE_TEST
const char *test_architecture = getenv("XCAT_TEST_ARCH");
#endif
bool xcat_configured;
bool interface_selected;
bool s390_ccw_boot;
memset(state, 0, sizeof(*state));
xcat_configured = xcat_cmdline_value(cmdline_text, "xcatd", state->xcat_endpoint,
@@ -332,6 +347,16 @@ void xcat_load_console_state(struct console_state *state) {
xcat_set_text(state->architecture, sizeof(state->architecture), "unknown");
xcat_set_text(state->kernel, sizeof(state->kernel), "unknown");
}
#ifdef XCAT_CONSOLE_TEST
if (test_architecture != NULL)
xcat_set_text(state->architecture, sizeof(state->architecture), "%s",
test_architecture);
#endif
s390_ccw_boot = strcmp(state->architecture, "s390x") == 0 &&
xcat_cmdline_value(cmdline_text, "xcat.bootloader", value,
sizeof(value)) &&
strcmp(value, "s390-ccw") == 0;
snprintf(path, sizeof(path), "%s/firmware/efi", sys_root);
if (strncmp(state->architecture, "ppc64", 5) == 0) {
@@ -345,6 +370,9 @@ void xcat_load_console_state(struct console_state *state) {
access(path, F_OK) == 0 ? "UEFI" : "Device Tree");
} else if (strncmp(state->architecture, "riscv", 5) == 0) {
xcat_set_text(state->firmware, sizeof(state->firmware), "OpenSBI");
} else if (strcmp(state->architecture, "s390x") == 0) {
xcat_set_text(state->firmware, sizeof(state->firmware), "%s",
s390_ccw_boot ? "s390-ccw BIOS" : "not reported");
} else {
snprintf(path, sizeof(path), "%s/firmware/efi", sys_root);
xcat_set_text(state->firmware, sizeof(state->firmware), "%s",
@@ -365,7 +393,12 @@ void xcat_load_console_state(struct console_state *state) {
if (!useful_identity(state->serial))
xcat_set_text(state->serial, sizeof(state->serial), "not reported");
snprintf(path, sizeof(path), "%s/class/dmi/id/product_uuid", sys_root);
if (!xcat_read_line(path, state->uuid, sizeof(state->uuid)) || !useful_identity(state->uuid))
xcat_read_line(path, state->uuid, sizeof(state->uuid));
if (strcmp(state->architecture, "s390x") == 0) {
xcat_set_text(state->serial, sizeof(state->serial), "not reported");
set_s390_identity(proc_root, state);
}
if (!useful_identity(state->uuid))
xcat_set_text(state->uuid, sizeof(state->uuid), "not reported");
interface_selected =
@@ -123,6 +123,42 @@ bool xcat_read_key(const char *path, const char *key, char *value, size_t size)
return found;
}
bool xcat_read_colon_key(const char *path, const char *key, char *value, size_t size) {
FILE *stream;
char *line = NULL;
size_t capacity = 0;
size_t key_length = strlen(key);
bool found = false;
if (key_length == 0 || size == 0)
return false;
stream = fopen(path, "r");
if (stream == NULL)
return false;
while (getline(&line, &capacity, stream) >= 0) {
char *start;
char *end;
size_t line_length = strlen(line);
if (line_length <= key_length || strncmp(line, key, key_length) != 0 ||
line[key_length] != ':')
continue;
start = line + key_length + 1;
while (isspace((unsigned char)*start))
start++;
end = start + strlen(start);
while (end > start && isspace((unsigned char)end[-1]))
end--;
*end = '\0';
xcat_copy_printable(value, size, start);
found = true;
break;
}
free(line);
fclose(stream);
return found;
}
bool xcat_safe_name(const char *value) {
const unsigned char *cursor = (const unsigned char *)value;
@@ -73,6 +73,14 @@ read_value() {
tr -d '\000\r\n' <"$value_file" | head -c 512
}
read_sysinfo_value() {
local name=$1
awk -F ':' -v name="$name" \
'$1 == name {sub(/^[[:space:]]+/, "", $2); sub(/[[:space:]]+$/, "", $2); print $2; exit}' \
"$proc_root/sysinfo" 2>/dev/null || true
}
send_packet() {
if [[ -n ${XCAT_DISCOVERY_SEND_COMMAND:-} ]]; then
"$XCAT_DISCOVERY_SEND_COMMAND" "$compressed_packet" "$XCATMASTER" "$XCATPORT"
@@ -125,12 +133,29 @@ system_vendor=$(read_value "$sys_root/sys/devices/virtual/dmi/id/sys_vendor" ||
serial=$(read_value "$sys_root/sys/devices/virtual/dmi/id/product_serial" || true)
uuid=$(read_value "$sys_root/sys/devices/virtual/dmi/id/product_uuid" || true)
machine_type=
s390_virtual=
[[ -z $system_vendor && -z $product_name ]] \
|| machine_type=${system_vendor:+$system_vendor:}$product_name
platform=$(awk -F ':' \
'/^platform[[:space:]]*:/ {sub(/^[[:space:]]+/, "", $2); print $2; exit}' \
"$proc_root/cpuinfo" 2>/dev/null || true)
if [[ -z $product_name ]]; then
if [[ $architecture == s390x ]]; then
system_vendor=$(read_sysinfo_value Manufacturer)
product_type=$(read_sysinfo_value Type)
product_model=$(read_sysinfo_value Model)
product_model=${product_model##* }
product_name=${product_type}${product_model:+-$product_model}
machine_type=$product_name
serial=
uuid=$(read_sysinfo_value 'VM00 UUID')
[[ -n $uuid ]] || uuid=$(read_sysinfo_value 'LPAR UUID')
platform=$(read_sysinfo_value 'VM00 Control Program')
if [[ -n $platform ]]; then
s390_virtual=1
else
platform=LPAR
fi
elif [[ -z $product_name ]]; then
product_name=$(read_value "$proc_root/device-tree/model" || true)
[[ -n $product_name ]] \
|| product_name=$(read_value \
@@ -148,12 +173,28 @@ node_type=
case "$system_vendor $product_name" in
*KVM*|*QEMU*|*VMware*|*VirtualBox*|*Bochs*|*Hyper-V*) node_type=virtual ;;
esac
[[ -z $s390_virtual ]] || node_type=virtual
cpu_count=$(awk '/^(processor|cpu)[[:space:]]*:/ {count++} END {print count + 0}' \
cpu_count=$(awk '
/^processor([[:space:]]+[0-9]+)?[[:space:]]*:/ {processors++}
/^cpu[[:space:]]*:/ {cpus++}
END {print (processors > 0 ? processors : cpus + 0)}' \
"$proc_root/cpuinfo" 2>/dev/null || printf '0')
cpu_type=$(awk -F ':' \
'/^(model name|cpu)[[:space:]]*:/ {sub(/^[[:space:]]+/, "", $2); print $2; exit}' \
"$proc_root/cpuinfo" 2>/dev/null || true)
cpu_type=$(awk -F ':' '
/^model name[[:space:]]*:/ && model == "" {
sub(/^[[:space:]]+/, "", $2); model = $2
}
/^cpu[[:space:]]*:/ && cpu == "" {
sub(/^[[:space:]]+/, "", $2); cpu = $2
}
/^vendor_id[[:space:]]*:/ && vendor == "" {
sub(/^[[:space:]]+/, "", $2); vendor = $2
}
END {
if (model != "") print model
else if (cpu != "") print cpu
else if (vendor != "") print vendor
}' "$proc_root/cpuinfo" 2>/dev/null || true)
memory=$(awk '/^MemTotal:/ {printf "%.0fMB", $2 / 1024; exit}' \
"$proc_root/meminfo" 2>/dev/null || true)
disk_size=$(lsblk -b -dn -o NAME,SIZE,TYPE 2>/dev/null \