mirror of
https://github.com/ibm-s390-linux/s390-tools.git
synced 2026-08-05 02:14:52 +00:00
Enable zdsfs to access datasets that were created after zdsfs was mounted without the need to remount zdsfs. This is done by re-reading the VTOC with every readdir system call. To ensure a consistent VTOC state the DASD device is reserved for every VTOC read and released afterwards. Signed-off-by: Stefan Haberland <sth@linux.ibm.com> Reviewed-by: Jan Hoeppner <hoeppner@linux.ibm.com> Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
884 lines
25 KiB
C
884 lines
25 KiB
C
/**
|
|
* \file libzds.h
|
|
* This is the main header file for the internal library libzds.
|
|
* Please note that this library should currently only be used
|
|
* by programs in the s390-tools package. It is not yet meant
|
|
* for external use as interfaces and definitions may change
|
|
* without further notice.
|
|
*
|
|
* Copyright IBM Corp. 2013, 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.
|
|
*/
|
|
|
|
/**
|
|
* @mainpage
|
|
* The libzds is a s390-tools internal library for use with DASD
|
|
* devices in raw_track_access mode.
|
|
*
|
|
* The regular operation mode of the DASD device driver allows only to
|
|
* access ECKD DASDs that were formatted with a specific record
|
|
* layout. The raw access mode of the DASD device driver allows to
|
|
* access any kind of ECKD DASD, but requires the correct use of
|
|
* the DIRECT_IO interface and leaves the interpretation of the data
|
|
* format on these devices to the user.
|
|
*
|
|
* This library supports the use of raw DASD devices by providing
|
|
* functions that
|
|
* @li access the device with DIRECT_IO and the correct buffer alignment
|
|
* @li provide access to label and VTOC data on the device
|
|
* @li provide access to simple z/OS data set formats
|
|
* (physical sequential (PS) and partitioned data sets (PDS))
|
|
*
|
|
*
|
|
* @section interface_groups Library Interface
|
|
*
|
|
* @subsection interface_structures Data Structures
|
|
*
|
|
* The data structures provided by this library can be divided into
|
|
* two types: Structures that represent external hardware and software
|
|
* interfaces, and structures that are defined by libzds itself:
|
|
*
|
|
* @ref external_interfaces
|
|
*
|
|
* @ref libzds_data
|
|
*
|
|
*
|
|
* @subsection interface_functions Functions
|
|
*
|
|
* The functions provided by this library are divided into 5 categories:
|
|
* base, low, mid, and highlevel functions and helper functions.
|
|
*
|
|
* The lower the level, the less dependent are the functions on the data
|
|
* that is stored on the DASDs. The higher the level the more abstract
|
|
* are the implemented concepts.
|
|
*
|
|
* The base level functions are needed to setup the internal data
|
|
* structures which the other functions work on. Otherwise, he use of higher
|
|
* level functions does not require the use of low level functions.
|
|
* For example: To simply read data from a data set, you just need the
|
|
* base and high level functions and can ignore the low and mid level
|
|
* functions.
|
|
*
|
|
* \ref libzds_functions_base
|
|
*
|
|
* \ref libzds_functions_low
|
|
*
|
|
* \ref libzds_functions_mid
|
|
*
|
|
* \ref libzds_functions_high
|
|
*
|
|
* \ref libzds_functions_helper
|
|
*
|
|
*
|
|
* @section naming_scheme Naming Scheme
|
|
*
|
|
* All interface functions start with lzds_ for libzds (could be changed later
|
|
* but libzds_ is quite long). Next is the entity the function works on,
|
|
* for example
|
|
* @li @c lzds_zdsroot_...
|
|
* @li @c lzds_dasd_...
|
|
*
|
|
* So if you know what entity you want to work on, you know where to look.
|
|
*
|
|
* Then follows the operation (add, get, read, alloc, ...).
|
|
* There are several verbs that can mean 'access data'.
|
|
* As a guideline we define the following meaning for use in this library:
|
|
* @li read: Will result in data being read from a device
|
|
* @li get: Get a value from one of the internal structures
|
|
* @li extract: Use the internal data to create higher level data,
|
|
* e.g. use the VTOC information of a DASD to create data
|
|
* set structures
|
|
* @li alloc: Create and return a libzds data structure
|
|
*
|
|
* @note For every alloc function there shall be a matching free function to
|
|
* release the memory. However, often the structure is created in the
|
|
* context of a another structure, but when it is freed, that is done in
|
|
* its own context. For example:
|
|
* lzds_zdsroot_alloc_dasditerator is matched by lzds_dasditerator_free
|
|
*
|
|
* Finally the object of the operation, what you want to get or achieve,
|
|
* e.g lzds_ds_get_is_PDS
|
|
*
|
|
* For the parmeter list, the general rule is:
|
|
* The subject comes first, the object last, further parameters in between.
|
|
*/
|
|
|
|
|
|
#ifndef LIB_LIBZDS_H
|
|
/**
|
|
* @brief Watchdog for libzds.h inclusion.
|
|
*/
|
|
#define LIB_LIBZDS_H
|
|
|
|
#include "lib/util_base.h"
|
|
#include "lib/util_list.h"
|
|
#include "vtoc.h"
|
|
|
|
|
|
|
|
/**
|
|
* \defgroup external_interfaces External constants and structures.
|
|
* @{
|
|
* @brief These constants and structures are related to
|
|
* hardware and software interfaces that are specified outside of
|
|
* libzds.
|
|
*
|
|
* @li For a description of ECKD data formats see
|
|
* 'IBM 3990/9390 Storage Control Reference', Document Number GA32-0274-05
|
|
* @li For a description of VTOC entries see
|
|
* 'z/OS DFSMSdfp Advanced Services', Document Number SC26-7400-11
|
|
* @li For a description of physical sequential and partitioned data sets see
|
|
* 'z/OS DFSMS Using Data Sets', Document Number SC26-7410-11
|
|
* @li For a description of the Linux on System z DASD device driver see
|
|
* 'Device Drivers, Features, and Commands (kernel 3.7)',
|
|
* Document Number SC33-8411-18
|
|
*/
|
|
|
|
|
|
/**
|
|
* @brief The size of one raw track when read via the DASD device driver
|
|
* with raw_track_access.
|
|
*
|
|
* When reading from a DASD in raw_track_access mode, you need to
|
|
* align your I/O to multiples of this size.
|
|
*/
|
|
#define RAWTRACKSIZE 65536
|
|
|
|
/**
|
|
* @brief Maximum size of one record on a track
|
|
*
|
|
* This is the maximum size of a single record on a track. If a track contains
|
|
* multiple records, the additional overhead will cause the sum of these
|
|
* multiple records to be smaller than the biggest single record, so MAXRECSIZE
|
|
* is also the upper limit for user data that a single track can hold.
|
|
*/
|
|
#define MAXRECSIZE 56664
|
|
|
|
|
|
/**
|
|
* @brief Maximum number of extents a data set can hold.
|
|
*
|
|
* We do not handle extended format data sets so we can have a total of 16
|
|
* extents per dataset (3 in the f1 and 13 in the f3 label).
|
|
*/
|
|
#define MAXEXTENTS 16
|
|
|
|
|
|
/**
|
|
* @brief Maximum size of a data set name string (including one byte for
|
|
* 0-termination)
|
|
*/
|
|
#define MAXDSNAMELENGTH 45
|
|
|
|
/**
|
|
* @brief Maximum size of a partitioned data set member name string
|
|
* (including one byte for 0-termination)
|
|
*/
|
|
#define MEMBERNAMELENGTH 9
|
|
|
|
/**
|
|
* @brief The maximum number of volumes (devices) that a multi volume data
|
|
* set can span.
|
|
*/
|
|
#define MAXVOLUMESPERDS 59
|
|
|
|
/**
|
|
* @brief Eight bytes of 0xFF are used in several cases to designate the end of data.
|
|
*
|
|
*/
|
|
#define ENDTOKEN 0xFFFFFFFFFFFFFFFFULL
|
|
|
|
|
|
|
|
/**
|
|
* @brief This structure represents the count field in an ECKD record.
|
|
*/
|
|
struct eckd_count {
|
|
/** @brief record ID
|
|
*
|
|
* In general the record ID is defined as just a 5 byte field.
|
|
* The interpretation of these 5 bytes as a struct cchhb_t is a common
|
|
* convention, which we assume here as well.
|
|
*/
|
|
cchhb_t recid;
|
|
/** @brief key length */
|
|
unsigned char kl;
|
|
/** @brief data length */
|
|
unsigned short dl;
|
|
} __attribute__ ((packed));
|
|
|
|
/**
|
|
* @brief A generic structure to describe a data set control block (DSCB)
|
|
*
|
|
* The elements of the VTOC are called DSCBs. All DSCBs have in common that
|
|
* they have a size of 140 bytes, and byte 44 is the identifier that
|
|
* determines the type of DSCB.
|
|
*/
|
|
struct dscb {
|
|
/** @brief key area
|
|
*
|
|
* This part of the DSCB is usually stored in the key part of an
|
|
* ECKD record in the VTOC. The contents depends on the format.
|
|
*/
|
|
char key[44];
|
|
/** @brief Format identifier
|
|
*
|
|
* This identifier determines the data layout of the rest of the
|
|
* DSCB. In a format-x DSCB this field is called DSxFMTID.
|
|
* The identifiers for format-1 to format-9 are the respective
|
|
* EBCDIC characters '1' to '9' (0xf1 to 0xf9).
|
|
* An empty DSCB record (format-0 DSCB) contains 140 zeros, so
|
|
* here the format id is 0x00.
|
|
*/
|
|
char fmtid;
|
|
/** @brief The residual data part of the DSCB
|
|
*
|
|
* The contents depends on the format.
|
|
*/
|
|
char data[95];
|
|
} __attribute__ ((packed));
|
|
|
|
|
|
/**
|
|
* @brief This structure represents a segment descriptor word (SDW),
|
|
* record descriptor word (RDW) or block descriptor word (BDW).
|
|
*
|
|
* These are used to describe data set blocks and records.
|
|
* (see z/OS DFSMS Using Data Sets)
|
|
*/
|
|
struct segment_header {
|
|
/** @brief Is this an empty segment (valid for SDW) */
|
|
unsigned short nullsegment:1;
|
|
/** @brief Length of the segment */
|
|
unsigned short length:15;
|
|
/** @brief reserved */
|
|
unsigned char reserved1:6;
|
|
/** @brief Segment control code (valid for SDW)
|
|
*
|
|
* 0: logical record consists of just this segment,
|
|
* 1: first segment in the logical record,
|
|
* 2: last segment in the logical record,
|
|
* 3: intermediate in the logical record
|
|
*/
|
|
unsigned char position:2;
|
|
/** @brief reserved */
|
|
unsigned char reserved3:8;
|
|
} __attribute__ ((packed));
|
|
|
|
|
|
|
|
/**
|
|
* @brief The key length of a PDS directory member record.
|
|
*/
|
|
#define PDS_DIR_KL 8
|
|
/**
|
|
* @brief The data length of a PDS directory member record.
|
|
*/
|
|
#define PDS_DIR_DL 256
|
|
|
|
/**
|
|
* @brief This structure represents and entry in the PDS directory and
|
|
* describes a member of the data set.
|
|
*
|
|
* This structure represents only the fixed part of the member
|
|
* entry. The variable size of the user data part is determined
|
|
* by the entry user_data_count.
|
|
* (see z/OS DFSMS Using Data Sets)
|
|
*/
|
|
struct pds_member_entry {
|
|
/** @brief Member name */
|
|
char name[8];
|
|
/** @brief Start track of the member (relative to start of the PDS) */
|
|
unsigned short track;
|
|
/** @brief Start record of the member */
|
|
unsigned char record;
|
|
/** @brief Is this entry an alias for another entry? */
|
|
unsigned char is_alias:1;
|
|
/** @brief How many TTRN note lists are contained in the user data. */
|
|
unsigned char ttrn_count:2;
|
|
/** @brief The user_data_count value counts 'half words' i.e. shorts! */
|
|
unsigned char user_data_count:5;
|
|
} __attribute__ ((packed));
|
|
|
|
|
|
/** @} */ /* end of group hardware */
|
|
|
|
|
|
|
|
/**
|
|
* @defgroup libzds_data libzds data structures
|
|
* @{
|
|
* @brief These are the data structures used by the libzds API.
|
|
*
|
|
* For users of libzds these are opaque data structures and they have
|
|
* no dependency on the implementation details of these structures.
|
|
* All libzds interface functions work on pointers to these structures,
|
|
* so programs that use the library do not need to know them either.
|
|
* This prevents users from accessing the data in unsupported ways
|
|
* allows us to change the implementation without changing the
|
|
* interface.
|
|
*/
|
|
|
|
/**
|
|
* @struct zdsroot
|
|
* @brief The root of all device and data set information.
|
|
*
|
|
* Note that data sets do not belong to DASDs, as they
|
|
* may span over more than one DASD.
|
|
*/
|
|
struct zdsroot;
|
|
|
|
/**
|
|
* @struct raw_vtoc
|
|
* @brief The VTOC is a directory of data sets on one DASD
|
|
*
|
|
* As the VTOC is the data area on the DASD that describes all data sets,
|
|
* this library will often have to refer to the various records in the VTOC.
|
|
* To make this more efficient, we will read the whole VTOC once and identify
|
|
* all elements (DSCBs). The raw data of the VTOC tracks and the index to the
|
|
* DSCBs is stored.
|
|
*/
|
|
struct raw_vtoc {
|
|
/** @brief The raw track data */
|
|
char *rawdata;
|
|
/** @brief This size of the raw track data in bytes */
|
|
unsigned long long rawdatasize;
|
|
/** @brief An array with pointers to the various DSCBs in the rawdata */
|
|
char **vtocindex;
|
|
/** @brief Number of entries in the index */
|
|
unsigned int vtocindexcount;
|
|
/** @brief Number of records per VTOC track
|
|
*
|
|
* @note While the DS4DEVDT field in the format 4 DSCB names the number
|
|
* if DSCBs per VTOC track, we count the records, which is DS4DEVDT + 1
|
|
* for record 0.
|
|
*/
|
|
unsigned int vtoc_rec_per_track;
|
|
/** @brief The track number at which the vtoc begins on the DASD */
|
|
unsigned int vtoctrackoffset;
|
|
/** @brief Start record of VTOC.
|
|
*
|
|
* The rawdata contains full tracks. This is the number of the first
|
|
* record that actually belongs to the VTOC
|
|
*/
|
|
unsigned int vtocrecno;
|
|
/** @brief The DASD this vtoc was read from */
|
|
struct dasd *dasd;
|
|
/** @brief Detailed error messages in case of a problem */
|
|
struct errorlog *log;
|
|
};
|
|
|
|
/**
|
|
* @struct dasd
|
|
* @brief Represents one physical device, may have a vtoc
|
|
*/
|
|
struct dasd {
|
|
/** @brief List head used to store a list of DASDs in struct zdsroot */
|
|
struct util_list_node list;
|
|
/** @brief Name of the block device, e.g. /dev/dasde */
|
|
char *device;
|
|
/** @brief File descriptor for the block device.
|
|
*
|
|
* The device is kept open for as along as the library uses it.
|
|
* This lets the system know that the device is still in use.
|
|
*/
|
|
int inusefd;
|
|
/* @brief where to find the volume label */
|
|
unsigned int label_block;
|
|
/** @brief Device geometry. How many cylinders does the DASD have. */
|
|
unsigned int cylinders;
|
|
/** @brief Device geometry. How many heads does the DASD have. */
|
|
unsigned int heads;
|
|
/** @brief The VTOC data that has been read from this device */
|
|
struct raw_vtoc *rawvtoc;
|
|
/** @brief The volume label that has been read from this device */
|
|
volume_label_t *vlabel;
|
|
/** @brief Detailed error messages in case of a problem */
|
|
struct errorlog *log;
|
|
};
|
|
|
|
/**
|
|
* @struct dasditerator
|
|
* @brief Allows to iterate over all dasds in the zdsroot
|
|
*/
|
|
struct dasditerator;
|
|
|
|
/**
|
|
* @struct dasdhandle
|
|
* @brief Represents the state of a DASD device while it is in use.
|
|
*
|
|
* For applications that need to read data directly from a DASD device.
|
|
* The idea is to have an abstract handle for a DASD that is in
|
|
* use, similar to a FILE pointer
|
|
*/
|
|
struct dasdhandle;
|
|
|
|
/**
|
|
* @struct dscbiterator
|
|
* @brief allows to iterate over all DSCBs in a vtoc
|
|
*/
|
|
struct dscbiterator;
|
|
|
|
/**
|
|
* @struct dataset
|
|
* @brief The whole of one data set
|
|
*
|
|
* May refer to one or more dataset parts
|
|
* and may have a list of partitioned dataset members.
|
|
*/
|
|
struct dataset;
|
|
|
|
/**
|
|
* @struct dsiterator
|
|
* @brief Allows to iterate over all data sets in the zdsroot
|
|
*/
|
|
struct dsiterator;
|
|
|
|
/**
|
|
* @struct pdsmember
|
|
* @brief If a data set is a partitioned data set (PDS) it
|
|
* may have zero or more PDS members
|
|
*/
|
|
struct pdsmember;
|
|
|
|
/**
|
|
* @struct memberiterator
|
|
* @brief Allows to iterate over all members in the dataset
|
|
*/
|
|
struct memberiterator;
|
|
|
|
/**
|
|
* @struct dshandle
|
|
* @brief Represents the state of a data set while it is in use
|
|
*
|
|
* This state includes the I/O buffers used for reading,
|
|
* the position within the data set, options used for processing the data,
|
|
* etc. The idea is to have an abstract handle for a data set that is in
|
|
* use, similar to a FILE pointer.
|
|
*/
|
|
struct dshandle;
|
|
|
|
/**
|
|
* @struct error_log
|
|
* @brief A stack of error messages that are related to the last error
|
|
*/
|
|
struct errorlog;
|
|
|
|
/** @} */ /* end of group libzds_data */
|
|
|
|
|
|
|
|
|
|
/**
|
|
* @defgroup libzds_functions_base Base functions
|
|
* @{
|
|
* @brief These functions are basic setup functions which need to
|
|
* be used before any of the low, mid or high level functions
|
|
* can be used. These functions concern the allocation and
|
|
* initialization of the zdsroot and the basic handling of devices.
|
|
*/
|
|
|
|
/**
|
|
* @brief Allocate a new zdsroot structure.
|
|
*/
|
|
int lzds_zdsroot_alloc(struct zdsroot **root);
|
|
|
|
/**
|
|
* @brief Free the memory of the given zdsroot structure.
|
|
*/
|
|
void lzds_zdsroot_free(struct zdsroot *root);
|
|
|
|
/**
|
|
* @brief Add a DASD device to the zdsroot.
|
|
*/
|
|
int lzds_zdsroot_add_device(struct zdsroot *root, const char *devnode,
|
|
struct dasd **dasd);
|
|
/**
|
|
* @brief Get the errorlog.
|
|
*/
|
|
void lzds_dasd_get_errorlog(struct dasd *dasd, struct errorlog **log);
|
|
|
|
/**
|
|
* @brief Allocate index that allows to iterate through all DASDs
|
|
* stored in the root.
|
|
*/
|
|
int lzds_zdsroot_alloc_dasditerator(struct zdsroot *root,
|
|
struct dasditerator **it);
|
|
/**
|
|
* @brief Free the dasditerator structure.
|
|
*/
|
|
void lzds_dasditerator_free(struct dasditerator *it);
|
|
|
|
/**
|
|
* @brief Get the next dasd structure.
|
|
*/
|
|
int lzds_dasditerator_get_next_dasd(struct dasditerator *it,
|
|
struct dasd **dasd);
|
|
|
|
/**
|
|
* @brief Return the device node name that was used for this dasd.
|
|
*/
|
|
void lzds_dasd_get_device(struct dasd *dasd, char **device);
|
|
|
|
/**
|
|
* @brief Get the dasd structure that belongs to the given device.
|
|
*/
|
|
int lzds_zdsroot_get_dasd_by_node_name(struct zdsroot *root, const char *device,
|
|
struct dasd **dasd);
|
|
|
|
/**
|
|
* @brief Get the errorlog.
|
|
*/
|
|
void lzds_zdsroot_get_errorlog(struct zdsroot *root, struct errorlog **log);
|
|
|
|
int lzds_errorlog_fprint(struct errorlog *log, FILE *stream);
|
|
|
|
/** @} */ /* end of group libzds_functions_base */
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
* @defgroup libzds_functions_low Low level interface functions.
|
|
* @{
|
|
* @brief Very basic functions, should all work on every kind DASD.
|
|
*
|
|
* These functions give access to the data on a DASD on a very
|
|
* low abstraction level. They do not dependent on the data on the
|
|
* device itself.
|
|
*
|
|
*/
|
|
|
|
/**
|
|
* @brief Based on the dasd device geometry, compute a track number from a
|
|
* given cchh_t (cylinder, head) address value.
|
|
*/
|
|
void lzds_dasd_cchh2trk(struct dasd *dasd, cchh_t *p, unsigned int *track);
|
|
|
|
/**
|
|
* @brief Get the number of cylinders that this DASD has.
|
|
*/
|
|
void lzds_dasd_get_cylinders(struct dasd *dasd, unsigned int *cylinders);
|
|
|
|
/**
|
|
* @brief Get the number of heads, that a cylinder of this DASD has.
|
|
*/
|
|
void lzds_dasd_get_heads(struct dasd *dasd, unsigned int *heads);
|
|
|
|
/**
|
|
* @brief Allocate a new dasd context structure for given data set.
|
|
*/
|
|
int lzds_dasd_alloc_dasdhandle(struct dasd *dasd, struct dasdhandle **dasdh);
|
|
|
|
/**
|
|
* @brief Free memory that was allocated for a dasdhandle.
|
|
*/
|
|
void lzds_dasdhandle_free(struct dasdhandle *dasdh);
|
|
|
|
/**
|
|
* @brief This makes the dasd context ready for read operations.
|
|
*/
|
|
int lzds_dasdhandle_open(struct dasdhandle *dasdh);
|
|
|
|
/**
|
|
* @brief This closes the file descriptor connected with the dasdhandle.
|
|
*/
|
|
int lzds_dasdhandle_close(struct dasdhandle *dasdh);
|
|
|
|
/**
|
|
* @brief Read raw tracks from the dasdhandle.
|
|
*/
|
|
int lzds_dasdhandle_read_tracks_to_buffer(struct dasdhandle *dasdh,
|
|
unsigned int starttrck,
|
|
unsigned int endtrck,
|
|
char *trackdata);
|
|
|
|
/** @} */ /* end of group libzds_functions_low */
|
|
|
|
|
|
|
|
/**
|
|
* @defgroup libzds_functions_mid Mid level interface functions
|
|
* @{
|
|
* @brief Functions that give access to low level structures like VTOC
|
|
* records.
|
|
*
|
|
* These functions give access to and rely on the meta data stored on
|
|
* the DASD, in particular the VTOC.
|
|
* These functions take the structure of the data on the
|
|
* device into account, so they may fail if this data is not
|
|
* correct (e.g. if the VTOC is broken).
|
|
*
|
|
* @todo The interface of the mid level functions is not properly structured yet.
|
|
*
|
|
*/
|
|
|
|
/**
|
|
* @brief Read the volume label from device. The data as stored as
|
|
* part of the struct dasd.
|
|
*/
|
|
int lzds_dasd_read_vlabel(struct dasd *dasd);
|
|
|
|
/**
|
|
* @brief Get the previously read volume label data..
|
|
*/
|
|
int lzds_dasd_get_vlabel(struct dasd *dasd, struct volume_label **vlabel);
|
|
|
|
/**
|
|
* @brief Read the vtoc data from device. The data as stored as part
|
|
* of the struct dasd.
|
|
*/
|
|
int lzds_dasd_read_rawvtoc(struct dasd *dasd, struct raw_vtoc *vtoc);
|
|
|
|
/**
|
|
* @brief Read the vtoc data from device. The data as stored as part
|
|
* of the struct dasd.
|
|
*/
|
|
int lzds_dasd_alloc_rawvtoc(struct dasd *dasd);
|
|
|
|
/**
|
|
* @brief Get the previously read raw_vtoc data.
|
|
*/
|
|
int lzds_dasd_get_rawvtoc(struct dasd *dasd, struct raw_vtoc **vtoc);
|
|
|
|
/**
|
|
* @brief Allocate index that allows to iterate through all DSCB
|
|
* records stored in the raw_vtoc.
|
|
*/
|
|
int lzds_raw_vtoc_alloc_dscbiterator(struct raw_vtoc *rawvtoc,
|
|
struct dscbiterator **it);
|
|
/**
|
|
* @brief Free the iterators memory
|
|
*/
|
|
void lzds_dscbiterator_free(struct dscbiterator *it);
|
|
|
|
/**
|
|
* @brief Get the next DSCB in the VTOC.
|
|
*/
|
|
int lzds_dscbiterator_get_next_dscb(struct dscbiterator *it,
|
|
struct dscb **dscb);
|
|
/**
|
|
* @brief Find and get a specific DSCB record by its cylinder, head
|
|
* and record address (cchhb_t)
|
|
*/
|
|
int lzds_raw_vtoc_get_dscb_from_cchhb(struct raw_vtoc *rv, cchhb_t *p,
|
|
struct dscb **dscb);
|
|
|
|
/** @} */ /* end of group libzds_functions_mid */
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
* @defgroup libzds_functions_high High level interface functions
|
|
* @{
|
|
* @brief These functions give access to the data on a DASD on a
|
|
* high abstraction level.
|
|
*
|
|
* These functions abstract away most of the low level details.
|
|
* They give access to the user data stored on the DASD using abstract
|
|
* concepts like 'data set' without requiring the user
|
|
* to do any low level analysis.
|
|
*/
|
|
|
|
/**
|
|
* @brief Search zdsroot for a specific data set.
|
|
*/
|
|
int lzds_zdsroot_find_dataset(struct zdsroot *root, const char *name,
|
|
struct dataset **ds);
|
|
|
|
/**
|
|
* @brief Allocate an iterator that will allow to iterate through all
|
|
* datasets on the index.
|
|
*/
|
|
int lzds_zdsroot_alloc_dsiterator(struct zdsroot *zdsroot,
|
|
struct dsiterator **it);
|
|
/**
|
|
* @brief Free memory of the given data set iterator.
|
|
*/
|
|
void lzds_dsiterator_free(struct dsiterator *it);
|
|
|
|
/**
|
|
* @brief Return the next data set the iterator points to.
|
|
*/
|
|
int lzds_dsiterator_get_next_dataset(struct dsiterator *it,
|
|
struct dataset **ds);
|
|
|
|
/**
|
|
* @brief Get the 'partitioned data set' status of a data set?
|
|
*/
|
|
void lzds_dataset_get_is_PDS(struct dataset *ds, int *ispds);
|
|
|
|
/**
|
|
* @brief Are all parts of a multi volume data set available?
|
|
*/
|
|
void lzds_dataset_get_is_complete(struct dataset *ds, int *iscomplete);
|
|
|
|
/**
|
|
* @brief Can the data set be opened and read with this library?
|
|
*/
|
|
void lzds_dataset_get_is_supported(struct dataset *ds, int *issupported);
|
|
|
|
/**
|
|
* @brief Get the name of a dataset as ASCII string.
|
|
*/
|
|
void lzds_dataset_get_name(struct dataset *ds, char **name);
|
|
|
|
/**
|
|
* @brief Get the format 1 DSCB for a data set. In case of a multi volume
|
|
* data set it returns the DSCB of the first volume.
|
|
*/
|
|
void lzds_dataset_get_format1_dscb(struct dataset *ds, format1_label_t **f1);
|
|
|
|
/**
|
|
* @brief Search the data set for a given member name and if a matching
|
|
* member is found return a struct pdsmember.
|
|
*/
|
|
int lzds_dataset_get_member_by_name(struct dataset *ds, char *membername,
|
|
struct pdsmember **member);
|
|
|
|
/**
|
|
* @brief Allocate an iterator that will allow to iterate through all members
|
|
* on a datasets.
|
|
*/
|
|
int lzds_dataset_alloc_memberiterator(struct dataset *ds,
|
|
struct memberiterator **it);
|
|
|
|
/**
|
|
* @brief Free memory of the given member iterator.
|
|
*/
|
|
void lzds_memberiterator_free(struct memberiterator *it);
|
|
|
|
/**
|
|
* @brief Return the next data set member the iterator points to.
|
|
*/
|
|
int lzds_memberiterator_get_next_member(struct memberiterator *it,
|
|
struct pdsmember **member);
|
|
|
|
/**
|
|
* @brief Allocate a new data set context structure for given data set.
|
|
*/
|
|
int lzds_dataset_alloc_dshandle(struct dataset *ds,
|
|
unsigned int tracks_per_frame,
|
|
struct dshandle **dsh);
|
|
|
|
/**
|
|
* @brief Free the memory of the given dshandle structure.
|
|
*/
|
|
void lzds_dshandle_free(struct dshandle *dsh);
|
|
|
|
/**
|
|
* @brief If the dsh points to a partitioned data set, this function will
|
|
* set which member of that PDS is read via the dsh.
|
|
*/
|
|
int lzds_dshandle_set_member(struct dshandle *dsh, char *membername);
|
|
|
|
/**
|
|
* @brief Read out the member pointer that has been set on this dshandle.
|
|
*/
|
|
void lzds_dshandle_get_member(struct dshandle *dsh,
|
|
struct pdsmember **member);
|
|
|
|
/**
|
|
* @brief Set the flag that causes the library to keep the record descriptor
|
|
* word (RDW) of variable records in the data stream.
|
|
*/
|
|
int lzds_dshandle_set_keepRDW(struct dshandle *dsh, int keepRDW);
|
|
|
|
/**
|
|
* @brief Read out the current setting of the RDW flag.
|
|
*/
|
|
void lzds_dshandle_get_keepRDW(struct dshandle *dsh, int *keepRDW);
|
|
|
|
/**
|
|
* @brief Prepares the dsh and the related devices for read operations.
|
|
*/
|
|
int lzds_dshandle_open(struct dshandle *dsh);
|
|
|
|
/**
|
|
* @brief Matching close operation for the data set context.
|
|
*/
|
|
void lzds_dshandle_close(struct dshandle *dsh);
|
|
|
|
/**
|
|
* @brief Read data from the data set to which the dsh points.
|
|
*/
|
|
int lzds_dshandle_read(struct dshandle *dsh, char *buf,
|
|
size_t size, ssize_t *rcsize);
|
|
|
|
/**
|
|
* @brief Move buffer position of dsh to offset.
|
|
*/
|
|
int lzds_dshandle_lseek(struct dshandle *dsh, long long offset,
|
|
long long *rcoffset);
|
|
|
|
/**
|
|
* @brief Get the current buffer position.
|
|
*/
|
|
void lzds_dshandle_get_offset(struct dshandle *dsh, long long *offset);
|
|
|
|
/**
|
|
* @brief Get the errorlog.
|
|
*/
|
|
void lzds_dshandle_get_errorlog(struct dshandle *dsh, struct errorlog **log);
|
|
|
|
/**
|
|
* @brief Set an upper limit for the seek buffer.
|
|
*/
|
|
int lzds_dshandle_set_seekbuffer(struct dshandle *dsh,
|
|
unsigned long long seek_buffer_size);
|
|
|
|
/**
|
|
* @brief Get the size of the data set in number of tracks (sum of all extents).
|
|
*/
|
|
void lzds_dataset_get_size_in_tracks(struct dataset *ds,
|
|
unsigned long long *tracks);
|
|
|
|
/**
|
|
* @brief Get the name of a partitioned dataset member.
|
|
*/
|
|
void lzds_pdsmember_get_name(struct pdsmember *member, char **name);
|
|
|
|
|
|
/**
|
|
* @brief Extract the data set information from the rawvtoc stored in the
|
|
* dasd and add it to the list of data sets stored in the zdsroot.
|
|
*/
|
|
int lzds_zdsroot_extract_datasets_from_dasd(struct zdsroot *root,
|
|
struct dasd *dasd);
|
|
|
|
|
|
void lzds_dslist_free(struct zdsroot *root);
|
|
|
|
|
|
/** @} */ /* end of group libzds_functions_high */
|
|
|
|
|
|
|
|
/**
|
|
* @defgroup libzds_functions_helper Helper functions
|
|
* @{
|
|
*
|
|
* @brief These functions do not fit in the hierarchy of the other
|
|
* libzds functions, but are useful helpers.
|
|
*/
|
|
|
|
/**
|
|
* @brief Translates a DS1RECFM byte to a recfm format string.
|
|
*/
|
|
void lzds_DS1RECFM_to_recfm(char DS1RECFM, char *buffer);
|
|
|
|
|
|
int lzds_analyse_open_count(struct zdsroot *root, int warn);
|
|
|
|
/** @} */ /* end of group libzds_functions_helper */
|
|
|
|
|
|
|
|
|
|
#endif /* LIB_LIBZDS_H */
|