[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[tyndur-devel] [PATCH 10/11] init: Unterstützung für LIOv2-Pipequellen
+ init: Wenn eine Datei in einem LIOv1-Service geöffnet wird, der eine
Pipe-Quelle hat, versucht init jetzt erst einmal die Quelle mit LIOv2
zu öffnen. Damit gehen LIOv1-Services auf LIOv2-Services (z.B. ext2
auf ata), aber nicht umgekehrt.
Signed-off-by: Kevin Wolf <kevin@xxxxxxxxxx>
---
src/include/syscallno.h | 1 +
src/kernel2/include/syscall.h | 3 ++
src/kernel2/src/syscall.c | 1 +
src/kernel2/src/syscalls/lostio.c | 26 ++++++++++++++++++
src/modules/include/syscall.h | 15 ++++++++++
src/modules/init/io.c | 52 +++++++++++++++++++++++++++++++++++++
src/modules/lib/syscalls/lostio.c | 34 ++++++++++++++++++++++++
7 files changed, 132 insertions(+), 0 deletions(-)
diff --git a/src/include/syscallno.h b/src/include/syscallno.h
index ad25dc3..47ab453 100644
--- a/src/include/syscallno.h
+++ b/src/include/syscallno.h
@@ -107,6 +107,7 @@
#define SYSCALL_LIO_TRUNCATE 97
#define SYSCALL_LIO_UNLINK 98
#define SYSCALL_LIO_SYNC_ALL 99
+#define SYSCALL_LIO_PASS_FD 100
#define SYSCALL_LIO_SRV_SERVICE_REGISTER 110
#define SYSCALL_LIO_SRV_TREE_SET_RING 111
diff --git a/src/kernel2/include/syscall.h b/src/kernel2/include/syscall.h
index 4ac87d0..9ff28f6 100644
--- a/src/kernel2/include/syscall.h
+++ b/src/kernel2/include/syscall.h
@@ -208,6 +208,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);
+/// Stream an anderen Prozess weitergeben
+int syscall_lio_pass_fd(lio_usp_stream_t* stream_id, pid_t pid);
+
/// Aus Stream lesen
void syscall_lio_read(lio_usp_stream_t* stream_id, uint64_t* offset,
size_t bytes, void* buffer, int updatepos, ssize_t* result);
diff --git a/src/kernel2/src/syscall.c b/src/kernel2/src/syscall.c
index a5eda73..80fa605 100644
--- a/src/kernel2/src/syscall.c
+++ b/src/kernel2/src/syscall.c
@@ -123,6 +123,7 @@ void syscall_init()
syscall_register(SYSCALL_LIO_STAT, &syscall_lio_stat, 2);
syscall_register(SYSCALL_LIO_UNLINK, &syscall_lio_unlink, 3);
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_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 987d29c..1c978d4 100644
--- a/src/kernel2/src/syscalls/lostio.c
+++ b/src/kernel2/src/syscalls/lostio.c
@@ -129,6 +129,32 @@ int syscall_lio_close(lio_usp_stream_t* stream_id)
return ret;
}
+/// Stream an anderen Prozess weitergeben
+int syscall_lio_pass_fd(lio_usp_stream_t* stream_id, pid_t pid)
+{
+ struct lio_usp_stream* fd;
+ struct lio_stream* stream;
+ pm_process_t* process;
+
+ process = pm_get(pid);
+ if (process == NULL) {
+ return -EINVAL;
+ }
+
+ // TODO: is_userspace
+ fd = lio_usp_get_stream(current_process, *stream_id);
+ if (fd == NULL) {
+ return -EBADF;
+ }
+
+ stream = fd->stream;
+ lio_usp_remove_stream(current_process, fd);
+ fd = lio_usp_add_stream(process, stream);
+ *stream_id = fd->usp_id;
+
+ return 0;
+}
+
/// Aus Stream lesen
void syscall_lio_read(lio_usp_stream_t* stream_id, uint64_t* offset,
size_t bytes, void* buffer, int updatepos, ssize_t* result)
diff --git a/src/modules/include/syscall.h b/src/modules/include/syscall.h
index 298e737..33cd98e 100644
--- a/src/modules/include/syscall.h
+++ b/src/modules/include/syscall.h
@@ -169,6 +169,21 @@ int lio_stat(lio_resource_t resource, struct lio_stat* sbuf);
int lio_close(lio_stream_t s);
/**
+ * Gibt einen Stream an einen anderen Prozess ab. Der Stream wird in diesem
+ * Prozess dabei ungültig.
+ *
+ * @param s Der abzugebenden Stream
+ * @param pid Zielprozess, der den Stream erhalten soll
+ *
+ * @return Stream-ID im Zielprozess bei Erfolg, negativ im Fehlerfall.
+ * Insbesondere:
+ *
+ * -EINVAL Es gibt keinen Prozess mit der gegebenen PID
+ * -EBADF Die Stream-ID ist ungültig
+ */
+lio_stream_t lio_pass_fd(lio_stream_t s, pid_t pid);
+
+/**
* Liest aus dem Stream ab der aktuellen Position des Dateizeigers und bewegt
* den Dateizeiger hinter das letzte gelesene Byte.
*
diff --git a/src/modules/init/io.c b/src/modules/init/io.c
index 56df8b0..4ce8e76 100644
--- a/src/modules/init/io.c
+++ b/src/modules/init/io.c
@@ -34,6 +34,7 @@
*/
#define MODULE_INIT
+#include <stdint.h>
#include "types.h"
#include "syscall.h"
#include "string.h"
@@ -51,9 +52,49 @@ void io_init()
register_message_handler("IO_OPEN ", &rpc_io_open);
}
+io_resource_t* newio_open(const char* service_name, const char* path,
+ uint8_t attr, pid_t pid)
+{
+ char* p;
+ lio_resource_t r;
+ lio_stream_t s;
+ io_resource_t* result = NULL;
+
+ // Nur fuer Pipequellen
+ if (attr != (IO_OPEN_MODE_READ | IO_OPEN_MODE_WRITE)) {
+ return NULL;
+ }
+
+ asprintf(&p, "%s:%s", service_name, path);
+ r = lio_resource(p, 1);
+ if (r < 0) {
+ goto out;
+ }
+
+ s = lio_open(r, LIO_READ | LIO_WRITE);
+ if (s < 0) {
+ goto out;
+ }
+
+ result = malloc(sizeof(*result));
+ *result = (io_resource_t) {
+ .lio2_stream = s,
+ .lio2_res = r,
+ .flags = IO_RES_FLAG_READAHEAD,
+ };
+
+out:
+ free(p);
+ return result;
+}
+
io_resource_t* io_open_res(const char* service_name, const char* path, io_resource_t* pipe_source, uint8_t attr, pid_t pid)
{
+ io_resource_t* newres;
+ if ((newres = newio_open(service_name, path, attr, pid))) {
+ return newres;
+ }
struct service_s* dest_service = NULL;
dest_service = get_service_by_name(service_name);
//printf("\nopen resource: service='%s' path='%s' => %x\n", service_name, path, dest_service);
@@ -63,6 +104,15 @@ io_resource_t* io_open_res(const char* service_name, const char* path, io_resour
return NULL;
}
+
+ // Pipequelle für den Service lesbar machen
+ if (pipe_source && IS_LIO2(pipe_source)) {
+ pipe_source->lio2_stream =
+ lio_pass_fd(pipe_source->lio2_stream, dest_service->pid);
+ if (pipe_source->lio2_stream < 0) {
+ return NULL;
+ }
+ }
//Daten fuer den open-rpc an den Service zusammenflicken
size_t open_request_size = strlen(path) + sizeof(io_resource_t) + sizeof(pid_t) + 6;
@@ -136,6 +186,8 @@ void rpc_io_open(pid_t pid, uint32_t correlation_id, size_t data_size, void* dat
if((pipe_source != NULL) && pipe_source->pid)
{
last_pid = pipe_source->pid;
+ } else if (pipe_source && IS_LIO2(pipe_source)) {
+ /* pipe_source bleibt gültig, aber es gibt keine PID */
} else {
pipe_source = NULL;
break;
diff --git a/src/modules/lib/syscalls/lostio.c b/src/modules/lib/syscalls/lostio.c
index 1961243..6cf8dc1 100644
--- a/src/modules/lib/syscalls/lostio.c
+++ b/src/modules/lib/syscalls/lostio.c
@@ -135,6 +135,40 @@ int lio_close(lio_stream_t s)
return result;
}
+/**
+ * Gibt einen Stream an einen anderen Prozess ab. Der Stream wird in diesem
+ * Prozess dabei ungültig.
+ *
+ * @param s Der abzugebenden Stream
+ * @param pid Zielprozess, der den Stream erhalten soll
+ *
+ * @return Stream-ID im Zielprozess bei Erfolg, negativ im Fehlerfall.
+ * Insbesondere:
+ *
+ * -EINVAL Es gibt keinen Prozess mit der gegebenen PID
+ * -EBADF Die Stream-ID ist ungültig
+ */
+lio_stream_t lio_pass_fd(lio_stream_t s, pid_t pid)
+{
+ volatile lio_stream_t stream = s;
+ int result;
+
+ asm(
+ "pushl %3;"
+ "pushl %2;"
+ "mov %1, %%eax;"
+ "int $0x30;"
+ "add $0x8, %%esp;"
+ : "=a" (result) : "i" (SYSCALL_LIO_PASS_FD), "r" (&stream), "r" (pid)
+ : "memory");
+
+ if (result < 0) {
+ return result;
+ } else {
+ return stream;
+ }
+}
+
static ssize_t read_syscall(lio_stream_t s, uint64_t offset, size_t bytes,
void* buf, int updatepos)
{
--
1.7.7