/* -*- mode:c; c-file-style:"k&r"; c-basic-offset: 4; tab-width:4; indent-tabs-mode:nil; mode:auto-fill; fill-column:78; -*- */
/* vim: set ts=4 sw=4 et tw=78 fo=cqt wm=0: */
/* Copyright (C) 2014 Stony Brook University
This file is part of Graphene Library OS.
Graphene Library OS is free software: you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public License
as published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
Graphene Library OS is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see . */
/*
* shim_handle.h
*
* Definitions of types and functions for file/handle bookkeeping.
*/
#ifndef _SHIM_HANDLE_H_
#define _SHIM_HANDLE_H_
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
/* start definition of shim handle */
enum shim_handle_type {
TYPE_FILE,
TYPE_DEV,
TYPE_PIPE,
TYPE_SOCK,
TYPE_DIR,
TYPE_SHM,
TYPE_SEM,
TYPE_MSG,
TYPE_FUTEX,
TYPE_STR,
TYPE_EPOLL,
};
struct shim_handle;
struct shim_thread;
struct shim_vma;
enum shim_file_type {
FILE_UNKNOWN,
FILE_REGULAR,
FILE_DIR,
FILE_DEV,
FILE_TTY,
};
struct shim_file_data {
LOCKTYPE lock;
struct atomic_int version;
bool queried;
enum shim_file_type type;
mode_t mode;
struct atomic_int size;
struct shim_qstr host_uri;
unsigned long atime;
unsigned long mtime;
unsigned long ctime;
unsigned long nlink;
};
struct shim_file_handle {
unsigned int version;
struct shim_file_data * data;
enum shim_file_type type;
uint64_t size;
uint64_t marker;
enum { FILEBUF_MAP, FILEBUF_NONE } buf_type;
uint64_t mapsize;
uint64_t mapoffset;
void * mapbuf;
};
#define FILE_HANDLE_DATA(hdl) ((hdl)->info.file.data)
#define FILE_DENTRY_DATA(dent) ((struct shim_file_data *) (dent)->data)
struct shim_dev_ops {
/* open: provide a filename relative to the mount point and flags,
modify the shim handle */
int (*open) (struct shim_handle * hdl, const char * name, int flags);
/* close: clean up the file state inside the handle */
int (*close) (struct shim_handle * hdl);
/* read: the content from the file opened as handle */
int (*read) (struct shim_handle * hdl, void * buf, size_t count);
/* write: the content from the file opened as handle */
int (*write) (struct shim_handle * hdl, const void * buf, size_t count);
/* flush: flush out user buffer */
int (*flush) (struct shim_handle * hdl);
/* seek: the content from the file opened as handle */
int (*seek) (struct shim_handle * hdl, off_t offset, int wence);
int (*truncate) (struct shim_handle * hdl, uint64_t len);
int (*mode) (const char * name, mode_t * mode);
/* stat, hstat: get status of the file */
int (*stat) (const char * name, struct stat * buf);
int (*hstat) (struct shim_handle * hdl, struct stat * buf);
};
struct shim_dev_handle {
struct shim_dev_ops dev_ops;
};
struct shim_pipe_handle {
#if USE_SIMPLE_PIPE == 1
struct shim_handle * pair;
#else
IDTYPE pipeid;
#endif
};
#define SOCK_STREAM 1
#define SOCK_DGRAM 2
#define SOCK_NONBLOCK 04000
#define SOCK_CLOEXEC 02000000
#define SOL_TCP 6
#define PF_LOCAL 1
#define PF_UNIX PF_LOCAL
#define PF_FILE PF_LOCAL
#define PF_INET 2
#define PF_INET6 10
#define AF_UNIX PF_UNIX
#define AF_INET PF_INET
#define AF_INET6 PF_INET6
enum shim_sock_state {
SOCK_CREATED,
SOCK_BOUND,
SOCK_CONNECTED,
SOCK_BOUNDCONNECTED,
SOCK_LISTENED,
SOCK_ACCEPTED,
SOCK_SHUTDOWN,
};
struct shim_unix_data {
unsigned int pipeid;
};
struct shim_sock_handle {
int domain;
int sock_type;
int protocol;
int error;
enum shim_sock_state sock_state;
union shim_sock_addr {
// INET addr
struct {
struct addr_inet {
unsigned short port;
unsigned short ext_port;
union {
struct in_addr v4;
struct in6_addr v6;
} addr;
} bind, conn;
} in;
// UNIX addr
struct addr_unix {
struct shim_dentry * dentry;
unsigned int pipeid;
struct shim_unix_data * data;
} un;
} addr;
struct shim_sock_option {
struct shim_sock_option * next;
int level;
int optname;
int optlen;
char optval[];
} * pending_options;
};
struct shim_dirent {
struct shim_dirent * next;
unsigned long ino; /* Inode number */
unsigned char type;
char name[]; /* File name (null-terminated) */
};
struct shim_dir_handle {
int offset;
struct shim_dentry * dotdot;
struct shim_dentry * dot;
struct shim_dentry ** buf;
struct shim_dentry ** ptr;
};
struct shim_shm_handle {
/* XXX: need to implement */
void * __reserved;
};
struct msg_type;
struct msg_item;
struct msg_client;
#define MAX_SYSV_CLIENTS 32
DEFINE_LIST(shim_msg_handle);
struct shim_msg_handle {
unsigned long msqkey; /* msg queue key from user */
IDTYPE msqid; /* msg queue identifier */
bool owned; /* owned by current process */
struct shim_ipc_info * owner;
LEASETYPE lease;
int perm; /* access permissions */
bool deleted; /* marking the queue deleted */
int nmsgs; /* number of msgs */
int currentsize; /* current size in bytes */
struct msg_qobj * queue;
int queuesize;
int queueused;
struct msg_qobj * freed;
PAL_HANDLE event; /* event for waiting */
int ntypes;
int maxtypes;
struct msg_type * types;
struct sysv_score scores[MAX_SYSV_CLIENTS];
LIST_TYPE(shim_msg_handle) list;
LIST_TYPE(shim_msg_handle) key_hlist;
LIST_TYPE(shim_msg_handle) qid_hlist;
};
struct sem_objs;
DEFINE_LIST(shim_sem_handle);
struct shim_sem_handle {
unsigned long semkey;
IDTYPE semid;
bool owned;
struct shim_ipc_info * owner;
LEASETYPE lease;
int perm;
bool deleted;
PAL_HANDLE event;
int nsems;
struct sem_obj * sems;
int nreqs;
struct sysv_score scores[MAX_SYSV_CLIENTS];
LISTP_TYPE(sem_ops) migrated;
LIST_TYPE(shim_sem_handle) list;
LIST_TYPE(shim_sem_handle) key_hlist;
LIST_TYPE(shim_sem_handle) sid_hlist;
};
DEFINE_LIST(futex_waiter);
DEFINE_LISTP(futex_waiter);
DEFINE_LIST(shim_futex_handle);
struct shim_futex_handle {
unsigned int * uaddr;
LISTP_TYPE(futex_waiter) waiters;
struct shim_vma * vma;
LIST_TYPE(shim_futex_handle) list;
};
struct shim_str_data {
REFTYPE ref_count;
char * str;
size_t len;
size_t buf_size;
bool dirty;
int (*update) (struct shim_handle * hdl);
int (*modify) (struct shim_handle * hdl);
};
struct shim_str_handle {
struct shim_str_data * data; /* inode is stored in dentry, too.
store pointer here for efficiency */
char * ptr;
};
DEFINE_LIST(shim_epoll_fd);
DEFINE_LISTP(shim_epoll_fd);
struct shim_epoll_handle {
int maxfds;
int nfds;
LISTP_TYPE(shim_epoll_fd) fds;
FDTYPE * pal_fds;
PAL_HANDLE * pal_handles;
int npals;
int nread;
int nwaiters;
AEVENTTYPE event;
};
struct shim_mount;
struct shim_qstr;
struct shim_dentry;
/* The epolls list links to the back field of the shim_epoll_fd structure
*/
struct shim_handle {
enum shim_handle_type type;
REFTYPE ref_count;
char fs_type[8];
struct shim_mount * fs;
struct shim_qstr path;
struct shim_dentry * dentry;
LISTP_TYPE(shim_epoll_fd) epolls;
struct shim_qstr uri; /* URI representing this handle, it is not
* necessary to be set. */
PAL_HANDLE pal_handle;
union {
struct shim_file_handle file;
struct shim_dev_handle dev;
struct shim_pipe_handle pipe;
struct shim_sock_handle sock;
struct shim_dir_handle dir;
struct shim_shm_handle shm;
struct shim_msg_handle msg;
struct shim_sem_handle sem;
struct shim_futex_handle futex;
struct shim_str_handle str;
struct shim_epoll_handle epoll;
} info;
int flags;
int acc_mode;
IDTYPE owner;
REFTYPE opened;
LOCKTYPE lock;
};
/* allocating / manage handle */
struct shim_handle * get_new_handle (void);
void flush_handle (struct shim_handle * hdl);
void open_handle (struct shim_handle * hdl);
void close_handle (struct shim_handle * hdl);
void get_handle (struct shim_handle * hdl);
void put_handle (struct shim_handle * hdl);
/* file descriptor table */
struct shim_fd_handle {
FDTYPE vfd; /* virtual file descriptor */
int flags; /* file descriptor flags, only FD_CLOEXEC */
struct shim_handle * handle;
};
#define MAX_MAX_FDS (65536)
#define DEFAULT_MAX_FDS (1024)
extern unsigned int max_fds;
struct shim_handle_map {
/* the top of created file descriptors */
FDTYPE fd_size;
FDTYPE fd_top;
/* refrence count and lock */
REFTYPE ref_count;
LOCKTYPE lock;
/* An array of file descriptor belong to this mapping */
struct shim_fd_handle ** map;
};
/* allocating file descriptors */
#define FD_NULL ((FDTYPE) -1)
#define HANDLE_ALLOCATED(fd_handle) ((fd_handle) && (fd_handle)->vfd != FD_NULL)
struct shim_handle * __get_fd_handle (FDTYPE fd, int * flags,
struct shim_handle_map * map);
struct shim_handle * get_fd_handle (FDTYPE fd, int * flags,
struct shim_handle_map * map);
int set_new_fd_handle (struct shim_handle * hdl, int flags,
struct shim_handle_map * map);
int set_new_fd_handle_by_fd (FDTYPE fd, struct shim_handle * hdl,
int flags, struct shim_handle_map * map);
struct shim_handle *
__detach_fd_handle (struct shim_fd_handle * fd, int * flags,
struct shim_handle_map * map);
struct shim_handle * detach_fd_handle (FDTYPE fd, int * flags,
struct shim_handle_map * map);
/* manage handle mapping */
int dup_handle_map (struct shim_handle_map ** new_map,
struct shim_handle_map * old_map);
int flush_handle_map (struct shim_handle_map * map);
void get_handle_map (struct shim_handle_map * map);
void put_handle_map (struct shim_handle_map * map);
int walk_handle_map (int (*callback) (struct shim_fd_handle *,
struct shim_handle_map *, void *),
struct shim_handle_map * map, void * arg);
int init_handle (void);
int init_important_handles (void);
size_t get_file_size (struct shim_handle * file);
int do_handle_read (struct shim_handle * hdl, void * buf, int count);
int do_handle_write (struct shim_handle * hdl, const void * buf, int count);
#endif /* _SHIM_HANDLE_H_ */