2 * Amanda, The Advanced Maryland Automatic Network Disk Archiver
3 * Copyright (c) 1991-1999 University of Maryland at College Park
6 * Permission to use, copy, modify, distribute, and sell this software and its
7 * documentation for any purpose is hereby granted without fee, provided that
8 * the above copyright notice appear in all copies and that both that
9 * copyright notice and this permission notice appear in supporting
10 * documentation, and that the name of U.M. not be used in advertising or
11 * publicity pertaining to distribution of the software without specific,
12 * written prior permission. U.M. makes no representations about the
13 * suitability of this software for any purpose. It is provided "as is"
14 * without express or implied warranty.
16 * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
18 * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
20 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
21 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23 * Authors: the Amanda Development Team. Its members are listed in a
24 * file named AUTHORS, in the root directory of this distribution.
27 * $Id: sendbackup-dump.c,v 1.90 2006/07/25 18:10:07 martinea Exp $
29 * send backup data using BSD dump
33 #include "sendbackup.h"
37 #define LEAF_AND_DIRS "sed -e \'\ns/^leaf[ \t]*[0-9]*[ \t]*\\.//\nt\n/^dir[ \t]/ {\ns/^dir[ \t]*[0-9]*[ \t]*\\.//\ns%$%/%\nt\n}\nd\n\'"
39 static amregex_t re_table[] = {
40 /* the various encodings of dump size */
41 /* this should also match BSDI pre-3.0's buggy dump program, that
42 produced doubled DUMP: DUMP: messages */
43 AM_SIZE_RE("DUMP: [0-9][0-9]* tape blocks", 1024, 1),
44 AM_SIZE_RE("dump: Actual: [0-9][0-9]* tape blocks", 1024, 1),
45 AM_SIZE_RE("backup: There are [0-9][0-9]* tape blocks on [0-9][0-9]* tapes",
47 AM_SIZE_RE("backup: [0-9][0-9]* tape blocks on [0-9][0-9]* tape\\(s\\)",
49 AM_SIZE_RE("backup: [0-9][0-9]* 1k blocks on [0-9][0-9]* volume\\(s\\)",
51 AM_SIZE_RE("DUMP: [0-9][0-9]* blocks \\([0-9][0-9]*KB\\) on [0-9][0-9]* volume",
53 AM_SIZE_RE("DUMP: [0-9][0-9]* blocks \\([0-9][0-9]*\\.[0-9][0-9]*MB\\) on [0-9][0-9]* volume",
55 AM_SIZE_RE("DUMP: [0-9][0-9]* blocks \\([0-9][0-9]*KB\\)",
57 AM_SIZE_RE("DUMP: [0-9][0-9]* blocks \\([0-9][0-9]*\\.[0-9][0-9]*MB\\)",
59 AM_SIZE_RE("DUMP: [0-9][0-9]* blocks", 512, 1),
60 AM_SIZE_RE("DUMP: [0-9][0-9]* bytes were dumped", 1, 1),
62 AM_SIZE_RE("vdump: Dumped [0-9][0-9]* of [0-9][0-9]* bytes", 1, 1),
64 AM_SIZE_RE("dump: Actual: [0-9][0-9]* blocks output to pipe", 1024, 1),
66 AM_SIZE_RE("dump: Dumped [0-9][0-9]* of [0-9][0-9]* bytes", 1, 1),
68 AM_SIZE_RE("DUMP: [0-9][0-9]* KB actual output", 1024, 1),
69 /* HPUX 10.20 and above vxdump */
70 AM_SIZE_RE("vxdump: [0-9][0-9]* tape blocks", 1024, 1),
72 AM_SIZE_RE("vxdump: [0-9][0-9]* blocks", 1024, 1),
74 AM_SIZE_RE(" VXDUMP: [0-9][0-9]* blocks", 512, 1),
76 AM_SIZE_RE(" UFSDUMP: [0-9][0-9]* blocks", 512, 1),
77 /* Irix 6.2 xfs dump */
78 AM_SIZE_RE("xfsdump: media file size [0-9][0-9]* bytes", 1, 1),
80 AM_SIZE_RE("DUMP: [0-9][0-9]* KB", 1024, 1),
82 /* strange dump lines */
83 AM_STRANGE_RE("should not happen"),
84 AM_STRANGE_RE("Cannot open"),
85 AM_STRANGE_RE("[Ee]rror"),
86 AM_STRANGE_RE("[Ff]ail"),
87 /* XXX add more ERROR entries here by scanning dump sources? */
89 /* any blank or non-strange DUMP: lines are marked as normal */
90 AM_NORMAL_RE("^ *DUMP:"),
91 AM_NORMAL_RE("^dump:"), /* OSF/1 */
92 AM_NORMAL_RE("^vdump:"), /* OSF/1 */
93 AM_NORMAL_RE("^ *vxdump:"), /* HPUX10 */
94 AM_NORMAL_RE("^ *vxfs *vxdump:"), /* Solaris */
95 AM_NORMAL_RE("^Dumping .* to stdout"), /* Sol vxdump */
96 AM_NORMAL_RE("^xfsdump:"), /* IRIX xfs */
97 AM_NORMAL_RE("^ *VXDUMP:"), /* Sinix */
98 AM_NORMAL_RE("^ *UFSDUMP:"), /* Sinix */
100 #ifdef VDUMP /* this is for OSF/1 3.2's vdump for advfs */
101 AM_NORMAL_RE("^The -s option is ignored"), /* OSF/1 */
102 AM_NORMAL_RE("^path"), /* OSF/1 */
103 AM_NORMAL_RE("^dev/fset"), /* OSF/1 */
104 AM_NORMAL_RE("^type"), /* OSF/1 */
105 AM_NORMAL_RE("^advfs id"), /* OSF/1 */
106 AM_NORMAL_RE("^[A-Z][a-z][a-z] [A-Z][a-z][a-z] .[0-9] [0-9]"), /* OSF/1 */
109 AM_NORMAL_RE("^backup:"), /* AIX */
110 AM_NORMAL_RE("^ Use the umount command to unmount the filesystem"),
112 AM_NORMAL_RE("^[ \t]*$"),
114 /* catch-all; DMP_STRANGE is returned for all other lines */
118 static void start_backup(dle_t *dle, char *host,
119 int dataf, int mesgf, int indexf);
120 static void end_backup(dle_t *dle, int status);
123 * doing similar to $ dump | compression | encryption
134 int dumpin, dumpout, compout;
135 char *dumpkeys = NULL;
140 char *indexcmd = NULL;
141 char level_str[NUM_STR_SIZE];
142 char *compopt = NULL;
143 char *encryptopt = skip_argument;
146 am_level_t *alevel = (am_level_t *)dle->levellist->data;
147 int level = alevel->level;
149 g_snprintf(level_str, SIZEOF(level_str), "%d", level);
151 qdisk = quote_string(dle->disk);
152 dbprintf(_("start: %s:%s lev %d\n"), host, qdisk, level);
154 g_fprintf(stderr, _("%s: start [%s:%s level %d]\n"),
155 get_pname(), host, qdisk, level);
158 /* apply client-side encryption here */
159 if (dle->encrypt == ENCRYPT_CUST ) {
160 encpid = pipespawn(dle->clnt_encrypt, STDIN_PIPE, 0,
161 &compout, &dataf, &mesgf,
162 dle->clnt_encrypt, encryptopt, NULL);
163 dbprintf(_("gnutar: pid %ld: %s\n"), (long)encpid, dle->clnt_encrypt);
168 /* now do the client-side compression */
171 if(dle->compress == COMP_FAST || dle->compress == COMP_BEST) {
172 compopt = skip_argument;
174 #if defined(COMPRESS_BEST_OPT) && defined(COMPRESS_FAST_OPT)
175 if(dle->compress == COMP_BEST) {
176 compopt = COMPRESS_BEST_OPT;
178 compopt = COMPRESS_FAST_OPT;
181 comppid = pipespawn(COMPRESS_PATH, STDIN_PIPE, 0,
182 &dumpout, &compout, &mesgf,
183 COMPRESS_PATH, compopt, NULL);
184 dbprintf(_("dump: pid %ld: %s"), (long)comppid, COMPRESS_PATH);
185 if(compopt != skip_argument) {
186 dbprintf(" %s", compopt);
189 } else if (dle->compress == COMP_CUST) {
190 compopt = skip_argument;
191 comppid = pipespawn(dle->compprog, STDIN_PIPE, 0,
192 &dumpout, &compout, &mesgf,
193 dle->compprog, compopt, NULL);
194 dbprintf(_("gnutar-cust: pid %ld: %s"),
195 (long)comppid, dle->compprog);
196 if(compopt != skip_argument) {
197 dbprintf(" %s", compopt);
206 device = amname_to_devname(dle->device);
207 fstype = amname_to_fstype(dle->device);
209 dbprintf(_("dumping device '%s' with '%s'\n"), device, fstype);
211 #if defined(USE_RUNDUMP) || !defined(DUMP)
212 cmd = vstralloc(amlibexecdir, "/", "rundump", NULL);
214 if (g_options->config)
215 config = g_options->config;
219 cmd = stralloc(DUMP);
220 cmdX = skip_argument;
221 config = skip_argument;
224 #ifndef AIX_BACKUP /* { */
226 #ifdef XFSDUMP /* { */
228 if (strcmp(amname_to_fstype(dle->device), "xfs") == 0)
233 char *progname = cmd = newvstralloc(cmd, amlibexecdir, "/", "rundump",
236 if (g_options->config)
237 config = g_options->config;
241 program->backup_name = XFSDUMP;
242 program->restore_name = XFSRESTORE;
244 indexcmd = vstralloc(XFSRESTORE,
250 " -e", " \'s/^/\\//\'",
252 info_tapeheader(dle);
254 start_index(dle->create_index, dumpout, mesgf, indexf, indexcmd);
256 dumpkeys = stralloc(level_str);
257 dumppid = pipespawn(progname, STDIN_PIPE, 0,
258 &dumpin, &dumpout, &mesgf,
261 !dle->record ? "-J" : skip_argument,
270 #ifdef VXDUMP /* { */
272 if (strcmp(amname_to_fstype(dle->device), "vxfs") == 0)
278 char *progname = cmd = newvstralloc(cmd, amlibexecdir, "/", "rundump",
281 if (g_options->config)
282 config = g_options->config;
286 char *progname = cmd = newvstralloc(cmd, VXDUMP, NULL);
287 cmdX = skip_argument;
288 config = skip_argument;
290 program->backup_name = VXDUMP;
291 program->restore_name = VXRESTORE;
293 dumpkeys = vstralloc(level_str,
294 !dle->record ? "" : "u",
299 indexcmd = vstralloc(VXRESTORE,
305 info_tapeheader(dle);
307 start_index(dle->create_index, dumpout, mesgf, indexf, indexcmd);
309 dumppid = pipespawn(progname, STDIN_PIPE, 0,
310 &dumpin, &dumpout, &mesgf,
324 if (strcmp(amname_to_fstype(dle->device), "advfs") == 0)
329 cmd = newvstralloc(cmd, amlibexecdir, "/", "rundump", NULL);
331 if (g_options->config)
332 config = g_options->config;
335 device = newstralloc(device, amname_to_dirname(dle->device));
336 program->backup_name = VDUMP;
337 program->restore_name = VRESTORE;
339 dumpkeys = vstralloc(level_str,
340 !dle->record ? "" : "u",
345 indexcmd = vstralloc(VRESTORE,
349 "sed -e \'\n/^\\./ {\ns/^\\.//\ns/, [0-9]*$//\ns/^\\.//\ns/ @-> .*$//\nt\n}\nd\n\'",
351 info_tapeheader(dle);
353 start_index(dle->create_index, dumpout, mesgf, indexf, indexcmd);
355 dumppid = pipespawn(cmd, STDIN_PIPE, 0,
356 &dumpin, &dumpout, &mesgf,
370 #define RESTORE "restore"
373 #ifdef HAVE_HONOR_NODUMP
374 # define PARAM_HONOR_NODUMP "h"
376 # define PARAM_HONOR_NODUMP ""
380 # if defined(__FreeBSD_version) && (__FreeBSD_version >= 500043)
381 # define FREEBSD_EXTRA_KEYS "bL"
383 # define FREEBSD_EXTRA_KEYS "b"
386 # define FREEBSD_EXTRA_KEYS ""
389 dumpkeys = vstralloc(level_str,
390 !dle->record ? "" : "u",
397 indexcmd = vstralloc(RESTORE,
400 /* not to /dev/null because of DU's dump */
404 info_tapeheader(dle);
406 start_index(dle->create_index, dumpout, mesgf, indexf, indexcmd);
408 dumppid = pipespawn(cmd, STDIN_PIPE, 0,
409 &dumpin, &dumpout, &mesgf,
417 #ifdef HAVE_HONOR_NODUMP
425 /* AIX backup program */
426 dumpkeys = vstralloc("-",
428 !dle->record ? "" : "u",
432 indexcmd = vstralloc(RESTORE,
439 info_tapeheader(dle);
441 start_index(dle->create_index, dumpout, mesgf, indexf, indexcmd);
443 dumppid = pipespawn(cmd, STDIN_PIPE, 0,
444 &dumpin, &dumpout, &mesgf,
459 /* close the write ends of the pipes */
466 if (dle->create_index)
476 (void)status; /* Quiet unused parameter warning */
478 /* don't need to do anything for dump */
481 backup_program_t dump_program = {
491 re_table, start_backup, end_backup