Bacula-users

[Bacula-users] Restore FIFO as a regular file

2012-12-09 00:27:39
Subject: [Bacula-users] Restore FIFO as a regular file
From: styopa <bacula-forum AT backupcentral DOT com>
To: bacula-users AT lists.sourceforge DOT net
Date: Sat, 08 Dec 2012 20:38:34 -0800
Hi everyone.

There is a problem in Bacula that if you read data from FIFO (aka named pipes), 
you have to restore to named pipes as well. But according to the manual there 
must be a program reading from these pipes before the FD will even open them. 
And since there is no way to figure out the future pipe filenames, we got a 
classic chicken-and-egg problem. Some people solve it by hardcoding the 
filename in a restore Bash script, but I think this is lame. Suppose you have 
several huge databases, and you want to restore just one of them.

I made a small patch to restore data as regular files. I took the source RPM 
package from Scientific Linux 6.3, so it must be the same for RHEL & Co. They 
offer Bacula 5.0.0.

I also wrote a Bash script to back up MySQL and Postgres to pipes with Bacula. 
I'll publish the source later when I clean up the code a little bit.

Hope this helps.

bacula-restore-fifo-as-file.patch
--- src/findlib/create_file.c.orig      2010-01-25 02:56:28.000000000 -0500
+++ src/findlib/create_file.c   2012-12-08 11:22:58.574438172 -0500
@@ -151,11 +151,10 @@
    case FT_REG:                       /* regular file */
       /* 
        * Note, we do not delete FT_RAW because these are device files
-       *  or FIFOs that should already exist. If we blow it away,
-       *  we may blow away a FIFO that is being used to read the
-       *  restore data, or we may blow away a partition definition.
+       *  that should already exist. If we blow it away,
+       *  we may blow away a partition definition.
        */
-      if (exists && attr->type != FT_RAW && attr->type != FT_FIFO) {
+      if (exists && attr->type != FT_RAW) {
          /* Get rid of old copy */
          Dmsg1(400, "unlink %s\n", attr->ofname);
          if (unlink(attr->ofname) == -1) {
@@ -205,6 +204,7 @@
       switch(attr->type) {
       case FT_REGE:
       case FT_REG:
+      case FT_FIFO:                   /* Bacula fifo to save data */
          Dmsg1(100, "Create=%s\n", attr->ofname);
          flags =  O_WRONLY | O_CREAT | O_TRUNC | O_BINARY; /*  O_NOFOLLOW; */
          if (IS_CTG(attr->statp.st_mode)) {
@@ -228,17 +228,8 @@
 
 #ifndef HAVE_WIN32  // none of these exists on MS Windows
       case FT_RAW:                    /* Bacula raw device e.g. /dev/sda1 */
-      case FT_FIFO:                   /* Bacula fifo to save data */
       case FT_SPEC:
-         if (S_ISFIFO(attr->statp.st_mode)) {
-            Dmsg1(400, "Restore fifo: %s\n", attr->ofname);
-            if (mkfifo(attr->ofname, attr->statp.st_mode) != 0 && errno != 
EEXIST) {
-               berrno be;
-               Qmsg2(jcr, M_ERROR, 0, _("Cannot make fifo %s: ERR=%s\n"),
-                     attr->ofname, be.bstrerror());
-               return CF_ERROR;
-            }
-         } else if (S_ISSOCK(attr->statp.st_mode)) {
+         if (S_ISSOCK(attr->statp.st_mode)) {
              Dmsg1(200, "Skipping restore of socket: %s\n", attr->ofname);
 #ifdef S_IFDOOR     // Solaris high speed RPC mechanism
          } else if (S_ISDOOR(attr->statp.st_mode)) {
@@ -257,23 +248,12 @@
                return CF_ERROR;
             }
          }
-         /*
-          * Here we are going to attempt to restore to a FIFO, which
-          *   means that the FIFO must already exist, AND there must
-          *   be some process already attempting to read from the
-          *   FIFO, so we open it write-only. 
-          */
-         if (attr->type == FT_RAW || attr->type == FT_FIFO) {
+
+         if (attr->type == FT_RAW) {
             btimer_t *tid;
-            Dmsg1(400, "FT_RAW|FT_FIFO %s\n", attr->ofname);
+            Dmsg1(400, "FT_RAW %s\n", attr->ofname);
             flags =  O_WRONLY | O_BINARY;
-            /* Timeout open() in 60 seconds */
-            if (attr->type == FT_FIFO) {
-               Dmsg0(400, "Set FIFO timer\n");
-               tid = start_thread_timer(jcr, pthread_self(), 60);
-            } else {
-               tid = NULL;
-            }
+            tid = NULL;
             if (is_bopen(bfd)) {
                Qmsg1(jcr, M_ERROR, 0, _("bpkt already open fid=%d\n"), 
bfd->fid);
             }

bacula-spec.patch
--- bacula.spec.orig    2012-10-02 09:31:59.000000000 -0400
+++ bacula.spec 2012-12-08 22:48:09.106440362 -0500
@@ -55,6 +56,8 @@
 Patch18: bacula-5.0.0-retention_period.patch
 #728693
 Patch19: bacula-5.0.0-logwatch.patch
+# Restoring from named pipe
+Patch99: bacula-restore-fifo-as-file.patch
 
 URL: http://www.bacula.org
 BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
@@ -394,6 +397,7 @@
 %patch17 -p1 -b .catalog
 %patch18 -p3 -b .period
 %patch19 -p2 -b .logwatch
+%patch99 -p0
 
 
 # Remove execution permissions from files we're packaging as docs later on

+----------------------------------------------------------------------
|This was sent by semenukha AT gmail DOT com via Backup Central.
|Forward SPAM to abuse AT backupcentral DOT com.
+----------------------------------------------------------------------



------------------------------------------------------------------------------
LogMeIn Rescue: Anywhere, Anytime Remote support for IT. Free Trial
Remotely access PCs and mobile devices and provide instant support
Improve your efficiency, and focus on delivering more value-add services
Discover what IT Professionals Know. Rescue delivers
http://p.sf.net/sfu/logmein_12329d2d
_______________________________________________
Bacula-users mailing list
Bacula-users AT lists.sourceforge DOT net
https://lists.sourceforge.net/lists/listinfo/bacula-users

<Prev in Thread] Current Thread [Next in Thread>