add function to create a postgresql-based VFS webdav

Fri, 28 Jan 2022 15:44:30 +0100

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Fri, 28 Jan 2022 15:44:30 +0100
branch
webdav
changeset 276
0cb4eda146c4
parent 275
535004faa1a5
child 277
7608af69739f

add function to create a postgresql-based VFS

src/server/daemon/vfs.c file | annotate | diff | comparison | revisions
src/server/plugins/postgresql/init.c file | annotate | diff | comparison | revisions
src/server/plugins/postgresql/init.h file | annotate | diff | comparison | revisions
src/server/plugins/postgresql/vfs.c file | annotate | diff | comparison | revisions
src/server/plugins/postgresql/vfs.h file | annotate | diff | comparison | revisions
src/server/public/vfs.h file | annotate | diff | comparison | revisions
--- a/src/server/daemon/vfs.c	Thu Jan 27 21:24:27 2022 +0100
+++ b/src/server/daemon/vfs.c	Fri Jan 28 15:44:30 2022 +0100
@@ -45,7 +45,7 @@
 #define VFS_MALLOC(pool, size) pool ? pool_malloc(pool, size) : malloc(size)
 #define VFS_FREE(pool, ptr) pool ? pool_free(pool, ptr) : free(ptr)
 
-static UcxMap *vfs_map;
+static UcxMap *vfs_type_map;
 
 static VFS sys_vfs = {
     sys_vfs_open,
@@ -79,20 +79,22 @@
 };
 
 int vfs_init() {
-    vfs_map = ucx_map_new(16);
-    if(!vfs_map) {
+    vfs_type_map = ucx_map_new(16);
+    if(!vfs_type_map) {
         return -1;
     }
     return 0;
 }
 
-void vfs_add(char *name, VFS *vfs) {
+int vfs_register_type(const char *name, vfs_create_func vfsCreate) {
     WS_ASSERT(name);
     
-    if(!vfs_map) {
-        vfs_init();
+    if(!vfs_type_map) {
+        if(vfs_init()) {
+            return 1;
+        }
     }
-    ucx_map_cstr_put(vfs_map, name, vfs);
+    return ucx_map_cstr_put(vfs_type_map, name, vfsCreate);
 }
 
 VFSContext* vfs_request_context(Session *sn, Request *rq) {
--- a/src/server/plugins/postgresql/init.c	Thu Jan 27 21:24:27 2022 +0100
+++ b/src/server/plugins/postgresql/init.c	Fri Jan 28 15:44:30 2022 +0100
@@ -29,6 +29,7 @@
 #include "init.h"
 
 #include "resource.h"
+#include "vfs.h"
 
 int pg_init(pblock *pb, Session *sn, Request *Rq) {
     if(resourcepool_register_type("postgresql", pg_get_resource_type())) {
@@ -36,5 +37,14 @@
         return REQ_ABORTED;
     }
     
+    if(pg_register_vfs(pb)) {
+        log_ereport(LOG_FAILURE, "pg-init: Cannot register vfs type");
+        return REQ_ABORTED;
+    }
+    
     return REQ_PROCEED;
 }
+
+int pg_register_vfs(pblock *pb) {
+    return vfs_register_type("postgresql", pg_vfs_create);
+}
--- a/src/server/plugins/postgresql/init.h	Thu Jan 27 21:24:27 2022 +0100
+++ b/src/server/plugins/postgresql/init.h	Fri Jan 28 15:44:30 2022 +0100
@@ -39,6 +39,8 @@
 
 int pg_init(pblock *pb, Session *sn, Request *Rq);
 
+int pg_register_vfs(pblock *pb);
+
 
 #ifdef __cplusplus
 }
--- a/src/server/plugins/postgresql/vfs.c	Thu Jan 27 21:24:27 2022 +0100
+++ b/src/server/plugins/postgresql/vfs.c	Fri Jan 28 15:44:30 2022 +0100
@@ -55,6 +55,46 @@
     pg_vfs_dirio_close
 };
 
+
+
+VFS* pg_vfs_create(Session *sn, Request *rq, pblock *pb) {
+    // resourcepool is required
+    char *resource_pool = pblock_find("resourcepool", pb);
+    if(!resource_pool) {
+        log_ereport(LOG_MISCONFIG, "pg_vfs_create: missing resourcepool parameter");
+        return NULL;
+    }
+    
+    // get the resource first (most likely to fail due to misconfig)
+    ResourceData *resdata = resourcepool_lookup(sn, rq, resource_pool, 0);
+    if(!resdata) {
+        log_ereport(LOG_MISCONFIG, "postgresql vfs: resource pool %s not found", resource_pool);
+        return NULL;
+    }
+    // resdata will be freed automatically when the request is finished
+    
+    // Create a new VFS object and a separate instance object
+    // VFS contains fptrs that can be copied from pg_vfs_class
+    // instance contains request specific data (PGconn)
+    VFS *vfs = pool_malloc(sn->pool, sizeof(VFS));
+    if(!vfs) {
+        return NULL;
+    }
+    
+    PgVFS *vfs_priv = pool_malloc(sn->pool, sizeof(PgVFS));
+    if(!vfs_priv) {
+        pool_free(sn->pool, vfs);
+        return NULL;
+    }
+    
+    memcpy(vfs, &pg_vfs_class, sizeof(VFS));
+    vfs->flags = 0;
+    vfs->instance = vfs_priv;
+    
+    return vfs;
+}
+
+
 /* -------------------------- VFS functions -------------------------- */
 
 SYS_FILE pg_vfs_open(VFSContext *ctx, const char *path, int oflags) {
--- a/src/server/plugins/postgresql/vfs.h	Thu Jan 27 21:24:27 2022 +0100
+++ b/src/server/plugins/postgresql/vfs.h	Fri Jan 28 15:44:30 2022 +0100
@@ -32,10 +32,18 @@
 #include "../../public/nsapi.h"
 #include "../../public/vfs.h"
 
+#include <libpq-fe.h>
+
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+typedef struct PgVFS {
+    ResourceData *pg_resource;
+    PGconn *connection;
+} PgVFS;
+    
+VFS* pg_vfs_create(Session *sn, Request *rq, pblock *pb);
     
 SYS_FILE pg_vfs_open(VFSContext *ctx, const char *path, int oflags);
 int pg_vfs_stat(VFSContext *ctx, const char *path, struct stat *buf);
--- a/src/server/public/vfs.h	Thu Jan 27 21:24:27 2022 +0100
+++ b/src/server/public/vfs.h	Fri Jan 28 15:44:30 2022 +0100
@@ -108,10 +108,12 @@
     void (*close)(VFS_DIR dir);
 };
 
+typedef VFS*(*vfs_create_func)(Session *sn, Request *rq, pblock *pb);
+
 /*
  * registers a new VFS
  */
-void vfs_add(char *name, VFS *vfs);
+int vfs_register_type(const char *name, vfs_create_func vfsCreate);
 
 /*
  * creates a VFSContext for a Request

mercurial