From 4e28047eb4cacc7b7208018a8c095102517517e8 Mon Sep 17 00:00:00 2001 From: Stefan Haberland Date: Thu, 10 Nov 2022 16:11:09 +0100 Subject: [PATCH] tunedasd: move tunedasd ioctls to libdasd MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move all DASD IOCTLs to libdasd and adapt all affected users accordingly. Signed-off-by: Stefan Haberland Reviewed-by: Jan Hoeppner Signed-off-by: Jan Höppner --- include/lib/dasd_base.h | 73 +++++++++++ libdasd/dasd_ioctl.c | 129 +++++++++++++++++++ tunedasd/src/disk.c | 268 ++++++++-------------------------------- 3 files changed, 252 insertions(+), 218 deletions(-) diff --git a/include/lib/dasd_base.h b/include/lib/dasd_base.h index b12e1f9c..11ec94b1 100644 --- a/include/lib/dasd_base.h +++ b/include/lib/dasd_base.h @@ -187,6 +187,61 @@ typedef struct format_check_t { #define DASD_FMT_ERR_RECORD_ID 4 #define DASD_FMT_ERR_KEY_LENGTH 5 +/* + * struct profile_info_t + * holds the profiling information + */ +typedef struct dasd_profile_info_t { + unsigned int dasd_io_reqs; /* # of requests processed at all */ + unsigned int dasd_io_sects; /* # of sectors processed at all */ + unsigned int dasd_io_secs[32]; /* request's sizes */ + unsigned int dasd_io_times[32]; /* requests's times */ + unsigned int dasd_io_timps[32]; /* requests's times per sector */ + unsigned int dasd_io_time1[32]; /* time from build to start */ + unsigned int dasd_io_time2[32]; /* time from start to irq */ + unsigned int dasd_io_time2ps[32]; /* time from start to irq */ + unsigned int dasd_io_time3[32]; /* time from irq to end */ + unsigned int dasd_io_nr_req[32]; /* # of requests in chanq */ +} dasd_profile_info_t; + +/* + * struct attrib_data_t + * represents the operation (cache) bits for the device. + * Used in DE to influence caching of the DASD. + */ +typedef struct attrib_data_t { + unsigned char operation : 3; /* cache operation mode */ + unsigned char reserved : 5; + unsigned short nr_cyl; /* no of cyliners for read ahaed */ + unsigned char reserved2[29]; /* for future use */ +} __attribute__((packed)) attrib_data_t; + +/* definition of operation (cache) bits within attributes of DE */ +#define DASD_NORMAL_CACHE 0x0 +#define DASD_BYPASS_CACHE 0x1 +#define DASD_INHIBIT_LOAD 0x2 +#define DASD_SEQ_ACCESS 0x3 +#define DASD_SEQ_PRESTAGE 0x4 +#define DASD_REC_ACCESS 0x5 + +/* + * Data returned by Sense Path Group ID (SNID) + */ +struct dasd_snid_data { + struct { + __u8 group : 2; + __u8 reserve : 2; + __u8 mode : 1; + __u8 res : 3; + } __attribute__((packed)) path_state; + __u8 pgid[11]; +} __attribute__((packed)); + +struct dasd_snid_ioctl_data { + struct dasd_snid_data data; + __u8 path_mask; +} __attribute__((packed)); + #ifndef __linux__ /* definition from hdreg.h */ struct hd_geometry { @@ -207,12 +262,24 @@ struct hd_geometry { #define BIODASDRSRV _IO(DASD_IOCTL_LETTER, 2) /* Release the device for the current LPAR */ #define BIODASDRLSE _IO(DASD_IOCTL_LETTER, 3) +/* Unconditional reserve the device for the current LPAR */ +#define BIODASDSLCK _IO(DASD_IOCTL_LETTER, 4) +/* reset profiling information of a device */ +#define BIODASDPRRST _IO(DASD_IOCTL_LETTER, 5) +/* retrieve profiling information of a device */ +#define BIODASDPRRD _IOR(DASD_IOCTL_LETTER, 2, dasd_profile_info_t) /* Get information on a dasd device (enhanced) */ #define BIODASDINFO2 _IOR(DASD_IOCTL_LETTER, 3, dasd_information2_t) +/* Get Attributes (cache operations) */ +#define BIODASDGATTR _IOR(DASD_IOCTL_LETTER, 5, attrib_data_t) /* #define BIODASDFORMAT _IOW(IOCTL_LETTER,0,format_data_t) , deprecated */ #define BIODASDFMT _IOW(DASD_IOCTL_LETTER, 1, format_data_t) +/* Set Attributes (cache operations) */ +#define BIODASDSATTR _IOW(DASD_IOCTL_LETTER, 2, attrib_data_t) /* Release Allocated Space */ #define BIODASDRAS _IOW(DASD_IOCTL_LETTER, 3, format_data_t) +/* Get Sense Path Group ID (SNID) data */ +#define BIODASDSNID _IOWR(DASD_IOCTL_LETTER, 1, struct dasd_snid_ioctl_data) /* Check device format according to format_data_t */ #define BIODASDCHECKFMT _IOWR(DASD_IOCTL_LETTER, 2, format_check_t) @@ -245,5 +312,11 @@ int dasd_is_ro(const char *device, bool *ro); int dasd_reread_partition_table(const char *device, int ntries); int dasd_disk_reserve(const char *device); int dasd_disk_release(const char *device); +int dasd_slock(const char *device); +int dasd_get_cache(const char *device, attrib_data_t *attrib_data); +int dasd_set_cache(const char *device, attrib_data_t *attrib_data); +int dasd_query_reserve(const char *device); +int dasd_profile(const char *device, dasd_profile_info_t *dasd_profile_info); +int dasd_reset_profile(const char *device); #endif /* LIB_DASD_BASE_H */ diff --git a/libdasd/dasd_ioctl.c b/libdasd/dasd_ioctl.c index f9549612..40e726c8 100644 --- a/libdasd/dasd_ioctl.c +++ b/libdasd/dasd_ioctl.c @@ -16,6 +16,7 @@ #include #include #include +#include #include "lib/dasd_base.h" @@ -321,3 +322,131 @@ int dasd_disk_release(const char *device) return 0; } + +/* + * Unconditionally reserve DASD disk + * + * An existing reserve lock is lifted (steal lock) and the device + * is reserved. + * + * @param[in] device node device node's name + * + * @retval 0 in case of success + * @retval errno in case of failure + */ +int dasd_slock(const char *device) +{ + int fd; + + fd = dasd_open_device(device, O_RDONLY); + RUN_IOCTL(fd, BIODASDSLCK, NULL); + dasd_close_device(fd); + + return 0; +} + +/* + * Get the caching algorithm used for the channel programs of this device. + * + * @param[in] device node device node's name + * @param[out] attrib_data pointer to dasd attrib data with: + * 'cache' is the caching mode + * 'no_cyl' the number of cylinders to be cached. + * + * @retval 0 in case of success + * @retval errno in case of failure + */ +int dasd_get_cache(const char *device, attrib_data_t *attrib_data) +{ + int fd; + + fd = dasd_open_device(device, O_RDONLY); + RUN_IOCTL(fd, BIODASDGATTR, attrib_data); + dasd_close_device(fd); + + return 0; +} + +/* + * Set the caching algorithm used for the channel programs of this device. + * + * @param[in] device node device node's name + * @param[in] attrib_data pointer to dasd attrib data with: + * 'cache' is the caching mode + * 'no_cyl' the number of cylinders to be cached. + * + * @retval 0 in case of success + * @retval errno in case of failure + */ +int dasd_set_cache(const char *device, attrib_data_t *attrib_data) +{ + int fd; + + fd = dasd_open_device(device, O_RDONLY); + RUN_IOCTL(fd, BIODASDSATTR, attrib_data); + dasd_close_device(fd); + + return 0; +} + +/* + * Get reserve status of device. + * + * @param[in] device node device node's name + * + * @retval errno in case of failure + * @retval 0 unreserved + * @retval 1 implicit reserved + * @retval 2 other reservation + * @retval 3 reserved + */ +int dasd_query_reserve(const char *device) +{ + struct dasd_snid_ioctl_data snid = { 0 }; + int fd; + + fd = dasd_open_device(device, O_RDONLY); + RUN_IOCTL(fd, BIODASDSNID, &snid); + dasd_close_device(fd); + + return snid.data.path_state.reserve; +} + +/* + * Get and print the profiling info of the device. + * + * @param[in] device node device node's name + * @param[in] dasd_profile_info pointer to dasd profile info + * + * @retval 0 in case of success + * @retval errno in case of failure + */ +int dasd_profile(const char *device, dasd_profile_info_t *dasd_profile_info) +{ + int fd; + + fd = dasd_open_device(device, O_RDONLY); + RUN_IOCTL(fd, BIODASDPRRD, dasd_profile_info); + dasd_close_device(fd); + + return 0; +} + +/* + * Reset the profiling counters of the device. + * + * @param[in] device node device node's name + * + * @retval 0 in case of success + * @retval errno in case of failure + */ +int dasd_reset_profile(const char *device) +{ + int fd; + + fd = dasd_open_device(device, O_RDONLY); + RUN_IOCTL(fd, BIODASDPRRST, NULL); + dasd_close_device(fd); + + return 0; +} diff --git a/tunedasd/src/disk.c b/tunedasd/src/disk.c index f2406514..1e8de16c 100644 --- a/tunedasd/src/disk.c +++ b/tunedasd/src/disk.c @@ -19,6 +19,7 @@ #include #include +#include "lib/dasd_base.h" #include "lib/dasd_sys.h" #include "disk.h" @@ -26,91 +27,6 @@ #define BUS_ID_SIZE 30 -/* - * DASD DEFINITIONS (copied from dasd.h) - */ - -#define DASD_IOCTL_LETTER 'D' - -/* - * struct profile_info_t - * holds the profiling information - */ -typedef struct dasd_profile_info_t { - unsigned int dasd_io_reqs; /* # of requests processed at all */ - unsigned int dasd_io_sects; /* # of sectors processed at all */ - unsigned int dasd_io_secs[32]; /* request's sizes */ - unsigned int dasd_io_times[32]; /* requests's times */ - unsigned int dasd_io_timps[32]; /* requests's times per sector */ - unsigned int dasd_io_time1[32]; /* time from build to start */ - unsigned int dasd_io_time2[32]; /* time from start to irq */ - unsigned int dasd_io_time2ps[32]; /*time from start to irq */ - unsigned int dasd_io_time3[32]; /* time from irq to end */ - unsigned int dasd_io_nr_req[32]; /* # of requests in chanq */ -} dasd_profile_info_t; - - -/* - * struct attrib_data_t - * represents the operation (cache) bits for the device. - * Used in DE to influence caching of the DASD. - */ -typedef struct attrib_data_t { - unsigned char operation:3; /* cache operation mode */ - unsigned char reserved:5; - unsigned short nr_cyl; /* no of cyliners for read ahaed */ - unsigned char reserved2[29]; /* for future use */ -} __attribute__ ((packed)) attrib_data_t; - -/* definition of operation (cache) bits within attributes of DE */ -#define DASD_NORMAL_CACHE 0x0 -#define DASD_BYPASS_CACHE 0x1 -#define DASD_INHIBIT_LOAD 0x2 -#define DASD_SEQ_ACCESS 0x3 -#define DASD_SEQ_PRESTAGE 0x4 -#define DASD_REC_ACCESS 0x5 - -/* - * Data returned by Sense Path Group ID (SNID) - */ -struct dasd_snid_data { - struct { - __u8 group:2; - __u8 reserve:2; - __u8 mode:1; - __u8 res:3; - } __attribute__ ((packed)) path_state; - __u8 pgid[11]; -} __attribute__ ((packed)); - -struct dasd_snid_ioctl_data { - struct dasd_snid_data data; - __u8 path_mask; -} __attribute__ ((packed)); - - -/* - * DASD-IOCTLs (copied from dasd.h) - */ -/* Issue a reserve/release command, rsp. */ -#define BIODASDRSRV _IO (DASD_IOCTL_LETTER,2) /* reserve */ -#define BIODASDRLSE _IO (DASD_IOCTL_LETTER,3) /* release */ -#define BIODASDSLCK _IO (DASD_IOCTL_LETTER,4) /* steal lock */ -/* reset profiling information of a device */ -#define BIODASDPRRST _IO (DASD_IOCTL_LETTER,5) - -/* retrieve profiling information of a device */ -#define BIODASDPRRD _IOR (DASD_IOCTL_LETTER,2,dasd_profile_info_t) -/* Get Attributes (cache operations) */ -#define BIODASDGATTR _IOR(DASD_IOCTL_LETTER,5,attrib_data_t) - -/* Set Attributes (cache operations) */ -#define BIODASDSATTR _IOW (DASD_IOCTL_LETTER,2,attrib_data_t) - -/* Get Sense Path Group ID (SNID) data */ -#define BIODASDSNID _IOWR(DASD_IOCTL_LETTER, 1, struct dasd_snid_ioctl_data) - - /* id definition for profile items */ enum prof_id { prof_reqs = 0, @@ -241,48 +157,33 @@ check_prof_item (char* prof_item) * 'cache' is the caching mode (see ESS docu for more info) and 'no_cyl' * the number of cylinders to be cached. */ -int -disk_get_cache (char* device) +int disk_get_cache(char *device) { - int fd; attrib_data_t attrib_data; - - /* Open device file */ - fd = open (device, O_RDONLY); - if (fd == -1) { - error_print ("<%s> - %s", device, strerror (errno)); - return -1; - } + int rc; - /* Get the given caching attributes */ - if (ioctl (fd, BIODASDGATTR, &attrib_data)) { - error_print ("Could not get cache attributes for device <%s>", - device); - close (fd); - return -1; - } + rc = dasd_get_cache(device, &attrib_data); + if (rc) + return rc; printf ("%s (%i cyl)\n", get_cache_name(attrib_data.operation), attrib_data.nr_cyl); - close (fd); return 0; } - /* * Set the caching algorithm used for the channel programs of this device. * 'cache' is the caching mode (see ESS docu for more info) and 'no_cyl' * the number of cylinders to be cached. */ -int -disk_set_cache (char* device, char* cache, char* no_cyl) +int disk_set_cache(char *device, char *cache, char *no_cyl) { - int fd; attrib_data_t attrib_data; - - /* get caching mode and # cylinders */ + int rc; + + /* get caching mode and # cylinders */ attrib_data.operation = check_cache (cache); attrib_data.nr_cyl = check_no_cyl (no_cyl); @@ -292,52 +193,34 @@ disk_set_cache (char* device, char* cache, char* no_cyl) attrib_data.nr_cyl); } - /* Open device file */ - fd = open (device, O_RDONLY); - if (fd == -1) { - error_print ("<%s> - %s", device, strerror (errno)); - return -1; - } - /* Set the given caching attributes */ printf ("Setting cache mode for device <%s>...\n", device); - if (ioctl (fd, BIODASDSATTR, &attrib_data)) { - error_print ("Could not set caching for device <%s>", device); - close (fd); + rc = dasd_set_cache(device, &attrib_data); + if (rc) { + error_print("Could not set caching for device <%s>", device); return -1; } - printf ("Done.\n"); - close (fd); + return 0; } - /* * Reserve the device. */ -int -disk_reserve (char* device) +int disk_reserve(char *device) { - int fd; - - /* Open device file */ - fd = open (device, O_RDONLY); - if (fd == -1) { - error_print ("<%s> - %s", device, strerror (errno)); - return -1; - } + int rc; /* Reserve device */ printf ("Reserving device <%s>...\n", device); - if (ioctl (fd, BIODASDRSRV)) { - error_print ("Could not reserve device <%s>", device); - close (fd); + rc = dasd_disk_reserve(device); + if (rc) { + error_print("Could not reserve device <%s>", device); return -1; } - printf ("Done.\n"); - close (fd); + printf("Done.\n"); return 0; } @@ -345,28 +228,18 @@ disk_reserve (char* device) /* * Release the device. */ -int -disk_release (char* device) +int disk_release(char *device) { - int fd; + int rc; - /* Open device file */ - fd = open (device, O_RDONLY); - if (fd == -1) { - error_print ("<%s> - %s", device, strerror (errno)); - return -1; - } - - /* Release device */ printf ("Releasing device <%s>...\n", device); - if (ioctl (fd, BIODASDRLSE)) { - error_print ("Could not release device <%s>", device); - close (fd); + rc = dasd_disk_release(device); + if (rc) { + error_print("Could not release device <%s>", device); return -1; } - printf ("Done.\n"); - close (fd); + printf("Done.\n"); return 0; } @@ -376,29 +249,19 @@ disk_release (char* device) * This means to reserve the device even if it was already reserved. * The current reserve is broken (steal lock). */ -int -disk_slock (char* device) +int disk_slock(char *device) { - int fd; - - /* Open device file */ - fd = open (device, O_RDONLY); - if (fd == -1) { - error_print ("<%s> - %s", device, strerror (errno)); - return -1; - } + int rc; /* Unconditional reserve device */ printf ("Unconditional reserving device <%s>...\n", device); - if (ioctl (fd, BIODASDSLCK)) { - error_print ("Could not unconditional reserve device <%s>", - device); - close (fd); + rc = dasd_slock(device); + if (rc) { + error_print("Could not unconditional reserve device <%s>", device); return -1; } - printf ("Done.\n"); - close (fd); + return 0; } @@ -407,27 +270,16 @@ disk_slock (char* device) * Uses the Sense Path Group ID (SNID) ioctl to find out if * a device is reserved to it's path group. */ -int -disk_query_reserve_status(char* device) +int disk_query_reserve_status(char *device) { - int fd; - struct dasd_snid_ioctl_data snid; + int rc; - /* Open device file */ - fd = open (device, O_RDONLY); - if (fd == -1) { - error_print ("<%s> - %s", device, strerror (errno)); + rc = dasd_query_reserve(device); + if (rc < 0) { + error_print("Could not read reserve status for device <%s>", device); return -1; } - snid.path_mask = 0; - /* Release device */ - if (ioctl(fd, BIODASDSNID, &snid)) { - error_print("Could not read reserve status" - " for device <%s>", device); - close (fd); - return -1; - } - switch (snid.data.path_state.reserve) { + switch (rc) { case 0: printf("none\n"); break; @@ -441,7 +293,7 @@ disk_query_reserve_status(char* device) printf("reserved\n"); break; } - close (fd); + return 0; } @@ -615,21 +467,14 @@ static int disk_profile_item(dasd_profile_info_t dasd_profile_info, /* * Get and print the profiling info of the device. */ -int -disk_profile (char* device, char* prof_item) +int disk_profile(char *device, char *prof_item) { - int fd, rc; dasd_profile_info_t dasd_profile_info; - - /* Open device file */ - fd = open (device, O_RDONLY); - if (fd == -1) { - error_print ("<%s> - %s", device, strerror (errno)); - return -1; - } + int rc; /* Get the profile info */ - if (ioctl (fd, BIODASDPRRD, &dasd_profile_info)) { + rc = dasd_profile(device, &dasd_profile_info); + if (rc) { switch (errno) { case EIO: /* profiling is not active */ error_print ("Profiling (on device <%s>) is not " @@ -639,7 +484,6 @@ disk_profile (char* device, char* prof_item) error_print ("Could not get profile info for device " "<%s>.", device); } - close (fd); return -1; } /* Check for profile item or summary */ @@ -648,38 +492,26 @@ disk_profile (char* device, char* prof_item) } else { rc = disk_profile_item (dasd_profile_info, prof_item); } - - close (fd); + return rc; } - /* * Reset the profiling counters of the device. */ -int -disk_reset_prof (char* device) +int disk_reset_prof(char *device) { - int fd; - - /* Open device file */ - fd = open (device, O_RDONLY); - if (fd == -1) { - error_print ("<%s> - %s", device, strerror (errno)); - return -1; - } + int rc; /* reset profile info */ printf ("Resetting profile info for device <%s>...\n", device); - if (ioctl (fd, BIODASDPRRST)) { - error_print ("Could not reset profile info for device <%s>", - device); - close (fd); + rc = dasd_reset_profile(device); + if (rc) { + error_print("Could not reset profile info for device <%s>", device); return -1; } - printf ("Done.\n"); - close (fd); + return 0; }