From 74c204ec878e287e4d5750e9e865f29557d38ae5 Mon Sep 17 00:00:00 2001 From: Ali Moeeny Date: Mon, 14 Sep 2015 14:43:37 -0400 Subject: [PATCH 01/10] added instructions for homebrew Just for the sake of completeness. --- README.md | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 3370283..4a75f77 100644 --- a/README.md +++ b/README.md @@ -18,9 +18,20 @@ Requirements * OS X 10.10.3 Yosemite or later * a 2010 or later Mac (i.e. a CPU that supports EPT) +Installation +------------ + +If you have home brew, then simply: + + $ brew update + $ brew install xhyve + +if not then: + Building -------- - + $ git clone https://github.com/mist64/xhyve + $ cd xhyve $ make The resulting binary will be in build/xhyve From eed74ba45d40dd7ea7f019290ec53c1bf13f3b2d Mon Sep 17 00:00:00 2001 From: Ali Moeeny Date: Tue, 15 Sep 2015 07:59:47 -0400 Subject: [PATCH 02/10] Fixed spelling of homebrew --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4a75f77..ecdf4fd 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ Requirements Installation ------------ -If you have home brew, then simply: +If you have homebrew, then simply: $ brew update $ brew install xhyve From fae82085cdf529ce8fcf8d8b3366943c5bffa3fa Mon Sep 17 00:00:00 2001 From: Rickard von Essen Date: Fri, 11 Sep 2015 16:08:35 +0200 Subject: [PATCH 03/10] Fixes #52: Help text (-h) for memory size (-m) is incorrect. --- src/xhyve.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/xhyve.c b/src/xhyve.c index 224a74b..55367c5 100644 --- a/src/xhyve.c +++ b/src/xhyve.c @@ -136,6 +136,7 @@ usage(int code) " -h: help\n" " -H: vmexit from the guest on hlt\n" " -l: LPC device configuration\n" + " -m: memory size in MB, may be suffixed with one of K, M, G or T\n" " -m: memory size in MB\n" " -M: print MAC address and exit if using vmnet\n" " -p: pin 'vcpu' to 'hostcpu'\n" From dad514462c40927a0d60a0adea3e99f5f1ca596d Mon Sep 17 00:00:00 2001 From: Ali Moeeny Date: Wed, 24 Feb 2016 07:45:12 -0500 Subject: [PATCH 04/10] changed the brew command to always pull HEAD --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ecdf4fd..24051cc 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ Installation If you have homebrew, then simply: $ brew update - $ brew install xhyve + $ brew install --HEAD xhyve if not then: From a9a041cb13a12c2e509a613190e09179da45b05f Mon Sep 17 00:00:00 2001 From: Ali Moeeny Date: Wed, 24 Feb 2016 07:49:54 -0500 Subject: [PATCH 05/10] added a comment to make the `--HEAD` more clear --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 24051cc..811f25b 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,8 @@ If you have homebrew, then simply: $ brew update $ brew install --HEAD xhyve +The `--HEAD` in the brew command ensures that you always get the latest changes, even if the homebrew database is not yet updated. If for any reason you don't want that simply do `brew install xhyve` . + if not then: Building From 7698501cf8150c3577667682011e3944d987e2f8 Mon Sep 17 00:00:00 2001 From: Ewoud Kohl van Wijngaarden Date: Thu, 24 Mar 2016 16:01:54 +0100 Subject: [PATCH 06/10] Fix typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7e5b685..e0924c5 100644 --- a/README.md +++ b/README.md @@ -56,7 +56,7 @@ It exposes the following peripherals to virtual machines: Notably absent are sound, USB, HID and any kind of graphics support. With a focus on server virtualization this is not strictly a requirement. bhyve may gain desktop virtualization capabilities in the future but this doesn't seem to be a priority. -Unlike QEMU, byhve also currently lacks any kind of guest-side firmware (QEMU uses the GPL3 [SeaBIOS](http://www.seabios.org)), but aims to provide a compatible [OVMF EFI](http://www.linux-kvm.org/page/OVMF) in the near future. It does however provide ACPI, SMBIOS and MP Tables. +Unlike QEMU, bhyve also currently lacks any kind of guest-side firmware (QEMU uses the GPL3 [SeaBIOS](http://www.seabios.org)), but aims to provide a compatible [OVMF EFI](http://www.linux-kvm.org/page/OVMF) in the near future. It does however provide ACPI, SMBIOS and MP Tables. bhyve architecture ------------------ From 791b47541b9fbb05b4bd25994a10750c37efb8eb Mon Sep 17 00:00:00 2001 From: Radu Popescu Date: Wed, 30 Mar 2016 23:35:22 +0200 Subject: [PATCH 07/10] Fixing compilation on OS X 10.11.4 and Xcode 7.3 OS X 10.11.4 (15E65) Xcode Version 7.3 (7D175) Apple LLVM version 7.3.0 (clang-703.0.29) --- src/vmm/io/vhpet.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/vmm/io/vhpet.c b/src/vmm/io/vhpet.c index 1d81861..3e13bda 100644 --- a/src/vmm/io/vhpet.c +++ b/src/vmm/io/vhpet.c @@ -221,7 +221,7 @@ vhpet_timer_interrupt(struct vhpet *vhpet, int n) lapic_intr_msi(vhpet->vm, vhpet->timer[n].msireg >> 32, vhpet->timer[n].msireg & 0xffffffff); return; - } + } pin = vhpet_timer_ioapic_pin(vhpet, n); if (pin == 0) { @@ -291,7 +291,7 @@ vhpet_handler(void *a) callout_deactivate(callout); if (!vhpet_counter_enabled(vhpet)) - xhyve_abort("vhpet(%p) callout with counter disabled\n", vhpet); + xhyve_abort("vhpet(%p) callout with counter disabled\n", (void*)vhpet); counter = vhpet_counter(vhpet, &now); vhpet_start_timer(vhpet, n, counter, now); @@ -483,7 +483,7 @@ vhpet_mmio_write(void *vm, UNUSED int vcpuid, uint64_t gpa, uint64_t val, int si if ((offset & 0x4) != 0) { mask <<= 32; data <<= 32; - } + } break; default: VM_CTR2(vhpet->vm, "hpet invalid mmio write: " @@ -638,7 +638,7 @@ vhpet_mmio_read(void *vm, UNUSED int vcpuid, uint64_t gpa, uint64_t *rval, int s if (offset == HPET_CAPABILITIES || offset == HPET_CAPABILITIES + 4) { data = vhpet_capabilities(); - goto done; + goto done; } if (offset == HPET_CONFIG || offset == HPET_CONFIG + 4) { From 86698000e1e5c72ba2df776b3dff3ff0c05dfbb7 Mon Sep 17 00:00:00 2001 From: xez Date: Wed, 30 Mar 2016 23:48:13 -0700 Subject: [PATCH 08/10] Remove duplicate -h line. --- src/xhyve.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/xhyve.c b/src/xhyve.c index 55367c5..7617f71 100644 --- a/src/xhyve.c +++ b/src/xhyve.c @@ -137,7 +137,6 @@ usage(int code) " -H: vmexit from the guest on hlt\n" " -l: LPC device configuration\n" " -m: memory size in MB, may be suffixed with one of K, M, G or T\n" - " -m: memory size in MB\n" " -M: print MAC address and exit if using vmnet\n" " -p: pin 'vcpu' to 'hostcpu'\n" " -P: vmexit from the guest on pause\n" From 4c50bfe7b7f158ce2b22817d6fe4b9d8a4dadd3e Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Fri, 1 Apr 2016 17:25:14 +0200 Subject: [PATCH 09/10] moved copy of lib9p to a git submodule --- .gitmodules | 3 + lib9p | 1 + lib9p/.gitignore | 33 -- lib9p/COPYRIGHT | 47 --- lib9p/GNUmakefile | 48 --- lib9p/Makefile | 16 - lib9p/backend/fs.c | 770 --------------------------------------- lib9p/connection.c | 178 --------- lib9p/example/server.c | 52 --- lib9p/fcall.h | 236 ------------ lib9p/hashtable.c | 172 --------- lib9p/hashtable.h | 63 ---- lib9p/lib9p.h | 186 ---------- lib9p/lib9p_impl.h | 78 ---- lib9p/log.c | 49 --- lib9p/log.h | 47 --- lib9p/pack.c | 453 ----------------------- lib9p/request.c | 444 ---------------------- lib9p/sbuf/sbuf.c | 106 ------ lib9p/sbuf/sbuf.h | 53 --- lib9p/transport/socket.c | 308 ---------------- lib9p/transport/socket.h | 40 -- lib9p/utils.c | 260 ------------- 23 files changed, 4 insertions(+), 3639 deletions(-) create mode 100644 .gitmodules create mode 160000 lib9p delete mode 100644 lib9p/.gitignore delete mode 100644 lib9p/COPYRIGHT delete mode 100644 lib9p/GNUmakefile delete mode 100644 lib9p/Makefile delete mode 100644 lib9p/backend/fs.c delete mode 100644 lib9p/connection.c delete mode 100644 lib9p/example/server.c delete mode 100644 lib9p/fcall.h delete mode 100644 lib9p/hashtable.c delete mode 100644 lib9p/hashtable.h delete mode 100644 lib9p/lib9p.h delete mode 100644 lib9p/lib9p_impl.h delete mode 100644 lib9p/log.c delete mode 100644 lib9p/log.h delete mode 100644 lib9p/pack.c delete mode 100644 lib9p/request.c delete mode 100644 lib9p/sbuf/sbuf.c delete mode 100644 lib9p/sbuf/sbuf.h delete mode 100644 lib9p/transport/socket.c delete mode 100644 lib9p/transport/socket.h delete mode 100644 lib9p/utils.c diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..d44c7a4 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "lib9p"] + path = lib9p + url = https://github.com/jceel/lib9p.git diff --git a/lib9p b/lib9p new file mode 160000 index 0000000..ddfdba4 --- /dev/null +++ b/lib9p @@ -0,0 +1 @@ +Subproject commit ddfdba40793f4bd2e988d4832cfadbf71ab7d024 diff --git a/lib9p/.gitignore b/lib9p/.gitignore deleted file mode 100644 index 3ccb06a..0000000 --- a/lib9p/.gitignore +++ /dev/null @@ -1,33 +0,0 @@ -# Object files -*.o -*.ko -*.obj -*.elf - -# Precompiled Headers -*.gch -*.pch - -# Libraries -*.lib -*.a -*.la -*.lo - -# Shared objects (inc. Windows DLLs) -*.dll -*.so -*.so.* -*.dylib - -# Executables -*.exe -*.out -*.app -*.i*86 -*.x86_64 -*.hex - -# Debug files -*.dSYM/ -/build/ \ No newline at end of file diff --git a/lib9p/COPYRIGHT b/lib9p/COPYRIGHT deleted file mode 100644 index b02f09a..0000000 --- a/lib9p/COPYRIGHT +++ /dev/null @@ -1,47 +0,0 @@ -Copyright 2016 Jakub Klama -All rights reserved - -Redistribution and use in source and binary forms, with or without -modification, are permitted providing that the following conditions -are met: -1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING -IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - -Some parts of the code are based on libixp (http://libs.suckless.org/libixp) -library code released under following license: - -© 2005-2006 Anselm R. Garbe -© 2006-2010 Kris Maglione - -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the "Software"), -to deal in the Software without restriction, including without limitation -the rights to use, copy, modify, merge, publish, distribute, sublicense, -and/or sell copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. diff --git a/lib9p/GNUmakefile b/lib9p/GNUmakefile deleted file mode 100644 index 5764787..0000000 --- a/lib9p/GNUmakefile +++ /dev/null @@ -1,48 +0,0 @@ -CFLAGS := \ - -Weverything \ - -Wno-padded \ - -Wno-gnu-zero-variadic-macro-arguments \ - -Wno-format-nonliteral \ - -Werror \ - -g \ - -O0 - -LIB_SRCS := \ - pack.c \ - connection.c \ - request.c \ - log.c \ - hashtable.c \ - utils.c \ - sbuf/sbuf.c \ - transport/socket.c \ - backend/fs.c - -SERVER_SRCS := \ - example/server.c - -BUILD_DIR := build -LIB_OBJS := $(addprefix build/,$(LIB_SRCS:.c=.o)) -SERVER_OBJS := $(SERVER_SRCS:.c=.o) -LIB := lib9p.dylib -SERVER := server - -all: build $(LIB) $(SERVER) - -$(LIB): $(LIB_OBJS) - cc -dynamiclib $^ -o $@ - -$(SERVER): $(SERVER_OBJS) $(LIB) - cc $< -o build/$(SERVER) -L. -l9p - -clean: - rm -rf build - -build: - mkdir build - mkdir build/sbuf - mkdir build/transport - mkdir build/backend - -build/%.o: %.c - $(CC) $(CFLAGS) -c $< -o $@ diff --git a/lib9p/Makefile b/lib9p/Makefile deleted file mode 100644 index 751d3e1..0000000 --- a/lib9p/Makefile +++ /dev/null @@ -1,16 +0,0 @@ -LIB= 9p -SHLIB_MAJOR= 1 -SRCS= pack.c \ - connection.c \ - request.c log.c \ - hashtable.c \ - utils.c \ - transport/socket.c \ - backend/fs.c - -INCS= lib9p.h -CFLAGS= -g -O0 - -LIBADD= sbuf - -.include diff --git a/lib9p/backend/fs.c b/lib9p/backend/fs.c deleted file mode 100644 index e410368..0000000 --- a/lib9p/backend/fs.c +++ /dev/null @@ -1,770 +0,0 @@ -/* - * Copyright 2016 Jakub Klama - * All rights reserved - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted providing that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - */ - -/* - * Based on libixp code: ©2007-2010 Kris Maglione - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "../lib9p.h" -#include "../lib9p_impl.h" -#include "../log.h" - -static struct openfile *open_fid(const char *); -static void dostat(struct l9p_stat *, char *, struct stat *, bool dotu); -static void generate_qid(struct stat *, struct l9p_qid *); -static void fs_attach(void *, struct l9p_request *); -static void fs_clunk(void *, struct l9p_request *); -static void fs_create(void *, struct l9p_request *); -static void fs_flush(void *, struct l9p_request *); -static void fs_open(void *, struct l9p_request *); -static void fs_read(void *, struct l9p_request *); -static void fs_remove(void *, struct l9p_request *); -static void fs_stat(void *, struct l9p_request *); -static void fs_walk(void *, struct l9p_request *); -static void fs_write(void *, struct l9p_request *); -static void fs_wstat(void *, struct l9p_request *); -static void fs_freefid(void *softc, struct l9p_openfile *f); - -struct fs_softc -{ - const char *fs_rootpath; - bool fs_readonly; - TAILQ_HEAD(, fs_tree) fs_auxtrees; -}; - -struct fs_tree -{ - const char *fst_name; - const char *fst_path; - bool fst_readonly; - TAILQ_ENTRY(fs_tree) fst_link; -}; - -struct openfile -{ - DIR *dir; - int fd; - char *name; - uid_t uid; - gid_t gid; -}; - -static struct openfile * -open_fid(const char *path) -{ - struct openfile *ret; - - ret = l9p_calloc(1, sizeof(*ret)); - ret->fd = -1; - ret->name = strdup(path); - return (ret); -} - -static void -dostat(struct l9p_stat *s, char *name, struct stat *buf, bool dotu) -{ - struct passwd *user; - struct group *group; - - memset(s, 0, sizeof(struct l9p_stat)); - - generate_qid(buf, &s->qid); - - s->type = 0; - s->dev = 0; - s->mode = buf->st_mode & 0777; - - if (S_ISDIR(buf->st_mode)) - s->mode |= L9P_DMDIR; - - if (S_ISLNK(buf->st_mode) && dotu) - s->mode |= L9P_DMSYMLINK; - - if (S_ISCHR(buf->st_mode) || S_ISBLK(buf->st_mode)) - s->mode |= L9P_DMDEVICE; - - if (S_ISSOCK(buf->st_mode)) - s->mode |= L9P_DMSOCKET; - - if (S_ISFIFO(buf->st_mode)) - s->mode |= L9P_DMNAMEDPIPE; - - s->atime = (uint32_t)buf->st_atime; - s->mtime = (uint32_t)buf->st_mtime; - s->length = (uint64_t)buf->st_size; - - /* XXX: not thread safe */ - s->name = strdup(basename(name)); - - if (!dotu) { - user = getpwuid(buf->st_uid); - group = getgrgid(buf->st_gid); - s->uid = user != NULL ? strdup(user->pw_name) : NULL; - s->gid = group != NULL ? strdup(group->gr_name) : NULL; - s->muid = user != NULL ? strdup(user->pw_name) : NULL; - } else { - /* - * When using 9P2000.u, we don't need to bother about - * providing user and group names in textual form. - */ - s->n_uid = buf->st_uid; - s->n_gid = buf->st_gid; - s->n_muid = buf->st_uid; - - if (S_ISLNK(buf->st_mode)) { - char target[MAXPATHLEN]; - ssize_t ret = readlink(name, target, MAXPATHLEN); - - if (ret < 0) { - s->extension = NULL; - return; - } - - s->extension = strndup(target, (size_t)ret); - } - - if (S_ISBLK(buf->st_mode)) { - asprintf(&s->extension, "b %d %d", major(buf->st_rdev), - minor(buf->st_rdev)); - } - - if (S_ISCHR(buf->st_mode)) { - asprintf(&s->extension, "c %d %d", major(buf->st_rdev), - minor(buf->st_rdev)); - } - } -} - -static void -generate_qid(struct stat *buf, struct l9p_qid *qid) -{ - qid->path = buf->st_ino; - qid->version = 0; - - if (S_ISREG(buf->st_mode)) - qid->type |= L9P_QTFILE; - - if (S_ISDIR(buf->st_mode)) - qid->type |= L9P_QTDIR; - - if (S_ISLNK(buf->st_mode)) - qid->type |= L9P_QTSYMLINK; -} - -static bool -check_access(struct stat *st, uid_t uid, int amode) -{ - struct passwd *pwd; - int groups[NGROUPS_MAX]; - int ngroups = NGROUPS_MAX; - int i; - - if (uid == 0) - return (true); - - if (st->st_uid == uid) { - if (amode == L9P_OREAD && st->st_mode & S_IRUSR) - return (true); - - if (amode == L9P_OWRITE && st->st_mode & S_IWUSR) - return (true); - - if (amode == L9P_OEXEC && st->st_mode & S_IXUSR) - return (true); - } - - /* Check for "other" access */ - if (amode == L9P_OREAD && st->st_mode & S_IROTH) - return (true); - - if (amode == L9P_OWRITE && st->st_mode & S_IWOTH) - return (true); - - if (amode == L9P_OEXEC && st->st_mode & S_IXOTH) - return (true); - - /* Check for group access */ - pwd = getpwuid(uid); - getgrouplist(pwd->pw_name, (int)pwd->pw_gid, groups, &ngroups); - - for (i = 0; i < ngroups; i++) { - if (st->st_gid == (gid_t)groups[i]) { - if (amode == L9P_OREAD && st->st_mode & S_IRGRP) - return (true); - - if (amode == L9P_OWRITE && st->st_mode & S_IWGRP) - return (true); - - if (amode == L9P_OEXEC && st->st_mode & S_IXGRP) - return (true); - } - } - - return (false); -} - -static void -fs_attach(void *softc, struct l9p_request *req) -{ - struct fs_softc *sc = (struct fs_softc *)softc; - struct openfile *file; - struct passwd *pwd; - uid_t uid; - - assert(req->lr_fid != NULL); - - file = open_fid(sc->fs_rootpath); - req->lr_fid->lo_qid.type = L9P_QTDIR; - req->lr_fid->lo_qid.path = (uintptr_t)req->lr_fid; - req->lr_fid->lo_aux = file; - req->lr_resp.rattach.qid = req->lr_fid->lo_qid; - - uid = req->lr_req.tattach.n_uname; - if (req->lr_conn->lc_version >= L9P_2000U && uid != (uid_t)-1) - pwd = getpwuid(uid); - else - pwd = getpwnam(req->lr_req.tattach.uname); - - if (pwd == NULL) { - l9p_respond(req, EPERM); - return; - } - - file->uid = pwd->pw_uid; - file->gid = pwd->pw_gid; - l9p_respond(req, 0); -} - -static void -fs_clunk(void *softc __unused, struct l9p_request *req) -{ - struct openfile *file; - - file = req->lr_fid->lo_aux; - assert(file != NULL); - - if (file->dir) { - closedir(file->dir); - file->dir = NULL; - } else if (file->fd != -1) { - close(file->fd); - file->fd = -1; - } - - l9p_respond(req, 0); -} - -static void -fs_create(void *softc, struct l9p_request *req) -{ - struct fs_softc *sc = softc; - struct openfile *file = req->lr_fid->lo_aux; - struct stat st; - char *newname; - mode_t mode = req->lr_req.tcreate.perm & 0777; - - assert(file != NULL); - - if (sc->fs_readonly) { - l9p_respond(req, EROFS); - return; - } - - asprintf(&newname, "%s/%s", file->name, req->lr_req.tcreate.name); - - if (stat(file->name, &st) != 0) { - l9p_respond(req, errno); - return; - } - - if (!check_access(&st, file->uid, L9P_OWRITE)) { - l9p_respond(req, EPERM); - return; - } - - if (req->lr_req.tcreate.perm & L9P_DMDIR) - mkdir(newname, mode); - else if (req->lr_req.tcreate.perm & L9P_DMSYMLINK) { - if (symlink(req->lr_req.tcreate.extension, newname) != 0) { - l9p_respond(req, errno); - return; - } - } else if (req->lr_req.tcreate.perm & L9P_DMNAMEDPIPE) { - if (mkfifo(newname, mode) != 0) { - l9p_respond(req, errno); - return; - } - } else if (req->lr_req.tcreate.perm & L9P_DMSOCKET) { - struct sockaddr_un sun; - int s = socket(AF_UNIX, SOCK_STREAM, 0); - - if (s < 0) { - l9p_respond(req, errno); - return; - } - - sun.sun_family = AF_UNIX; - sun.sun_len = sizeof(struct sockaddr_un); - strncpy(sun.sun_path, newname, sizeof(sun.sun_path)); - - if (bind(s, (struct sockaddr *)&sun, sun.sun_len) < 0) { - l9p_respond(req, errno); - return; - } - - if (close(s) != 0) { - l9p_respond(req, errno); - return; - } - } else if (req->lr_req.tcreate.perm & L9P_DMDEVICE) { - char type; - int major, minor; - - if (sscanf(req->lr_req.tcreate.extension, "%c %u %u", - &type, &major, &minor) < 2) { - l9p_respond(req, EINVAL); - return; - } - - switch (type) { - case 'b': - if (mknod(newname, S_IFBLK | mode, - makedev(major, minor)) != 0) - { - l9p_respond(req, errno); - return; - } - break; - case 'c': - if (mknod(newname, S_IFCHR | mode, - makedev(major, minor)) != 0) - { - l9p_respond(req, errno); - return; - } - break; - default: - l9p_respond(req, EINVAL); - return; - } - } else { - file->fd = open(newname, - O_CREAT | O_TRUNC | req->lr_req.tcreate.mode, - mode); - } - - if (lchown(newname, file->uid, file->gid) != 0) { - l9p_respond(req, errno); - return; - } - - if (stat(newname, &st) != 0) { - l9p_respond(req, errno); - return; - } - - generate_qid(&st, &req->lr_resp.rcreate.qid); - l9p_respond(req, 0); -} - -static void -fs_flush(void *softc __unused, struct l9p_request *req) -{ - - /* XXX: not used because this transport is synchronous */ - l9p_respond(req, 0); -} - -static void -fs_open(void *softc __unused, struct l9p_request *req) -{ - struct l9p_connection *conn = req->lr_conn; - struct openfile *file = req->lr_fid->lo_aux; - struct stat st; - - assert(file != NULL); - - if (stat(file->name, &st) != 0) { - l9p_respond(req, errno); - return; - } - - if (!check_access(&st, file->uid, req->lr_req.topen.mode)) { - l9p_respond(req, EPERM); - return; - } - - if (S_ISDIR(st.st_mode)) - file->dir = opendir(file->name); - else { - file->fd = open(file->name, req->lr_req.topen.mode); - if (file->fd < 0) { - l9p_respond(req, EPERM); - return; - } - } - - generate_qid(&st, &req->lr_resp.ropen.qid); - - req->lr_resp.ropen.iounit = conn->lc_max_io_size; - l9p_respond(req, 0); -} - -static void -fs_read(void *softc __unused, struct l9p_request *req) -{ - struct openfile *file; - struct l9p_stat l9stat; - bool dotu = req->lr_conn->lc_version >= L9P_2000U; - ssize_t ret; - - file = req->lr_fid->lo_aux; - assert(file != NULL); - - if (file->dir != NULL) { - struct dirent *d; - struct stat st; - - for (;;) { - d = readdir(file->dir); - if (d) { - lstat(d->d_name, &st); - dostat(&l9stat, d->d_name, &st, dotu); - if (l9p_pack_stat(req, &l9stat) != 0) { - seekdir(file->dir, -1); - break; - } - - continue; - } - - break; - } - } else { - size_t niov = l9p_truncate_iov(req->lr_data_iov, - req->lr_data_niov, req->lr_req.io.count); - -#if defined(__FreeBSD__) - ret = preadv(file->fd, req->lr_data_iov, niov, - req->lr_req.io.offset); -#else - /* XXX: not thread safe, should really use aio_listio. */ - if (lseek(file->fd, (off_t)req->lr_req.io.offset, SEEK_SET) < 0) - { - l9p_respond(req, errno); - return; - } - - ret = (uint32_t)readv(file->fd, req->lr_data_iov, (int)niov); -#endif - - if (ret < 0) { - l9p_respond(req, errno); - return; - } - - req->lr_resp.io.count = (uint32_t)ret; - } - - l9p_respond(req, 0); -} - -static void -fs_remove(void *softc, struct l9p_request *req) -{ - struct fs_softc *sc = softc; - struct openfile *file; - struct stat st; - - file = req->lr_fid->lo_aux; - assert(file); - - if (sc->fs_readonly) { - l9p_respond(req, EROFS); - return; - } - - if (lstat(file->name, &st) != 0) { - l9p_respond(req, errno); - return; - } - - if (!check_access(&st, file->uid, L9P_OWRITE)) { - l9p_respond(req, EPERM); - return; - } - - if (S_ISDIR(st.st_mode)) { - if (rmdir(file->name) != 0) { - l9p_respond(req, errno); - return; - } - } else { - if (unlink(file->name) != 0) { - l9p_respond(req, errno); - return; - } - } - - l9p_respond(req, 0); -} - -static void -fs_stat(void *softc __unused, struct l9p_request *req) -{ - struct openfile *file; - struct stat st; - bool dotu = req->lr_conn->lc_version >= L9P_2000U; - - file = req->lr_fid->lo_aux; - assert(file); - - lstat(file->name, &st); - dostat(&req->lr_resp.rstat.stat, file->name, &st, dotu); - - l9p_respond(req, 0); -} - -static void -fs_walk(void *softc __unused, struct l9p_request *req) -{ - uint16_t i; - struct stat buf; - struct openfile *file = req->lr_fid->lo_aux; - struct openfile *newfile; - char name[MAXPATHLEN]; - - strcpy(name, file->name); - - for (i = 0; i < req->lr_req.twalk.nwname; i++) { - strcat(name, "/"); - strcat(name, req->lr_req.twalk.wname[i]); - if (lstat(name, &buf) < 0){ - l9p_respond(req, ENOENT); - return; - } - - generate_qid(&buf, &req->lr_resp.rwalk.wqid[i]); - } - - newfile = open_fid(name); - newfile->uid = file->uid; - newfile->gid = file->gid; - req->lr_newfid->lo_aux = newfile; - req->lr_resp.rwalk.nwqid = i; - l9p_respond(req, 0); -} - -static void -fs_write(void *softc, struct l9p_request *req) -{ - struct fs_softc *sc = softc; - struct openfile *file; - ssize_t ret; - - file = req->lr_fid->lo_aux; - assert(file != NULL); - - if (sc->fs_readonly) { - l9p_respond(req, EROFS); - return; - } - - size_t niov = l9p_truncate_iov(req->lr_data_iov, - req->lr_data_niov, req->lr_req.io.count); - -#if defined(__FreeBSD__) - ret = pwritev(file->fd, req->lr_data_iov, niov, - req->lr_req.io.offset); -#else - /* XXX: not thread safe, should really use aio_listio. */ - if (lseek(file->fd, (off_t)req->lr_req.io.offset, SEEK_SET) < 0) { - l9p_respond(req, errno); - return; - } - - ret = writev(file->fd, req->lr_data_iov, - (int)niov); -#endif - - if (ret < 0) { - l9p_respond(req, errno); - return; - } - - req->lr_resp.io.count = (uint32_t)ret; - l9p_respond(req, 0); -} - -static void -fs_wstat(void *softc, struct l9p_request *req) -{ - struct fs_softc *sc = softc; - struct openfile *file; - struct l9p_stat *l9stat = &req->lr_req.twstat.stat; - - file = req->lr_fid->lo_aux; - assert(file != NULL); - - /* - * XXX: - * - * stat(9P) sez: - * - * Either all the changes in wstat request happen, or none of them - * does: if the request succeeds, all changes were made; if it fails, - * none were. - * - * Atomicity is clearly missing in current implementation. - */ - - if (sc->fs_readonly) { - l9p_respond(req, EROFS); - return; - } - - if (l9stat->atime != (uint32_t)~0) { - /* XXX: not implemented, ignore */ - } - - if (l9stat->mtime != (uint32_t)~0) { - /* XXX: not implemented, ignore */ - } - - if (l9stat->dev != (uint32_t)~0) { - l9p_respond(req, EPERM); - return; - } - - if (l9stat->length != (uint64_t)~0) { - if (file->dir != NULL) { - l9p_respond(req, EINVAL); - return; - } - - if (truncate(file->name, (off_t)l9stat->length) != 0) { - l9p_respond(req, errno); - return; - } - } - - if (req->lr_conn->lc_version >= L9P_2000U) { - if (lchown(file->name, l9stat->n_uid, l9stat->n_gid) != 0) { - l9p_respond(req, errno); - return; - } - } - - if (l9stat->mode != (uint32_t)~0) { - if (chmod(file->name, l9stat->mode & 0777) != 0) { - l9p_respond(req, errno); - return; - } - } - - if (strlen(l9stat->name) > 0) { - /* XXX: not thread safe */ - char *dir = dirname(file->name); - char *newname; - - asprintf(&newname, "%s/%s", dir, l9stat->name); - rename(file->name, newname); - - free(newname); - } - - l9p_respond(req, 0); -} - -static void -fs_freefid(void *softc __unused, struct l9p_openfile *fid) -{ - struct openfile *f = fid->lo_aux; - - if (f == NULL) { - /* Nothing to do here */ - return; - } - - if (f->fd != -1) - close(f->fd); - - if (f->dir) - closedir(f->dir); - - free(f->name); - free(f); -} - -int -l9p_backend_fs_init(struct l9p_backend **backendp, const char *root) -{ - struct l9p_backend *backend; - struct fs_softc *sc; - - backend = l9p_malloc(sizeof(*backend)); - backend->attach = fs_attach; - backend->clunk = fs_clunk; - backend->create = fs_create; - backend->flush = fs_flush; - backend->open = fs_open; - backend->read = fs_read; - backend->remove = fs_remove; - backend->stat = fs_stat; - backend->walk = fs_walk; - backend->write = fs_write; - backend->wstat = fs_wstat; - backend->freefid = fs_freefid; - - sc = l9p_malloc(sizeof(*sc)); - sc->fs_rootpath = strdup(root); - sc->fs_readonly = false; - backend->softc = sc; - - setpassent(1); - - *backendp = backend; - return (0); -} diff --git a/lib9p/connection.c b/lib9p/connection.c deleted file mode 100644 index 2edbbba..0000000 --- a/lib9p/connection.c +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Copyright 2016 Jakub Klama - * All rights reserved - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted providing that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - */ - -#include -#include -#include -#include -#include -#include "lib9p.h" -#include "lib9p_impl.h" -#include "hashtable.h" -#include "log.h" - -int -l9p_server_init(struct l9p_server **serverp, struct l9p_backend *backend) -{ - struct l9p_server *server; - - server = l9p_calloc(1, sizeof (*server)); - server->ls_max_version = L9P_2000U; - server->ls_backend = backend; - LIST_INIT(&server->ls_conns); - - *serverp = server; - return (0); -} - -int -l9p_connection_init(struct l9p_server *server, struct l9p_connection **conn) -{ - struct l9p_connection *newconn; - - assert(server != NULL); - assert(conn != NULL); - - newconn = l9p_calloc(1, sizeof (*newconn)); - newconn->lc_server = server; - newconn->lc_msize = L9P_DEFAULT_MSIZE; - ht_init(&newconn->lc_files, 100); - ht_init(&newconn->lc_requests, 100); - LIST_INSERT_HEAD(&server->ls_conns, newconn, lc_link); - *conn = newconn; - - return (0); -} - -void -l9p_connection_free(struct l9p_connection *conn) -{ - - LIST_REMOVE(conn, lc_link); - free(conn); -} - -void -l9p_connection_on_send_response(struct l9p_connection *conn, - l9p_send_response_t cb, void *aux) -{ - - conn->lc_send_response = cb; - conn->lc_send_response_aux = aux; -} - -void -l9p_connection_on_get_response_buffer(struct l9p_connection *conn, - l9p_get_response_buffer_t cb, void *aux) -{ - - conn->lc_get_response_buffer = cb; - conn->lc_get_response_buffer_aux = aux; -} - -void -l9p_connection_recv(struct l9p_connection *conn, const struct iovec *iov, - const size_t niov, void *aux) -{ - struct l9p_request *req; - - req = l9p_calloc(1, sizeof (struct l9p_request)); - req->lr_aux = aux; - req->lr_conn = conn; - ht_add(&conn->lc_requests, req->lr_req.hdr.tag, req); - - req->lr_req_msg.lm_mode = L9P_UNPACK; - req->lr_req_msg.lm_niov = niov; - memcpy(req->lr_req_msg.lm_iov, iov, sizeof (struct iovec) * niov); - - req->lr_resp_msg.lm_mode = L9P_PACK; - - if (l9p_pufcall(&req->lr_req_msg, &req->lr_req, conn->lc_version) != 0) { - L9P_LOG(L9P_WARNING, "cannot unpack received message"); - return; - } - - if (conn->lc_get_response_buffer(req, req->lr_resp_msg.lm_iov, - &req->lr_resp_msg.lm_niov, conn->lc_get_response_buffer_aux) != 0) { - L9P_LOG(L9P_WARNING, "cannot obtain buffers for response"); - return; - } - - l9p_dispatch_request(req); -} - -void -l9p_connection_close(struct l9p_connection *conn) -{ - struct ht_iter iter; - struct l9p_openfile *fid; - struct l9p_request *req; - - /* Drain pending requests (if any) */ - ht_iter(&conn->lc_requests, &iter); - while ((req = ht_next(&iter)) != NULL) { - l9p_respond(req, EINTR); - ht_remove_at_iter(&iter); - } - - /* Close opened files (if any) */ - ht_iter(&conn->lc_files, &iter); - while ((fid = ht_next(&iter)) != NULL) { - conn->lc_server->ls_backend->freefid( - conn->lc_server->ls_backend->softc, fid); - ht_remove_at_iter(&iter); - } - - ht_destroy(&conn->lc_requests); - ht_destroy(&conn->lc_files); -} - -struct l9p_openfile * -l9p_connection_alloc_fid(struct l9p_connection *conn, uint32_t fid) -{ - struct l9p_openfile *file; - - file = l9p_calloc(1, sizeof (struct l9p_openfile)); - file->lo_fid = fid; - file->lo_conn = conn; - if (ht_add(&conn->lc_files, fid, file) != 0) { - free(file); - return (NULL); - } - - return (file); -} - -void -l9p_connection_remove_fid(struct l9p_connection *conn, struct l9p_openfile *fid) -{ - - conn->lc_server->ls_backend->freefid(conn->lc_server->ls_backend->softc, - fid); - - ht_remove(&conn->lc_files, fid->lo_fid); -} diff --git a/lib9p/example/server.c b/lib9p/example/server.c deleted file mode 100644 index 7241234..0000000 --- a/lib9p/example/server.c +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2016 Jakub Klama - * All rights reserved - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted providing that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - */ - -#include -#include -#include -#include "../lib9p.h" -#include "../transport/socket.h" -#include "../backend/fs.h" - -int -main(int argc, const char *argv[]) -{ - struct l9p_backend *fs_backend; - struct l9p_server *server; - - if (argc < 2) - errx(1, "Usage: server "); - - if (l9p_backend_fs_init(&fs_backend, argv[1]) != 0) - err(1, "cannot init backend"); - - if (l9p_server_init(&server, fs_backend) != 0) - err(1, "cannot create server"); - - server->ls_max_version = L9P_2000U; - l9p_start_server(server, "0.0.0.0", "564"); -} diff --git a/lib9p/fcall.h b/lib9p/fcall.h deleted file mode 100644 index a67cb7a..0000000 --- a/lib9p/fcall.h +++ /dev/null @@ -1,236 +0,0 @@ -/* - * Copyright 2016 Jakub Klama - * All rights reserved - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted providing that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - */ - -/* - * Based on libixp code: ©2007-2010 Kris Maglione - */ - -#ifndef LIB9P_FCALL_H -#define LIB9P_FCALL_H - -#include - -#define L9P_MAX_WELEM 256 - -enum l9p_ftype { - L9P_TVERSION = 100, - L9P_RVERSION, - L9P_TAUTH = 102, - L9P_RAUTH, - L9P_TATTACH = 104, - L9P_RATTACH, - L9P_TERROR = 106, /* illegal */ - L9P_RERROR, - L9P_TFLUSH = 108, - L9P_RFLUSH, - L9P_TWALK = 110, - L9P_RWALK, - L9P_TOPEN = 112, - L9P_ROPEN, - L9P_TCREATE = 114, - L9P_RCREATE, - L9P_TREAD = 116, - L9P_RREAD, - L9P_TWRITE = 118, - L9P_RWRITE, - L9P_TCLUNK = 120, - L9P_RCLUNK, - L9P_TREMOVE = 122, - L9P_RREMOVE, - L9P_TSTAT = 124, - L9P_RSTAT, - L9P_TWSTAT = 126, - L9P_RWSTAT, -}; - -enum l9p_qid_type { - L9P_QTDIR = 0x80, /* type bit for directories */ - L9P_QTAPPEND = 0x40, /* type bit for append only files */ - L9P_QTEXCL = 0x20, /* type bit for exclusive use files */ - L9P_QTMOUNT = 0x10, /* type bit for mounted channel */ - L9P_QTAUTH = 0x08, /* type bit for authentication file */ - L9P_QTTMP = 0x04, /* type bit for non-backed-up file */ - L9P_QTSYMLINK = 0x02, /* type bit for symbolic link */ - L9P_QTFILE = 0x00 /* type bits for plain file */ -}; - -#define L9P_DMDIR 0x80000000 -enum { - L9P_DMAPPEND = 0x40000000, - L9P_DMEXCL = 0x20000000, - L9P_DMMOUNT = 0x10000000, - L9P_DMAUTH = 0x08000000, - L9P_DMTMP = 0x04000000, - L9P_DMSYMLINK = 0x02000000, - /* 9P2000.u extensions */ - L9P_DMDEVICE = 0x00800000, - L9P_DMNAMEDPIPE = 0x00200000, - L9P_DMSOCKET = 0x00100000, - L9P_DMSETUID = 0x00080000, - L9P_DMSETGID = 0x00040000, -}; - -enum { - L9P_OREAD = 0, /* open for read */ - L9P_OWRITE = 1, /* write */ - L9P_ORDWR = 2, /* read and write */ - L9P_OEXEC = 3, /* execute, == read but check execute permission */ - L9P_OTRUNC = 16, /* or'ed in (except for exec), truncate file first */ - L9P_OCEXEC = 32, /* or'ed in, close on exec */ - L9P_ORCLOSE = 64, /* or'ed in, remove on close */ - L9P_ODIRECT = 128, /* or'ed in, direct access */ - L9P_ONONBLOCK = 256, /* or'ed in, non-blocking call */ - L9P_OEXCL = 0x1000, /* or'ed in, exclusive use (create only) */ - L9P_OLOCK = 0x2000, /* or'ed in, lock after opening */ - L9P_OAPPEND = 0x4000 /* or'ed in, append only */ -}; - -struct l9p_hdr { - uint8_t type; - uint16_t tag; - uint32_t fid; -}; - -struct l9p_qid { - enum l9p_qid_type type; - uint32_t version; - uint64_t path; -}; - -struct l9p_stat { - uint16_t type; - uint32_t dev; - struct l9p_qid qid; - uint32_t mode; - uint32_t atime; - uint32_t mtime; - uint64_t length; - char *name; - char *uid; - char *gid; - char *muid; - char *extension; - uid_t n_uid; - gid_t n_gid; - uid_t n_muid; -}; - -struct l9p_f_version { - struct l9p_hdr hdr; - uint32_t msize; - char *version; -}; - -struct l9p_f_tflush { - struct l9p_hdr hdr; - uint16_t oldtag; -}; - -struct l9p_f_error { - struct l9p_hdr hdr; - char *ename; - uint32_t errnum; -}; - -struct l9p_f_ropen { - struct l9p_hdr hdr; - struct l9p_qid qid; - uint32_t iounit; -}; - -struct l9p_f_rauth { - struct l9p_hdr hdr; - struct l9p_qid aqid; -}; - -struct l9p_f_attach { - struct l9p_hdr hdr; - uint32_t afid; - char *uname; - char *aname; - uid_t n_uname; -}; - -struct l9p_f_tcreate { - struct l9p_hdr hdr; - uint32_t perm; - char *name; - uint8_t mode; /* +Topen */ - char *extension; -}; - -struct l9p_f_twalk { - struct l9p_hdr hdr; - uint32_t newfid; - uint16_t nwname; - char *wname[L9P_MAX_WELEM]; -}; - -struct l9p_f_rwalk { - struct l9p_hdr hdr; - uint16_t nwqid; - struct l9p_qid wqid[L9P_MAX_WELEM]; -}; - -struct l9p_f_io { - struct l9p_hdr hdr; - uint64_t offset; /* Tread, Twrite */ - uint32_t count; /* Tread, Twrite, Rread */ - char *data; /* Twrite, Rread */ -}; - -struct l9p_f_rstat { - struct l9p_hdr hdr; - struct l9p_stat stat; -}; - -struct l9p_f_twstat { - struct l9p_hdr hdr; - struct l9p_stat stat; -}; - -union l9p_fcall { - struct l9p_hdr hdr; - struct l9p_f_version version; - struct l9p_f_tflush tflush; - struct l9p_f_ropen ropen; - struct l9p_f_ropen rcreate; - struct l9p_f_ropen rattach; - struct l9p_f_error error; - struct l9p_f_rauth rauth; - struct l9p_f_attach tattach; - struct l9p_f_attach tauth; - struct l9p_f_tcreate tcreate; - struct l9p_f_tcreate topen; - struct l9p_f_twalk twalk; - struct l9p_f_rwalk rwalk; - struct l9p_f_twstat twstat; - struct l9p_f_rstat rstat; - struct l9p_f_io io; -}; - -#endif /* LIB9P_FCALL_H */ diff --git a/lib9p/hashtable.c b/lib9p/hashtable.c deleted file mode 100644 index 0e2bd4e..0000000 --- a/lib9p/hashtable.c +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Copyright 2016 Jakub Klama - * All rights reserved - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted providing that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - */ - -#include -#include -#include -#include -#include -#include -#include "lib9p_impl.h" -#include "hashtable.h" - -void -ht_init(struct ht *h, size_t size) -{ - size_t i; - - memset(h, 0, sizeof(struct ht)); - h->ht_nentries = size; - h->ht_entries = l9p_calloc(size, sizeof(struct ht_entry)); - - for (i = 0; i < size; i++) - TAILQ_INIT(&h->ht_entries[i].hte_items); -} - -void -ht_destroy(struct ht *h) -{ - struct ht_entry *he; - struct ht_item *hi; - size_t i; - - for (i = 0; i < h->ht_nentries; i++) { - he = &h->ht_entries[i]; - hi = TAILQ_FIRST(&he->hte_items); - - while ((hi = TAILQ_NEXT(hi, hti_link)) != NULL) - TAILQ_REMOVE(&he->hte_items, hi, hti_link); - } - - free(h->ht_entries); - free(h); -} - -void * -ht_find(struct ht *h, uint32_t hash) -{ - struct ht_entry *entry; - struct ht_item *item; - - entry = &h->ht_entries[hash % h->ht_nentries]; - - TAILQ_FOREACH(item, &entry->hte_items, hti_link) { - if (item->hti_hash == hash) - return (item->hti_data); - } - - return (NULL); -} - -int -ht_add(struct ht *h, uint32_t hash, void *value) -{ - struct ht_entry *entry; - struct ht_item *item; - - entry = &h->ht_entries[hash % h->ht_nentries]; - - TAILQ_FOREACH(item, &entry->hte_items, hti_link) { - if (item->hti_hash == hash) { - errno = EEXIST; - return (-1); - } - } - - item = l9p_calloc(1, sizeof(struct ht_item)); - item->hti_hash = hash; - item->hti_data = value; - TAILQ_INSERT_TAIL(&entry->hte_items, item, hti_link); - - return (0); -} - -int -ht_remove(struct ht *h, uint32_t hash) -{ - struct ht_entry *entry; - struct ht_item *item, *tmp; - size_t slot = hash % h->ht_nentries; - - entry = &h->ht_entries[slot]; - - TAILQ_FOREACH_SAFE(item, &entry->hte_items, hti_link, tmp) { - if (item->hti_hash == hash) { - TAILQ_REMOVE(&entry->hte_items, item, hti_link); - free(item->hti_data); - free(item); - return (0); - } - } - - errno = ENOENT; - return (-1); -} - -int -ht_remove_at_iter(struct ht_iter *iter) -{ - assert(iter != NULL); - - if (iter->htit_cursor == NULL) { - errno = EINVAL; - return (-1); - } - - TAILQ_REMOVE(&iter->htit_parent->ht_entries[iter->htit_slot].hte_items, - iter->htit_cursor, hti_link); - return (0); -} - -void -ht_iter(struct ht *h, struct ht_iter *iter) -{ - iter->htit_parent = h; - iter->htit_slot = 0; - iter->htit_cursor = TAILQ_FIRST(&h->ht_entries[0].hte_items); -} - -void * -ht_next(struct ht_iter *iter) -{ - struct ht_item *item; - - item = iter->htit_cursor; - -retry: - if ((iter->htit_cursor = TAILQ_NEXT(iter->htit_cursor, hti_link)) == NULL) - { - if (iter->htit_slot == iter->htit_parent->ht_nentries) - return (NULL); - - iter->htit_slot++; - goto retry; - - } - - return (item); -} diff --git a/lib9p/hashtable.h b/lib9p/hashtable.h deleted file mode 100644 index 0b28385..0000000 --- a/lib9p/hashtable.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 2016 Jakub Klama - * All rights reserved - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted providing that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - */ - -#ifndef LIB9P_HASHTABLE_H -#define LIB9P_HASHTABLE_H - -#include - -struct ht { - struct ht_entry * ht_entries; - size_t ht_nentries; -}; - -struct ht_entry { - TAILQ_HEAD(, ht_item) hte_items; -}; - -struct ht_item { - uint32_t hti_hash; - void * hti_data; - TAILQ_ENTRY(ht_item) hti_link; -}; - -struct ht_iter { - struct ht * htit_parent; - struct ht_item * htit_cursor; - size_t htit_slot; -}; - -void ht_init(struct ht *h, size_t size); -void ht_destroy(struct ht *h); -void *ht_find(struct ht *h, uint32_t hash); -int ht_add(struct ht *h, uint32_t hash, void *value); -int ht_remove(struct ht *h, uint32_t hash); -int ht_remove_at_iter(struct ht_iter *iter); -void ht_iter(struct ht *h, struct ht_iter *iter); -void *ht_next(struct ht_iter *iter); - -#endif /* LIB9P_HASHTABLE_H */ diff --git a/lib9p/lib9p.h b/lib9p/lib9p.h deleted file mode 100644 index 4de3d26..0000000 --- a/lib9p/lib9p.h +++ /dev/null @@ -1,186 +0,0 @@ -/* - * Copyright 2016 Jakub Klama - * All rights reserved - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted providing that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - */ - - -#ifndef LIB9P_LIB9P_H -#define LIB9P_LIB9P_H - -#include -#include -#include -#include -#include - -#if defined(__FreeBSD__) -#include -#else -#include "sbuf/sbuf.h" -#endif - -#include "fcall.h" -#include "hashtable.h" - -#define L9P_DEFAULT_MSIZE 8192 -#define L9P_MAX_IOV 8 - -struct l9p_request; - -typedef int (l9p_get_response_buffer_t) (struct l9p_request *, - struct iovec *, size_t *, void *); - -typedef int (l9p_send_response_t) (struct l9p_request *, const struct iovec *, - const size_t, const size_t, void *); - -enum l9p_pack_mode { - L9P_PACK, - L9P_UNPACK -}; - -enum l9p_integer_type { - L9P_BYTE = 1, - L9P_WORD = 2, - L9P_DWORD = 4, - L9P_QWORD = 8 -}; - -enum l9p_version { - L9P_2000 = 0, - L9P_2000U = 1, - L9P_2000L = 2, - L9P_INVALID_VERSION = 3 -}; - -struct l9p_message { - enum l9p_pack_mode lm_mode; - struct iovec lm_iov[L9P_MAX_IOV]; - size_t lm_niov; - size_t lm_cursor_iov; - size_t lm_cursor_offset; - size_t lm_size; -}; - -struct l9p_request { - uint32_t lr_tag; - struct l9p_message lr_req_msg; - struct l9p_message lr_resp_msg; - struct l9p_message lr_readdir_msg; - union l9p_fcall lr_req; - union l9p_fcall lr_resp; - struct l9p_openfile *lr_fid; - struct l9p_openfile *lr_newfid; - struct l9p_connection *lr_conn; - pthread_t lr_thread; - void *lr_aux; - struct iovec lr_data_iov[L9P_MAX_IOV]; - size_t lr_data_niov; -}; - -struct l9p_openfile { - void *lo_aux; - uint32_t lo_fid; - struct l9p_qid lo_qid; - struct l9p_connection *lo_conn; -}; - -struct l9p_connection { - struct l9p_server *lc_server; - enum l9p_version lc_version; - pthread_mutex_t lc_send_lock; - uint32_t lc_msize; - uint32_t lc_max_io_size; - l9p_send_response_t *lc_send_response; - l9p_get_response_buffer_t *lc_get_response_buffer; - void *lc_get_response_buffer_aux; - void *lc_send_response_aux; - void *lc_softc; - struct ht lc_files; - struct ht lc_requests; - LIST_ENTRY(l9p_connection) lc_link; -}; - -struct l9p_server { - struct l9p_backend *ls_backend; - enum l9p_version ls_max_version; - LIST_HEAD(, l9p_connection) ls_conns; -}; - -struct l9p_backend { - void *softc; - void (*attach)(void *, struct l9p_request *); - void (*clunk)(void *, struct l9p_request *); - void (*create)(void *, struct l9p_request *); - void (*flush)(void *, struct l9p_request *); - void (*open)(void *, struct l9p_request *); - void (*read)(void *, struct l9p_request *); - void (*remove)(void *, struct l9p_request *); - void (*stat)(void *, struct l9p_request *); - void (*walk)(void *, struct l9p_request *); - void (*write)(void *, struct l9p_request *); - void (*wstat)(void *, struct l9p_request *); - void (*freefid)(void *, struct l9p_openfile *); -}; - -int l9p_pufcall(struct l9p_message *msg, union l9p_fcall *fcall, - enum l9p_version version); -int l9p_pustat(struct l9p_message *msg, struct l9p_stat *s, - enum l9p_version version); -uint16_t l9p_sizeof_stat(struct l9p_stat *stat, enum l9p_version version); -int l9p_pack_stat(struct l9p_request *req, struct l9p_stat *s); - -int l9p_server_init(struct l9p_server **serverp, struct l9p_backend *backend); - -int l9p_connection_init(struct l9p_server *server, - struct l9p_connection **connp); -void l9p_connection_free(struct l9p_connection *conn); -void l9p_connection_on_send_response(struct l9p_connection *conn, - l9p_send_response_t *cb, void *aux); -void l9p_connection_on_get_response_buffer(struct l9p_connection *conn, - l9p_get_response_buffer_t *cb, void *aux); -void l9p_connection_recv(struct l9p_connection *conn, const struct iovec *iov, - size_t niov, void *aux); -void l9p_connection_close(struct l9p_connection *conn); -struct l9p_openfile *l9p_connection_alloc_fid(struct l9p_connection *conn, - uint32_t fid); -void l9p_connection_remove_fid(struct l9p_connection *conn, - struct l9p_openfile *fid); - -void l9p_dispatch_request(struct l9p_request *req); -void l9p_respond(struct l9p_request *req, int errnum); - -void l9p_seek_iov(struct iovec *iov1, size_t niov1, struct iovec *iov2, - size_t *niov2, size_t seek); -size_t l9p_truncate_iov(struct iovec *iov, size_t niov, size_t length); -void l9p_describe_qid(struct l9p_qid *qid, struct sbuf *sb); -void l9p_describe_fcall(union l9p_fcall *fcall, enum l9p_version version, - struct sbuf *sb); -void l9p_describe_stat(struct l9p_stat *st, struct sbuf *sb); -void l9p_freefcall(union l9p_fcall *fcall); -void l9p_freestat(struct l9p_stat *stat); - -int l9p_backend_fs_init(struct l9p_backend **backendp, const char *root); - -#endif /* LIB9P_LIB9P_H */ diff --git a/lib9p/lib9p_impl.h b/lib9p/lib9p_impl.h deleted file mode 100644 index 3653517..0000000 --- a/lib9p/lib9p_impl.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright 2016 Jakub Klama - * All rights reserved - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted providing that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - */ - -#ifndef LIB9P_LIB9P_IMPL_H -#define LIB9P_LIB9P_IMPL_H - -#include -#include - -#ifndef _KERNEL -static inline void * -l9p_malloc(size_t size) -{ - void *r = malloc(size); - - if (r == NULL) { - fprintf(stderr, "cannot allocate %zd bytes: out of memory\n", - size); - abort(); - } - - return (r); -} - -static inline void * -l9p_calloc(size_t n, size_t size) -{ - void *r = calloc(n, size); - - if (r == NULL) { - fprintf(stderr, "cannot allocate %zd bytes: out of memory\n", - n * size); - abort(); - } - - return (r); -} - -static inline void * -l9p_realloc(void *ptr, size_t newsize) -{ - void *r = realloc(ptr, newsize); - - if (r == NULL) { - fprintf(stderr, "cannot allocate %zd bytes: out of memory\n", - newsize); - abort(); - } - - return (r); -} -#endif /* _KERNEL */ - -#endif /* LIB9P_LIB9P_IMPL_H */ diff --git a/lib9p/log.c b/lib9p/log.c deleted file mode 100644 index ff65b3f..0000000 --- a/lib9p/log.c +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2016 Jakub Klama - * All rights reserved - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted providing that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - */ - -#include -#include -#include "log.h" - -static const char *l9p_log_level_names[] = { - "DEBUG", - "INFO", - "WARN", - "ERROR" -}; - -void -l9p_logf(enum l9p_log_level level, const char *func, const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - fprintf(stderr, "[%s]\t %s: ", l9p_log_level_names[level], func); - vfprintf(stderr, fmt, ap); - fprintf(stderr, "\n"); - va_end(ap); -} diff --git a/lib9p/log.h b/lib9p/log.h deleted file mode 100644 index 7d3d8d3..0000000 --- a/lib9p/log.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2016 Jakub Klama - * All rights reserved - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted providing that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - */ - -#ifndef LIB9P_LOG_H -#define LIB9P_LOG_H - -enum l9p_log_level -{ - L9P_DEBUG, - L9P_INFO, - L9P_WARNING, - L9P_ERROR -}; - -void l9p_logf(enum l9p_log_level level, const char *func, const char *fmt, ...); - -#if defined(L9P_DEBUG) -#define L9P_LOG(level, fmt, ...) l9p_logf(level, __func__, fmt, ##__VA_ARGS__) -#else -#define L9P_LOG(level, fmt, ...) -#endif - -#endif /* LIB9P_LOG_H */ diff --git a/lib9p/pack.c b/lib9p/pack.c deleted file mode 100644 index 13758c5..0000000 --- a/lib9p/pack.c +++ /dev/null @@ -1,453 +0,0 @@ -/* - * Copyright 2016 Jakub Klama - * All rights reserved - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted providing that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - */ - -/* - * Based on libixp code: ©2007-2010 Kris Maglione - */ - -#include -#include -#include -#include -#include -#include -#include "lib9p.h" -#include "lib9p_impl.h" - -#define N(ary) (sizeof(ary) / sizeof(*ary)) -#define STRING_SIZE(s) (L9P_WORD + (s != NULL ? (uint16_t)strlen(s) : 0)) -#define QID_SIZE (L9P_BYTE + L9P_DWORD + L9P_QWORD) - -static int l9p_iov_io(struct l9p_message *, void *, size_t); -static inline int l9p_pu8(struct l9p_message *, uint8_t *); -static inline int l9p_pu16(struct l9p_message *, uint16_t *); -static inline int l9p_pu32(struct l9p_message *, uint32_t *); -static inline int l9p_pu64(struct l9p_message *, uint64_t *); -static int l9p_pustring(struct l9p_message *, char **s); -static int l9p_pustrings(struct l9p_message *, uint16_t *, char *[], size_t); -static int l9p_puqid(struct l9p_message *, struct l9p_qid *); -static int l9p_puqids(struct l9p_message *, uint16_t *, struct l9p_qid *q); - -static int -l9p_iov_io(struct l9p_message *msg, void *buffer, size_t len) -{ - size_t done = 0; - size_t left = len; - - assert(msg != NULL); - - if (len == 0) - return (0); - - if (msg->lm_cursor_iov >= msg->lm_niov) - return (-1); - - assert(buffer != NULL); - - while (left > 0) { - size_t idx = msg->lm_cursor_iov; - size_t space = msg->lm_iov[idx].iov_len - msg->lm_cursor_offset; - size_t towrite = MIN(space, left); - - if (msg->lm_mode == L9P_PACK) { - memcpy((char *)msg->lm_iov[idx].iov_base + - msg->lm_cursor_offset, (char *)buffer + done, - towrite); - } - - if (msg->lm_mode == L9P_UNPACK) { - memcpy((char *)buffer + done, - (char *)msg->lm_iov[idx].iov_base + - msg->lm_cursor_offset, towrite); - } - - msg->lm_cursor_offset += towrite; - - if (space - towrite == 0) { - /* Advance to next iov */ - msg->lm_cursor_iov++; - msg->lm_cursor_offset = 0; - - if (msg->lm_cursor_iov > msg->lm_niov) - return (-1); - } - - done += towrite; - left -= towrite; - } - - msg->lm_size += done; - return ((int)done); -} - -static inline int -l9p_pu8(struct l9p_message *msg, uint8_t *val) -{ - - return (l9p_iov_io(msg, val, sizeof (uint8_t))); -} - -static inline int -l9p_pu16(struct l9p_message *msg, uint16_t *val) -{ - - return (l9p_iov_io(msg, val, sizeof (uint16_t))); -} - -static inline int -l9p_pu32(struct l9p_message *msg, uint32_t *val) -{ - - return (l9p_iov_io(msg, val, sizeof (uint32_t))); -} - -static inline int -l9p_pu64(struct l9p_message *msg, uint64_t *val) -{ - - return (l9p_iov_io(msg, val, sizeof (uint64_t))); -} - -static int -l9p_pustring(struct l9p_message *msg, char **s) -{ - uint16_t len; - - if (msg->lm_mode == L9P_PACK) - len = *s != NULL ? (uint16_t)strlen(*s) : 0; - - if (l9p_pu16(msg, &len) < 0) - return (-1); - - if (msg->lm_mode == L9P_UNPACK) - *s = l9p_calloc(1, len + 1); - - if (l9p_iov_io(msg, *s, len) < 0) - return (-1); - - return (len + 2); -} - -static int -l9p_pustrings(struct l9p_message *msg, uint16_t *num, char *strings[], - size_t max) -{ - size_t i; - int ret; - int r = 0; - - l9p_pu16(msg, num); - - for (i = 0; i < MIN(*num, max); i++) { - ret = l9p_pustring(msg, &strings[i]); - if (ret < 1) - return (-1); - - r += ret; - } - - return (r); -} - -static int -l9p_puqid(struct l9p_message *msg, struct l9p_qid *qid) -{ - int r = 0; - - r += l9p_pu8(msg, (uint8_t *) & qid->type); - r += l9p_pu32(msg, &qid->version); - r += l9p_pu64(msg, &qid->path); - - return (r); -} - -static int -l9p_puqids(struct l9p_message *msg, uint16_t *num, struct l9p_qid *qids) -{ - int i, ret, r = 0; - l9p_pu16(msg, num); - - for (i = 0; i < *num; i++) { - ret = l9p_puqid(msg, &qids[i]); - if (ret < 0) - return (-1); - - r += ret; - } - - return (r); -} - -int -l9p_pustat(struct l9p_message *msg, struct l9p_stat *stat, - enum l9p_version version) -{ - int r = 0; - uint16_t size; - - if (msg->lm_mode == L9P_PACK) - size = l9p_sizeof_stat(stat, version) - 2; - - r += l9p_pu16(msg, &size); - r += l9p_pu16(msg, &stat->type); - r += l9p_pu32(msg, &stat->dev); - r += l9p_puqid(msg, &stat->qid); - r += l9p_pu32(msg, &stat->mode); - r += l9p_pu32(msg, &stat->atime); - r += l9p_pu32(msg, &stat->mtime); - r += l9p_pu64(msg, &stat->length); - r += l9p_pustring(msg, &stat->name); - r += l9p_pustring(msg, &stat->uid); - r += l9p_pustring(msg, &stat->gid); - r += l9p_pustring(msg, &stat->muid); - - if (version == L9P_2000U) { - r += l9p_pustring(msg, &stat->extension); - r += l9p_pu32(msg, &stat->n_uid); - r += l9p_pu32(msg, &stat->n_gid); - r += l9p_pu32(msg, &stat->n_muid); - } - - if (r < size + 2) - return (-1); - - return (r); -} - -int -l9p_pufcall(struct l9p_message *msg, union l9p_fcall *fcall, - enum l9p_version version) -{ - uint32_t length = 0; - - l9p_pu32(msg, &length); - l9p_pu8(msg, &fcall->hdr.type); - l9p_pu16(msg, &fcall->hdr.tag); - - switch (fcall->hdr.type) { - case L9P_TVERSION: - case L9P_RVERSION: - l9p_pu32(msg, &fcall->version.msize); - l9p_pustring(msg, &fcall->version.version); - break; - - case L9P_TAUTH: - l9p_pu32(msg, &fcall->tauth.afid); - l9p_pustring(msg, &fcall->tauth.uname); - l9p_pustring(msg, &fcall->tauth.aname); - if (version == L9P_2000U) - l9p_pu32(msg, &fcall->tauth.n_uname); - break; - - case L9P_RAUTH: - l9p_puqid(msg, &fcall->rauth.aqid); - break; - - case L9P_RATTACH: - l9p_puqid(msg, &fcall->rattach.qid); - break; - - case L9P_TATTACH: - l9p_pu32(msg, &fcall->hdr.fid); - l9p_pu32(msg, &fcall->tattach.afid); - l9p_pustring(msg, &fcall->tattach.uname); - l9p_pustring(msg, &fcall->tattach.aname); - if (version == L9P_2000U) - l9p_pu32(msg, &fcall->tattach.n_uname); - break; - - case L9P_RERROR: - l9p_pustring(msg, &fcall->error.ename); - if (version == L9P_2000U) - l9p_pu32(msg, &fcall->error.errnum); - break; - - case L9P_TFLUSH: - l9p_pu16(msg, &fcall->tflush.oldtag); - break; - - case L9P_TWALK: - l9p_pu32(msg, &fcall->hdr.fid); - l9p_pu32(msg, &fcall->twalk.newfid); - l9p_pustrings(msg, &fcall->twalk.nwname, - fcall->twalk.wname, N(fcall->twalk.wname)); - break; - - case L9P_RWALK: - l9p_puqids(msg, &fcall->rwalk.nwqid, fcall->rwalk.wqid); - break; - - case L9P_TOPEN: - l9p_pu32(msg, &fcall->hdr.fid); - l9p_pu8(msg, &fcall->topen.mode); - break; - - case L9P_ROPEN: - case L9P_RCREATE: - l9p_puqid(msg, &fcall->ropen.qid); - l9p_pu32(msg, &fcall->ropen.iounit); - break; - - case L9P_TCREATE: - l9p_pu32(msg, &fcall->hdr.fid); - l9p_pustring(msg, &fcall->tcreate.name); - l9p_pu32(msg, &fcall->tcreate.perm); - l9p_pu8(msg, &fcall->tcreate.mode); - if (version == L9P_2000U) - l9p_pustring(msg, &fcall->tcreate.extension); - break; - - case L9P_TREAD: - l9p_pu32(msg, &fcall->hdr.fid); - l9p_pu64(msg, &fcall->io.offset); - l9p_pu32(msg, &fcall->io.count); - break; - - case L9P_RREAD: - l9p_pu32(msg, &fcall->io.count); - break; - - case L9P_TWRITE: - l9p_pu32(msg, &fcall->hdr.fid); - l9p_pu64(msg, &fcall->io.offset); - l9p_pu32(msg, &fcall->io.count); - break; - - case L9P_RWRITE: - l9p_pu32(msg, &fcall->io.count); - break; - - case L9P_TCLUNK: - case L9P_TSTAT: - case L9P_TREMOVE: - l9p_pu32(msg, &fcall->hdr.fid); - break; - - case L9P_RSTAT: - { - uint16_t size = l9p_sizeof_stat(&fcall->rstat.stat, - version); - l9p_pu16(msg, &size); - l9p_pustat(msg, &fcall->rstat.stat, version); - } - break; - - case L9P_TWSTAT: - { - uint16_t size; - l9p_pu32(msg, &fcall->hdr.fid); - l9p_pu16(msg, &size); - l9p_pustat(msg, &fcall->twstat.stat, version); - } - break; - } - - if (msg->lm_mode == L9P_PACK) { - /* Rewind to the beginning */ - uint32_t len = (uint32_t)msg->lm_size; - msg->lm_cursor_offset = 0; - msg->lm_cursor_iov = 0; - - /* - * Subtract 4 bytes from message size, becase we're - * overwriting size (rewinding message to the beginning) - * and writing again. - */ - msg->lm_size -= sizeof (uint32_t); - - if (fcall->hdr.type == L9P_RREAD) - len += fcall->io.count; - - l9p_pu32(msg, &len); - } - - return (0); -} - -void -l9p_freefcall(union l9p_fcall *fcall) -{ - uint16_t i; - - switch (fcall->hdr.type) { - case L9P_TVERSION: - case L9P_RVERSION: - free(fcall->version.version); - return; - case L9P_TATTACH: - free(fcall->tattach.aname); - free(fcall->tattach.uname); - return; - case L9P_TWALK: - for (i = 0; i < fcall->twalk.nwname; i++) - free(fcall->twalk.wname[i]); - return; - case L9P_TCREATE: - case L9P_TOPEN: - free(fcall->tcreate.name); - free(fcall->tcreate.extension); - return; - case L9P_RSTAT: - l9p_freestat(&fcall->rstat.stat); - return; - case L9P_TWSTAT: - l9p_freestat(&fcall->twstat.stat); - return; - } -} - -void -l9p_freestat(struct l9p_stat *stat) -{ - free(stat->name); - free(stat->extension); - free(stat->uid); - free(stat->gid); - free(stat->muid); -} - -uint16_t -l9p_sizeof_stat(struct l9p_stat *stat, enum l9p_version version) -{ - uint16_t size = L9P_WORD /* size */ - + L9P_WORD /* type */ - + L9P_DWORD /* dev */ - + QID_SIZE /* qid */ - + 3 * L9P_DWORD /* mode, atime, mtime */ - + L9P_QWORD /* length */ - + STRING_SIZE(stat->name) - + STRING_SIZE(stat->uid) - + STRING_SIZE(stat->gid) - + STRING_SIZE(stat->muid); - - if (version == L9P_2000U) { - size += STRING_SIZE(stat->extension) - + 3 * L9P_DWORD; - } - - return (size); -} diff --git a/lib9p/request.c b/lib9p/request.c deleted file mode 100644 index 5ff1aa7..0000000 --- a/lib9p/request.c +++ /dev/null @@ -1,444 +0,0 @@ -/* - * Copyright 2016 Jakub Klama - * All rights reserved - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted providing that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - */ - -#include -#include -#include -#include -#include -#if defined(__FreeBSD__) -#include -#else -#include "sbuf/sbuf.h" -#endif -#include "lib9p.h" -#include "lib9p_impl.h" -#include "fcall.h" -#include "hashtable.h" -#include "log.h" - -#define N(x) (sizeof(x) / sizeof(x[0])) - -static void l9p_dispatch_tversion(struct l9p_request *req); -static void l9p_dispatch_tattach(struct l9p_request *req); -static void l9p_dispatch_tclunk(struct l9p_request *req); -static void l9p_dispatch_tflush(struct l9p_request *req); -static void l9p_dispatch_tcreate(struct l9p_request *req); -static void l9p_dispatch_topen(struct l9p_request *req); -static void l9p_dispatch_tread(struct l9p_request *req); -static void l9p_dispatch_tremove(struct l9p_request *req); -static void l9p_dispatch_tstat(struct l9p_request *req); -static void l9p_dispatch_twalk(struct l9p_request *req); -static void l9p_dispatch_twrite(struct l9p_request *req); -static void l9p_dispatch_twstat(struct l9p_request *req); - -static const struct -{ - enum l9p_ftype type; - void (*handler)(struct l9p_request *); -} l9p_handlers[] = { - {L9P_TVERSION, l9p_dispatch_tversion}, - {L9P_TATTACH, l9p_dispatch_tattach}, - {L9P_TCLUNK, l9p_dispatch_tclunk}, - {L9P_TFLUSH, l9p_dispatch_tflush}, - {L9P_TCREATE, l9p_dispatch_tcreate}, - {L9P_TOPEN, l9p_dispatch_topen}, - {L9P_TREAD, l9p_dispatch_tread}, - {L9P_TWRITE, l9p_dispatch_twrite}, - {L9P_TREMOVE, l9p_dispatch_tremove}, - {L9P_TSTAT, l9p_dispatch_tstat}, - {L9P_TWALK, l9p_dispatch_twalk}, - {L9P_TWSTAT, l9p_dispatch_twstat} -}; - -static const char *l9p_versions[] = { - "9P2000", - "9P2000.u", - "9P2000.L" -}; - -void -l9p_dispatch_request(struct l9p_request *req) -{ -#if defined(L9P_DEBUG) - struct sbuf *sb; -#endif - size_t i; - -#if defined(L9P_DEBUG) - sb = sbuf_new_auto(); - l9p_describe_fcall(&req->lr_req, req->lr_conn->lc_version, sb); - sbuf_done(sb); - - L9P_LOG(L9P_DEBUG, "%s", sbuf_data(sb)); - sbuf_delete(sb); -#endif - - req->lr_tag = req->lr_req.hdr.tag; - - for (i = 0; i < N(l9p_handlers); i++) { - if (req->lr_req.hdr.type == l9p_handlers[i].type) { - l9p_handlers[i].handler(req); - return; - } - } - - L9P_LOG(L9P_WARNING, "unknown request of type %d", req->lr_req.hdr.type); - l9p_respond(req, ENOSYS); -} - -void -l9p_respond(struct l9p_request *req, int errnum) -{ - struct l9p_connection *conn = req->lr_conn; - size_t iosize; -#if defined(L9P_DEBUG) - struct sbuf *sb; -#endif - - switch (req->lr_req.hdr.type) { - case L9P_TATTACH: - if (errnum != 0) - l9p_connection_remove_fid(conn, req->lr_fid); - - break; - case L9P_TCLUNK: - case L9P_TREMOVE: - if (req->lr_fid != NULL) - l9p_connection_remove_fid(conn, req->lr_fid); - break; - - case L9P_TWALK: - if (errnum != 0 && req->lr_newfid != NULL && - req->lr_newfid != req->lr_fid) - l9p_connection_remove_fid(conn, req->lr_newfid); - - break; - } - - req->lr_resp.hdr.tag = req->lr_req.hdr.tag; - - if (errnum == 0) - req->lr_resp.hdr.type = req->lr_req.hdr.type + 1; - else { - req->lr_resp.hdr.type = L9P_RERROR; - req->lr_resp.error.ename = strerror(errnum); - req->lr_resp.error.errnum = (uint32_t)errnum; - } - -#if defined(L9P_DEBUG) - sb = sbuf_new_auto(); - l9p_describe_fcall(&req->lr_resp, L9P_2000, sb); - sbuf_done(sb); - - L9P_LOG(L9P_DEBUG, "%s", sbuf_data(sb)); - sbuf_delete(sb); -#endif - - if (l9p_pufcall(&req->lr_resp_msg, &req->lr_resp, conn->lc_version) != 0) { - L9P_LOG(L9P_ERROR, "cannot pack response"); - goto out; - } - - iosize = req->lr_resp_msg.lm_size; - - /* Include I/O size in calculation for Rread response */ - if (req->lr_resp.hdr.type == L9P_RREAD) - iosize += req->lr_resp.io.count; - - conn->lc_send_response(req, req->lr_resp_msg.lm_iov, - req->lr_resp_msg.lm_niov, iosize, conn->lc_send_response_aux); - -out: - l9p_freefcall(&req->lr_req); - l9p_freefcall(&req->lr_resp); - free(req); -} - -int -l9p_pack_stat(struct l9p_request *req, struct l9p_stat *st) -{ - struct l9p_connection *conn = req->lr_conn; - struct l9p_message *msg = &req->lr_readdir_msg; - uint16_t size = l9p_sizeof_stat(st, conn->lc_version); - - if (msg->lm_size == 0) { - /* Initialize message */ - msg->lm_mode = L9P_PACK; - msg->lm_niov = req->lr_data_niov; - memcpy(msg->lm_iov, req->lr_data_iov, - sizeof (struct iovec) * req->lr_data_niov); - } - - if (req->lr_resp.io.count + size > req->lr_req.io.count) { - l9p_freestat(st); - return (-1); - } - - if (l9p_pustat(msg, st, conn->lc_version) < 0) { - l9p_freestat(st); - return (-1); - } - - req->lr_resp.io.count += size; - l9p_freestat(st); - return (0); -} - -static void -l9p_dispatch_tversion(struct l9p_request *req) -{ - struct l9p_connection *conn = req->lr_conn; - enum l9p_version remote_version = L9P_INVALID_VERSION; - size_t i; - - for (i = 0; i < N(l9p_versions); i++) { - if (strcmp(req->lr_req.version.version, l9p_versions[i]) == 0) { - remote_version = (enum l9p_version)i; - break; - } - } - - if (remote_version == L9P_INVALID_VERSION) { - L9P_LOG(L9P_ERROR, "unsupported remote version: %s", - req->lr_req.version.version); - l9p_respond(req, ENOSYS); - return; - } - - L9P_LOG(L9P_INFO, "remote version: %s", l9p_versions[remote_version]); - L9P_LOG(L9P_INFO, "local version: %s", - l9p_versions[conn->lc_server->ls_max_version]); - - conn->lc_version = MIN(remote_version, conn->lc_server->ls_max_version); - conn->lc_msize = MIN(req->lr_req.version.msize, conn->lc_msize); - conn->lc_max_io_size = conn->lc_msize - 24; - req->lr_resp.version.version = strdup(l9p_versions[conn->lc_version]); - req->lr_resp.version.msize = conn->lc_msize; - l9p_respond(req, 0); -} - -static void -l9p_dispatch_tattach(struct l9p_request *req) -{ - struct l9p_connection *conn = req->lr_conn; - - req->lr_fid = l9p_connection_alloc_fid(conn, req->lr_req.hdr.fid); - if (req->lr_fid == NULL) - req->lr_fid = ht_find(&conn->lc_files, req->lr_req.hdr.fid); - - conn->lc_server->ls_backend->attach(conn->lc_server->ls_backend->softc, req); -} - -static void -l9p_dispatch_tclunk(struct l9p_request *req) -{ - struct l9p_connection *conn = req->lr_conn; - - req->lr_fid = ht_find(&conn->lc_files, req->lr_req.hdr.fid); - if (req->lr_fid == NULL) { - l9p_respond(req, EBADF); - return; - } - - conn->lc_server->ls_backend->clunk(conn->lc_server->ls_backend->softc, req); -} - -static void -l9p_dispatch_tflush(struct l9p_request *req) -{ - struct l9p_connection *conn = req->lr_conn; - - if (!conn->lc_server->ls_backend->flush) { - l9p_respond(req, ENOSYS); - return; - } - - conn->lc_server->ls_backend->flush(conn->lc_server->ls_backend->softc, req); -} - -static void -l9p_dispatch_tcreate(struct l9p_request *req) -{ - struct l9p_connection *conn = req->lr_conn; - - req->lr_fid = ht_find(&conn->lc_files, req->lr_req.hdr.fid); - if (req->lr_fid == NULL) { - l9p_respond(req, EBADF); - return; - } - - if (!conn->lc_server->ls_backend->create) { - l9p_respond(req, ENOSYS); - return; - } - - conn->lc_server->ls_backend->create(conn->lc_server->ls_backend->softc, req); -} - -static void -l9p_dispatch_topen(struct l9p_request *req) -{ - struct l9p_connection *conn = req->lr_conn; - - req->lr_fid = ht_find(&conn->lc_files, req->lr_req.hdr.fid); - if (!req->lr_fid) { - l9p_respond(req, EBADF); - return; - } - - if (!conn->lc_server->ls_backend->open) { - l9p_respond(req, ENOSYS); - return; - } - - conn->lc_server->ls_backend->open(conn->lc_server->ls_backend->softc, req); -} - -static void -l9p_dispatch_tread(struct l9p_request *req) -{ - struct l9p_connection *conn = req->lr_conn; - - req->lr_fid = ht_find(&conn->lc_files, req->lr_req.hdr.fid); - if (!req->lr_fid) { - l9p_respond(req, EBADF); - return; - } - - l9p_seek_iov(req->lr_resp_msg.lm_iov, req->lr_resp_msg.lm_niov, - req->lr_data_iov, &req->lr_data_niov, 11); - - conn->lc_server->ls_backend->read(conn->lc_server->ls_backend->softc, req); -} - -static void -l9p_dispatch_tremove(struct l9p_request *req) -{ - struct l9p_connection *conn = req->lr_conn; - - req->lr_fid = ht_find(&conn->lc_files, req->lr_req.hdr.fid); - if (!req->lr_fid) { - l9p_respond(req, EBADF); - return; - } - - if (!conn->lc_server->ls_backend->remove) { - l9p_respond(req, ENOSYS); - return; - } - - conn->lc_server->ls_backend->remove(conn->lc_server->ls_backend->softc, req); -} - -static void -l9p_dispatch_tstat(struct l9p_request *req) -{ - struct l9p_connection *conn = req->lr_conn; - - req->lr_fid = ht_find(&conn->lc_files, req->lr_req.hdr.fid); - if (!req->lr_fid) { - l9p_respond(req, EBADF); - return; - } - - if (!conn->lc_server->ls_backend->stat) { - l9p_respond(req, ENOSYS); - return; - } - - conn->lc_server->ls_backend->stat(conn->lc_server->ls_backend->softc, req); -} - -static void -l9p_dispatch_twalk(struct l9p_request *req) -{ - struct l9p_connection *conn = req->lr_conn; - - req->lr_fid = ht_find(&conn->lc_files, req->lr_req.hdr.fid); - if (req->lr_fid == NULL) { - l9p_respond(req, EBADF); - return; - } - - if (req->lr_req.twalk.hdr.fid != req->lr_req.twalk.newfid) { - req->lr_newfid = l9p_connection_alloc_fid(conn, - req->lr_req.twalk.newfid); - if (req->lr_newfid == NULL) { - l9p_respond(req, EBADF); - return; - } - } - - if (!conn->lc_server->ls_backend->walk) { - l9p_respond(req, ENOSYS); - return; - } - - conn->lc_server->ls_backend->walk(conn->lc_server->ls_backend->softc, req); -} - -static void -l9p_dispatch_twrite(struct l9p_request *req) -{ - struct l9p_connection *conn = req->lr_conn; - - req->lr_fid = ht_find(&conn->lc_files, req->lr_req.twalk.hdr.fid); - if (req->lr_fid == NULL) { - l9p_respond(req, EBADF); - return; - } - - if (!conn->lc_server->ls_backend->write) { - l9p_respond(req, ENOSYS); - return; - } - - l9p_seek_iov(req->lr_req_msg.lm_iov, req->lr_req_msg.lm_niov, - req->lr_data_iov, &req->lr_data_niov, 23); - - conn->lc_server->ls_backend->write(conn->lc_server->ls_backend->softc, req); -} - -static void -l9p_dispatch_twstat(struct l9p_request *req) -{ - struct l9p_connection *conn = req->lr_conn; - - req->lr_fid = ht_find(&conn->lc_files, req->lr_req.hdr.fid); - if (!req->lr_fid) { - l9p_respond(req, EBADF); - return; - } - - if (!conn->lc_server->ls_backend->wstat) { - l9p_respond(req, ENOSYS); - return; - } - - conn->lc_server->ls_backend->wstat(conn->lc_server->ls_backend->softc, req); -} diff --git a/lib9p/sbuf/sbuf.c b/lib9p/sbuf/sbuf.c deleted file mode 100644 index 0978d77..0000000 --- a/lib9p/sbuf/sbuf.c +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright 2016 Jakub Klama - * All rights reserved - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted providing that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - */ - -/* - * Minimal libsbuf reimplementation for Mac OS X. - */ - -#include -#include -#include -#include -#include -#include "sbuf.h" - -#define SBUF_INITIAL_SIZE 128 - -struct sbuf * -sbuf_new_auto() -{ - struct sbuf *s; - - s = malloc(sizeof(struct sbuf)); - s->s_buf = calloc(1, SBUF_INITIAL_SIZE + 1); - s->s_capacity = SBUF_INITIAL_SIZE; - s->s_size = 0; - - return (s); -} - -int -sbuf_printf(struct sbuf *s, const char *fmt, ...) -{ - int ret; - va_list ap; - - va_start(ap, fmt); - ret = sbuf_vprintf(s, fmt, ap); - va_end(ap); - - return (ret); -} - -int -sbuf_vprintf(struct sbuf *s, const char *fmt, va_list args) -{ - va_list copy; - int req; - - va_copy(copy, args); - req = vsnprintf(NULL, 0, fmt, copy); - va_end(copy); - - if (s->s_size + req >= s->s_capacity) { - s->s_capacity = s->s_size + req + 1; - s->s_buf = realloc(s->s_buf, (size_t)s->s_capacity); - } - - req = vsnprintf(s->s_buf + s->s_size, req + 1, fmt, args); - s->s_size += req; - - return (req); -} - -char * -sbuf_data(struct sbuf *s) -{ - return (s->s_buf); -} - -int -sbuf_done(struct sbuf *s) -{ - s->s_buf[s->s_size] = '\0'; - return (0); -} - -void -sbuf_delete(struct sbuf *s) -{ - free(s->s_buf); - free(s); -} diff --git a/lib9p/sbuf/sbuf.h b/lib9p/sbuf/sbuf.h deleted file mode 100644 index fd6dd62..0000000 --- a/lib9p/sbuf/sbuf.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2016 Jakub Klama - * All rights reserved - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted providing that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - */ - -/* - * Minimal libsbuf reimplementation for Mac OS X. - */ - -#ifndef LIB9P_SBUF_H -#define LIB9P_SBUF_H - -#include - -struct sbuf -{ - char *s_buf; - int s_size; - int s_capacity; - int s_position; -}; - -struct sbuf *sbuf_new_auto(void); -int sbuf_printf(struct sbuf *s, const char *fmt, ...); -int sbuf_vprintf(struct sbuf *s, const char *fmt, va_list args); -int sbuf_done(struct sbuf *s); -void sbuf_delete(struct sbuf *s); -char *sbuf_data(struct sbuf *s); - -#endif /* LIB9P_SBUF_H */ - diff --git a/lib9p/transport/socket.c b/lib9p/transport/socket.c deleted file mode 100644 index bf54240..0000000 --- a/lib9p/transport/socket.c +++ /dev/null @@ -1,308 +0,0 @@ -/* - * Copyright 2016 Jakub Klama - * All rights reserved - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted providing that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "../lib9p.h" -#include "../lib9p_impl.h" -#include "../log.h" -#include "socket.h" - -struct l9p_socket_softc -{ - struct l9p_connection *ls_conn; - struct sockaddr ls_sockaddr; - socklen_t ls_socklen; - pthread_t ls_thread; - int ls_fd; -}; - -static int l9p_socket_readmsg(struct l9p_socket_softc *, void **, size_t *); -static int l9p_socket_get_response_buffer(struct l9p_request *, - struct iovec *, size_t *, void *); -static int l9p_socket_send_response(struct l9p_request *, const struct iovec *, - const size_t, const size_t, void *); -static void *l9p_socket_thread(void *); -static ssize_t xread(int, void *, size_t); -static ssize_t xwrite(int, void *, size_t); - -int -l9p_start_server(struct l9p_server *server, const char *host, const char *port) -{ - struct addrinfo *res, *res0, hints; - struct kevent kev[2]; - struct kevent event[2]; - int err, kq, i, val, evs, nsockets = 0; - int sockets[2]; - - memset(&hints, 0, sizeof(hints)); - hints.ai_family = PF_UNSPEC; - hints.ai_socktype = SOCK_STREAM; - err = getaddrinfo(host, port, &hints, &res0); - - if (err) - return (-1); - - for (res = res0; res; res = res->ai_next) { - int s = socket(res->ai_family, res->ai_socktype, - res->ai_protocol); - - val = 1; - setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)); - - if (s < 0) - continue; - - if (bind(s, res->ai_addr, res->ai_addrlen) < 0) { - close(s); - continue; - } - - sockets[nsockets] = s; - EV_SET(&kev[nsockets++], s, EVFILT_READ, EV_ADD | EV_ENABLE, 0, - 0, 0); - listen(s, 10); - } - - kq = kqueue(); - - if (kevent(kq, kev, nsockets, NULL, 0, NULL) < 0) { - L9P_LOG(L9P_ERROR, "kevent(): %s", strerror(errno)); - return (-1); - } - - for (;;) { - evs = kevent(kq, NULL, 0, event, nsockets, NULL); - if (evs < 0) { - if (errno == EINTR) - continue; - - L9P_LOG(L9P_ERROR, "kevent(): %s", strerror(errno)); - return (-1); - } - - for (i = 0; i < evs; i++) { - struct sockaddr client_addr; - socklen_t client_addr_len; - int news = accept((int)event[i].ident, &client_addr, - &client_addr_len); - - if (news < 0) { - L9P_LOG(L9P_WARNING, "accept(): %s", - strerror(errno)); - continue; - } - - l9p_socket_accept(server, news, &client_addr, - client_addr_len); - } - } - -} - -void -l9p_socket_accept(struct l9p_server *server, int conn_fd, - struct sockaddr *client_addr, socklen_t client_addr_len) -{ - struct l9p_socket_softc *sc; - struct l9p_connection *conn; - char host[NI_MAXHOST + 1]; - char serv[NI_MAXSERV + 1]; - int err; - - err = getnameinfo(client_addr, client_addr_len, host, NI_MAXHOST, serv, - NI_MAXSERV, NI_NUMERICHOST | NI_NUMERICSERV); - - if (err != 0) { - L9P_LOG(L9P_WARNING, "cannot look up client name: %s", - gai_strerror(err)); - } else - L9P_LOG(L9P_INFO, "new connection from %s:%s", host, serv); - - if (l9p_connection_init(server, &conn) != 0) { - L9P_LOG(L9P_ERROR, "cannot create new connection"); - return; - } - - sc = l9p_calloc(1, sizeof(*sc)); - sc->ls_conn = conn; - sc->ls_fd = conn_fd; - - l9p_connection_on_send_response(conn, l9p_socket_send_response, sc); - l9p_connection_on_get_response_buffer(conn, - l9p_socket_get_response_buffer, sc); - - pthread_create(&sc->ls_thread, NULL, l9p_socket_thread, sc); -} - -static void * -l9p_socket_thread(void *arg) -{ - struct l9p_socket_softc *sc = (struct l9p_socket_softc *)arg; - struct iovec iov; - void *buf; - size_t length; - - for (;;) { - if (l9p_socket_readmsg(sc, &buf, &length) != 0) - break; - - iov.iov_base = buf; - iov.iov_len = length; - l9p_connection_recv(sc->ls_conn, &iov, 1, NULL); - } - - L9P_LOG(L9P_INFO, "connection closed"); - return (NULL); -} - -static int -l9p_socket_readmsg(struct l9p_socket_softc *sc, void **buf, size_t *size) -{ - uint32_t msize; - size_t toread; - void *buffer; - int fd = sc->ls_fd; - - assert(fd > 0); - - buffer = l9p_malloc(sizeof(uint32_t)); - - if (xread(fd, buffer, sizeof(uint32_t)) != sizeof(uint32_t)) { - L9P_LOG(L9P_ERROR, "short read: %s", strerror(errno)); - return (-1); - } - - msize = *(uint32_t *)buffer; - toread = msize - sizeof(uint32_t); - buffer = realloc(buffer, msize); - - if (xread(fd, (char *)buffer + sizeof(uint32_t), toread) != (ssize_t)toread) { - L9P_LOG(L9P_ERROR, "short read: %s", strerror(errno)); - return (-1); - } - - *size = msize; - *buf = buffer; - L9P_LOG(L9P_INFO, "%p: read complete message, buf=%p size=%d", - sc->ls_conn, buffer, msize); - - return (0); -} - -static int -l9p_socket_get_response_buffer(struct l9p_request *req, struct iovec *iov, - size_t *niovp, void *arg __unused) -{ - size_t size = req->lr_conn->lc_msize; - void *buf; - - buf = l9p_malloc(size); - iov[0].iov_base = buf; - iov[0].iov_len = size; - - *niovp = 1; - return (0); -} - -static int -l9p_socket_send_response(struct l9p_request *req __unused, - const struct iovec *iov, const size_t niov __unused, const size_t iolen, - void *arg) -{ - struct l9p_socket_softc *sc = (struct l9p_socket_softc *)arg; - - assert(sc->ls_fd > 0); - - L9P_LOG(L9P_DEBUG, "%p: sending reply, buf=%p, size=%d", arg, - iov[0].iov_base, iolen); - - if (xwrite(sc->ls_fd, iov[0].iov_base, iolen) != (int)iolen) { - L9P_LOG(L9P_ERROR, "short write: %s", strerror(errno)); - return (-1); - } - - free(iov[0].iov_base); - return (0); -} - -static ssize_t -xread(int fd, void *buf, size_t count) -{ - size_t done = 0; - ssize_t ret; - - while (done < count) { - ret = read(fd, (char *)buf + done, count - done); - if (ret < 0) { - if (errno == EINTR) - continue; - - return (-1); - } - - if (ret == 0) - return ((ssize_t)done); - - done += (size_t)ret; - } - - return ((ssize_t)done); -} - -static ssize_t -xwrite(int fd, void *buf, size_t count) -{ - size_t done = 0; - ssize_t ret; - - while (done < count) { - ret = write(fd, (char *)buf + done, count - done); - if (ret < 0) { - if (errno == EINTR) - continue; - - return (-1); - } - - if (ret == 0) - return ((ssize_t)done); - - done += (size_t)ret; - } - - return ((ssize_t)done); -} diff --git a/lib9p/transport/socket.h b/lib9p/transport/socket.h deleted file mode 100644 index b022da1..0000000 --- a/lib9p/transport/socket.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2016 Jakub Klama - * All rights reserved - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted providing that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - */ - -#ifndef LIB9P_SOCKET_H -#define LIB9P_SOCKET_H - -#include -#include -#include "../lib9p.h" - -int l9p_start_server(struct l9p_server *server, const char *host, - const char *port); -void l9p_socket_accept(struct l9p_server *server, int conn_fd, - struct sockaddr *client_addr, socklen_t client_addr_len); - -#endif /* LIB9P_SOCKET_H */ diff --git a/lib9p/utils.c b/lib9p/utils.c deleted file mode 100644 index 347c5ae..0000000 --- a/lib9p/utils.c +++ /dev/null @@ -1,260 +0,0 @@ -/* - * Copyright 2016 Jakub Klama - * All rights reserved - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted providing that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - */ - -#include -#include -#include -#include -#include -#if defined(__FreeBSD__) -#include -#else -#include "sbuf/sbuf.h" -#endif -#include "lib9p.h" -#include "fcall.h" - -static const char *ftype_names[] = { - "Tversion", - "Rversion", - "Tauth", - "Rauth", - "Tattach", - "Rattach", - "Terror", - "Rerror", - "Tflush", - "Rflush", - "Twalk", - "Rwalk", - "Topen", - "Ropen", - "Tcreate", - "Rcreate", - "Tread", - "Rread", - "Twrite", - "Rwrite", - "Tclunk", - "Rclunk", - "Tremove", - "Rremove", - "Tstat", - "Rstat", - "Twstat", - "Rwstat" -}; - -void -l9p_seek_iov(struct iovec *iov1, size_t niov1, struct iovec *iov2, - size_t *niov2, size_t seek) -{ - size_t remainder = 0; - size_t left = seek; - size_t i, j; - - for (i = 0; i < niov1; i++) { - size_t toseek = MIN(left, iov1[i].iov_len); - left -= toseek; - - if (toseek == iov1[i].iov_len) - continue; - - if (left == 0) { - remainder = toseek; - break; - } - } - - for (j = i; j < niov1; j++) { - iov2[j - i].iov_base = (char *)iov1[j].iov_base + remainder; - iov2[j - i].iov_len = iov1[j].iov_len - remainder; - remainder = 0; - } - - *niov2 = j - i; -} - -size_t -l9p_truncate_iov(struct iovec *iov, size_t niov, size_t length) -{ - size_t i, done = 0; - - for (i = 0; i < niov; i++) { - size_t toseek = MIN(length - done, iov[i].iov_len); - done += toseek; - - if (toseek < iov[i].iov_len) { - iov[i].iov_len = toseek; - return (i + 1); - } - } - - return (niov); -} - -void -l9p_describe_qid(struct l9p_qid *qid, struct sbuf *sb) -{ - - assert(qid != NULL); - assert(sb != NULL); - - sbuf_printf(sb, "<0x%02x,%u,0x%016" PRIx64 ">", qid->type, qid->version, - qid->path); -} - -void -l9p_describe_stat(struct l9p_stat *st, struct sbuf *sb) -{ - - assert(st != NULL); - assert(sb != NULL); - - sbuf_printf(sb, "type=0x%04x dev=%d name=\"%s\" uid=\"%s\"", - st->type, st->dev, st->name, st->uid); -} - -void -l9p_describe_fcall(union l9p_fcall *fcall, enum l9p_version version, - struct sbuf *sb) -{ - uint8_t type; - int i; - - assert(fcall != NULL); - assert(sb != NULL); - assert(version <= L9P_2000L && version >= L9P_2000); - - type = fcall->hdr.type; - - if (type < 100 || type > 127) { - sbuf_printf(sb, " tag=%d", type, - fcall->hdr.tag); - return; - } - - sbuf_printf(sb, "%s tag=%d", ftype_names[type - L9P_TVERSION], - fcall->hdr.tag); - - switch (type) { - case L9P_TVERSION: - case L9P_RVERSION: - sbuf_printf(sb, " version=\"%s\" msize=%d", fcall->version.version, - fcall->version.msize); - return; - case L9P_TAUTH: - sbuf_printf(sb, "afid=%d uname=\"%s\" aname=\"%s\"", fcall->hdr.fid, - fcall->tauth.uname, fcall->tauth.aname); - return; - case L9P_TATTACH: - sbuf_printf(sb, " fid=%d afid=%d uname=\"%s\" aname=\"%s\"", - fcall->hdr.fid, fcall->tattach.afid, fcall->tattach.uname, - fcall->tattach.aname); - if (version >= L9P_2000U) - sbuf_printf(sb, " n_uname=%d", fcall->tattach.n_uname); - return; - case L9P_RERROR: - sbuf_printf(sb, " ename=\"%s\" errnum=%d", fcall->error.ename, - fcall->error.errnum); - return; - case L9P_TFLUSH: - sbuf_printf(sb, " oldtag=%d", fcall->tflush.oldtag); - return; - case L9P_TWALK: - sbuf_printf(sb, " fid=%d newfid=%d wname=\"", - fcall->hdr.fid, fcall->twalk.newfid); - - for (i = 0; i < fcall->twalk.nwname; i++) { - sbuf_printf(sb, "%s", fcall->twalk.wname[i]); - if (i != fcall->twalk.nwname - 1) - sbuf_printf(sb, "/"); - } - sbuf_printf(sb, "\""); - return; - case L9P_RWALK: - sbuf_printf(sb, " wqid=["); - for (i = 0; i < fcall->rwalk.nwqid; i++) { - l9p_describe_qid(&fcall->rwalk.wqid[i], sb); - if (i != fcall->rwalk.nwqid - 1) - sbuf_printf(sb, ","); - } - sbuf_printf(sb, "]"); - return; - case L9P_TOPEN: - sbuf_printf(sb, " fid=%d mode=%d", fcall->hdr.fid, - fcall->tcreate.mode); - - return; - case L9P_ROPEN: - sbuf_printf(sb, " qid="); - l9p_describe_qid(&fcall->ropen.qid, sb); - sbuf_printf(sb, " iounit=%d", fcall->ropen.iounit); - return; - case L9P_TCREATE: - sbuf_printf(sb, " fid=%d name=\"%s\" perm=0x%08x mode=%d", - fcall->hdr.fid, fcall->tcreate.name, fcall->tcreate.perm, - fcall->tcreate.mode); - return; - case L9P_RCREATE: - return; - case L9P_TREAD: - sbuf_printf(sb, " fid=%d offset=%" PRIu64 " count=%u", fcall->hdr.fid, - fcall->io.offset, fcall->io.count); - return; - - case L9P_RREAD: - case L9P_RWRITE: - sbuf_printf(sb, " count=%d", fcall->io.count); - return; - case L9P_TWRITE: - sbuf_printf(sb, " fid=%d offset=%" PRIu64 " count=%u", fcall->hdr.fid, - fcall->io.offset, fcall->io.count); - return; - case L9P_TCLUNK: - sbuf_printf(sb, " fid=%d ", fcall->hdr.fid); - return; - case L9P_TREMOVE: - sbuf_printf(sb, " fid=%d", fcall->hdr.fid); - return; - case L9P_RREMOVE: - return; - case L9P_TSTAT: - sbuf_printf(sb, " fid=%d", fcall->hdr.fid); - return; - case L9P_RSTAT: - sbuf_printf(sb, " "); - l9p_describe_stat(&fcall->rstat.stat, sb); - return; - case L9P_TWSTAT: - sbuf_printf(sb, " fid=%d ", fcall->hdr.fid); - l9p_describe_stat(&fcall->twstat.stat, sb); - return; - case L9P_RWSTAT: - return; - } -} From 01f396c44019bf7d31e94b478d584939f4fde6cf Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Fri, 1 Apr 2016 17:44:46 +0200 Subject: [PATCH 10/10] added little paragraph about virtio-9p to the readme --- README.md | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 1ec81ba..72cfb77 100644 --- a/README.md +++ b/README.md @@ -28,11 +28,11 @@ If you have homebrew, then simply: The `--HEAD` in the brew command ensures that you always get the latest changes, even if the homebrew database is not yet updated. If for any reason you don't want that simply do `brew install xhyve` . -if not then: +if not then: Building -------- - $ git clone https://github.com/mist64/xhyve + $ git clone --recursive https://github.com/mist64/xhyve $ cd xhyve $ make @@ -153,7 +153,7 @@ xhyve architecture ------------------------------┼------------------------------ |syscall xnu kernel V - + VMX host VMX nested paging @@ -182,6 +182,22 @@ instead of: Where *X* is your tap device, i.e. */dev/tapX*. +File Sharing +------ +You can setup shared folders between OS X and your guest by using the `virtio-9p` device. +9P / VirtFS is a shared FS protocol introduced by Bell's Plan 9 OS. +More information is available in the [KVM wiki](http://www.linux-kvm.org/page/9p_virtio). + +Adding a VirtFS device to your VM: + + $ xhyve -s 5,virtio-9p,hostshare=/Users/example/shared,ro ... + +Inside the Linux VM: + + $ mount -t 9p -o trans=virtio,version=9p2000.L hostshare /tmp/host_files + +The `hostshare` identifier can be changed to support multiple mounts. + Issues ------ If you are, or were, running any version of VirtualBox, prior to 4.3.30 or 5.0,