Add an option and test implementation for the full-duplex ack protocol.
authorMatthew Dillon <dillon@dragonflybsd.org>
Wed, 6 Jul 2005 06:06:44 +0000 (06:06 +0000)
committerMatthew Dillon <dillon@dragonflybsd.org>
Wed, 6 Jul 2005 06:06:44 +0000 (06:06 +0000)
sbin/jscan/jfile.c
sbin/jscan/jscan.8
sbin/jscan/jscan.c
sbin/jscan/jscan.h
sbin/jscan/jstream.c

index e5241a3..9154c27 100644 (file)
@@ -31,7 +31,7 @@
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  * 
- * $DragonFly: src/sbin/jscan/jfile.c,v 1.4 2005/07/05 04:08:07 dillon Exp $
+ * $DragonFly: src/sbin/jscan/jfile.c,v 1.5 2005/07/06 06:06:44 dillon Exp $
  */
 
 #include "jscan.h"
  * Open a journal for directional scanning
  */
 struct jfile *
-jopen_stream(const char *path, enum jdirection jdir)
+jopen_stream(const char *path, enum jdirection jdir, int flags)
 {
     FILE *fp;
     struct jfile *jf;
 
     if ((fp = fopen(path, "r")) == NULL)
        return (NULL);
-    if ((jf = jopen_fp(fp, jdir)) == NULL)
+    if ((jf = jopen_fp(fp, jdir, flags)) == NULL)
        fclose (fp);
     return(jf);
 }
 
 struct jfile *
-jopen_fp(FILE *fp, enum jdirection jdir)
+jopen_fp(FILE *fp, enum jdirection jdir, int flags)
 {
     struct jfile *jf;
 
@@ -62,6 +62,7 @@ jopen_fp(FILE *fp, enum jdirection jdir)
     jf->jf_fp = fp;
     jf->jf_direction = jdir;
     jf->jf_setpt = -1;
+    jf->jf_flags = flags;
     if (jdir == JF_BACKWARDS) {
        fseeko(jf->jf_fp, 0L, SEEK_END);
        jf->jf_pos = ftello(jf->jf_fp);
@@ -142,6 +143,15 @@ jread(struct jfile *jf, void *buf, int bytes)
     }
 }
 
+int
+jwrite(struct jfile *jf, void *buf, int bytes)
+{
+    int n;
+
+    n = write(fileno(jf->jf_fp), buf, bytes);
+    return(n);
+}
+
 void
 jset(struct jfile *jf)
 {
index 3a24ffe..73872df 100644 (file)
@@ -31,7 +31,7 @@
 .\" OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.\" $DragonFly: src/sbin/jscan/jscan.8,v 1.2 2005/07/05 00:26:03 dillon Exp $
+.\" $DragonFly: src/sbin/jscan/jscan.8,v 1.3 2005/07/06 06:06:44 dillon Exp $
 .\"
 .Dd March 6, 2005
 .Dt JSCAN 8
@@ -41,7 +41,7 @@
 .Nd journal file processing program
 .Sh SYNOPSIS
 .Nm
-.Fl rd
+.Fl 2rd
 .Op Ar journal_files
 .Pp
 .Sh DESCRIPTION
@@ -50,6 +50,9 @@ The
 utility scans journal files for the purposes of debugging dumps, restoration,
 undo, mirroring, and other journaling features.
 .Bl -tag -width indent
+.It Fl 2
+Implement the full-duplex acknowledgement protocol on the input descriptor.
+Note that shell pipes are full-duplex and can be used with this option.
 .It Fl d
 dumps the contents of the journaling file in a human readable format.
 .It Fl r
index b52fb9f..68088ae 100644 (file)
@@ -31,7 +31,7 @@
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  * 
- * $DragonFly: src/sbin/jscan/jscan.c,v 1.3 2005/07/05 00:26:03 dillon Exp $
+ * $DragonFly: src/sbin/jscan/jscan.c,v 1.4 2005/07/06 06:06:44 dillon Exp $
  */
 
 #include "jscan.h"
@@ -47,12 +47,16 @@ main(int ac, char **av)
 {
     int ch;
     int i;
+    int jfflags = 0;
     enum jdirection direction = JF_FORWARDS;
     enum jmode jmode = JS_NONE;
     struct jfile *jf;
 
-    while ((ch = getopt(ac, av, "dmr")) != -1) {
+    while ((ch = getopt(ac, av, "2dmrw:W:")) != -1) {
        switch(ch) {
+       case '2':
+           jfflags |= JF_FULL_DUPLEX;
+           break;
        case 'd':
            debug_opt = 1;
            if (jmode == JS_NONE)
@@ -64,6 +68,10 @@ main(int ac, char **av)
        case 'r':
            direction = JF_BACKWARDS;
            break;
+       case 'W':
+           /* fallthrough */
+       case 'w':
+           /* not implemented yet */
        default:
            fprintf(stderr, "unknown option: -%c\n", optopt);
            usage(av[0]);
@@ -85,9 +93,9 @@ main(int ac, char **av)
     } else {
        for (i = optind; i < ac; ++i) {
            if (strcmp(av[i], "stdin") == 0)
-               jf = jopen_fp(stdin, direction);
+               jf = jopen_fp(stdin, direction, jfflags);
            else
-               jf = jopen_stream(av[i], direction);
+               jf = jopen_stream(av[i], direction, jfflags);
            if (jf != NULL) {
                switch(jmode) {
                case JS_MIRROR:
index 58379ad..19a0cb8 100644 (file)
@@ -31,7 +31,7 @@
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  * 
- * $DragonFly: src/sbin/jscan/jscan.h,v 1.4 2005/07/05 02:38:34 dillon Exp $
+ * $DragonFly: src/sbin/jscan/jscan.h,v 1.5 2005/07/06 06:06:44 dillon Exp $
  */
 
 #include <sys/types.h>
@@ -60,8 +60,11 @@ struct jfile {
     FILE               *jf_fp;
     enum jdirection    jf_direction;
     int                        jf_error;
+    int                        jf_flags;
 };
 
+#define JF_FULL_DUPLEX 0x0001
+
 struct jdata {
     struct jdata       *jd_next;
     int                        jd_size;
@@ -116,11 +119,12 @@ char *dupdatapath(const void *buf, int bytes);
 
 struct jstream *jscan_stream(struct jfile *jf);
 void jscan_dispose(struct jstream *js);
-struct jfile *jopen_stream(const char *path, enum jdirection jdir);
-struct jfile *jopen_fp(FILE *fp, enum jdirection jdir);
+struct jfile *jopen_stream(const char *path, enum jdirection jdir, int flags);
+struct jfile *jopen_fp(FILE *fp, enum jdirection jdir, int flags);
 void jclose_stream(struct jfile *jf);
 void jalign(struct jfile *jf);
 int jread(struct jfile *jf, void *buf, int bytes);
+int jwrite(struct jfile *jf, void *buf, int bytes);
 void jset(struct jfile *jf);
 void jreturn(struct jfile *jf);
 void jflush(struct jfile *jf);
index d390e26..cffe96a 100644 (file)
@@ -31,7 +31,7 @@
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  * 
- * $DragonFly: src/sbin/jscan/jstream.c,v 1.3 2005/07/05 02:38:34 dillon Exp $
+ * $DragonFly: src/sbin/jscan/jstream.c,v 1.4 2005/07/06 06:06:44 dillon Exp $
  */
 
 #include "jscan.h"
@@ -63,6 +63,7 @@ jscan_stream(struct jfile *jf)
 {
     struct journal_rawrecbeg head;
     struct journal_rawrecend tail;
+    struct journal_ackrecord ack;
     int recsize;
     int search;
     int error;
@@ -116,6 +117,24 @@ jscan_stream(struct jfile *jf)
                break;
            }
 
+           /*
+            * XXX if the stream is full duplex send the ack back now.  This
+            * really needs to be delayed until the transaction is committed,
+            * but there are stalling issues if the transaction being
+            * collected exceeds to the size of the FIFO.  So for now this
+            * is just for testing.
+            */
+           if (jf->jf_flags & JF_FULL_DUPLEX) {
+               bzero(&ack, sizeof(ack));
+               ack.rbeg.begmagic = JREC_BEGMAGIC;
+               ack.rbeg.streamid = JREC_STREAMID_ACK;
+               ack.rbeg.transid = head.transid;
+               ack.rbeg.recsize = sizeof(ack);
+               ack.rend.endmagic = JREC_ENDMAGIC;
+               ack.rend.recsize = sizeof(ack);
+               jwrite(jf, &ack, sizeof(ack));
+           }
+
            /*
             * note: recsize is aligned (the actual record size),
             * head.recsize is unaligned (the actual payload size).