Introduced direct-connected services, which offer pipe semantics.
authorSapan Bhatia <sapanb@cs.princeton.edu>
Mon, 3 Mar 2008 00:19:43 +0000 (00:19 +0000)
committerSapan Bhatia <sapanb@cs.princeton.edu>
Mon, 3 Mar 2008 00:19:43 +0000 (00:19 +0000)
In the long term, this will be more stable than the previous strategy.
IN the short term (for the next 1-2 days) vsys is broken... don't use it

.dep
Makefile
directfifowatcher.ml [new file with mode: 0644]
dirwatcher.ml
frontend.ml
main.ml

diff --git a/.dep b/.dep
index 3ec5199..60ed53b 100644 (file)
--- a/.dep
+++ b/.dep
@@ -1,12 +1,22 @@
+backend.cmo: inotify.cmi globals.cmo frontend.cmo fifowatcher.cmo \
+    dirwatcher.cmo 
+backend.cmx: inotify.cmi globals.cmx frontend.cmx fifowatcher.cmx \
+    dirwatcher.cmx 
+conffile.cmo: globals.cmo 
+conffile.cmx: globals.cmx 
+directfifowatcher.cmo: splice.cmo inotify.cmi globals.cmo dirwatcher.cmo 
+directfifowatcher.cmx: splice.cmx inotify.cmi globals.cmx dirwatcher.cmx 
 dirwatcher.cmo: inotify.cmi globals.cmo fdwatcher.cmo 
 dirwatcher.cmx: inotify.cmi globals.cmx fdwatcher.cmx 
 fdwatcher.cmo: globals.cmo 
 fdwatcher.cmx: globals.cmx 
-fifowatcher.cmo: inotify.cmi globals.cmo fdwatcher.cmo dirwatcher.cmo 
-fifowatcher.cmx: inotify.cmi globals.cmx fdwatcher.cmx dirwatcher.cmx 
-frontend.cmo: globals.cmo fifowatcher.cmo 
-frontend.cmx: globals.cmx fifowatcher.cmx 
+fifowatcher.cmo: splice.cmo inotify.cmi globals.cmo fdwatcher.cmo \
+    dirwatcher.cmo 
+fifowatcher.cmx: splice.cmx inotify.cmi globals.cmx fdwatcher.cmx \
+    dirwatcher.cmx 
+frontend.cmo: globals.cmo directfifowatcher.cmo 
+frontend.cmx: globals.cmx directfifowatcher.cmx 
 main.cmo: inotify.cmi globals.cmo frontend.cmo fifowatcher.cmo fdwatcher.cmo \
-    dirwatcher.cmo backend.cmo 
+    dirwatcher.cmo conffile.cmo backend.cmo 
 main.cmx: inotify.cmi globals.cmx frontend.cmx fifowatcher.cmx fdwatcher.cmx \
-    dirwatcher.cmx backend.cmx 
+    dirwatcher.cmx conffile.cmx backend.cmx 
index 55e146c..fad8ce3 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -31,10 +31,10 @@ ocaml_inotify-0.4/inotify.cmxa:
        $(MAKE) -C ocaml_inotify-0.4 && cp -f ocaml_inotify-0.4/inotify_stubs.o ./
 
 vsys: ocaml_inotify-0.4/inotify.cmxa globals.cmx fdwatcher.cmx conffile.cmx splice_stub.o splice.cmx dirwatcher.cmx fifowatcher.cmx frontend.cmx backend.cmx main.cmx docs 
-       ocamlopt -I ocaml_inotify-0.4 str.cmxa unix.cmxa inotify.cmxa globals.cmx fdwatcher.cmx dirwatcher.cmx splice.cmx splice_stub.o fifowatcher.cmx frontend.cmx backend.cmx str.cmxa conffile.cmx main.cmx -o vsys
+       ocamlopt -I ocaml_inotify-0.4 str.cmxa unix.cmxa inotify.cmxa globals.cmx fdwatcher.cmx dirwatcher.cmx splice.cmx splice_stub.o directfifowatcher.cmx frontend.cmx backend.cmx str.cmxa conffile.cmx main.cmx -o vsys
 
-vsys.b: ocaml_inotify-0.4/inotify.cma inotify.cmi globals.ml fdwatcher.ml dirwatcher.ml fifowatcher.ml frontend.ml backend.ml main.ml
-       ocamlc -g str.cma unix.cma ocaml_inotify-0.4/inotify.cma globals.cmo fdwatcher.cmo dirwatcher.cmo fifowatcher.cmo frontend.cmo backend.cmo str.cma conffile.cmo main.cmo -o vsys.b
+vsys.b: ocaml_inotify-0.4/inotify.cma inotify.cmi globals.ml fdwatcher.ml dirwatcher.ml directfifowatcher.ml frontend.ml backend.ml main.ml
+       ocamlc -g str.cma unix.cma ocaml_inotify-0.4/inotify.cma globals.cmo fdwatcher.cmo dirwatcher.cmo directfifowatcher.cmo frontend.cmo backend.cmo str.cma conffile.cmo main.cmo -o vsys.b
 
 install: vsys
        cp vsys $(INSTALL_DIR)/usr/bin
diff --git a/directfifowatcher.ml b/directfifowatcher.ml
new file mode 100644 (file)
index 0000000..3f89ad4
--- /dev/null
@@ -0,0 +1,90 @@
+(** fifowatcher.ml: Routines to handle non-persistent scripts *)
+
+open Inotify
+open Unix
+open Globals
+open Dirwatcher
+open Printf
+open Splice
+
+let backend_prefix = ref ""
+let direct_fifo_table: (string,(string*string) option) Hashtbl.t = Hashtbl.create 1024
+
+let rec list_check lst elt =
+  match lst with
+    | [] -> false
+    | car::cdr -> if (car==elt) then true else list_check cdr elt
+
+
+
+
+(* vsys is activated when a client opens an in file *)
+let connect_file fqp_in =
+  (* Do we care about this file? *)
+  let entry_info = try
+    Hashtbl.find direct_fifo_table fqp_in with _ -> fprintf logfd "[Alert] Access via unauthorized vsys entry: %s\n" fqp_in;flush logfd;None in
+    match entry_info with
+      | Some(execpath,slice_name) ->
+          fprintf logfd "Executing %s for slice %s\n" execpath slice_name;flush logfd;
+          begin
+            let len = String.length fqp_in in
+            let fqp = String.sub fqp_in 0 (len-3) in
+            let fqp_out = String.concat "." [fqp;"out"] in
+            let fifo_fdin =
+              try openfile fqp_in [O_RDONLY;O_NONBLOCK] 0o777 with
+                  e->fprintf logfd "Error opening and connecting FIFO: %s\n" fqp_in;flush logfd;raise e
+            in
+            let fifo_fdout =
+              try openfile fqp_out [O_WRONLY;O_NONBLOCK] 0o777 with
+                  _->fprintf logfd "%s Output pipe not open, using stdout in place of %s\n" slice_name fqp_out;flush logfd;stdout
+            in
+              try ignore(create_process execpath [|execpath;slice_name|] fifo_fdin fifo_fdout fifo_fdout) with e -> fprintf logfd "Error executing service: %s\n" execpath;flush logfd
+          end
+      | None -> ()
+
+
+(** Make a pair of fifo entries *)
+let mkentry fqp abspath perm uname = 
+  fprintf logfd "Making entry %s->%s\n" fqp abspath;flush logfd;
+  let fifoin=sprintf "%s.in" fqp in
+  let fifoout=sprintf "%s.out" fqp in
+    (try Unix.unlink fifoin with _ -> ());
+    (try Unix.unlink fifoout with _ -> ());
+    (try 
+       let infname =(sprintf "%s.in" fqp) in
+       let outfname =(sprintf "%s.out" fqp) in
+         Unix.mkfifo infname 0o666;
+         Unix.mkfifo outfname 0o666;
+         ( (* Make the user the owner of the pipes in a non-chroot environment *)
+           if (!Globals.nochroot) then
+             let pwentry = Unix.getpwnam uname in
+               Unix.chown infname pwentry.pw_uid pwentry.pw_gid; 
+               Unix.chown outfname pwentry.pw_uid pwentry.pw_gid
+         );
+         Success
+     with 
+         e->fprintf logfd "Error creating FIFO: %s->%s. May be something wrong at the frontend.\n" fqp fifoout;flush logfd;Failed)
+
+(** Open fifos for a session. SHOULD NOt shutdown vsys if the fifos don't exist *)
+let openentry fqp backend_spec =
+  let fqp_in = String.concat "." [fqp;"in"] in
+    Hashtbl.replace direct_fifo_table fqp_in (Some(backend_spec))
+
+(** Close fifos that just got removed *)
+let closeentry fqp =
+  let fqp_in = String.concat "." [fqp;"in"] in
+    Hashtbl.remove direct_fifo_table fqp_in
+
+let direct_fifo_handler dirname evlist fname =
+  printf "Received event %s %s\n" dirname fname;flush Pervasives.stdout;
+  let is_event = list_check evlist in
+    if (is_event Open) then 
+      let fqp_in = String.concat "/" [dirname;fname] in
+        connect_file fqp_in
+
+let add_dir_watch fqp =
+  Dirwatcher.add_watch fqp [S_Open] (Some(direct_fifo_handler))
+
+let del_dir_watch fqp =
+  (* XXX Dirwatcher.del_watch fqp *)
+  ()
index fed87d4..e43de77 100644 (file)
@@ -22,10 +22,17 @@ let handle_dir_event dirname evlist str =
         flush logfd
 
 let add_watch dir events handler =
-  fprintf logfd "Adding watch for %s\n" dir;flush logfd;
+  printf "Adding watch for %s\n" dir;flush Pervasives.stdout;
   let wd = Inotify.add_watch fd dir events in
       Hashtbl.add wdmap wd (dir,handler)
 
+        (* XXX
+let del_watch dir =
+  fprintf logfd "Removing watch for %s\n" dir;flush logfd;
+  let wd = Inotify.rm_watch fd dir in
+      Hashtbl.remove wdmap wd 
+         *)
+
 let asciiz s =
   let rec findfirstnul str idx len =
     if ((idx==len) || 
index ab4f176..335782a 100644 (file)
@@ -3,7 +3,7 @@
 open Printf
 open Unix
 open Globals
-open Fifowatcher
+open Directfifowatcher
 
 (** frontendhandler class: Methods to create and unlink pipes and directories 
   @param root_dir vsys directory inside a slice
@@ -18,57 +18,64 @@ object(this)
     @param abspath Absolute path of the entry
     @param perm Permissions of the entry at the frontend *)
   method mkentry (rp:relpath) abspath perm = 
-            let realperm = perm land (lnot 0o111) in
-    match rp with Relpath(rel) ->
-      let fqp = String.concat "/" [root_dir;rel] in
-      let res = Fifowatcher.mkentry fqp abspath realperm slice_name in
-        match res with 
-          | Success ->
-              Fifowatcher.openentry fqp (abspath,slice_name) realperm
-          | _ -> ()
+    let realperm = perm land (lnot 0o111) in
+      match rp with Relpath(rel) ->
+        let fqp = String.concat "/" [root_dir;rel] in
+        let res = Directfifowatcher.mkentry fqp abspath realperm slice_name in
+          match res with 
+            | Success ->
+                Directfifowatcher.openentry fqp (abspath,slice_name)
+            | _ -> ()
 
   (** A new directory was created at the backend, make a corresponding directory
     at the frontend. Refer to mkentry for parameters *)
   method mkdir rp perm =
     match rp with Relpath(rel) ->
-    let fqp = String.concat "/" [root_dir;rel] in
-      try 
-            let s = Unix.stat fqp in
-              if (s.st_kind<>S_DIR) then
-                begin
-                        Unix.unlink fqp;
-                        Unix.mkdir fqp perm
-                end
-              else if (s.st_perm <> perm) then
-                begin
-                        fprintf logfd "Removing directory %s\n" fqp;
-                        flush logfd;
-                        Unix.rmdir fqp;
-                        Unix.mkdir fqp perm
-                end
-      with Unix.Unix_error(_,_,_) ->
-        Unix.mkdir fqp perm
+      let fqp = String.concat "/" [root_dir;rel] in
+        try 
+          let s = Unix.stat fqp in
+            if (s.st_kind<>S_DIR) then
+              begin
+                Unix.unlink fqp;
+                Unix.mkdir fqp perm
+              end
+            else if (s.st_perm <> perm) then
+              begin
+                Unix.rmdir fqp;
+                Unix.mkdir fqp perm
+              end;
+        with Unix.Unix_error(_,_,_) ->
+          Unix.mkdir fqp perm;
+        Directfifowatcher.add_dir_watch fqp
+
+
+
+            
 
   (** Functions corresponding to file deletion/directory removal *)
 
   (** *)
   method unlink rp =
     match rp with Relpath(rel) ->
-    let fqp1 = String.concat "/" [root_dir;rel] in
-    let fqp_in = String.concat "." [fqp1;"in"] in
-    let fqp2 = String.concat "/" [root_dir;rel] in
-    let fqp_out = String.concat "." [fqp2;"out"] in
-      try 
-        Unix.unlink fqp_in;
-        Unix.unlink fqp_out
-      with _ ->
-        fprintf logfd "Hm. %s disappeared. Looks like slice %s shot itself in the foot\n" fqp1 (this#get_slice_name ());flush logfd
+      let fqp = String.concat "/" [root_dir;rel] in
+      let fqp_in = String.concat "." [fqp;"in"] in
+      let fqp_out = String.concat "." [fqp;"out"] in
+        Directfifowatcher.closeentry fqp;
+        try 
+          Unix.unlink fqp_in;
+          Unix.unlink fqp_out
+        with _ ->
+          fprintf logfd "Hm. %s disappeared. Looks like slice %s shot itself in the foot\n" fqp (this#get_slice_name ());flush logfd
 
   method rmdir rp =
     match rp with Relpath(rel) ->
-    let fqp = String.concat "/" [root_dir;rel] in
-      try
-      Unix.rmdir fqp
-      with _ ->
-        fprintf logfd "Hm. %s disappeared. Looks like slice %s shot itself in the foot\n" fqp (this#get_slice_name ());flush logfd
+      let fqp = String.concat "/" [root_dir;rel] in
+        Directfifowatcher.del_dir_watch fqp;
+        try
+          Unix.rmdir fqp
+        with _ ->
+          fprintf logfd "Hm. %s disappeared or not empty. Looks like slice %s shot itself in the foot\n" fqp (this#get_slice_name ());flush logfd
+
+  initializer 
+    Directfifowatcher.add_dir_watch root_dir
 end
diff --git a/main.ml b/main.ml
index 5ec2952..534f915 100644 (file)
--- a/main.ml
+++ b/main.ml
@@ -4,7 +4,6 @@ open Printf
 open Inotify
 open Backend
 open Frontend
-open Fifowatcher
 open Conffile
 
 let input_file_list = ref []
@@ -44,7 +43,6 @@ let _ =
           end;
 
             Dirwatcher.initialize ();
-            Fifowatcher.initialize ();
             if (!Globals.conffile <> "") then
               begin
               let frontends = Conffile.read_frontends !Globals.conffile in