From: Sapan Bhatia Date: Mon, 3 Mar 2008 00:19:43 +0000 (+0000) Subject: Introduced direct-connected services, which offer pipe semantics. X-Git-Tag: vsys-0.7-4~24 X-Git-Url: http://git.onelab.eu/?p=vsys.git;a=commitdiff_plain;h=c9636f84acdab799ccfc5d50824138db70d0a5d3 Introduced direct-connected services, which offer pipe semantics. 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 --- diff --git a/.dep b/.dep index 3ec5199..60ed53b 100644 --- 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 diff --git a/Makefile b/Makefile index 55e146c..fad8ce3 100644 --- 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 index 0000000..3f89ad4 --- /dev/null +++ b/directfifowatcher.ml @@ -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 *) + () diff --git a/dirwatcher.ml b/dirwatcher.ml index fed87d4..e43de77 100644 --- a/dirwatcher.ml +++ b/dirwatcher.ml @@ -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) || diff --git a/frontend.ml b/frontend.ml index ab4f176..335782a 100644 --- a/frontend.ml +++ b/frontend.ml @@ -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 --- 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