]> git.sur5r.net Git - bacula/bacula/commitdiff
kes Implement a BSOCK send() method that writes the whole record
authorKern Sibbald <kern@sibbald.com>
Sat, 17 Feb 2007 18:04:29 +0000 (18:04 +0000)
committerKern Sibbald <kern@sibbald.com>
Sat, 17 Feb 2007 18:04:29 +0000 (18:04 +0000)
     in a single write() request rather than in two.

git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@4199 91ce42f0-d328-0410-95d8-f526ca767f89

bacula/src/lib/Makefile.in
bacula/src/lib/bnet.c
bacula/src/lib/bsock.c [new file with mode: 0644]
bacula/src/lib/bsock.h
bacula/src/lib/btimers.c
bacula/src/lib/mem_pool.c
bacula/src/lib/mem_pool.h
bacula/technotes-2.1

index e8c54a17e5f5b5f2707c8e31ed3a2ecdc8d7d4f9..683eed556b0b2b6a34a8f7fe40d97a4ac338392a 100644 (file)
@@ -24,7 +24,7 @@ dummy:
 
 LIBSRCS = attr.c base64.c berrno.c bsys.c bget_msg.c \
          bnet.c bnet_server.c runscript.c \
-         bpipe.c bsnprintf.c btime.c \
+         bsock.c bpipe.c bsnprintf.c btime.c \
          cram-md5.c crc32.c crypto.c daemon.c edit.c fnmatch.c \
          hmac.c idcache.c jcr.c lex.c alist.c dlist.c \
          md5.c message.c mem_pool.c openssl.c parse_conf.c \
@@ -37,7 +37,7 @@ LIBSRCS = attr.c base64.c berrno.c bsys.c bget_msg.c \
 
 LIBOBJS = attr.o base64.o berrno.o bsys.o bget_msg.o \
          bnet.o bnet_server.o runscript.o \
-         bpipe.o bsnprintf.o btime.o \
+         bsock.o bpipe.o bsnprintf.o btime.o \
          cram-md5.o crc32.o crypto.o daemon.o edit.o enh_fnmatch.o fnmatch.o \
          hmac.o idcache.o jcr.o lex.o alist.o dlist.o \
          md5.o message.o mem_pool.o openssl.o parse_conf.o \
index 3c2d88be5f0bf14bba9d80a11850272bf8e046f1..a5ffb495567c23613e3b3b0ae658aa4f9428b022 100644 (file)
@@ -1,13 +1,3 @@
-/*
- * Network Utility Routines
- *
- *  by Kern Sibbald
- *
- * Adapted and enhanced for Bacula, originally written
- * for inclusion in the Apcupsd package
- *
- *   Version $Id$
- */
 /*
    Bacula® - The Network Backup Solution
 
    (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
    Switzerland, email:ftf@fsfeurope.org.
 */
+/*
+ * Network Utility Routines
+ *
+ *  by Kern Sibbald
+ *
+ * Adapted and enhanced for Bacula, originally written
+ * for inclusion in the Apcupsd package
+ *
+ *   Version $Id$
+ */
 
 
 #include "bacula.h"
@@ -69,7 +69,7 @@ static pthread_mutex_t ip_mutex = PTHREAD_MUTEX_INITIALIZER;
  * read requests
  */
 
-static int32_t read_nbytes(BSOCK * bsock, char *ptr, int32_t nbytes)
+int32_t read_nbytes(BSOCK * bsock, char *ptr, int32_t nbytes)
 {
    int32_t nleft, nread;
 
@@ -110,7 +110,7 @@ static int32_t read_nbytes(BSOCK * bsock, char *ptr, int32_t nbytes)
  * It may require several writes.
  */
 
-static int32_t write_nbytes(BSOCK * bsock, char *ptr, int32_t nbytes)
+int32_t write_nbytes(BSOCK * bsock, char *ptr, int32_t nbytes)
 {
    int32_t nleft, nwritten;
 
@@ -374,6 +374,12 @@ int bnet_despool_to_bsock(BSOCK * bsock, void update_attr_spool_size(ssize_t siz
  * Returns: false on failure
  *          true  on success
  */
+bool bnet_send(BSOCK *bsock)
+{
+   return bsock->send();
+}
+
+#ifdef xxx
 bool bnet_send(BSOCK * bsock)
 {
    int32_t rc;
@@ -382,7 +388,7 @@ bool bnet_send(BSOCK * bsock)
    if (bsock->errors || bsock->terminated || bsock->msglen > 1000000) {
       return false;
    }
-   pktsiz = htonl((int32_t) bsock->msglen);
+   pktsiz = htonl((int32_t)bsock->msglen);
    /* send int32_t containing size of data packet */
    bsock->timer_start = watchdog_time;  /* start timer */
    bsock->timed_out = 0;
@@ -447,6 +453,7 @@ bool bnet_send(BSOCK * bsock)
    }
    return true;
 }
+#endif
 
 /*
  * Establish a TLS connection -- server side
@@ -917,7 +924,8 @@ bool bnet_fsend(BSOCK * bs, const char *fmt, ...)
       }
       bs->msg = realloc_pool_memory(bs->msg, maxlen + maxlen / 2);
    }
-   return bnet_send(bs);
+   return bs->send();
+// return bnet_send(bs);
 }
 
 int bnet_get_peer(BSOCK *bs, char *buf, socklen_t buflen) {
diff --git a/bacula/src/lib/bsock.c b/bacula/src/lib/bsock.c
new file mode 100644 (file)
index 0000000..9b1cdf1
--- /dev/null
@@ -0,0 +1,132 @@
+/*
+   Bacula® - The Network Backup Solution
+
+   Copyright (C) 2007-2007 Free Software Foundation Europe e.V.
+
+   The main author of Bacula is Kern Sibbald, with contributions from
+   many others, a complete list can be found in the file AUTHORS.
+   This program is Free Software; you can redistribute it and/or
+   modify it under the terms of version two of the GNU General Public
+   License as published by the Free Software Foundation plus additions
+   that are listed in the file LICENSE.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.
+
+   Bacula® is a registered trademark of John Walker.
+   The licensor of Bacula is the Free Software Foundation Europe
+   (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
+   Switzerland, email:ftf@fsfeurope.org.
+*/
+/*
+ * Network Utility Routines
+ *
+ *  by Kern Sibbald
+ *
+ *   Version $Id: bnet.c 3670 2006-11-21 16:13:58Z kerns $
+ */
+
+
+#include "bacula.h"
+#include "jcr.h"
+#include <netdb.h>
+
+/*
+ * Send a message over the network. The send consists of
+ * two network packets. The first is sends a 32 bit integer containing
+ * the length of the data packet which follows.
+ *
+ * Returns: false on failure
+ *          true  on success
+ */
+bool BSOCK::send()
+{
+   int32_t rc;
+   int32_t pktsiz;
+   int32_t *hdr;
+
+   if (errors || terminated || msglen > 1000000) {
+      return false;
+   }
+   /* Compute total packet length */
+   if (msglen <= 0) {
+      pktsiz = sizeof(pktsiz);               /* signal, no data */
+   } else {
+      pktsiz = msglen + sizeof(pktsiz);      /* data */
+   }
+   /* Store packet length at head of message -- note, we
+    *  have reserved an int32_t just before msg, so we can
+    *  store there 
+    */
+   hdr = (int32_t *)(msg - (int)sizeof(pktsiz));
+   *hdr = htonl(msglen);                     /* store signal/length */
+
+   out_msg_no++;            /* increment message number */
+
+   /* send data packet */
+   timer_start = watchdog_time;  /* start timer */
+   timed_out = 0;
+   /* Full I/O done in one write */
+   rc = write_nbytes(this, (char *)hdr, pktsiz);
+   timer_start = 0;         /* clear timer */
+   if (rc != pktsiz) {
+      errors++;
+      if (errno == 0) {
+         b_errno = EIO;
+      } else {
+         b_errno = errno;
+      }
+      if (rc < 0) {
+         if (!suppress_error_msgs) {
+            Qmsg5(jcr, M_ERROR, 0,
+                  _("Write error sending %d bytes to %s:%s:%d: ERR=%s\n"), 
+                  msglen, who,
+                  host, port, bnet_strerror(this));
+         }
+      } else {
+         Qmsg5(jcr, M_ERROR, 0,
+               _("Wrote %d bytes to %s:%s:%d, but only %d accepted.\n"),
+               msglen, who, host, port, rc);
+      }
+      return false;
+   }
+   return true;
+}
+
+/*
+ * Format and send a message
+ *  Returns: false on error
+ *           true  on success
+ */
+bool BSOCK::fsend(const char *fmt, ...)
+{
+   va_list arg_ptr;
+   int maxlen;
+
+   if (errors || terminated) {
+      return false;
+   }
+   /* This probably won't work, but we vsnprintf, then if we
+    * get a negative length or a length greater than our buffer
+    * (depending on which library is used), the printf was truncated, so
+    * get a bigger buffer and try again.
+    */
+   for (;;) {
+      maxlen = sizeof_pool_memory(msg) - 1;
+      va_start(arg_ptr, fmt);
+      msglen = bvsnprintf(msg, maxlen, fmt, arg_ptr);
+      va_end(arg_ptr);
+      if (msglen > 0 && msglen < (maxlen - 5)) {
+         break;
+      }
+      msg = realloc_pool_memory(msg, maxlen + maxlen / 2);
+   }
+   return send();
+}
index 66e1961923e279668c776ae90ce54fd8baad33c8..923771b863d07d3b7ab81c3222ae8461ca380041 100644 (file)
@@ -1,16 +1,3 @@
-/*
- * Bacula Sock Structure definition
- *
- * Kern Sibbald, May MM
- *
- * Zero msglen from other end indicates soft eof (usually
- *   end of some binary data stream, but not end of conversation).
- *
- * Negative msglen, is special "signal" (no data follows).
- *   See below for SIGNAL codes.
- *
- *   Version $Id$
- */
 /*
    Bacula® - The Network Backup Solution
 
    (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
    Switzerland, email:ftf@fsfeurope.org.
 */
+/*
+ * Bacula Sock Structure definition
+ *
+ * Kern Sibbald, May MM
+ *
+ * Zero msglen from other end indicates soft eof (usually
+ *   end of some binary data stream, but not end of conversation).
+ *
+ * Negative msglen, is special "signal" (no data follows).
+ *   See below for SIGNAL codes.
+ *
+ *   Version $Id$
+ */
+
 
-struct BSOCK {
+class BSOCK {
+public:
    uint64_t read_seqno;               /* read sequence number */
    uint32_t in_msg_no;                /* input message number */
    uint32_t out_msg_no;               /* output message number */
@@ -67,6 +69,11 @@ struct BSOCK {
    JCR *jcr;                          /* jcr or NULL for error msgs */
    struct sockaddr client_addr;    /* client's IP address */
    struct sockaddr_in peer_addr;    /* peer's IP address */
+
+   /* methods -- in bsock.c */
+   bool send();
+   bool fsend(const char*, ...);
+
 };
 
 /* Signal definitions for use in bnet_sig() */
@@ -102,3 +109,6 @@ enum {
 #define BNET_TLS_NONE     0           /* cannot do TLS */
 #define BNET_TLS_OK       1           /* can do, but not required on my end */
 #define BNET_TLS_REQUIRED 2           /* TLS is required */
+
+int32_t read_nbytes(BSOCK * bsock, char *ptr, int32_t nbytes);
+int32_t write_nbytes(BSOCK * bsock, char *ptr, int32_t nbytes);
index 85d1d3a2bada79270569babc039b358f9b896a86..2001284f0e9cee0e73ff3ff53a8d35de824d5199 100644 (file)
@@ -1,13 +1,7 @@
-/*
- * Process and thread timer routines, built on top of watchdogs.
- *
- *    Nic Bellamy <nic@bellamy.co.nz>, October 2004.
- *
-*/
 /*
    Bacula® - The Network Backup Solution
 
-   Copyright (C) 2004-2006 Free Software Foundation Europe e.V.
+   Copyright (C) 2004-2007 Free Software Foundation Europe e.V.
 
    The main author of Bacula is Kern Sibbald, with contributions from
    many others, a complete list can be found in the file AUTHORS.
    (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
    Switzerland, email:ftf@fsfeurope.org.
 */
+/*
+ * Process and thread timer routines, built on top of watchdogs.
+ *
+ *    Nic Bellamy <nic@bellamy.co.nz>, October 2004.
+ *
+*/
 
 #include "bacula.h"
 #include "jcr.h"
index 686c164e66de160c9e32d1dcc1e148c7d2822f38..0e6be81d0b84d191fbc87bd2821e9efab0bba4a5 100644 (file)
@@ -1,28 +1,7 @@
-/*
- *  Bacula memory pool routines.
- *
- *  The idea behind these routines is that there will be
- *  pools of memory that are pre-allocated for quick
- *  access. The pools will have a fixed memory size on allocation
- *  but if need be, the size can be increased. This is
- *  particularly useful for filename
- *  buffers where 256 bytes should be sufficient in 99.99%
- *  of the cases, but when it isn't we want to be able to
- *  increase the size.
- *
- *  A major advantage of the pool memory aside from the speed
- *  is that the buffer carrys around its size, so to ensure that
- *  there is enough memory, simply call the check_pool_memory_size()
- *  with the desired size and it will adjust only if necessary.
- *
- *           Kern E. Sibbald
- *
- *   Version $Id$
- */
 /*
    Bacula® - The Network Backup Solution
 
-   Copyright (C) 2000-2006 Free Software Foundation Europe e.V.
+   Copyright (C) 2000-2007 Free Software Foundation Europe e.V.
 
    The main author of Bacula is Kern Sibbald, with contributions from
    many others, a complete list can be found in the file AUTHORS.
    (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
    Switzerland, email:ftf@fsfeurope.org.
 */
+/*
+ *  Bacula memory pool routines.
+ *
+ *  The idea behind these routines is that there will be
+ *  pools of memory that are pre-allocated for quick
+ *  access. The pools will have a fixed memory size on allocation
+ *  but if need be, the size can be increased. This is
+ *  particularly useful for filename
+ *  buffers where 256 bytes should be sufficient in 99.99%
+ *  of the cases, but when it isn't we want to be able to
+ *  increase the size.
+ *
+ *  A major advantage of the pool memory aside from the speed
+ *  is that the buffer carrys around its size, so to ensure that
+ *  there is enough memory, simply call the check_pool_memory_size()
+ *  with the desired size and it will adjust only if necessary.
+ *
+ *           Kern E. Sibbald
+ *
+ *   Version $Id$
+ */
 
 #include "bacula.h"
 
@@ -90,6 +90,7 @@ struct abufhead {
    int32_t ablen;                     /* Buffer length in bytes */
    int32_t pool;                      /* pool */
    struct abufhead *next;             /* pointer to next free buffer */
+   int32_t bnet_size;                 /* dummy for bnet_send() */
 };
 
 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
index 0a6b123e7645b657af61ed225579060aa1fbafba..10e999c1db795d64f6058fe11378671372bbffa9 100644 (file)
@@ -1,14 +1,7 @@
-/*
- * Memory Pool prototypes
- *
- *  Kern Sibbald, MM
- *
- *   Version $Id$
- */
 /*
    Bacula® - The Network Backup Solution
 
-   Copyright (C) 2000-2006 Free Software Foundation Europe e.V.
+   Copyright (C) 2000-2007 Free Software Foundation Europe e.V.
 
    The main author of Bacula is Kern Sibbald, with contributions from
    many others, a complete list can be found in the file AUTHORS.
    (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
    Switzerland, email:ftf@fsfeurope.org.
 */
+/*
+ * Memory Pool prototypes
+ *
+ *  Kern Sibbald, MM
+ *
+ *   Version $Id$
+ */
 
 #ifndef __MEM_POOL_H_
 #define __MEM_POOL_H_
@@ -102,14 +102,14 @@ public:
    int strcat(const char *str);
 };
 
-int pm_strcat (POOLMEM **pm, const char *str);
-int pm_strcat (POOLMEM *&pm, const char *str);
-int pm_strcat (POOL_MEM &pm, const char *str);
-int pm_strcat (POOLMEM *&pm, POOL_MEM &str);
-int pm_strcpy (POOLMEM **pm, const char *str);
-int pm_strcpy (POOLMEM *&pm, const char *str);
-int pm_strcpy (POOL_MEM &pm, const char *str);
-int pm_strcpy (POOLMEM *&pm, POOL_MEM &str);
+int pm_strcat(POOLMEM **pm, const char *str);
+int pm_strcat(POOLMEM *&pm, const char *str);
+int pm_strcat(POOL_MEM &pm, const char *str);
+int pm_strcat(POOLMEM *&pm, POOL_MEM &str);
+int pm_strcpy(POOLMEM **pm, const char *str);
+int pm_strcpy(POOLMEM *&pm, const char *str);
+int pm_strcpy(POOL_MEM &pm, const char *str);
+int pm_strcpy(POOLMEM *&pm, POOL_MEM &str);
 
 
 #endif
index 5b8c2efb5d8d8265805eadd2fa61699ead0d926f..8899e16a4eefa646d280d7909657f0eb5329280e 100644 (file)
@@ -2,6 +2,8 @@
 
 General:
 17Feb07
+kes  Implement a BSOCK send() method that writes the whole record
+     in a single write() request rather than in two.
 ebl  add update volume=xxx recyclepool=yyyy
      volume takes recyclepool from pool when using update volume=xxx from pool
      TODO: update manual