Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ipc-sockets #21

Merged
merged 51 commits into from
Sep 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
41a0679
ipc: structure for unix sockets
jewelcodes Sep 5, 2024
fcba94d
io: start of per-process I/O descriptors
jewelcodes Sep 6, 2024
16445be
errno: system error numbers
jewelcodes Sep 6, 2024
f712421
ipc: prototypes for socket syscalls
jewelcodes Sep 6, 2024
82200da
types: added ssize_t to posix types
jewelcodes Sep 6, 2024
4d3e431
io: prevent multiple includes
jewelcodes Sep 6, 2024
cdf4d13
sched: stdin, stdout, and stderr descriptors for new processes
jewelcodes Sep 6, 2024
156cedf
sched-io: moved max I/O descriptors to io.h
jewelcodes Sep 6, 2024
7de83bb
io: allocate I/O descriptors for process
jewelcodes Sep 6, 2024
9825872
io: close I/O descriptors
jewelcodes Sep 6, 2024
349cef5
ipc: socket creation with socket()
jewelcodes Sep 6, 2024
1891baa
x86_64: fix in releaseLock()
jewelcodes Sep 6, 2024
c53991a
ipc: socket initialization and limits
jewelcodes Sep 6, 2024
3f0bcba
ipc: protect socket list with spinlock
jewelcodes Sep 6, 2024
c366c54
ipc: implemented socket bind()
jewelcodes Sep 6, 2024
f861a3f
ipc: added nonblocking flags
jewelcodes Sep 6, 2024
50eb798
ipc: account for flags in socket()
jewelcodes Sep 6, 2024
25f4b02
ipc: added listener to socket struct
jewelcodes Sep 6, 2024
c606528
ipc: changed max sockets to 262k
jewelcodes Sep 6, 2024
cdd2e1a
ipc: find socket by address
jewelcodes Sep 6, 2024
aa87cf0
ipc: adjusted socket descriptor structure for connection-oriented com…
jewelcodes Sep 6, 2024
701f8d0
ipc: expose socket spinlock
jewelcodes Sep 7, 2024
3d65710
ipc: socket connect()
jewelcodes Sep 7, 2024
b09a353
ipc: socket listen()
jewelcodes Sep 7, 2024
5ce5aa1
ipc: ensure protocol compatibility in connect()
jewelcodes Sep 7, 2024
5d1a968
ipc: socket register function
jewelcodes Sep 7, 2024
a910e3e
ipc: socket accept()
jewelcodes Sep 7, 2024
e5a0685
syscalls: allow for blocking syscalls
jewelcodes Sep 7, 2024
b673281
ipc: fix for I/O descriptor flags
jewelcodes Sep 7, 2024
cef9e08
syscalls: added socket syscalls
jewelcodes Sep 7, 2024
2df1cfb
syscalls: use thread paging context during syscall handling
jewelcodes Sep 7, 2024
6e4bedc
io: bug fix where pointers were not stored
jewelcodes Sep 7, 2024
1e513de
ipc: bug fix in socket creation
jewelcodes Sep 7, 2024
9aab931
x86_64: fixed a subtle bug in page context cloning
jewelcodes Sep 7, 2024
e0513f6
sched: fork() clones I/O descriptors
jewelcodes Sep 7, 2024
5fa8035
sched: debugging function to dump thread queue
jewelcodes Sep 7, 2024
d9f1d77
syscalls: fix blocking dispatcher
jewelcodes Sep 7, 2024
455d012
syscalls: additional fixes for blocking syscalls
jewelcodes Sep 7, 2024
e7a5a25
sched: show remaining time slice in queue dump
jewelcodes Sep 7, 2024
d80cb8a
ipc: decrement backlog and check for null pointers in accept()
jewelcodes Sep 7, 2024
a11e5e8
errno: typo
jewelcodes Sep 7, 2024
53664e3
ipc: send() for unix sockets
jewelcodes Sep 7, 2024
cf69a83
ipc: track lengths of data sent via sockets
jewelcodes Sep 7, 2024
7617cd4
ipc: socket recv()
jewelcodes Sep 7, 2024
67aa54e
syscalls: exposed recv() and send()
jewelcodes Sep 7, 2024
0664e51
ipc: release socket spinlock after recv()
jewelcodes Sep 7, 2024
cacc7b5
ipc: fix in connect() where peer wasn't being assigned to self
jewelcodes Sep 7, 2024
aa9f649
ipc: fix connection peers
jewelcodes Sep 7, 2024
f5e408a
sched: changed thread time slices
jewelcodes Sep 7, 2024
dc9e8bc
ipc: fix potential memory leak in send()
jewelcodes Sep 7, 2024
3aee115
syscalls: reduce variable scope where unnecessary
jewelcodes Sep 7, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 88 additions & 0 deletions src/include/errno.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/*
* lux - a lightweight unix-like operating system
* Omar Elghoul, 2024
*
* Core Microkernel
*/

#pragma once

/* System Error Numbers */

#define E2BIG 1 // too many args
#define EACCES 2 // access denied
#define EADDRINUSE 3 // address in use
#define EADDRNOTAVAIL 4 // address not available
#define EAFNOSUPPORT 5 // address family not supported
#define EAGAIN 6 // resource busy, try again
#define EALREADY 7 // connection already in progress
#define EBADF 8 // bad file descriptor
#define EBADMSG 9 // bad message
#define EBUSY 10 // resource busy
#define ECANCELED 11 // canceled
#define ECHILD 12 // no child processes
#define ECONNABORTED 13 // connection aborted
#define ECONNREFUSED 14 // connection refused
#define ECONNRESET 15 // connection reset
#define EDEADLK 16 // deadlock
#define EDESTADDRREQ 17 // destination address required
#define EDOM 18 // function argument not in domain
#define EDQUOT 19 // reserved
#define EEXIST 20 // file exists
#define EFAULT 21 // bad address
#define EFBIG 22 // file too big
#define EHOSTUNREACH 23 // host unreachable
#define EIDRM 24 // identifier removed
#define EILSEQ 25 // illegal byte sequence
#define EINPROGRESS 26 // operation in progress
#define EINTR 27 // interrupted function
#define EINVAL 28 // invalid argument
#define EIO 29 // I/O error
#define EISCONN 30 // socket already connected
#define EISDIR 31 // directory
#define ELOOP 32 // looping symlinks
#define EMFILE 33 // file descriptor too big
#define EMLINK 34 // too many links
#define EMSGSIZE 35 // message too large
#define EMULTIHOP 36 // reserved
#define ENAMETOOLONG 37 // file name too long
#define ENETDOWN 38 // network is down
#define ENETRESET 39 // connection aborted by network
#define ENETUNREACH 40 // network unreachable
#define ENFILE 41 // too many files open
#define ENOBUFS 42 // no buffers available
#define ENODEV 43 // no such device
#define ENOENT 44 // no such file/directory
#define ENOEXEC 45 // executable file error
#define ENOLCK 46 // no locks available
#define ENOLINK 47 // reserved
#define ENOMEM 48 // ran out of memory
#define ENOMSG 49 // no message of desired type
#define ENOPROTOOPT 50 // protocol not implemented
#define ENOSPC 51 // ran out of storage
#define ENOSYS 52 // function not supported
#define ENOTCONN 53 // socket not connected
#define ENOTDIR 54 // not a directory nor symlink to directory
#define ENOTEMPTY 55 // directory not empty
#define ENOTRECOVERABLE 56 // unrecoverable error
#define ENOTSOCK 57 // not a socket
#define ENOTSUP 58 // operation not supported
#define EOPNOTSUPP ENOTSUP
#define ENOTTY 59 // inappropriate I/O
#define ENXIO 60 // no such device or address
#define EOVERFLOW 61 // value larger than data type
#define EOWNERDEAD 62 // previous owner died
#define EPERM 63 // operation not permitted
#define EPIPE 64 // broken pipe
#define EPROTO 65 // protocol error
#define EPROTONOSUPPORT 66 // protocol not supported
#define EPROTOTYPE 67 // wrong protocol type
#define ERANGE 68 // result too large
#define EROFS 69 // read-only file system
#define ESPIPE 70 // invalid seek
#define ESRCH 71 // no such process
#define ESTALE 72 // reserved
#define ETIMEDOUT 73 // connection timeout
#define ETXTBSY 74 // text file busy
#define EWOULDBLOCK 75 // blocking operation
#define EXDEV 76 // cross-device link
42 changes: 42 additions & 0 deletions src/include/kernel/io.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* lux - a lightweight unix-like operating system
* Omar Elghoul, 2024
*
* Core Microkernel
*/

/* Abstractions for file systems and sockets */

#pragma once

#include <stdint.h>
#include <stdbool.h>
#include <kernel/sched.h>

#define MAX_IO_DESCRIPTORS 1024 // max files/sockets open per process

// these are special and reserved descriptors
#define IO_STDIN 0
#define IO_STDOUT 1
#define IO_STDERR 2

#define IO_WAITING 3 // only used during setup
#define IO_FILE 4
#define IO_SOCKET 5

/* I/O descriptor flags */
#define O_NONBLOCK 0x0001
#define O_NDELAY O_NONBLOCK
#define O_CLOEXEC 0x0002

// TODO: decide whether to implement named pipes as files or an independent type

typedef struct IODescriptor {
bool valid;
int type;
uint16_t flags;
void *data; // file or socket-specific data
} IODescriptor;

int openIO(void *, void **);
void closeIO(void *, void *);
14 changes: 9 additions & 5 deletions src/include/kernel/sched.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@
#include <stddef.h>
#include <sys/types.h>
#include <kernel/syscalls.h>
#include <kernel/io.h>

// ideal number of context switches per second
// still not sure of how to decide on this value so it'll probably change
#define SCHED_SWITCH_RATE 200
#define SCHED_TIME_SLICE 1 // ms

#define MAX_PID 99999

Expand All @@ -25,9 +25,9 @@
#define THREAD_ZOMBIE 3
#define THREAD_SLEEP 4

#define PRIORITY_HIGH 0
#define PRIORITY_NORMAL 1
#define PRIORITY_LOW 2
#define PRIORITY_LOW 1
#define PRIORITY_NORMAL 2
#define PRIORITY_HIGH 3

typedef struct Thread {
int status, cpu, priority;
Expand Down Expand Up @@ -56,6 +56,9 @@ typedef struct Process {
char *env; // environmental variables
char *command; // command line with arguments

struct IODescriptor io[MAX_IO_DESCRIPTORS];
int iodCount;

size_t threadCount;
size_t childrenCount;

Expand All @@ -81,6 +84,7 @@ void setScheduling(bool);
void blockThread(Thread *);
void unblockThread(Thread *);
Process *getProcessQueue();
void schedStatus();

pid_t kthreadCreate(void *(*)(void *), void *);
pid_t processCreate();
Expand Down
75 changes: 75 additions & 0 deletions src/include/kernel/socket.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/*
* lux - a lightweight unix-like operating system
* Omar Elghoul, 2024
*
* Core Microkernel
*/

#pragma once

#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>
#include <kernel/sched.h>
#include <sys/types.h>

/* system-wide limits */
#define MAX_SOCKETS (1 << 18) // 262k
#define SOCKET_DEFAULT_BACKLOG 1024 // default socket backlog size

/* socket family/domain - only Unix sockets will be implemented in the kernel */
#define AF_UNIX 1
#define AF_LOCAL AF_UNIX

/* socket type - these will be ignored for local Unix sockets */
/* the kernel will ensure packets are sent and received in the same order */
#define SOCK_STREAM 1 // stream-oriented
#define SOCK_DGRAM 2 // datagram-oriented
#define SOCK_SEQPACKET 3 // connection-oriented

/* additional socket flags */
#define SOCK_NONBLOCK 0x100
#define SOCK_CLOEXEC 0x200

typedef uint16_t sa_family_t;
typedef size_t socklen_t;

/* generic socket */
struct sockaddr {
sa_family_t sa_family;
char sa_data[512];
};

/* Unix domain socket */
struct sockaddr_un {
sa_family_t sun_family; // AF_UNIX
char sun_path[512]; // filename
};

/* socket-specific I/O descriptor (see io.h) */
typedef struct SocketDescriptor {
Process *process;
struct sockaddr address;
bool listener;
int type, protocol, backlogMax, backlogCount;
int inboundCount, outboundCount;
void **inbound, **outbound;
size_t *inboundLen, *outboundLen;
struct SocketDescriptor **backlog; // for incoming connections via connect()
struct SocketDescriptor *peer; // for peer-to-peer connections
} SocketDescriptor;

void socketInit();
SocketDescriptor *getLocalSocket(const struct sockaddr *, socklen_t);
void socketLock();
void socketRelease();
int socketRegister(SocketDescriptor *);

/* socket system calls */
int socket(Thread *, int, int, int);
int connect(Thread *, int, const struct sockaddr *, socklen_t);
int bind(Thread *, int, const struct sockaddr *, socklen_t);
int listen(Thread *, int, int);
int accept(Thread *, int, struct sockaddr *, socklen_t *);
ssize_t recv(Thread *, int, void *, size_t, int);
ssize_t send(Thread *, int, const void *, size_t, int);
4 changes: 2 additions & 2 deletions src/include/kernel/syscalls.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@
#include <stdbool.h>
#include <kernel/sched.h>

#define MAX_SYSCALL 12 // for now
#define MAX_SYSCALL 37 // for now

typedef struct SyscallRequest {
bool busy, queued;
bool busy, queued, unblock;

uint64_t function;
uint64_t params[4];
Expand Down
1 change: 1 addition & 0 deletions src/include/sys/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,4 @@ typedef uint64_t off_t;
typedef uint64_t time_t;
typedef uint16_t blksize_t;
typedef uint64_t blkcnt_t;
typedef int64_t ssize_t;
60 changes: 60 additions & 0 deletions src/io.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
* lux - a lightweight unix-like operating system
* Omar Elghoul, 2024
*
* Core Microkernel
*/

/* Abstractions for file systems and sockets */

#include <errno.h>
#include <stdlib.h>
#include <kernel/sched.h>
#include <kernel/io.h>

/* openIO(): opens an I/O descriptor in a process
* params: p - process to open descriptor in
* params: iod - destination to store pointer to I/O descriptor structure
* returns: I/O descriptor, negative error code on fail
*/

int openIO(void *pv, void **iodv) {
Process *p = (Process *)pv;
IODescriptor **iod = (IODescriptor **)iodv;

if(p->iodCount >= MAX_IO_DESCRIPTORS) return -ESRCH;

/* randomly allocate descriptors instead of sequential numbering */
int desc;
do {
desc = rand() % MAX_IO_DESCRIPTORS;
} while(p->io[desc].valid);

p->io[desc].valid = true;
p->io[desc].type = IO_WAITING;
p->io[desc].data = NULL;

p->iodCount++;

*iod = &p->io[desc];
return desc;
}

/* closeIO(): closes an I/O descriptor in a process
* params: pv - process to close descriptor in
* params: iodv - descriptor to close
* returns: nothing
*/

void closeIO(void *pv, void *iodv) {
Process *p = (Process *)pv;
IODescriptor *iod = (IODescriptor *) iodv;

if(iod->valid) {
iod->valid = false;
if(iod->data) free(iod->data);
iod->data = NULL;

p->iodCount--;
}
}
Loading
Loading