Files
s390-tools/libdasd/dasd_sys.c
Marc Hartmayer 983233730c zipl: add missing static declarations
Fix Sparse findings like:

 warning: symbol 'hash_table_find' was not declared. Should it be static?

Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-02-02 11:54:30 +01:00

228 lines
4.6 KiB
C

/*
* dasd - Library for DASD related functions
*
* DASD related helper functions for accessing device information via sysfs
*
* Copyright IBM Corp. 2016, 2017
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*/
#include <errno.h>
#include <stdlib.h>
#include "lib/dasd_base.h"
#include "lib/dasd_sys.h"
#include "lib/util_file.h"
#include "lib/util_path.h"
#include "lib/util_sys.h"
/**
* Get raw-track access mode status
*
* The "devnode" parameter can be any valid relative or absolute path to
* a DASD device node, for example:
*
* - /dev/dasda
* - /dev/disk/by-path/ccw-0.0.bf20
*
* @param[in] devnode Device node of interest
*
* @retval 1 Raw-track access mode is enabled
* @retval 0 Raw-track access mode is disabled or
* cannot be determined
*/
int dasd_sys_raw_track_access(char *devnode)
{
char busid[DASD_BUS_ID_SIZE];
char *path;
FILE *fp;
int rc;
if (util_sys_get_dev_addr(devnode, busid) != 0)
return 0;
path = util_path_sysfs("bus/ccw/devices/%s/raw_track_access", busid);
fp = fopen(path, "r");
if (!fp) {
free(path);
return 0;
}
rc = fgetc(fp) - '0';
fclose(fp);
free(path);
return (rc == 1) ? 1 : 0;
}
/**
* Is volume extent space efficient a.k.a. thin-provisioned
*
* The "devnode" parameter can be any valid relative or absolute path to
* a DASD device node, for example:
*
* - /dev/dasda
* - /dev/disk/by-path/ccw-0.0.bf20
*
* @param[in] devnode Device node of interest
*
* @retval 1 Volume is extent space efficient
* @retval 0 Volume is not extent space efficient or
* cannot be determined
*/
int dasd_sys_ese(char *devnode)
{
char busid[DASD_BUS_ID_SIZE];
char *path;
FILE *fp;
int rc;
if (util_sys_get_dev_addr(devnode, busid) != 0)
return 0;
path = util_path_sysfs("bus/ccw/devices/%s/ese", busid);
fp = fopen(path, "r");
if (!fp) {
free(path);
return 0;
}
rc = fgetc(fp) - '0';
fclose(fp);
free(path);
return (rc == 1) ? 1 : 0;
}
static int dasd_get_pm_from_chpid(char *busid, unsigned int chpid, int *mask)
{
unsigned int val;
int count, i;
char *path;
FILE *fp;
path = util_path_sysfs("bus/ccw/devices/%s/../chpids", busid);
*mask = 0;
fp = fopen(path, "r");
if (!fp) {
free(path);
return ENODEV;
}
for (i = 0; i < 8; i++) {
count = fscanf(fp, " %x", &val);
if (count != 1) {
fclose(fp);
return EIO;
}
if (val == chpid)
*mask = 0x80 >> i;
}
fclose(fp);
free(path);
return 0;
}
/**
* reset chpid
*
* The "devnode" parameter can be any valid relative or absolute path to
* a DASD device node, for example:
*
* - /dev/dasda
* - /dev/disk/by-path/ccw-0.0.bf20
*
* @param[in] devnode Device node of interest
* @param[in] chpid The chpid to reset
* If NULL all chpids will be reset
*
* @return 0 on success, otherwise one of the following error codes:
* - EINVAL No valid chpid specified.
* - ENODEV Could not open device.
* - ENOENT Specified chpid not found.
* - EIO Other I/O error
*
*/
int dasd_reset_chpid(char *devnode, char *chpid_char)
{
unsigned int chpid;
char busid[DASD_BUS_ID_SIZE];
int mask, rc;
char *endptr;
char *path;
FILE *fp;
if (util_sys_get_dev_addr(devnode, busid) != 0)
return ENODEV;
if (!chpid_char) {
path = util_path_sysfs("bus/ccw/devices/%s/path_reset", busid);
fp = fopen(path, "w");
if (!fp) {
free(path);
return ENODEV;
}
fprintf(fp, "%s", "all\n");
fclose(fp);
free(path);
return 0;
}
errno = 0;
chpid = strtoul(chpid_char, &endptr, 16);
if (errno || (endptr && (*endptr != '\0')))
return EINVAL;
rc = dasd_get_pm_from_chpid(busid, chpid, &mask);
if (rc)
return rc;
if (!mask)
return ENOENT;
path = util_path_sysfs("bus/ccw/devices/%s/path_reset", busid);
fp = fopen(path, "w");
if (!fp) {
free(path);
return ENODEV;
}
fprintf(fp, "%02x", mask);
fclose(fp);
free(path);
return 0;
}
/**
* Read amount of host with access to \p device
*
* The \p device can be any valid relative or absolute path to a DASD device
* node, for example:
*
* - /dev/dasda
* - /dev/disk/by-path/ccw-0.0.bf20
*
* @param[in] device Device node of interest
*
* @retval n Number of hosts with access to \p device
* @retval 0 Value could not be determined
*/
int dasd_get_host_access_count(char *device)
{
char busid[DASD_BUS_ID_SIZE];
char *path;
long value;
if (util_sys_get_dev_addr(device, busid) != 0)
return 0;
path = util_path_sysfs("bus/ccw/devices/%s/host_access_count", busid);
if (util_file_read_l(&value, 10, path))
value = 0;
free(path);
return value;
}