mirror of
https://github.com/ibm-s390-linux/s390-tools.git
synced 2026-08-05 02:14:52 +00:00
zdev: modify zdev_id to read the site_id from loadparm
The currently active site can be found from the loadparm attribute which is located at /sys/firmware/ipl/loadparm. Read the value of loadparm and extract the site_id. The loadparm is an 8 byte alphanumerical IPL parameter. The content of loadparm can be of different forms to indicate different boot menu options, which are used by Linux for selecting the respective boot menu entries. To indicate the site-id, loadparm adds a 'S' character. Where, the following character after 'S' indicates either the site-id or indivcation to derive the site-id from SSID. For example, If the loadparm value is Sn,'n' is the integer which could be one of the valid site_ids from 0 to 9; i.e when booted on site-1, loadparm value will be S1. If loadparm value is "SS", zdev_id extracts the site_id from the SSID of the current ipl device. For ccw and zfcp devices, the current ipl device-id can be found at /sys/firmware/ipl/device. In any case, if the loadparm contains invalid value, or empty, the site_id will be default to the common-site. After the first invocation of the zdev_id from udev-rule, the site-id information is stored in /run/zdev_id.env file. This will reduce the number of further invocation of zdev_id from within udev-rules. Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com> Signed-off-by: Vineeth Vijayan <vneethv@linux.ibm.com> Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
This commit is contained in:
committed by
Jan Höppner
parent
d2317943c0
commit
c8ad5f57d0
15
zdev/include/zdev_id.h
Normal file
15
zdev/include/zdev_id.h
Normal file
@@ -0,0 +1,15 @@
|
||||
/*
|
||||
* zdev - Modify and display the persistent configuration of devices
|
||||
*
|
||||
* Copyright IBM Corp. 2022
|
||||
*
|
||||
* s390-tools is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*/
|
||||
|
||||
#ifndef ZDEV_ID_H
|
||||
#define ZDEV_ID_H
|
||||
|
||||
#define ZDEV_SITE_ID_FILE "/run/zdev_id.env"
|
||||
|
||||
#endif /* ZDEV_ID_H */
|
||||
@@ -11,9 +11,17 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "zdev_id.h"
|
||||
|
||||
#define SYSINFO "/proc/sysinfo"
|
||||
#define CMDLINE "/proc/cmdline"
|
||||
#define LOADPARM "/sys/firmware/ipl/loadparm"
|
||||
#define IPL_DEV_ID "/sys/firmware/ipl/device"
|
||||
#define IPL_DEV_TYPE "/sys/firmware/ipl/ipl_type"
|
||||
#define SITE_FALLBACK 10
|
||||
|
||||
#define WHITESPACE " \t\n"
|
||||
|
||||
static void array_add(char ***array_p, int *num_p, const char *str)
|
||||
@@ -140,15 +148,139 @@ out:
|
||||
printf("ZDEV_NO_AUTO=%d\n", no_auto);
|
||||
}
|
||||
|
||||
/*
|
||||
* If the erraneous loadparm provides a site_id which is not valid,
|
||||
* default it to the common-site id.
|
||||
*/
|
||||
static int validate_site(int site_id)
|
||||
{
|
||||
if (site_id < SITE_FALLBACK)
|
||||
return site_id;
|
||||
return SITE_FALLBACK;
|
||||
}
|
||||
|
||||
/* get the ipl device and extract the SSID */
|
||||
static int get_site_id(void)
|
||||
{
|
||||
FILE *fd;
|
||||
char *line;
|
||||
size_t n;
|
||||
int site_id = SITE_FALLBACK, ssid;
|
||||
|
||||
fd = fopen(IPL_DEV_ID, "r");
|
||||
if (!fd)
|
||||
goto fail_safe;
|
||||
|
||||
if (getline(&line, &n, fd) == -1)
|
||||
goto out;
|
||||
|
||||
if (sscanf(line, "%*d.%d.%*d", &ssid) == 1)
|
||||
site_id = validate_site(ssid);
|
||||
|
||||
out:
|
||||
free(line);
|
||||
fclose(fd);
|
||||
fail_safe:
|
||||
return site_id;
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the ipl type and see if it belongs to ccw or zfcp, if different,
|
||||
* default it to common-site.
|
||||
*/
|
||||
static int read_ssid(void)
|
||||
{
|
||||
FILE *fd;
|
||||
char *line = NULL;
|
||||
size_t n;
|
||||
int site_id = SITE_FALLBACK;
|
||||
|
||||
fd = fopen(IPL_DEV_TYPE, "r");
|
||||
if (!fd)
|
||||
goto out;
|
||||
|
||||
if (getline(&line, &n, fd) != -1) {
|
||||
if (strcmp(line, "ccw") == 0 || strcmp(line, "zfcp"))
|
||||
site_id = get_site_id();
|
||||
}
|
||||
|
||||
free(line);
|
||||
fclose(fd);
|
||||
out:
|
||||
return site_id;
|
||||
}
|
||||
|
||||
static void write_zdev_site_id(int site_id)
|
||||
{
|
||||
FILE *fd;
|
||||
|
||||
fd = fopen(ZDEV_SITE_ID_FILE, "w");
|
||||
if (!fd)
|
||||
err(1, "Could not write to zdev_site_id file");
|
||||
if (site_id == SITE_FALLBACK)
|
||||
fprintf(fd, "ZDEV_SITE_ID=\n");
|
||||
else
|
||||
fprintf(fd, "ZDEV_SITE_ID=%d\n", site_id);
|
||||
|
||||
fclose(fd);
|
||||
}
|
||||
|
||||
/* Read the loadparm and extract the current site_id.
|
||||
* loadparm can contains either Sn or "Ss". Sn indicate the site_id, where
|
||||
* 'n' is the integer which could be one of the valid site_ids from 0 to 9.
|
||||
* When loadparm value is "Ss", zdev_id extracts the site_id from the SSID
|
||||
* of the current ipl device. For ccw and zfcp devices, the current ipl
|
||||
* device-id can be found at /sys/firmware/ipl/device.
|
||||
* For all other invalid cases, set ZDEV_SITE_ID to NULL.
|
||||
*/
|
||||
|
||||
static void process_loadparm(const char *filename)
|
||||
{
|
||||
size_t n;
|
||||
FILE *fd;
|
||||
char *line = NULL, *substr;
|
||||
int site_id = SITE_FALLBACK;
|
||||
|
||||
fd = fopen(filename, "r");
|
||||
if (!fd)
|
||||
goto out;
|
||||
|
||||
/*
|
||||
* We expect the value here to be either SX, where X is the site-id
|
||||
* or SS,in which case, the site-id will be derived from the SSID
|
||||
*/
|
||||
if ((getline(&line, &n, fd)) != -1) {
|
||||
substr = strchr(line, 'S');
|
||||
if (!substr)
|
||||
goto out;
|
||||
|
||||
if (isdigit(substr[1]))
|
||||
site_id = validate_site(atoi(&substr[1]));
|
||||
else if (substr[1] == 'S')
|
||||
site_id = read_ssid();
|
||||
}
|
||||
|
||||
free(line);
|
||||
fclose(fd);
|
||||
out:
|
||||
write_zdev_site_id(site_id);
|
||||
if (site_id == SITE_FALLBACK)
|
||||
printf("ZDEV_SITE_ID=\n");
|
||||
else
|
||||
printf("ZDEV_SITE_ID=%d\n", site_id);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char *sysinfo, *cmdline;
|
||||
char *sysinfo, *cmdline, *loadparm;
|
||||
|
||||
sysinfo = argc < 2 ? SYSINFO : argv[1];
|
||||
cmdline = argc < 3 ? CMDLINE : argv[2];
|
||||
loadparm = argc < 4 ? LOADPARM : argv[3];
|
||||
|
||||
process_sysinfo(sysinfo);
|
||||
process_cmdline(cmdline);
|
||||
process_loadparm(loadparm);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user