cw(4)

NAME
cw - Clockwise driver

SYNOPSIS
#include <$CW/h/cwif.h>

CONFIG
The Clockwise driver makes available dynamic partitions (a set of dynamic partition blocks, possible allocated on a number of disks) to applications or file systems. Dynamic partitions can be scheduled by associating a QualityofService contract on an opened dynamic partition. Dynamic partitions can be accessed through its block or character device (e.g. /dev/cw_dir/b_usr0 or /dev/cw_dir/c_StarWars1.mpg). Block devices are typically used for EXT2 file system storage, and character devices are typically used for streamed I/O storage (such as an MPEG movie). Currently only character devices support QoS settings and a-synchronous transfers.

DESCRIPTION
The Clockwise driver is behaves much like a real disk driver. It supports open, close, read and write functionality. In addition, there are some ioctl's specific for Clockwise.

CW_ADDDISK
    Add a disk to Clockwise. This call needs to be performed prior to starting Clockwise. This call expects the following parameters:
        #define CW_MAXDTYPE 16
        typedef struct {
          char   add_dtype[CW_MAXDTYPE];
          kdev_t add_rdev;
        } cwadddisk_t;
    Here add_dtype represents the type of the disk (e.g. ST19101W) and add_rdev represents the block device number of the underlying disk driver.

CW_GO
    Inform Clockwise to start executing. All superblocks are read from disk and verified. This function does not need a parameter.

CW_NEWDP
    Create an empty dynamic partition on a set of disks. This parameter consumes the following parameters:
        typedef struct {
        #define CWMAXDPNAME 256
          char     re_dpname[CWMAXDPNAME];
          uint32_t re_nb;
          uint32_t re_bpd;
          uint32_t re_dbmhi;
          uint32_t re_dbmlo;
          uint32_t re_bnum;
        } cwreserve_t;
    The parameter re_dpname specifies the name of the dynamic partition to allocate. If the name is already in use, an error is returned. The parameters re_nb, re_bpd and re_bnum specify the number of dynamic partition blocks, the number of dynamic partition blocks per disk to allocate and the starting block number to allocate. Finally, the parameters re_dbmhi and re_dbmlo specify which logical disks to use during the allocation. This call returns the allocated dynamic partition number.

CW_DIE
    Inform Clockwise to stop executing. If there are open references to Clockwise (e.g. a file system is still mounted), this call fails. This call has no parameters.

CW_QOS
    Associate a set of QualityofService parameters with an opened dynamic partition. Clockwise executes a schedulability analysis with these parameters and when successful, the application is certain that all its deadlines are met. When there are insufficient resources available, an error indicating so is returned. The call takes the following parameters:
        typedef struct {
          uint32_t qos_bw;
          uint32_t qos_bs;
          uint32_t qos_bnum;
          uint32_t qos_nb;
          Time_t   qos_start;
          Time_t   qos_duration;
        } cwqos_t;
    The parameter qos_bw represents the requested bandwidth in bytes per second. The parameter qos_bs represents the requested block size. The period is determined through these two parameters. The parameters qos_bnum and qos_nb represent the range on the dynamic partition that needs real-time service. The last two parameters qos_start and qos_duration represent when the real-time service is required. Multiple QoS requests per dynamic partitions are allowed, but only a single QoS value can be associated per dynamic partition per disk (so, when a dynamic partition is distributed on two disk, each disk can have a different QoS value).

CW_GEOM
    Download a set of geometry parameters into Clockwise. These parameters describe the particulars of a specified disk. This call expects the following parameters:
        #define NUMZONES    20
        #define CW_MAXDTYPE 16
        typedef struct {
          char	     ge_dtype[CW_MAXDTYPE];
          uint32_t   ge_rpm;
          uint32_t   ge_nheads;
          uint32_t   ge_ncyls;
          int        ge_nzones;
          struct {
            uint32_t gez_start;
            uint32_t gez_spt;
            uint32_t gez_ntracks;
          } ge_zones[NUMZONES];
        } cwgeometry_t;
    The disk that is described by this data structure is named by the variable ge_dtype. It rotates with a speed of ge_rpm rotations per minute, it consists of ge_nheads, it has ge_ncyls number of cylinders, and the disk has ge_nzones zones. For each the zones (with a maximum of NUMZONES), the parameter gez_start defines the start sector on disk, the parameters gez_spt defines the number of sectors per track for that zone, and the parameter gez_ntracks defines the number of tracks in that zone.

CW_SEEKTIME
    Downloads a seek performance table into Clockwise for a specific disk. This call expects the following parameters:
        #define CW_MAXDTYPE 16
        typedef struct {
          uint32_t   se_nt;
          Time_t     se_t;
        } cwsetime_t;
        typedef struct {
          char       st_dtype[CW_MAXDTYPE];
          int        st_ne;
          cwsetime_t st_e[1];
        } cwseektimes_t;
    The seek table that is described by the above parameters is described by the variable: st_dtype. For each measured seek value, an entry of type cwsetime_t is included in the data structure cwseektimes_t. The parameter st_ne describes the number of measured seek value. The parameter se_nt defines the number of tracks over which a seek is performed. The parameter se_t describes the time it takes to perform such a seek operation. The seek performance table is used to determine the service times when an application requests real-time performance.

CW_IORTIME, CW_IOWTIME
    Download disk read and write performance tables into Clockwise. These calls use the following parameters:
        #define CW_MAXDTYPE 16
        typedef struct {
          uint32_t   io_bs;
          Time_t     io_t;
        } cwiotime_t;
        typedef struct {
          char       iot_dtype[CW_MAXDTYPE];
          int        iot_zone;
          int        iot_ne;
          cwiotime_t iot_e[1];
        } cwiotimes_t;
    The I/O performance table that is described by the above parameters is described by the variable: st_dtype. The zone number for which the performance tables are valid are described by the parameter iot_zone. For each measured value, iot_e describes how long (io_t) reading or writing a block of size io_bs takes. The number of such entries is described by the parameter iot_ne. The I/O performance tables are used to determine the service times when an application requests real-time performance.

CW_INODE(dp)
    This call returns the inode of a dynamic partition with number dp. The call returns a data structure with the following fields for each allocated dynamic partition block:
        typedef struct {
          uint32_t i_ldisk;
          uint32_t i_daddr;
        } cwdinode_t;
    For each allocated disk block, the parameter i_ldisk is the logical disk ID, and the parameter i_daddr is the physical disk address of the first sector of the dynamic partition block. The calling application must make sure that the presented buffer is large enough to hold the data. By reading from dynamic partition 255 information can be obtained on the sizes of the inodes. When reading this dynamic partition, Clockwise returns data structures that are formatted as follows:
        #define CWMAXDPNAME 256
        #define CW_FTMAGIC  0x03031988
        #define CW_FTBUSY   0x23051996
        typedef struct {
          char     ft_name[CWMAXDPNAME];
          uint64_t ft_fsize;
          uint32_t ft_iaddr;
          uint32_t ft_isize;
          uint32_t ft_magic;
          uint32_t ft_idisk;
          uint32_t ft_type;
        } cwftabentry_t;
    Here, ft_name is the name of the dynamic partition. The parameter ft_fsize is the size of the dynamic partition in bytes. The disk address of the inode is given by the parameters ft_idisk and ft_iaddr for the logical disk number and the disk address of the inode. The parameter ft_isize shows the size of the inode in bytes. The parameter ft_magic show if the dynamic partition is being created (CW_FTBUSY), or simply exists (CW_FTMAGIC). The type parameter is currently unused.

CW_RELEASE
    Release a read or write request in an a-synchronous manner. Note that for this call the associated file needs to be opened with the O_NDELAY flag set. The results of the call can be picked up by calling read(2) or write(2) with the same buffer address as below. The status of the call can be polled with select(2).
        typedef enum { CWRead, CWWrite } cwcmd_t;
        typedef struct {
          cwcmd_t rel_rw;
          uint8_t *rel_buf;
          size_t  rel_size;
          loff_t  rel_offs;
        } cwrelease_t;
    To release a request, the above data structure describes the specifics of the request. The parameter rel_rw specifies a read or write request. The parameter rel_buf presents the buffer address to be used. Note that this buffer needs to be locked in memory (see mlock(2)). If the buffer is not locked, Clockwise tries to lock the buffer. If this locking fails, Clockwise returns an error. The size of the buffer is given by rel_size and the offset in the dynamic partition is given by rel_offs. Note that when picking up the results of the request, the file pointer needs to be set to this offset. For large dynamic partition (i.e. larger than 2GB), use llseek(2) to set the file pointer.

CW_BSIZE
    Return the used block size in sectors of 512 bytes. This call expects a buffer of size uint32_t.

CW_RMDP(dp)
    Remove a dynamic partition, which is identified by the parameter dp. This call also frees up all allocated disk space for the dynamic partition. There are no parameters to this call.

CW_GETINFO
    This call returns a number of basic Clockwise parameters. The following data structure is made available:
        #define NUMDISKS    64
        #define CW_MAXDTYPE 16
        typedef struct {
          uint32_t   info_fdisk;
          uint32_t   info_ftab;
          struct {
            char     ipd_dtype[CW_MAXDTYPE];
            uint32_t ipd_blocksz;
            uint32_t ipd_nblocks;
            kdev_t   ipd_kdev;
            uint32_t ipd_ldisk;
          } info_pd[NUMDISKS];
        } cwinfo_t;
    The parameters info_fdisk and info_ftab identify the location of the dynamic partition table. This table lists for all available dynamic partitions the address and size of the inode (basically the cwftabentry_t data structure -- see above). For all disks that are available, the name of the disk type is given by ipd_dtype, the used block size (in number of 512 byte sectors) is represented by ipd_blocksz, the number of dynamic partition blocks on disk is given by ipd_nblocks, the major and minor device number of the actual driver and disk is given by ipd_kdev and the logical disk identification is given by ipd_ldisk.

CW_MOVE
    Move one or more dynamic partition blocks to a different location. This call expects the following data structure:
        typedef struct {
          loff_t   mv_offs;
          uint32_t mv_size;
          uint32_t mv_ldisk;
          uint32_t mv_daddr;
        } cwmove_t;
    Here mv_offs represents the starting offset in bytes of the first dynamic partition block that needs to be moved (the offset is round down to the dynamic partition block), and mv_size represents the number of bytes that need to be moved (again, round up to the nearest dynamic partition block size). The parameters mv_ldisk and mv_daddr represent the destination address of the blocks. If the requested address cannot be allocated because the block is already in use, this call fails. Note that this call is not yet implemented.

CW_GETFTAB
    Returns the cwftabentry_t for the currently opened dynamic partition (see above).

CW_TRUNCATE
    Truncates the current dynamic partition to the specified dynamic partition size. This call expects a uint64_t that represents the new file size in bytes. If the dynamic partition size is smaller or equal to the requested size, this call is a no-op.

BUGS
Many, probably.

FILES
/dev/clockwise: Clockwise raw device.
/dev/cw_dir/*: individual dynamic partitions.

SEE ALSO
filesystems(5)