From: Octavian Purdila <octavian.purdila@intel.com>
To: linux-arch@vger.kernel.org
Cc: linux-kernel@vger.kernel.org, thehajime@gmail.com,
Octavian Purdila <octavian.purdila@intel.com>
Subject: [RFC PATCH 20/28] lkl tools: host lib: filesystem helpers
Date: Tue, 3 Nov 2015 22:20:51 +0200 [thread overview]
Message-ID: <1446582059-17355-21-git-send-email-octavian.purdila@intel.com> (raw)
In-Reply-To: <1446582059-17355-1-git-send-email-octavian.purdila@intel.com>
Add LKL applications APIs to mount and unmount a filesystem from a
disk added via lkl_disk_add().
Also add open/close/read directory wrappers on top of
lkl_sys_getdents64.
Signed-off-by: Octavian Purdila <octavian.purdila@intel.com>
---
tools/lkl/include/lkl.h | 66 +++++++++++++++
tools/lkl/lib/fs.c | 218 ++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 284 insertions(+)
create mode 100644 tools/lkl/lib/fs.c
diff --git a/tools/lkl/include/lkl.h b/tools/lkl/include/lkl.h
index 0c30b23..e6a9c77 100644
--- a/tools/lkl/include/lkl.h
+++ b/tools/lkl/include/lkl.h
@@ -40,4 +40,70 @@ union lkl_disk_backstore {
*/
int lkl_disk_add(union lkl_disk_backstore backstore);
+/**
+ * lkl_mount_dev - mount a disk
+ *
+ * This functions creates a device file for the given disk, creates a mount
+ * point and mounts the device over the mount point.
+ *
+ * @disk_id - the disk id identifying the disk to be mounted
+ * @fs_type - filesystem type
+ * @flags - mount flags
+ * @data - additional filesystem specific mount data
+ * @mnt_str - a string that will be filled by this function with the path where
+ * the filisystem has been mounted
+ * @mnt_str_len - size of mnt_str
+ * @returns - 0 on success, a negative value on error
+ */
+long lkl_mount_dev(unsigned int disk_id, const char *fs_type, int flags,
+ void *data, char *mnt_str, int mnt_str_len);
+
+/**
+ * lkl_umount_dev - umount a disk
+ *
+ * This functions umounts the given disks and removes the device file and the
+ * mount point.
+ *
+ * @disk_id - the disk id identifying the disk to be mounted
+ * @flags - umount flags
+ * @timeout_ms - timeout to wait for the kernel to flush closed files so that
+ * umount can succeed
+ * @returns - 0 on success, a negative value on error
+ */
+long lkl_umount_dev(unsigned int disk_id, int flags, long timeout_ms);
+
+/**
+ * lkl_opendir - open a directory
+ *
+ * @path - directory path
+ * @err - pointer to store the error in case of failure
+ * @returns - a handle to be used when calling lkl_readdir
+ */
+struct lkl_dir *lkl_opendir(const char *path, int *err);
+
+/**
+ * lkl_closedir - close the directory
+ *
+ * @dir - the directory handler as returned by lkl_opendir
+ */
+void lkl_closedir(struct lkl_dir *dir);
+
+/**
+ * lkl_readdir - get the next available entry of the directory
+ *
+ * @dir - the directory handler as returned by lkl_opendir
+ * @returns - a lkl_dirent64 entry or NULL if the end of the directory stream is
+ * reached or if an error occurred; check lkl_errdir() to distinguish between
+ * errors or end of the directory stream
+ */
+struct lkl_dirent64 *lkl_readdir(struct lkl_dir *dir);
+
+/**
+ * lkl_errdir - checks if an error occurred during the last lkl_readdir call
+ *
+ * @dir - the directory handler as returned by lkl_opendir
+ * @returns - 0 if no error occurred, or a negative value otherwise
+ */
+int lkl_errdir(struct lkl_dir *dir);
+
#endif
diff --git a/tools/lkl/lib/fs.c b/tools/lkl/lib/fs.c
new file mode 100644
index 0000000..16f4d44
--- /dev/null
+++ b/tools/lkl/lib/fs.c
@@ -0,0 +1,218 @@
+#include <stdio.h>
+#include <string.h>
+#include <lkl_host.h>
+
+long lkl_mount_sysfs(void)
+{
+ long ret;
+ static int sysfs_mounted;
+
+ if (sysfs_mounted)
+ return 0;
+
+ ret = lkl_sys_mkdir("/sys", 0700);
+ if (ret)
+ return ret;
+
+ ret = lkl_sys_mount("none", "sys", "sysfs", 0, NULL);
+
+ if (ret == 0)
+ sysfs_mounted = 1;
+
+ return ret;
+}
+
+static long get_virtio_blkdev(int disk_id)
+{
+ char sysfs_path[] = "/sys/block/vda/dev";
+ char buf[16] = { 0, };
+ long fd, ret;
+ int major, minor;
+
+ ret = lkl_mount_sysfs();
+ if (ret)
+ return ret;
+
+ sysfs_path[strlen("/sys/block/vd")] += disk_id;
+
+ fd = lkl_sys_open(sysfs_path, LKL_O_RDONLY, 0);
+ if (fd < 0)
+ return fd;
+
+ ret = lkl_sys_read(fd, buf, sizeof(buf));
+ if (ret < 0)
+ goto out_close;
+
+ if (ret == sizeof(buf)) {
+ ret = -LKL_ENOBUFS;
+ goto out_close;
+ }
+
+ ret = sscanf(buf, "%d:%d", &major, &minor);
+ if (ret != 2) {
+ ret = -LKL_EINVAL;
+ goto out_close;
+ }
+
+ ret = LKL_MKDEV(major, minor);
+
+out_close:
+ lkl_sys_close(fd);
+
+ return ret;
+}
+
+long lkl_mount_dev(unsigned int disk_id, const char *fs_type, int flags,
+ void *data, char *mnt_str, int mnt_str_len)
+{
+ char dev_str[] = { "/dev/xxxxxxxx" };
+ unsigned int dev;
+ int err;
+
+ if (mnt_str_len < sizeof("/mnt/xxxxxxxx"))
+ return -LKL_ENOMEM;
+
+ dev = get_virtio_blkdev(disk_id);
+
+ snprintf(dev_str, sizeof(dev_str), "/dev/%08x", dev);
+ snprintf(mnt_str, mnt_str_len, "/mnt/%08x", dev);
+
+ err = lkl_sys_access("/dev", LKL_S_IRWXO);
+ if (err < 0) {
+ if (err == -LKL_ENOENT)
+ err = lkl_sys_mkdir("/dev", 0700);
+ if (err < 0)
+ return err;
+ }
+
+ err = lkl_sys_mknod(dev_str, LKL_S_IFBLK | 0600, dev);
+ if (err < 0)
+ return err;
+
+ err = lkl_sys_access("/mnt", LKL_S_IRWXO);
+ if (err < 0) {
+ if (err == -LKL_ENOENT)
+ err = lkl_sys_mkdir("/mnt", 0700);
+ if (err < 0)
+ return err;
+ }
+
+ err = lkl_sys_mkdir(mnt_str, 0700);
+ if (err < 0) {
+ lkl_sys_unlink(dev_str);
+ return err;
+ }
+
+ err = lkl_sys_mount(dev_str, mnt_str, fs_type, flags, data);
+ if (err < 0) {
+ lkl_sys_unlink(dev_str);
+ lkl_sys_rmdir(mnt_str);
+ return err;
+ }
+
+ return 0;
+}
+
+long lkl_umount_dev(unsigned int disk_id, int flags, long timeout_ms)
+{
+ char dev_str[] = { "/dev/xxxxxxxx" };
+ char mnt_str[] = { "/mnt/xxxxxxxx" };
+ long incr = 10000000; /* 10 ms */
+ struct lkl_timespec ts = {
+ .tv_sec = 0,
+ .tv_nsec = incr,
+ };
+ unsigned int dev;
+ int err;
+
+ dev = get_virtio_blkdev(disk_id);
+
+ snprintf(dev_str, sizeof(dev_str), "/dev/%08x", dev);
+ snprintf(mnt_str, sizeof(mnt_str), "/mnt/%08x", dev);
+
+ do {
+ err = lkl_sys_umount(mnt_str, flags);
+ if (err == -LKL_EBUSY) {
+ lkl_sys_nanosleep(&ts, NULL);
+ timeout_ms -= incr / 1000000;
+ }
+ } while (err == -LKL_EBUSY && timeout_ms > 0);
+
+ if (err)
+ return err;
+
+ err = lkl_sys_unlink(dev_str);
+ if (err)
+ return err;
+
+ return lkl_sys_rmdir(mnt_str);
+}
+
+struct lkl_dir {
+ int fd;
+ char buf[1024];
+ char *pos;
+ int len;
+};
+
+struct lkl_dir *lkl_opendir(const char *path, int *err)
+{
+ struct lkl_dir *dir = lkl_host_ops.mem_alloc(sizeof(struct lkl_dir));
+
+ if (!dir) {
+ *err = -LKL_ENOMEM;
+ return NULL;
+ }
+
+ dir->fd = lkl_sys_open(path, LKL_O_RDONLY | LKL_O_DIRECTORY, 0);
+ if (dir->fd < 0) {
+ *err = dir->fd;
+ lkl_host_ops.mem_free(dir);
+ return NULL;
+ }
+
+ dir->len = 0;
+ dir->pos = NULL;
+
+ return dir;
+}
+
+void lkl_closedir(struct lkl_dir *dir)
+{
+ lkl_sys_close(dir->fd);
+ lkl_host_ops.mem_free(dir);
+}
+
+struct lkl_dirent64 *lkl_readdir(struct lkl_dir *dir)
+{
+ struct lkl_dirent64 *de;
+
+ if (dir->len < 0)
+ return NULL;
+
+ if (!dir->pos || dir->pos - dir->buf >= dir->len)
+ goto read_buf;
+
+return_de:
+ de = (struct lkl_dirent64 *)dir->pos;
+ dir->pos += de->d_reclen;
+
+ return de;
+
+read_buf:
+ dir->pos = NULL;
+ dir->len = lkl_sys_getdents64(dir->fd, dir->buf, sizeof(dir->buf));
+ if (dir->len <= 0)
+ return NULL;
+
+ dir->pos = dir->buf;
+ goto return_de;
+}
+
+int lkl_errdir(struct lkl_dir *dir)
+{
+ if (dir->len >= 0)
+ return 0;
+
+ return dir->len;
+}
--
2.1.0
next prev parent reply other threads:[~2015-11-03 20:27 UTC|newest]
Thread overview: 55+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-11-03 20:20 [RFC PATCH 00/28] Linux Kernel Library Octavian Purdila
2015-11-03 20:20 ` [RFC PATCH 01/28] asm-generic: atomic64: allow using generic atomic64 on 64bit platforms Octavian Purdila
2015-11-03 20:20 ` [RFC PATCH 02/28] kbuild: allow architectures to automatically define kconfig symbols Octavian Purdila
2015-11-03 20:20 ` [RFC PATCH 03/28] lkl: architecture skeleton for Linux kernel library Octavian Purdila
2015-11-03 20:20 ` [RFC PATCH 04/28] lkl: host interface Octavian Purdila
2015-11-03 23:30 ` Hajime Tazaki
2015-11-03 20:20 ` [RFC PATCH 05/28] lkl: memory handling Octavian Purdila
2015-11-03 20:20 ` [RFC PATCH 06/28] lkl: kernel threads support Octavian Purdila
2015-11-03 20:20 ` [RFC PATCH 07/28] lkl: interrupt support Octavian Purdila
2015-11-03 20:20 ` [RFC PATCH 08/28] lkl: system call interface and application API Octavian Purdila
2015-11-07 23:24 ` Arnd Bergmann
2015-11-08 3:49 ` Octavian Purdila
2015-11-08 10:26 ` Arnd Bergmann
2015-11-03 20:20 ` [RFC PATCH 09/28] lkl: timers, time and delay support Octavian Purdila
2015-11-03 20:20 ` [RFC PATCH 10/28] lkl: memory mapped I/O support Octavian Purdila
2015-11-03 20:20 ` [RFC PATCH 11/28] lkl: basic kernel console support Octavian Purdila
2015-11-03 20:20 ` [RFC PATCH 12/28] init: allow architecture code to overide run_init_process Octavian Purdila
2015-11-03 20:20 ` [RFC PATCH 13/28] lkl: initialization and cleanup Octavian Purdila
2015-11-03 20:20 ` [RFC PATCH 14/28] lkl: plug in the build system Octavian Purdila
2015-11-03 20:20 ` [RFC PATCH 15/28] lkl tools: skeleton for host side library, tests and tools Octavian Purdila
2015-11-03 20:20 ` [RFC PATCH 16/28] lkl tools: host lib: add lkl_strerror and lkl_printf Octavian Purdila
2015-11-03 20:20 ` [RFC PATCH 17/28] lkl tools: host lib: memory mapped I/O helpers Octavian Purdila
2015-11-03 20:20 ` [RFC PATCH 18/28] lkl tools: host lib: virtio devices Octavian Purdila
2015-11-03 20:20 ` [RFC PATCH 19/28] lkl tools: host lib: virtio block device Octavian Purdila
2015-11-07 12:24 ` Richard Weinberger
2015-11-08 4:15 ` Octavian Purdila
2015-11-08 13:30 ` Richard Weinberger
2015-11-03 20:20 ` Octavian Purdila [this message]
2015-11-03 20:20 ` [RFC PATCH 21/28] lkl tools: host lib: posix host operations Octavian Purdila
2015-11-07 23:16 ` Arnd Bergmann
2015-11-08 4:01 ` Octavian Purdila
2015-11-08 10:35 ` Arnd Bergmann
2015-11-03 20:20 ` [RFC PATCH 22/28] lkl tools: "boot" test Octavian Purdila
2015-11-03 20:20 ` [RFC PATCH 23/28] lkl tools: tool that converts a filesystem image to tar Octavian Purdila
2015-11-03 20:20 ` [RFC PATCH 24/28] lkl tools: tool that reads/writes to/from a filesystem image Octavian Purdila
2015-11-03 20:20 ` [RFC PATCH 25/28] signal: use CONFIG_X86_32 instead of __i386__ Octavian Purdila
2015-11-03 20:20 ` [RFC PATCH 26/28] asm-generic: vmlinux.lds.h: allow customized rodata section name Octavian Purdila
2015-11-03 20:20 ` [RFC PATCH 27/28] lkl: add support for Windows hosts Octavian Purdila
2015-11-03 20:20 ` [RFC PATCH 28/28] lkl tools: add support for Windows host Octavian Purdila
2015-11-03 21:40 ` [RFC PATCH 00/28] Linux Kernel Library Richard Weinberger
2015-11-03 22:45 ` Richard W.M. Jones
2015-11-03 23:23 ` Hajime Tazaki
2015-11-03 23:24 ` Octavian Purdila
2015-11-04 13:22 ` Austin S Hemmelgarn
2015-11-04 13:50 ` Richard W.M. Jones
2015-11-04 14:15 ` Octavian Purdila
2015-11-07 0:35 ` Richard Weinberger
2015-11-07 7:19 ` Richard W.M. Jones
2015-11-07 10:48 ` Richard W.M. Jones
2015-11-09 16:35 ` Octavian Purdila
2015-11-08 4:16 ` Octavian Purdila
2015-11-08 4:36 ` Octavian Purdila
2015-11-03 23:06 ` Octavian Purdila
[not found] ` <1670BE0E-C0E0-4D45-BF16-1FF60C298149@gmail.com>
2015-11-09 15:11 ` Octavian Purdila
2015-11-08 13:45 ` Hajime Tazaki
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1446582059-17355-21-git-send-email-octavian.purdila@intel.com \
--to=octavian.purdila@intel.com \
--cc=linux-arch@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=thehajime@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®