[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[tyndur-devel] [PATCH 2/7] kernel2: Unterstützung von lio_dup()
+ kernel2: Neuer Syscall lio_dup(), um zusätzliche Stream-IDs für
geöffnete Streams zu bekommen (entweder um eine bestimmte ID zu
überschreiben oder um eine Kopie weiterzureichen)
Signed-off-by: Kevin Wolf <kevin@xxxxxxxxxx>
---
src/include/syscallno.h | 1 +
src/kernel2/include/lostio/userspace.h | 4 ++++
src/kernel2/include/syscall.h | 3 +++
src/kernel2/src/lostio/userspace.c | 13 +++++++++---
src/kernel2/src/syscall.c | 1 +
src/kernel2/src/syscalls/lostio.c | 37 ++++++++++++++++++++++++++++++++++
src/modules/include/syscall.h | 14 +++++++++++++
src/modules/lib/syscalls/lostio.c | 33 ++++++++++++++++++++++++++++++
8 files changed, 103 insertions(+), 3 deletions(-)
diff --git a/src/include/syscallno.h b/src/include/syscallno.h
index 5fa5cf1..3938718 100644
--- a/src/include/syscallno.h
+++ b/src/include/syscallno.h
@@ -109,6 +109,7 @@
#define SYSCALL_LIO_SYNC_ALL 99
#define SYSCALL_LIO_PASS_FD 100
#define SYSCALL_LIO_PROBE_SERVICE 101
+#define SYSCALL_LIO_DUP 102
#define SYSCALL_LIO_SRV_SERVICE_REGISTER 110
#define SYSCALL_LIO_SRV_TREE_SET_RING 111
diff --git a/src/kernel2/include/lostio/userspace.h b/src/kernel2/include/lostio/userspace.h
index cde9778..8e53501 100644
--- a/src/kernel2/include/lostio/userspace.h
+++ b/src/kernel2/include/lostio/userspace.h
@@ -46,6 +46,10 @@
struct lio_usp_stream* lio_usp_add_stream(pm_process_t* proc,
struct lio_stream* stream);
+/** Weist einem Stream eine gegebene Userspace-ID zu */
+struct lio_usp_stream* lio_usp_do_add_stream(pm_process_t* proc,
+ struct lio_stream* stream, lio_usp_stream_t id);
+
/**
* Gibt den zur Userspace-ID gehörenden Stream zurück, oder NULL wenn es
* keinen passenden Stream gibt.
diff --git a/src/kernel2/include/syscall.h b/src/kernel2/include/syscall.h
index d7fce53..c979373 100644
--- a/src/kernel2/include/syscall.h
+++ b/src/kernel2/include/syscall.h
@@ -211,6 +211,9 @@ void syscall_lio_open(lio_usp_resource_t* resid, int flags,
/// Stream schließen
int syscall_lio_close(lio_usp_stream_t* stream_id);
+/// Zusätzliche ID für Stream erstellen
+int syscall_lio_dup(lio_usp_stream_t* source, lio_usp_stream_t* dest);
+
/// Stream an anderen Prozess weitergeben
int syscall_lio_pass_fd(lio_usp_stream_t* stream_id, pid_t pid);
diff --git a/src/kernel2/src/lostio/userspace.c b/src/kernel2/src/lostio/userspace.c
index 76874fc..6fd5638 100644
--- a/src/kernel2/src/lostio/userspace.c
+++ b/src/kernel2/src/lostio/userspace.c
@@ -96,13 +96,13 @@ void lio_usp_remove_resource(struct lio_resource* res)
}
/** Weist einem Stream eine Userspace-ID zu */
-struct lio_usp_stream* lio_usp_add_stream(pm_process_t* proc,
- struct lio_stream* stream)
+struct lio_usp_stream* lio_usp_do_add_stream(pm_process_t* proc,
+ struct lio_stream* stream, lio_usp_stream_t id)
{
struct lio_usp_stream* entry = malloc(sizeof(*entry));
entry->stream = stream;
- entry->usp_id = new_streamid();
+ entry->usp_id = id;
tree_insert(proc->lio_streams, entry);
stream->usp_refcount++;
@@ -110,6 +110,13 @@ struct lio_usp_stream* lio_usp_add_stream(pm_process_t* proc,
return entry;
}
+/** Weist einem Stream eine Userspace-ID zu */
+struct lio_usp_stream* lio_usp_add_stream(pm_process_t* proc,
+ struct lio_stream* stream)
+{
+ return lio_usp_do_add_stream(proc, stream, new_streamid());
+}
+
/**
* Gibt den zur Userspace-ID gehörenden Stream zurück, oder NULL wenn es
* keinen passenden Stream gibt.
diff --git a/src/kernel2/src/syscall.c b/src/kernel2/src/syscall.c
index d1628ba..557ab12 100644
--- a/src/kernel2/src/syscall.c
+++ b/src/kernel2/src/syscall.c
@@ -131,6 +131,7 @@ void syscall_init()
syscall_register(SYSCALL_LIO_SYNC_ALL, &syscall_lio_sync_all, 0);
syscall_register(SYSCALL_LIO_PASS_FD, &syscall_lio_pass_fd, 2);
syscall_register(SYSCALL_LIO_PROBE_SERVICE, &syscall_lio_probe_service, 2);
+ syscall_register(SYSCALL_LIO_DUP, &syscall_lio_dup, 2);
syscall_register(SYSCALL_LIO_SRV_SERVICE_REGISTER,
&syscall_lio_srv_service_register, 4);
diff --git a/src/kernel2/src/syscalls/lostio.c b/src/kernel2/src/syscalls/lostio.c
index eecffac..73aa98e 100644
--- a/src/kernel2/src/syscalls/lostio.c
+++ b/src/kernel2/src/syscalls/lostio.c
@@ -118,6 +118,43 @@ int syscall_lio_close(lio_usp_stream_t* stream_id)
return lio_usp_unref_stream(current_process, fd);
}
+/// Zusätzliche ID für Stream erstellen
+int syscall_lio_dup(lio_usp_stream_t* source, lio_usp_stream_t* dest)
+{
+ struct lio_usp_stream* old_fd;
+ struct lio_usp_stream* new_fd;
+ int ret;
+
+ // TODO: is_userspace (source und dest)
+ if (*dest < -1) {
+ return -EBADF;
+ }
+
+ old_fd = lio_usp_get_stream(current_process, *source);
+ if (old_fd == NULL) {
+ return -EBADF;
+ }
+
+ new_fd = lio_usp_get_stream(current_process, *dest);
+ if (old_fd == new_fd) {
+ return 0;
+ } else if (new_fd != NULL) {
+ ret = lio_usp_unref_stream(current_process, new_fd);
+ if (ret < 0) {
+ return ret;
+ }
+ }
+
+ if (*dest != -1) {
+ new_fd = lio_usp_do_add_stream(current_process, old_fd->stream, *dest);
+ } else {
+ new_fd = lio_usp_add_stream(current_process, old_fd->stream);
+ }
+
+ *dest = new_fd->usp_id;
+ return 0;
+}
+
/// Stream an anderen Prozess weitergeben
int syscall_lio_pass_fd(lio_usp_stream_t* stream_id, pid_t pid)
{
diff --git a/src/modules/include/syscall.h b/src/modules/include/syscall.h
index 7ab42a4..2fac1f4 100644
--- a/src/modules/include/syscall.h
+++ b/src/modules/include/syscall.h
@@ -149,6 +149,20 @@ lio_resource_t lio_resource(const char* path, bool follow_symlink);
lio_stream_t lio_open(lio_resource_t resource, int flags);
/**
+ * Erstellt eine zusätzliche Stream-ID für einen Stream.
+ *
+ * @param source Der zu duplizierende Stream
+ * @param dest Neue ID, die der Stream erhalten soll, oder -1 für eine
+ * beliebige freie ID. Wenn diese ID bereits einen Stream bezeichnet, wird
+ * dieser geschlossen.
+ *
+ * @return Neue Stream-ID bei Erfolg, negativ im Fehlerfall. Insbesondere:
+ *
+ * -EBADF Ein der Stream-IDs ist ungültig
+ */
+lio_stream_t lio_dup(lio_stream_t source, lio_stream_t dest);
+
+/**
* Gibt Informationen zu einer Ressource zurück.
*
* @param resource ID der Ressource
diff --git a/src/modules/lib/syscalls/lostio.c b/src/modules/lib/syscalls/lostio.c
index 81658b7..b898e7a 100644
--- a/src/modules/lib/syscalls/lostio.c
+++ b/src/modules/lib/syscalls/lostio.c
@@ -116,6 +116,39 @@ int lio_stat(lio_resource_t resource, struct lio_stat* sbuf)
}
/**
+ * Erstellt eine zusätzliche Stream-ID für einen Stream.
+ *
+ * @param source Der zu duplizierende Stream
+ * @param dest Neue ID, die der Stream erhalten soll, oder -1 für eine
+ * beliebige freie ID. Wenn diese ID bereits einen Stream bezeichnet, wird
+ * dieser geschlossen.
+ *
+ * @return Neue Stream-ID bei Erfolg, negativ im Fehlerfall. Insbesondere:
+ *
+ * -EBADF Ein der Stream-IDs ist ungültig
+ */
+lio_stream_t lio_dup(lio_stream_t source, lio_stream_t dest)
+{
+ volatile lio_stream_t d = dest;
+ int result;
+
+ asm(
+ "pushl %3;"
+ "pushl %2;"
+ "mov %1, %%eax;"
+ "int $0x30;"
+ "add $0x8, %%esp;"
+ : "=a" (result) : "i" (SYSCALL_LIO_DUP), "r" (&source), "r" (&d)
+ : "memory");
+
+ if (result < 0) {
+ return result;
+ } else {
+ return d;
+ }
+}
+
+/**
* Schließt einen Stream.
*
* @param s Der zu schließende Stream
--
2.1.4