source: MondoRescue/branches/2.2.10/mondo/src/common/libmondo-verify.c@ 2508

Last change on this file since 2508 was 2508, checked in by Bruno Cornec, 14 years ago

r3287@localhost (orig r2285): bruno | 2009-07-20 11:36:47 +0200

r3285@localhost: bruno | 2009-07-20 11:17:35 +0200
Apply fix in 2.2.10 around multi USB device handling to 2.2.9 as well


r3291@localhost (orig r2288): bruno | 2009-07-21 16:48:31 +0200
Copy 2.2.10 test script in to 2.2.9 for memory problm analysis


r3293@localhost (orig r2290): bruno | 2009-07-22 14:03:44 +0200

  • Fix a printing error in mindi for the tar command
  • Fix all mr_asprintf which had no second param as a string


r3295@localhost (orig r2292): bruno | 2009-07-22 16:55:00 +0200

  • Fix #160 and #346 by rewriting the message.txt file with more valid information gathered in mindi


r3300@localhost (orig r2294): bruno | 2009-07-23 01:58:08 +0200

Man pages patch from Joe Ross (joe.ross_at_gmail.com)


r3303@localhost (orig r2297): bruno | 2009-07-23 17:43:49 +0200
Fix a remaining display error for 2.2.9. That version has been tested OK in a lab.


r3304@localhost (orig r2298): bruno | 2009-07-23 18:18:27 +0200

  • Remove memory leak for the last modification


r3308@localhost (orig r2302): bruno | 2009-07-24 21:18:50 +0200
Improve logging of mountlist.txt


r3310@localhost (orig r2304): bruno | 2009-07-27 19:45:10 +0200

  • popup_and_get_string needs an allocated buffer for the moment so fixing the calls with dyn. ones
  • Fix a bug in mem.c for mr_strcat, which wasn't modifying the right pointer level


r3311@localhost (orig r2305): bruno | 2009-07-27 19:49:35 +0200
Avoid a memory leak in the previous patch


r3314@localhost (orig r2308): bruno | 2009-07-27 20:59:06 +0200
Fix a bug in mr_strcat backported from 2.2.10. Should solve our seg faults.


r3315@localhost (orig r2309): bruno | 2009-07-28 02:14:23 +0200
Cosmetic changes to allow for quality to not giv false positive


r3343@localhost (orig r2311): bruno | 2009-08-18 02:13:43 +0200
Fix for initramfs detection with 2.6.30 (Hugo Vanwoerkom hvw59601_at_care2.com)


r3367@localhost (orig r2333): bruno | 2009-08-18 16:26:26 +0200
Adds a precision for -U option in man page on raw device usage and not partition name


r3373@localhost (orig r2336): bruno | 2009-08-20 17:37:41 +0200

  • Precise the combined usage of -E and -I in mondoarchive (Case 4601017223)


r3379@localhost (orig r2342): bruno | 2009-08-21 16:27:10 +0200


r3383@localhost (orig r2344): bruno | 2009-08-24 13:37:09 +0200

r3382@localhost: bruno | 2009-08-24 13:30:25 +0200
In NFS mode also propose access to expert, interactive, ... entry at boot prompt


r3388@localhost (orig r2346): bruno | 2009-08-27 11:41:16 +0200
Adds fdisk -l result in Log File at restore time


r3389@localhost (orig r2347): bruno | 2009-08-27 13:51:00 +0200

  • Solve tmp dir creation which sometimes was trying to create /%xx dirs. Should fix #293 for good


r3390@localhost (orig r2348): bruno | 2009-08-27 13:54:25 +0200
Improve logging (minor)


r3394@localhost (orig r2350): bruno | 2009-08-28 02:24:19 +0200
Change inerface of evaluate_mountlist and spread_flaws_across_three_lines in order to solve bugs linked to strings management in these functions. May fix a restoration crash seen by some customers


r3397@localhost (orig r2353): bruno | 2009-08-28 19:03:45 +0200

  • Addition of a nomd option to avoid starting mdadm
  • mpath is now already started if there was a mpath entry in mountlist


r3399@localhost (orig r2355): bruno | 2009-08-29 00:56:50 +0200
Remove function spread_flaws_across_three_lines and expand it at the single place where it was useful, and fix memory allocation issues in it.


r3402@localhost (orig r2358): bruno | 2009-09-01 19:02:35 +0200
P2V doc updated (Lester Wade lester.wade_at_hp.com)


r3404@localhost (orig r2360): bruno | 2009-09-01 19:26:53 +0200
Website update to refer to new P2V document


r3405@localhost (orig r2361): bruno | 2009-09-03 13:54:25 +0200

  • Fix a case where the NFS dir in restore mode was mounted rw (linked to bug #291 could create a huge problem)


r3407@localhost (orig r2363): bruno | 2009-09-03 14:46:46 +0200
More verbose at installation of additional tools


r3409@localhost (orig r2365): bruno | 2009-09-03 18:08:32 +0200

  • New update from Lester Wade (lester.wade_at_hp.com) for P2V doc


r3410@localhost (orig r2366): bruno | 2009-09-05 01:28:18 +0200
place the code of mondo_makefilelist before its call



r3411@localhost (orig r2367): bruno | 2009-09-06 01:51:26 +0200

  • Advertising for project-builder on the website added


r3412@localhost (orig r2368): bruno | 2009-09-07 15:36:23 +0200
Fix compilation issue


r3413@localhost (orig r2369): bruno | 2009-09-07 18:03:40 +0200
Another compilation issue fixed.


r3415@localhost (orig r2371): bruno | 2009-09-08 13:40:25 +0200

  • Fix a problem a error detection in evaluate_mountlist which casued nuke mode to abort. Error string should also be better now.


r3417@localhost (orig r2373): bruno | 2009-09-08 13:55:31 +0200
Avoid asking the Prefix name in NFS mode twice


r3418@localhost (orig r2374): bruno | 2009-09-08 20:04:07 +0200

  • Try to fix garbled screen progression in text mode based on 2.2.10 modifications which are working


r3424@localhost (orig r2380): bruno | 2009-09-09 20:30:47 +0200

  • Change NFS support into a NetFS support to allow for multiple protocol in addition to NFS (NEEDS TESTING)
  • Better logging to detect a potential nuke issue


r3425@localhost (orig r2381): bruno | 2009-09-10 02:05:55 +0200
Fix a missing param for sshfs call


r3428@localhost (orig r2384): bruno | 2009-09-10 13:02:56 +0200

  • Remove separate function look_for_duplicate_mountpoints used only once and whose interface created problems with caller


r3430@localhost (orig r2386): bruno | 2009-09-10 16:06:52 +0200
Be compatible on backup type by making old nfs recognized as netfs and proto forced


r3431@localhost (orig r2387): bruno | 2009-09-10 18:40:47 +0200
Fix a problem in netfs analysis in mondoarchive


r3432@localhost (orig r2388): bruno | 2009-09-10 20:25:13 +0200
Fix mondoarchive CLI analysis for NETFS type of requests


r3434@localhost (orig r2390): bruno | 2009-09-11 03:05:20 +0200

  • Adds ext3 initrd support for 2.6.30


r3437@localhost (orig r2393): bruno | 2009-09-11 11:56:52 +0200

  • Tries to add support for bzip2 and lzma initramfs (preliminary, not tested) for 2.6.30


r3438@localhost (orig r2394): bruno | 2009-09-12 02:53:02 +0200
Fix interface of evaluate_mountlist (remove 2nd param useless) and fix nuke mode which wasn't working.


r3441@localhost (orig r2397): bruno | 2009-09-14 18:54:34 +0200
Fix a format issue in text mode on percentage


r3452@localhost (orig r2398): bruno | 2009-09-15 16:00:13 +0200

  • Fix a bug where flaws_str could be NULL and wasn't tested correctly.


r3453@localhost (orig r2399): bruno | 2009-09-15 19:28:39 +0200

  • Use protocol name when displaying restore progress instead of netfs
  • Ask for network protocol name at restore time


r3455@localhost (orig r2401): bruno | 2009-09-15 19:34:19 +0200
Wrong structure member name was used


r3456@localhost (orig r2402): bruno | 2009-09-16 13:04:17 +0200
Use dir for shell related commands and dir1 for C related actions in open_and_list_dir to avoid missing some files with { in names e.g.


r3457@localhost (orig r2403): bruno | 2009-09-16 16:32:03 +0200

  • At restore time read the netfs protocol in the conf file


r3462@localhost (orig r2408): bruno | 2009-09-18 15:17:08 +0200
Remove useless script


r3463@localhost (orig r2409): bruno | 2009-09-18 15:25:35 +0200

  • Split deplist.txt into multiple conf files under deplist.d in the conf dir. This will allow to have a minimal.conf file for initrd content to analyze to improve support of new embedded feature in the future (sshfs, live install). The other conf files contain the additional commands to put in the all.tar.gz. For the moment, mindi is still working the same. THis infra will allow that support in a near future. deplist.txt is now reserved for the admin additional commands.


r3465@localhost (orig r2410): bruno | 2009-09-18 19:10:54 +0200

  • Better list of mandatory tools
  • Adds fuse and sshfs support in initrd


r3466@localhost (orig r2411): bruno | 2009-09-18 20:32:47 +0200
sshfs also needs ssh at restore time in initrd


r3478@localhost (orig r2418): bruno | 2009-09-23 23:22:39 +0200
Modify getfattr call to have all extended attributes, including non user ones. (patch from Kevin Ritzenthaler Kevin.Ritzenthaler_at_hp.com) and fix #357


r3479@localhost (orig r2419): bruno | 2009-09-23 23:50:34 +0200
star only supports ACL when used with exustar mode. Fix #356.


r3482@localhost (orig r2422): bruno | 2009-09-24 16:53:24 +0200

  • Adds support for bnx2x (BL 460 G6) and auth_rpcgss (Debian 2.6.31)


r3485@localhost (orig r2423): bruno | 2009-09-25 16:38:40 +0200
Fix an issue in is_this_device_mounted (string freed before last usage)


r3486@localhost (orig r2424): bruno | 2009-09-25 18:44:01 +0200

  • analyze-my-lvm now removes excluded devices from list coming from mondoarchive
  • new mr_make_devlist_from_pathlist which handle the new bkpinfo->exclude_devs field containing the excluded devices and remove corresponding code from libmondo-cli.c
  • Move DSF code into libmondo-devices.c for coherency, and only the previous function is made externally available
  • Remove dev_to_exclude in libmondo-archive.c which wasn't working correctly and replace it with bkpinfo->exclude_devs


r3487@localhost (orig r2425): bruno | 2009-09-25 18:58:23 +0200

  • Improving ssh support at restore time by providing a shadow file


r3489@localhost (orig r2426): bruno | 2009-09-25 19:42:09 +0200

  • Attempt to stay backward compatible without protocol for -n option


r3490@localhost (orig r2427): bruno | 2009-09-28 02:08:06 +0200
Avoids null param for excludes_devs for mindi call


r3492@localhost (orig r2429): bruno | 2009-09-28 11:46:16 +0200

  • Simplify GetInitrdFilesystemToUse which doesn't need to detect everything, but just know if it's initramfs (new mode) or a compressed FS ext2/3 (older mode) as initrd is anyway re-made by mindi. Should fix #353


r3494@localhost (orig r2431): bruno | 2009-09-28 13:16:18 +0200

  • Use only the AWK veriable everywhere and not the awk command


r3495@localhost (orig r2432): bruno | 2009-09-28 14:16:31 +0200
Warning emited in case of duplicate mountpoints or devices in fstab found


r3496@localhost (orig r2433): bruno | 2009-09-28 15:55:17 +0200
ssh in the restore env needs some dlopened libs (libnss_compat|files)


r3497@localhost (orig r2434): bruno | 2009-09-28 16:33:14 +0200
Compiler warning fixed


r3498@localhost (orig r2435): bruno | 2009-09-28 17:55:26 +0200
Improve user management for NetFS cases


r3499@localhost (orig r2436): bruno | 2009-09-29 01:48:32 +0200

  • Improve deplist.d/* files
  • adds libnss for ssh support in boot disk
  • Solve a memory management issue in DSF module (strtok => mr_strtok)
  • DSF now also supports partitions in addition to full disks
  • Adds debug in open_and_list_dir


r3500@localhost (orig r2437): bruno | 2009-09-29 10:41:56 +0200

  • Fix udev support in init for Mandriva 2009.1 (udevadm settle is blocking)


r3501@localhost (orig r2438): bruno | 2009-09-29 14:41:36 +0200

  • Improvements on sshfs/ssh management in restore mode
  • Include now all minimal requirements for sshfs


r3502@localhost (orig r2439): bruno | 2009-09-29 18:46:08 +0200

  • Avoids error message if some ssh conf files do not exist


r3503@localhost (orig r2440): bruno | 2009-09-29 18:57:13 +0200

  • Avoids comment analysis in the new code handling deplist.d


r3504@localhost (orig r2441): bruno | 2009-09-29 19:34:34 +0200

  • fuse device is needed at restore time for sshfs


r3505@localhost (orig r2442): bruno | 2009-09-29 20:02:36 +0200

  • Improves udev timeout handling


r3506@localhost (orig r2443): bruno | 2009-09-29 20:43:38 +0200

  • priority given to env var for tmpdir
  • fuse FS excluded from tmpdir computation


r3518@localhost (orig r2447): bruno | 2009-10-04 01:58:08 +0200

  • Iprove USB log in case of error by adding the conf file


r3519@localhost (orig r2448): bruno | 2009-10-05 11:06:13 +0200


r3520@localhost (orig r2449): bruno | 2009-10-06 01:10:35 +0200

  • Adds support for grub2 conf file grub.cfg in addition to menu.lst


r3521@localhost (orig r2450): bruno | 2009-10-06 01:24:02 +0200

  • Fix a mr_asprintf usage without & causing a seg fault.


r3523@localhost (orig r2452): bruno | 2009-10-06 12:47:56 +0200
CIFS mounts shouldn't be part of the mountlist analysis (should help solving #288)


r3524@localhost (orig r2453): bruno | 2009-10-07 10:17:03 +0200

  • Fix a bug in handling of -E option with real devices (bad report in function mr_make_devlist_from_pathlist of the test between -E and -I)


r3525@localhost (orig r2454): bruno | 2009-10-07 10:19:02 +0200

  • Fix an error in the test for grub conf files (or used instead of and)


r3526@localhost (orig r2455): bruno | 2009-10-07 16:14:59 +0200
afio is under /bin on Debian


r3527@localhost (orig r2456): bruno | 2009-10-07 17:31:26 +0200

  • Adds support for libcrc32c (needed by bnx2x)


r3532@localhost (orig r2457): bruno | 2009-10-09 13:33:44 +0200

  • Apply path from Matthew Cline (matt_at_nightrealms.com) in order to fix #359


r3533@localhost (orig r2458): bruno | 2009-10-09 13:41:02 +0200
Adds a conf file example for mindi and fix #360


r3535@localhost (orig r2459): bruno | 2009-10-09 15:13:01 +0200
MOde of conf file


r3546@localhost (orig r2461): bruno | 2009-10-14 01:12:24 +0200

  • umount freshly created VFAT partition on USB key as Ubunu has an automounter mounting it as soon as created (Steffen Neumann sneumann_at_ipb-halle.de)


r3566@localhost (orig r2463): bruno | 2009-10-26 01:34:16 +0100

  • Reset an error counter before blanking a DVD to avoid always returning an error (Vincent Raman vincent.raman_at_macqel.eu)


r3567@localhost (orig r2464): bruno | 2009-10-26 13:57:14 +0100
bzip2 is under /bin on Debian


r3568@localhost (orig r2465): bruno | 2009-10-28 01:46:30 +0100
some distro hold lvm commands under /usr/sbin


r3595@localhost (orig r2469): bruno | 2009-11-10 12:22:10 +0100
/dev/shm is now part of the default exclude list


r3596@localhost (orig r2470): bruno | 2009-11-10 12:32:40 +0100
Remove useless pb_log and MONDO_TRACEFILE


r3597@localhost (orig r2471): bruno | 2009-11-10 12:57:58 +0100
Improve analysis of kernel modules by printing whether it's a live or extra module which has not been found (Matthew Cline) as reported in #362


r3598@localhost (orig r2472): bruno | 2009-11-10 13:21:46 +0100

  • Default to DVD size when in iso or netfs mode


r3599@localhost (orig r2473): bruno | 2009-11-10 14:13:10 +0100

  • Fix #363 where exclude_paths was extended up to memory limit dumping core


r3600@localhost (orig r2474): bruno | 2009-11-10 14:31:14 +0100

  • Update deplist for Debian support


r3602@localhost (orig r2476): bruno | 2009-11-11 02:44:42 +0100

  • small improvement for loging in USB case


r3603@localhost (orig r2477): bruno | 2009-11-11 13:29:27 +0100

  • Adds a nolvm boot option at restore time


r3604@localhost (orig r2478): bruno | 2009-11-11 19:54:51 +0100

  • Fix #367 - the for loop doesn't make any test now, as it was computed before entering the loop, leading to an error, and was also made inside the loop anyway.


r3605@localhost (orig r2479): bruno | 2009-11-12 00:32:45 +0100

  • Add support for diskdumplib driver useful for RHEL 3 and IBM xseries 336


r3606@localhost (orig r2480): bruno | 2009-11-12 01:09:40 +0100

  • If using nolvm, mondorestore should also not nalyze and handle i-want-my-lvm


r3608@localhost (orig r2482): bruno | 2009-11-14 12:54:11 +0100
Fix bunzip2 on debian as well


r3610@localhost (orig r2484): bruno | 2009-11-15 00:44:19 +0100

  • Adds support for variable serial port console, with defalut to /dev/ttyS0, and a boot param to change it with serial=/dev/ttySx


r3615@localhost (orig r2485): bruno | 2009-11-15 01:34:33 +0100

r3614@localhost: bruno | 2009-11-15 01:34:12 +0100
Adds a space in exclude paths


r3623@localhost (orig r2487): bruno | 2009-11-18 20:41:40 +0100

r3620@localhost: bruno | 2009-11-18 10:31:36 +0100

  • Only link /dev/tty to serial port when there is indeed a serial port. If not breaks mondorestore on normal console


r3631@localhost (orig r2490): bruno | 2009-11-24 01:48:29 +0100
Put news below in the main page to make it more readable


r3648@localhost (orig r2492): bruno | 2009-11-25 23:50:13 +0100

r3647@localhost: bruno | 2009-11-25 23:49:11 +0100

  • Add warning for -f and SW Raid as in 2.2.10


r3650@localhost (orig r2493): bruno | 2009-11-26 00:19:52 +0100

r3649@localhost: bruno | 2009-11-26 00:18:27 +0100

  • Addition of the german translation made by Magnus Rasche (Magnus.rasche_at_gmx.de) and Website inclusion


r3652@localhost (orig r2495): bruno | 2009-11-27 15:55:55 +0100
cosmetic display fix
r3659@localhost (orig r2498): bruno | 2009-12-05 17:53:03 +0100
nfsopt restore boot time option added to support custom mount options for network restore


r3684@localhost (orig r2501): bruno | 2009-12-17 00:35:08 +0100
Fix #375 mondo will segfault if the partition in sensibly_set_tmpdir_and_scratchdir() is read-only (cylau)


r3685@localhost (orig r2502): bruno | 2009-12-17 01:02:47 +0100

  • Fix an issue in the function listing kernel modules when not found


r3686@localhost (orig r2503): bruno | 2009-12-17 01:15:01 +0100
Adds scsi_dump_register to mindi SCSI_MODS for RHEL3 + IBM servers


r3701@localhost (orig r2504): bruno | 2009-12-23 02:24:33 +0100

  • Addition of the Lab for Mondorescue


r3702@localhost (orig r2505): bruno | 2009-12-23 02:41:17 +0100
Web site update for Lab MondoRescue delivery


r3706@localhost (orig r2506): bruno | 2010-01-04 11:31:53 +0100

  • Fix a bug when isodir is / only when splitting it in iso_path and iso_mnt


r3707@localhost (orig r2507): bruno | 2010-01-04 13:22:49 +0100

  • Fix #377: Segfault in pause_and_ask_for_cdr() (ggeens)


  • Property svn:keywords set to Id
File size: 35.6 KB
Line 
1/***************************************************************************
2$Id: libmondo-verify.c 2508 2010-01-04 18:21:55Z bruno $
3***************************************************************************/
4
5
6/**
7 * @file
8 * Functions for verifying backups (booted from hard drive, not CD).
9 */
10
11#include "my-stuff.h"
12#include "mr_mem.h"
13#include "mondostructures.h"
14#include "libmondo-verify.h"
15#include "libmondo-gui-EXT.h"
16#include "libmondo-files-EXT.h"
17#include "libmondo-fork-EXT.h"
18#include "libmondo-stream-EXT.h"
19#include "libmondo-string-EXT.h"
20#include "libmondo-devices-EXT.h"
21#include "libmondo-tools-EXT.h"
22#include "lib-common-externs.h"
23
24/*@unused@*/
25//static char cvsid[] = "$Id: libmondo-verify.c 2508 2010-01-04 18:21:55Z bruno $";
26
27/**
28 * The number of the most recently verified afioball.
29 * @ingroup globalGroup
30 */
31int g_last_afioball_number = -1;
32
33extern char *g_getfacl;
34extern char *g_getfattr;
35extern char *MONDO_LOGFILE;
36
37/* Reference to global bkpinfo */
38extern struct s_bkpinfo *bkpinfo;
39
40
41/**
42 * Generate the filename of a tarball to verify.
43 * @param bkpinfo The backup information structure. @c bkpinfo->zip_suffix is the only field used.
44 * @param mountpoint The directory where the CD/DVD/ISO is mounted.
45 * @param setno The afioball number to get the location of.
46 * @return The absolute path to the afioball.
47 * @note The returned string points to static data that will be overwritten with each call.
48 * @ingroup stringGroup
49 */
50char *vfy_tball_fname(char *mountpoint, int setno)
51{
52 /*@ buffers ******************************************************* */
53 static char output[MAX_STR_LEN];
54
55 assert(bkpinfo != NULL);
56 assert_string_is_neither_NULL_nor_zerolength(mountpoint);
57 sprintf(output, "%s/archives/%d.star.%s", mountpoint, setno, bkpinfo->zip_suffix);
58 if (!does_file_exist(output)) {
59 sprintf(output, "%s/archives/%d.afio.%s", mountpoint, setno, bkpinfo->zip_suffix);
60 }
61 return (output);
62}
63
64
65/**
66 * Generate a list of the files that have changed, based on @c afio @c -r
67 * messages.
68 * @param changedfiles_fname Filename of the place to put a list of afio's reported changed.
69 * @param ignorefiles_fname Filename of a list of files to ignore (use "" if none).
70 * @param stderr_fname File containing afio's stderr output.
71 * @return The number of differences found (0 for a perfect backup).
72 * @bug This function seems orphaned.
73 * @ingroup utilityGroup
74 */
75long
76generate_list_of_changed_files(char *changedfiles_fname,
77 char *ignorefiles_fname, char *stderr_fname)
78{
79 /*@ buffer ********************************************************** */
80 char *command = NULL;
81 char *afio_found_changes = NULL;
82
83 /*@ int ************************************************************* */
84 int res = 0;
85
86 /*@ long ************************************************************ */
87 long afio_diffs = 0;
88
89 assert_string_is_neither_NULL_nor_zerolength(changedfiles_fname);
90 assert_string_is_neither_NULL_nor_zerolength(ignorefiles_fname);
91 assert_string_is_neither_NULL_nor_zerolength(stderr_fname);
92
93 mr_asprintf(afio_found_changes, "%s.afio", ignorefiles_fname);
94 sync();
95
96 log_msg(1, "Now scanning log file for 'afio: ' stuff");
97 mr_asprintf(command, "grep \"afio: \" %s | sed 's/afio: //' | grep -vE '^/dev/.*$' >> %s", stderr_fname, afio_found_changes);
98 log_msg(2, command);
99 res = system(command);
100 mr_free(command);
101
102 if (res) {
103 log_msg(2, "Warning - failed to think");
104 }
105
106 log_msg(1, "Now scanning log file for 'star: ' stuff");
107 mr_asprintf(command, "grep \"star: \" %s | sed 's/star: //' | grep -vE '^/dev/.*$' >> %s", stderr_fname, afio_found_changes);
108 log_msg(2, command);
109 res = system(command);
110 mr_free(command);
111
112 if (res) {
113 log_msg(2, "Warning - failed to think");
114 }
115 afio_diffs = count_lines_in_file(afio_found_changes);
116 mr_asprintf(command, "sort %s %s %s | uniq -c | awk '{ if ($1==\"2\") {print $2;};}' | grep -v \"incheckentry xwait()\" > %s", ignorefiles_fname, afio_found_changes, afio_found_changes, changedfiles_fname);
117 mr_free(afio_found_changes);
118 log_msg(2, command);
119 paranoid_system(command);
120 mr_free(command);
121 return (afio_diffs);
122}
123
124
125/**
126 * @addtogroup LLverifyGroup
127 * @{
128 */
129/**
130 * Verify all afioballs stored on the inserted CD (or an ISO image).
131 * @param bkpinfo The backup information structure. @c bkpinfo->backup_media_type
132 * is used in this function, and the structure is also passed to verify_an_afioball_from_CD().
133 * @param mountpoint The location the CD/DVD/ISO is mounted on.
134 * @return The number of sets containing differences (0 for success).
135 */
136int verify_afioballs_on_CD(char *mountpoint)
137{
138
139 /*@ buffers ********************************************************* */
140 char *tmp = NULL;
141 char *mds = NULL;
142
143 /*@ int ************************************************************* */
144 int set_number = 0;
145 int retval = 0;
146 int total_sets = 0;
147 int percentage = 0;
148
149 assert_string_is_neither_NULL_nor_zerolength(mountpoint);
150 assert(bkpinfo != NULL);
151
152 for (set_number = 0;
153 set_number < 9999
154 &&
155 !does_file_exist(vfy_tball_fname(mountpoint, set_number));
156 set_number++);
157 if (!does_file_exist(vfy_tball_fname(mountpoint, set_number))) {
158 return (0);
159 }
160
161 if (g_last_afioball_number != set_number - 1) {
162 if (set_number == 0) {
163 log_msg(1,
164 "Weird error in verify_afioballs_on_CD() but it's really a cosmetic error, nothing more");
165 } else {
166 retval++;
167 log_to_screen("Warning - missing set(s) between %d and %d\n", g_last_afioball_number, set_number - 1);
168 }
169 }
170 mds = media_descriptor_string(bkpinfo->backup_media_type);
171 mr_asprintf(tmp, "Verifying %s #%d's tarballs", mds, g_current_media_number);
172 mr_free(mds);
173
174 open_evalcall_form(tmp);
175 mr_free(tmp);
176
177 for (total_sets = set_number;
178 does_file_exist(vfy_tball_fname(mountpoint, total_sets));
179 total_sets++) {
180 log_msg(1, "total_sets = %d", total_sets);
181 }
182 for (;
183 does_file_exist(vfy_tball_fname(mountpoint, set_number));
184 set_number++) {
185 percentage =
186 (set_number - g_last_afioball_number) * 100 / (total_sets -
187 g_last_afioball_number);
188 update_evalcall_form(percentage);
189 log_msg(1, "set = %d", set_number);
190 retval +=
191 verify_an_afioball_from_CD(vfy_tball_fname(mountpoint, set_number));
192 }
193 g_last_afioball_number = set_number - 1;
194 close_evalcall_form();
195 return (retval);
196}
197
198/**
199 * Verify all slices stored on the inserted CD (or a mounted ISO image).
200 * @param bkpinfo The backup information structure. Fields used:
201 * - @c compression_level
202 * - @c restore_path
203 * - @c use_lzo
204 * - @c zip_suffix
205 * @param mtpt The mountpoint the CD/DVD/ISO is mounted on.
206 * @return The number of differences (0 for perfect biggiefiles).
207 */
208int verify_all_slices_on_CD(char *mtpt)
209{
210
211 /*@ buffer ********************************************************** */
212 char *tmp = NULL;
213 char *mountpoint = NULL;
214 char *command = NULL;
215 char *mds = NULL;
216 char *sz_exe = NULL;
217 static char *bufblkA = NULL;
218 static char *bufblkB = NULL;
219 const long maxbufsize = 65536L;
220 long currsizA = 0;
221 long currsizB = 0;
222 long j;
223
224 /*@ long ************************************************************ */
225 long bigfile_num = 0;
226 long slice_num = -1;
227 int res;
228
229 static FILE *forig = NULL;
230 static struct s_filename_and_lstat_info biggiestruct;
231 static long last_bigfile_num = -1;
232 static long last_slice_num = -1;
233 FILE *pin;
234 FILE *fin;
235 int retval = 0;
236
237 if (!bufblkA) {
238 if (!(bufblkA = malloc(maxbufsize))) {
239 fatal_error("Cannot malloc bufblkA");
240 }
241 }
242 if (!bufblkB) {
243 if (!(bufblkB = malloc(maxbufsize))) {
244 fatal_error("Cannot malloc bufblkB");
245 }
246 }
247
248 assert(bkpinfo != NULL);
249 assert_string_is_neither_NULL_nor_zerolength(mtpt);
250
251 if (bkpinfo->compression_level > 0) {
252 if (bkpinfo->use_lzo) {
253 mr_asprintf(sz_exe, "lzop");
254 } else if (bkpinfo->use_gzip) {
255 mr_asprintf(sz_exe, "gzip");
256 } else if (bkpinfo->use_lzma) {
257 mr_asprintf(sz_exe, "lzma");
258 } else {
259 mr_asprintf(sz_exe, "bzip2");
260 }
261 }
262
263 log_it("before vsbf");
264 mds = media_descriptor_string(bkpinfo->backup_media_type);
265 mr_asprintf(tmp, "Verifying %s#%d's big files", mds, g_current_media_number);
266 mr_free(mds);
267
268 open_evalcall_form(tmp);
269 mr_free(tmp);
270
271 log_it("after vsbf");
272 mr_asprintf(mountpoint, "%s/archives", mtpt);
273 if (last_bigfile_num == -1) {
274 bigfile_num = 0;
275 slice_num = 0;
276 } else if (slice_num == 0) {
277 bigfile_num = last_bigfile_num + 1;
278 slice_num = 0;
279 } else {
280 bigfile_num = last_bigfile_num;
281 slice_num = last_slice_num + 1;
282 }
283 while (does_file_exist(slice_fname(bigfile_num, slice_num, mountpoint, bkpinfo->zip_suffix))
284 ||
285 does_file_exist(slice_fname(bigfile_num, slice_num, mountpoint, ""))) {
286 // handle slices until end of CD
287 if (slice_num == 0) {
288 log_msg(2, "ISO=%d bigfile=%ld --START--", g_current_media_number, bigfile_num);
289 if (! (fin = fopen(slice_fname(bigfile_num, slice_num, mountpoint, ""), "r"))) {
290 log_msg(2, "Cannot open bigfile's info file");
291 } else {
292 if (fread ((void *) &biggiestruct, 1, sizeof(biggiestruct), fin) < sizeof(biggiestruct)) {
293 log_msg(2, "Unable to get biggiestruct");
294 }
295 paranoid_fclose(fin);
296 }
297 if (bkpinfo->restore_path) {
298 mr_asprintf(tmp, "%s/%s", bkpinfo->restore_path, biggiestruct.filename);
299 log_msg(2, "Opening biggiefile #%ld - '%s'", bigfile_num, tmp);
300 forig = fopen(tmp, "r");
301 mr_free(tmp);
302
303 if (!forig) {
304 log_msg(2, "Failed to open bigfile. Darn.");
305 log_to_screen("%s/%s not found on live filesystem", bkpinfo->restore_path, biggiestruct.filename);
306 mr_asprintf(tmp, "echo \"%s/%s not found\" >> %s/biggies.changed", bkpinfo->restore_path, biggiestruct.filename, bkpinfo->tmpdir);
307 system(tmp);
308 mr_free(tmp);
309
310 bigfile_num++;
311 slice_num = 0;
312 retval++;
313 } else {
314 slice_num++;
315 }
316 } else {
317 log_it("Unable to open bigfile as restore_path is NULL");
318 }
319 } else if (does_file_exist(slice_fname(bigfile_num, slice_num, mountpoint, "")) &&
320 (length_of_file(slice_fname(bigfile_num, slice_num, mountpoint, "")) == 0)) {
321 log_msg(2, "ISO=%d bigfile=%ld ---END---",
322 g_current_media_number, bigfile_num);
323 bigfile_num++;
324 paranoid_fclose(forig);
325 slice_num = 0;
326 } else {
327 log_msg(2, "ISO=%d bigfile=%ld slice=%ld", g_current_media_number, bigfile_num, slice_num);
328 if ((!does_file_exist(slice_fname(bigfile_num, slice_num, mountpoint, ""))) && (sz_exe != NULL)) {
329 mr_asprintf(command, "%s -dc %s 2>> %s", sz_exe, slice_fname(bigfile_num, slice_num, mountpoint, bkpinfo->zip_suffix), MONDO_LOGFILE);
330 } else {
331 mr_asprintf(command, "cat %s 2>> %s", slice_fname(bigfile_num, slice_num, mountpoint, ""), MONDO_LOGFILE);
332 }
333 pin = popen(command, "r");
334 mr_free(command);
335 if (pin) {
336 res = 0;
337 while (!feof(pin)) {
338 currsizA = fread(bufblkA, 1, maxbufsize, pin);
339 if (currsizA <= 0) {
340 break;
341 }
342 currsizB = fread(bufblkB, 1, currsizA, forig);
343 if (currsizA != currsizB) {
344 res++;
345 } else {
346 for (j = 0;
347 j < currsizA && bufblkA[j] == bufblkB[j];
348 j++);
349 if (j < currsizA) {
350 res++;
351 }
352 }
353 }
354 paranoid_pclose(pin);
355 if (res && !strncmp(biggiestruct.filename, "/dev/", 5)) {
356 log_msg(3,
357 "Ignoring differences between %s and live filesystem because it's a device and therefore the archives are stored via ntfsclone, not dd.",
358 biggiestruct.filename);
359 log_msg(3,
360 "If you really want verification for %s, please contact the devteam and offer an incentive.",
361 biggiestruct.filename);
362 res = 0;
363 }
364 if (res) {
365 log_msg(0,
366 "afio: \"%s\": Corrupt biggie file, says libmondo-archive.c",
367 biggiestruct.filename);
368 retval++;
369 }
370 }
371 slice_num++;
372 }
373 }
374 mr_free(mountpoint);
375 mr_free(sz_exe);
376
377 last_bigfile_num = bigfile_num;
378 last_slice_num = slice_num - 1;
379 if (last_slice_num < 0) {
380 last_bigfile_num--;
381 }
382 close_evalcall_form();
383 if (bufblkA) {
384 paranoid_free(bufblkA);
385 }
386 if (bufblkB) {
387 paranoid_free(bufblkB);
388 }
389 return (0);
390}
391
392
393
394
395
396
397/**
398 * Verify one afioball from the CD.
399 * You should be changed to the root directory (/) for this to work.
400 * @param bkpinfo The backup information structure. Fields used:
401 * - @c bkpinfo->use_lzo
402 * - @c bkpinfo->tmpdir
403 * - @c bkpinfo->zip_exe
404 * - @c bkpinfo->zip_suffix
405 * @param tarball_fname The filename of the afioball to verify.
406 * @return 0, always.
407 */
408int verify_a_tarball(char *tarball_fname)
409{
410 /*@ buffers ********************************************************* */
411 char *command = NULL;
412 char *outlog = NULL;
413 char *tmp = NULL;
414
415 /*@ pointers ******************************************************* */
416 FILE *pin;
417
418 /*@ long *********************************************************** */
419 long diffs = 0;
420 /* getcwd(old_pwd,MAX_STR_LEN-1); */
421
422
423 assert(bkpinfo != NULL);
424 assert_string_is_neither_NULL_nor_zerolength(tarball_fname);
425
426 log_it("Verifying fileset '%s'", tarball_fname);
427 mr_asprintf(outlog, "%s/afio.log", bkpinfo->tmpdir);
428 /* if programmer forgot to say which compression thingy to use then find out */
429 if (strstr(tarball_fname, ".lzo") && strcmp(bkpinfo->zip_suffix, "lzo")) {
430 log_msg(2, "OK, I'm going to start using lzop.");
431 mr_free(bkpinfo->zip_exe);
432 mr_asprintf(bkpinfo->zip_exe, "lzop");
433 mr_free(bkpinfo->zip_suffix);
434 mr_asprintf(bkpinfo->zip_suffix, "lzo");
435 bkpinfo->use_lzo = TRUE;
436 bkpinfo->use_gzip = FALSE;
437 bkpinfo->use_lzma = FALSE;
438 }
439 if (strstr(tarball_fname, ".gz") && strcmp(bkpinfo->zip_suffix, "gz")) {
440 log_msg(2, "OK, I'm going to start using gzip.");
441 mr_free(bkpinfo->zip_exe);
442 mr_asprintf(bkpinfo->zip_exe, "gzip");
443 mr_free(bkpinfo->zip_suffix);
444 mr_asprintf(bkpinfo->zip_suffix, "gz");
445 bkpinfo->use_lzo = FALSE;
446 bkpinfo->use_gzip = TRUE;
447 bkpinfo->use_lzma = FALSE;
448 }
449 if (strstr(tarball_fname, ".bz2") && strcmp(bkpinfo->zip_suffix, "bz2")) {
450 log_msg(2, "OK, I'm going to start using bzip2.");
451 mr_free(bkpinfo->zip_exe);
452 mr_asprintf(bkpinfo->zip_exe, "bzip2");
453 mr_free(bkpinfo->zip_suffix);
454 mr_asprintf(bkpinfo->zip_suffix, "bz2");
455 bkpinfo->use_lzo = FALSE;
456 bkpinfo->use_gzip = FALSE;
457 bkpinfo->use_lzma = FALSE;
458 }
459 if (strstr(tarball_fname, ".lzma") && strcmp(bkpinfo->zip_suffix, "lzma")) {
460 log_msg(2, "OK, I'm going to start using lzma.");
461 mr_free(bkpinfo->zip_exe);
462 mr_asprintf(bkpinfo->zip_exe, "lzma");
463 mr_free(bkpinfo->zip_suffix);
464 mr_asprintf(bkpinfo->zip_suffix, "lzma");
465 bkpinfo->use_lzo = FALSE;
466 bkpinfo->use_gzip = FALSE;
467 bkpinfo->use_lzma = TRUE;
468 }
469 if (bkpinfo->zip_exe == NULL) {
470 mr_asprintf(bkpinfo->zip_exe, "none");
471 }
472 if (bkpinfo->zip_suffix == NULL) {
473 mr_asprintf(bkpinfo->zip_suffix, "");
474 }
475 unlink(outlog);
476 if (strstr(tarball_fname, ".star")) {
477 bkpinfo->use_star = TRUE;
478 if (strstr(tarball_fname, ".bz2"))
479 mr_asprintf(command, "star -diff diffopts=mode,size,data file=%s %s >> %s 2>> %s", tarball_fname, (strstr(tarball_fname, ".bz2")) ? "-bz" : " ", outlog, outlog);
480 } else {
481 bkpinfo->use_star = FALSE;
482 /* Here we suppose that there is always a compression program called */
483 if (bkpinfo->zip_exe) {
484 mr_asprintf(command, "afio -r -P %s -Z %s >> %s 2>> %s", bkpinfo->zip_exe, tarball_fname, outlog, outlog);
485 } else {
486 mr_asprintf(command, "afio -r -Z %s >> %s 2>> %s", tarball_fname, outlog, outlog);
487 }
488 }
489 log_msg(6, "command=%s", command);
490 paranoid_system(command);
491 mr_free(command);
492
493 if (length_of_file(outlog) < 10) {
494 mr_asprintf(command, "cat %s >> %s", outlog, MONDO_LOGFILE);
495 } else {
496 mr_asprintf(command, "cut -d: -f%d %s | sort -u", (bkpinfo->use_star) ? 1 : 2, outlog);
497 pin = popen(command, "r");
498 if (pin) {
499 for (mr_getline(tmp, pin); !feof(pin); mr_getline(tmp, pin)) {
500 if (bkpinfo->use_star) {
501 if (!strstr(tmp, "diffopts=")) {
502 while (strlen(tmp) > 0 && tmp[strlen(tmp) - 1] < 32) {
503 tmp[strlen(tmp) - 1] = '\0';
504 }
505 if (strchr(tmp, '/')) {
506 if (!diffs) {
507 log_msg(0, "'%s' - differences found", tarball_fname);
508 }
509 log_msg(0, "star: /%s", strip_afio_output_line(tmp));
510 diffs++;
511 }
512 }
513 } else {
514 if (!diffs) {
515 log_msg(0, "'%s' - differences found", tarball_fname);
516 }
517 log_msg(0, "afio: /%s", strip_afio_output_line(tmp));
518 diffs++;
519 }
520 mr_free(tmp);
521 }
522 mr_free(tmp);
523 paranoid_pclose(pin);
524 } else {
525 log_OS_error(command);
526 }
527 }
528 mr_free(command);
529 mr_free(outlog);
530 return (0);
531}
532
533
534
535
536
537
538/**
539 * Verify one afioball from the CD.
540 * Checks for existence (calls fatal_error() if it does not exist) and
541 * then calls verify_an_afioball().
542 * @param bkpinfo The backup information structure. Passed to verify_an_afioball().
543 * @param tarball_fname The filename of the afioball to verify.
544 * @return The return value of verify_an_afioball().
545 * @see verify_an_afioball
546 */
547int
548verify_an_afioball_from_CD(char *tarball_fname)
549{
550
551 /*@ int ************************************************************* */
552 int res = 0;
553
554 assert_string_is_neither_NULL_nor_zerolength(tarball_fname);
555
556 log_msg(1, "Verifying %s", tarball_fname);
557 if (!does_file_exist(tarball_fname)) {
558 fatal_error("Cannot verify nonexistent afioball");
559 }
560 res = verify_a_tarball(tarball_fname);
561 return (res);
562}
563
564
565/**
566 * Verify one afioball from the opened tape/CD stream.
567 * Copies the file from tape to tmpdir and then calls verify_an_afioball().
568 * @param bkpinfo The backup information structure. Passed to verify_an_afioball().
569 * @param orig_fname The original filename of the afioball to verify.
570 * @param size The size of the afioball to verify.
571 * @return The return value of verify_an_afioball().
572 * @see verify_an_afioball
573 */
574int
575verify_an_afioball_from_stream(char *orig_fname, long long size)
576{
577
578 /*@ int ************************************************************** */
579 int retval = 0;
580 int res = 0;
581
582 /*@ buffers ********************************************************** */
583 char *tmp = NULL;
584 char *tarball_fname = NULL;
585
586 /*@ pointers ********************************************************* */
587 char *p;
588
589 assert(bkpinfo != NULL);
590 assert_string_is_neither_NULL_nor_zerolength(orig_fname);
591
592 p = strrchr(orig_fname, '/');
593 if (!p) {
594 p = orig_fname;
595 } else {
596 p++;
597 }
598 mr_asprintf(tmp, "mkdir -p %s/tmpfs", bkpinfo->tmpdir);
599 paranoid_system(tmp);
600 mr_free(tmp);
601
602 mr_asprintf(tarball_fname, "%s/tmpfs/temporary-%s", bkpinfo->tmpdir, p);
603 read_file_from_stream_to_file(tarball_fname, size);
604 res = verify_a_tarball(tarball_fname);
605 if (res) {
606 log_msg(0, "Afioball '%s' no longer matches your live filesystem", p);
607 retval++;
608 }
609 unlink(tarball_fname);
610 mr_free(tarball_fname);
611 return (retval);
612}
613
614
615/**
616 * Verify one biggiefile form the opened tape/CD stream.
617 * @param bkpinfo The backup information structure. @c bkpinfo->tmpdir is the only field used.
618 * @param biggie_fname The filename of the biggiefile to verify.
619 * @param size The size in bytes of said biggiefile.
620 * @return 0 for success (even if the file doesn't match); nonzero for a tape error.
621 */
622int
623verify_a_biggiefile_from_stream(char *biggie_fname, long long size)
624{
625
626 /*@ int ************************************************************* */
627 int retval = 0;
628 int res = 0;
629 int current_slice_number = 0;
630 int ctrl_chr = '\0';
631
632 /*@ char ************************************************************ */
633 char *test_file = NULL;
634 char *biggie_cksum = NULL;
635 char *orig_cksum = NULL;
636 char *tmp = NULL;
637 char *slice_fnam;
638
639 /*@ pointers ******************************************************** */
640 char *p;
641
642 /*@ long long ******************************************************* */
643 long long slice_siz;
644
645 malloc_string(slice_fnam);
646 assert(bkpinfo != NULL);
647 assert_string_is_neither_NULL_nor_zerolength(biggie_fname);
648
649 p = strrchr(biggie_fname, '/');
650 if (!p) {
651 p = biggie_fname;
652 } else {
653 p++;
654 }
655 mr_asprintf(test_file, "%s/temporary-%s", bkpinfo->tmpdir, p);
656 for (res =
657 read_header_block_from_stream(&slice_siz, slice_fnam, &ctrl_chr);
658 ctrl_chr != BLK_STOP_A_BIGGIE;
659 res =
660 read_header_block_from_stream(&slice_siz, slice_fnam, &ctrl_chr)) {
661 if (ctrl_chr != BLK_START_AN_AFIO_OR_SLICE) {
662 wrong_marker(BLK_START_AN_AFIO_OR_SLICE, ctrl_chr);
663 }
664 res = read_file_from_stream_to_file(test_file, slice_siz);
665 unlink(test_file);
666 res =
667 read_header_block_from_stream(&slice_siz, slice_fnam, &ctrl_chr);
668 if (ctrl_chr != BLK_STOP_AN_AFIO_OR_SLICE) {
669 log_msg(2, "test_file = %s", test_file);
670 wrong_marker(BLK_STOP_AN_AFIO_OR_SLICE, ctrl_chr);
671 }
672 current_slice_number++;
673 retval += res;
674 }
675 mr_asprintf(biggie_cksum, "%s", slice_fnam);
676 if (biggie_cksum[0] != '\0') {
677 orig_cksum = calc_checksum_of_file(biggie_fname);
678 if (strcmp(biggie_cksum, orig_cksum)) {
679 log_msg(2, "orig cksum=%s; curr cksum=%s", biggie_cksum, orig_cksum);
680 log_to_screen("%s has changed on live filesystem", biggie_fname);
681
682 mr_asprintf(tmp, "echo \"%s\" >> %s/biggies.changed", biggie_fname, bkpinfo->tmpdir);
683 system(tmp);
684 mr_free(tmp);
685 }
686 mr_free(orig_cksum);
687 }
688 mr_free(biggie_cksum);
689 mr_free(test_file);
690 paranoid_free(slice_fnam);
691 return (retval);
692}
693
694
695/**
696 * Verify all afioballs from the opened tape/CD stream.
697 * @param bkpinfo The backup information structure. Fields used:
698 * - @c bkpinfo->tmpdir
699 *
700 * @return 0 for success (even if there are differences); nonzero for a tape error.
701 */
702int verify_afioballs_from_stream()
703{
704 /*@ int ********************************************************** */
705 int retval = 0;
706 int res = 0;
707 long current_afioball_number = 0;
708 int ctrl_chr = 0;
709 int total_afioballs = 0;
710
711 /*@ buffers ***************************************************** */
712 char *tmp = NULL;
713 char *fname;
714 char *curr_xattr_list_fname = NULL;
715 char *curr_acl_list_fname = NULL;
716
717 /*@ long long *************************************************** */
718 long long size = 0;
719
720 assert(bkpinfo != NULL);
721 malloc_string(fname);
722
723 if (g_getfattr) {
724 mr_asprintf(curr_xattr_list_fname, XATTR_BIGGLST_FNAME_RAW_SZ, bkpinfo->tmpdir);
725 }
726 if (g_getfacl) {
727 mr_asprintf(curr_acl_list_fname, ACL_BIGGLST_FNAME_RAW_SZ, bkpinfo->tmpdir);
728 }
729 log_to_screen("Verifying regular archives on tape");
730 total_afioballs = get_last_filelist_number() + 1;
731 open_progress_form("Verifying filesystem",
732 "I am verifying archives against your live filesystem now.",
733 "Please wait. This may take a couple of hours.", "",
734 total_afioballs);
735 res = read_header_block_from_stream(&size, fname, &ctrl_chr);
736 if (ctrl_chr != BLK_START_AFIOBALLS) {
737 log_it("YOU SHOULD NOT GET HERE");
738 log_it("Grabbing the EXAT files");
739 if (ctrl_chr == BLK_START_EXTENDED_ATTRIBUTES) {
740 res =
741 read_EXAT_files_from_tape(&size, fname, &ctrl_chr,
742 curr_xattr_list_fname,
743 curr_acl_list_fname);
744 }
745 }
746 if (ctrl_chr != BLK_START_AFIOBALLS) {
747 wrong_marker(BLK_START_AFIOBALLS, ctrl_chr);
748 }
749 if (g_getfattr) {
750 mr_free(curr_xattr_list_fname);
751 }
752 if (g_getfacl) {
753 mr_free(curr_acl_list_fname);
754 }
755
756 for (res = read_header_block_from_stream(&size, fname, &ctrl_chr);
757 ctrl_chr != BLK_STOP_AFIOBALLS;
758 res = read_header_block_from_stream(&size, fname, &ctrl_chr)) {
759 if (g_getfattr) {
760 mr_asprintf(curr_xattr_list_fname, XATTR_LIST_FNAME_RAW_SZ, bkpinfo->tmpdir, current_afioball_number);
761 }
762 if (g_getfacl) {
763 mr_asprintf(curr_acl_list_fname, ACL_LIST_FNAME_RAW_SZ, bkpinfo->tmpdir, current_afioball_number);
764 }
765 if (ctrl_chr == BLK_START_EXTENDED_ATTRIBUTES) {
766 log_it("Reading EXAT files from tape");
767 res =
768 read_EXAT_files_from_tape(&size, fname, &ctrl_chr,
769 curr_xattr_list_fname,
770 curr_acl_list_fname);
771 }
772 if (g_getfattr) {
773 mr_free(curr_xattr_list_fname);
774 }
775 if (g_getfacl) {
776 mr_free(curr_acl_list_fname);
777 }
778 if (ctrl_chr != BLK_START_AN_AFIO_OR_SLICE) {
779 wrong_marker(BLK_START_AN_AFIO_OR_SLICE, ctrl_chr);
780 }
781 mr_asprintf(tmp, "Verifying fileset #%ld", current_afioball_number);
782 update_progress_form(tmp);
783 mr_free(tmp);
784
785 res = verify_an_afioball_from_stream(fname, size);
786 if (res) {
787 log_to_screen("Afioball %ld differs from live filesystem", current_afioball_number);
788 }
789 retval += res;
790 current_afioball_number++;
791 g_current_progress++;
792 res = read_header_block_from_stream(&size, fname, &ctrl_chr);
793 if (ctrl_chr != BLK_STOP_AN_AFIO_OR_SLICE) {
794 wrong_marker(BLK_STOP_AN_AFIO_OR_SLICE, ctrl_chr);
795 }
796 }
797 log_msg(1, "All done with afioballs");
798 close_progress_form();
799 paranoid_free(fname);
800 return (retval);
801}
802
803/**
804 * Verify all biggiefiles on the opened CD/tape stream.
805 * @param bkpinfo The backup information structure. Fields used:
806 * - @c bkpinfo->restore_path
807 * - @c bkpinfo->tmpdir
808 *
809 * @return 0 for success (even if there are differences); nonzero for a tape error.
810 */
811int verify_biggiefiles_from_stream()
812{
813
814 /*@ int ************************************************************ */
815 int retval = 0;
816 int res = 0;
817 int ctrl_chr = 0;
818
819 /*@ long *********************************************************** */
820 long noof_biggiefiles = 0;
821 long current_biggiefile_number = 0;
822
823 /*@ buffers ******************************************************** */
824 char *orig_fname;
825 char *logical_fname = NULL;
826 char *comment = NULL;
827 char *curr_xattr_list_fname = NULL;
828 char *curr_acl_list_fname = NULL;
829 /*@ pointers ******************************************************* */
830 char *p;
831
832 /*@ long long size ************************************************* */
833 long long size = 0;
834
835 assert(bkpinfo != NULL);
836 malloc_string(orig_fname);
837
838 if (g_getfattr) {
839 mr_asprintf(curr_xattr_list_fname, XATTR_BIGGLST_FNAME_RAW_SZ, bkpinfo->tmpdir);
840 }
841 if (g_getfacl) {
842 mr_asprintf(curr_acl_list_fname, ACL_BIGGLST_FNAME_RAW_SZ, bkpinfo->tmpdir);
843 }
844 mr_asprintf(comment, "Verifying all bigfiles.");
845 log_to_screen(comment);
846 res = read_header_block_from_stream(&size, orig_fname, &ctrl_chr);
847 if (ctrl_chr != BLK_START_BIGGIEFILES) {
848 if (ctrl_chr == BLK_START_EXTENDED_ATTRIBUTES) {
849 log_it("Grabbing the EXAT biggiefiles");
850 res =
851 read_EXAT_files_from_tape(&size, orig_fname,
852 &ctrl_chr, curr_xattr_list_fname,
853 curr_acl_list_fname);
854 }
855 }
856 if (g_getfattr) {
857 mr_free(curr_xattr_list_fname);
858 }
859 if (g_getfacl) {
860 mr_free(curr_acl_list_fname);
861 }
862
863 if (ctrl_chr != BLK_START_BIGGIEFILES) {
864 wrong_marker(BLK_START_BIGGIEFILES, ctrl_chr);
865 }
866 noof_biggiefiles = (long) size;
867 log_msg(1, "noof_biggiefiles = %ld", noof_biggiefiles);
868 open_progress_form("Verifying big files", comment,
869 "Please wait. This may take some time.", "",
870 noof_biggiefiles);
871 mr_free(comment);
872
873 for (res = read_header_block_from_stream(&size, orig_fname, &ctrl_chr);
874 ctrl_chr != BLK_STOP_BIGGIEFILES;
875 res = read_header_block_from_stream(&size, orig_fname, &ctrl_chr))
876 {
877 if (ctrl_chr != BLK_START_A_NORMBIGGIE
878 && ctrl_chr != BLK_START_A_PIHBIGGIE) {
879 wrong_marker(BLK_START_A_NORMBIGGIE, ctrl_chr);
880 }
881 p = strrchr(orig_fname, '/');
882 if (!p) {
883 p = orig_fname;
884 } else {
885 p++;
886 }
887 mr_asprintf(comment, "Verifying bigfile #%ld (%ld K)", current_biggiefile_number, (long) size >> 10);
888 update_progress_form(comment);
889 mr_free(comment);
890
891 if (bkpinfo->restore_path) {
892 mr_asprintf(logical_fname, "%s/%s", bkpinfo->restore_path, orig_fname);
893 res = verify_a_biggiefile_from_stream(logical_fname, size);
894 mr_free(logical_fname);
895 retval += res;
896 } else {
897 log_it("Unable to verify bigfile as restore_path is NULL");
898 }
899
900 current_biggiefile_number++;
901 g_current_progress++;
902 }
903 close_progress_form();
904 paranoid_free(orig_fname);
905 return (retval);
906}
907
908/* @} - end of LLverifyGroup */
909
910
911/**
912 * Verify the USB device
913 * @param bkpinfo The backup information structure. Fields used:
914 * - @c bkpinfo->media_device
915 * - @c bkpinfo->tmpdir
916 * - @c bkpinfo->verify_data
917 *
918 * @return 0 for success (even if differences are found), nonzero for failure.
919 * @ingroup verifyGroup
920 */
921int verify_usb_image()
922{
923
924 /*@ int ************************************************************ */
925 int retval = 0;
926
927 /*@ buffers ******************************************************** */
928 char *mountpoint = NULL;
929 char *tmp = NULL;
930 char *tmp1 = NULL;
931 char *fname = NULL;
932 int ret = 0;
933#ifdef __FreeBSD__
934 char mdd[32];
935 char *mddevice = mdd;
936 int vndev = 2;
937#else
938//skip
939#endif
940
941 assert(bkpinfo != NULL);
942
943 if (bkpinfo->media_device == NULL) {
944 return(1);
945 }
946
947 mr_asprintf(fname, "%s1", bkpinfo->media_device);
948 if (is_this_device_mounted(fname)) {
949 log_msg(1, "USB device mounted. Remounting it at the right place");
950 mr_asprintf(tmp, "umount %s", fname);
951 run_program_and_log_output(tmp, FALSE);
952 paranoid_free(tmp);
953 }
954 paranoid_free(fname);
955
956 log_msg(1, "Mounting USB device.");
957 mr_asprintf(mountpoint, "%s/usb", bkpinfo->tmpdir);
958 mr_asprintf(tmp, "mkdir -p %s", mountpoint);
959 run_program_and_log_output(tmp, FALSE);
960 paranoid_free(tmp);
961 /* Mindi always create one single parition on the USB dev */
962 mr_asprintf(tmp, "mount %s1 %s", bkpinfo->media_device, mountpoint);
963 ret = run_program_and_log_output(tmp, FALSE);
964 paranoid_free(tmp);
965 if (ret) {
966 paranoid_free(mountpoint);
967 return(ret);
968 }
969
970 sync();
971 log_msg(2, "OK, I've mounted the USB Disk/Key\n");
972 mr_asprintf(tmp, "%s/archives/NOT-THE-LAST", mountpoint);
973 if (!does_file_exist(tmp)) {
974 log_msg
975 (2,
976 "This is the last USB device. I am therefore setting bkpinfo->verify_data to FALSE.");
977 bkpinfo->verify_data = FALSE;
978/*
979 (a) It's an easy way to tell the calling subroutine that we've finished &
980 there are no more device to be verified; (b) It stops the post-backup verifier
981 from running after the per-device verifier has run too.
982*/
983 }
984 paranoid_free(tmp);
985 verify_afioballs_on_CD(mountpoint);
986 log_it("before verify_all_slices");
987 verify_all_slices_on_CD(mountpoint);
988
989 mr_asprintf(tmp1, "umount %s", mountpoint);
990#ifdef __FreeBSD__
991 ret += system(tmp1);
992 ret += kick_vn(mddevice);
993 if (ret)
994#else
995 if (system(tmp1))
996#endif
997 {
998 log_to_screen("%s failed; unable to unmount USB device\n", tmp1);
999 retval++;
1000 } else {
1001 log_msg(2, "OK, I've unmounted the USB device\n");
1002 }
1003 mr_free(tmp1);
1004 mr_free(mountpoint);
1005 return (retval);
1006}
1007
1008
1009/**
1010 * Verify the CD indicated by @c g_current_media_number.
1011 * @param bkpinfo The backup information structure. Fields used:
1012 * - @c bkpinfo->isodir
1013 * - @c bkpinfo->prefix
1014 * - @c bkpinfo->manual_cd_tray
1015 * - @c bkpinfo->media_device
1016 * - @c bkpinfo->netfs_remote_dir
1017 * - @c bkpinfo->tmpdir
1018 * - @c bkpinfo->verify_data
1019 *
1020 * @return 0 for success (even if differences are found), nonzero for failure.
1021 * @ingroup verifyGroup
1022 */
1023int verify_cd_image()
1024{
1025
1026 /*@ int ************************************************************ */
1027 int retval = 0;
1028
1029 /*@ buffers ******************************************************** */
1030 char *mountpoint = NULL;
1031 char *command = NULL;
1032 char *tmp = NULL;
1033 char *fname = NULL;
1034#ifdef __FreeBSD__
1035 char mdd[32];
1036 char *mddevice = mdd;
1037 int ret = 0;
1038 int vndev = 2;
1039#else
1040//skip
1041#endif
1042
1043 assert(bkpinfo != NULL);
1044
1045 if (bkpinfo->media_device == NULL) {
1046 return(1);
1047 }
1048
1049 mr_asprintf(mountpoint, "%s/cdrom", bkpinfo->tmpdir);
1050 if (((bkpinfo->isodir == NULL) && (bkpinfo->netfs_remote_dir == NULL)) || (bkpinfo->prefix == NULL)) {
1051 fatal_error("No iso filename preparation possible");
1052 }
1053 if (bkpinfo->netfs_remote_dir) {
1054 // NETFS
1055 mr_asprintf(fname, "%s/%s/%s-%d.iso", bkpinfo->isodir, bkpinfo->netfs_remote_dir, bkpinfo->prefix, g_current_media_number);
1056 } else {
1057 // ISO
1058 mr_asprintf(fname, "%s/%s-%d.iso", bkpinfo->isodir, bkpinfo->prefix, g_current_media_number);
1059 }
1060
1061 mkdir(mountpoint, 1777);
1062 sync();
1063 if (!does_file_exist(fname)) {
1064 log_msg(2, "%s not found; assuming you backed up to CD; verifying CD...", fname);
1065 if (bkpinfo->manual_cd_tray) {
1066 popup_and_OK("Please push CD tray closed.");
1067 }
1068 if (find_and_mount_actual_cd(mountpoint)) {
1069 log_to_screen("failed to mount actual CD");
1070 mr_free(mountpoint);
1071 mr_free(fname);
1072 return (1);
1073 }
1074 } else {
1075 log_msg(2, "%s found; verifying ISO...", fname);
1076#ifdef __FreeBSD__
1077 ret = 0;
1078 vndev = 2;
1079 mddevice = make_vn(fname);
1080 if (ret) {
1081 log_to_screen("make_vn of %s failed; unable to verify ISO\n", fname);
1082 mr_free(mountpoint);
1083 mr_free(fname);
1084 return (1);
1085 }
1086 mr_asprintf(command, "mount_cd9660 %s %s", mddevice, mountpoint);
1087#else
1088 mr_asprintf(command, "mount -o loop,ro -t iso9660 %s %s", fname, mountpoint);
1089#endif
1090 if (run_program_and_log_output(command, FALSE)) {
1091 log_to_screen("%s failed; unable to mount ISO image\n", command);
1092 mr_free(mountpoint);
1093 mr_free(command);
1094 mr_free(fname);
1095 return (1);
1096 }
1097 mr_free(command);
1098 }
1099 log_msg(2, "OK, I've mounted the ISO/CD\n");
1100 mr_asprintf(tmp, "%s/archives/NOT-THE-LAST", mountpoint);
1101 if (!does_file_exist(tmp)) {
1102 log_msg
1103 (2,
1104 "This is the last CD. I am therefore setting bkpinfo->verify_data to FALSE.");
1105 bkpinfo->verify_data = FALSE;
1106/*
1107 (a) It's an easy way to tell the calling subroutine that we've finished &
1108 there are no more CD's to be verified; (b) It stops the post-backup verifier
1109 from running after the per-CD verifier has run too.
1110*/
1111 }
1112 mr_free(tmp);
1113
1114 verify_afioballs_on_CD(mountpoint);
1115 log_it("before verify_all_slices");
1116 verify_all_slices_on_CD(mountpoint);
1117
1118#ifdef __FreeBSD__
1119 ret = 0;
1120 mr_asprintf(command, "umount %s", mountpoint);
1121 ret += system(command);
1122 ret += kick_vn(mddevice);
1123 if (ret) {
1124#else
1125 mr_asprintf(command, "umount %s", mountpoint);
1126 if (system(command)) {
1127#endif
1128 log_to_screen("%s failed; unable to unmount ISO image\n", command);
1129
1130 retval++;
1131 } else {
1132 log_msg(2, "OK, I've unmounted the ISO file\n");
1133 }
1134 mr_free(mountpoint);
1135 mr_free(command);
1136
1137 if (!does_file_exist(fname)) {
1138 mr_asprintf(command, "umount %s", bkpinfo->media_device);
1139 run_program_and_log_output(command, 2);
1140 mr_free(command);
1141
1142 if (!bkpinfo->please_dont_eject && eject_device(bkpinfo->media_device)) {
1143 log_msg(2, "Failed to eject CD-ROM drive");
1144 }
1145 }
1146 mr_free(fname);
1147 return (retval);
1148}
1149
1150/**
1151 * Verify all backups on tape.
1152 * This should be done after the backup process has already closed the tape.
1153 * @param bkpinfo The backup information structure. Passed to various helper functions.
1154 * @return 0 for success (even if thee were differences), nonzero for failure.
1155 * @ingroup verifyGroup
1156 */
1157int verify_tape_backups()
1158{
1159
1160 /*@ int ************************************************************ */
1161 int retval = 0;
1162
1163 /*@ buffers ******************************************************** */
1164 char *tmp = NULL;
1165 char *changed_files_fname = NULL;
1166
1167 /*@ long *********************************************************** */
1168 long diffs = 0;
1169
1170 assert(bkpinfo != NULL);
1171
1172 log_msg(3, "verify_tape_backups --- starting");
1173 log_to_screen("Verifying backups");
1174 openin_tape();
1175/* verify archives themselves */
1176 retval += verify_afioballs_from_stream();
1177 retval += verify_biggiefiles_from_stream();
1178/* find the final blocks */
1179 sync();
1180 sleep(2);
1181 closein_tape();
1182/* close tape; exit */
1183// fclose(g_tape_stream); <-- not needed; is handled by closein_tape()
1184 mr_asprintf(tmp, "rm -f %s/biggies.changed %s/changed.files 2> /dev/null", bkpinfo->tmpdir, bkpinfo->tmpdir);
1185 paranoid_system(tmp);
1186 mr_free(tmp);
1187
1188 mr_asprintf(changed_files_fname, "%s/changed.files", bkpinfo->tmpdir);
1189 mr_asprintf(tmp, "grep -E '^%s:.*$' %s | cut -d'\"' -f2 | sort -u | awk '{print \"/\"$0;};' | tr -s '/' '/' | grep -v \"(total of\" | grep -v \"incheckentry.*xwait\" | grep -vE '^/afio:.*$' | grep -vE '^dev/.*$' > %s", (bkpinfo->use_star) ? "star" : "afio", MONDO_LOGFILE, changed_files_fname);
1190 log_msg(2, "Running command to derive list of changed files");
1191 log_msg(2, tmp);
1192 if (system(tmp)) {
1193 if (does_file_exist(changed_files_fname) && length_of_file(changed_files_fname) > 2) {
1194 log_to_screen("Warning - unable to check logfile to derive list of changed files");
1195 } else {
1196 log_to_screen("No differences found. Therefore, no 'changed.files' text file.");
1197 }
1198 }
1199 mr_free(tmp);
1200
1201 mr_asprintf(tmp, "cat %s/biggies.changed >> %s", bkpinfo->tmpdir, changed_files_fname);
1202 paranoid_system(tmp);
1203 mr_free(tmp);
1204
1205 diffs = count_lines_in_file(changed_files_fname);
1206 if (diffs > 0) {
1207 mr_asprintf(tmp, "cp -f %s %s/changed.files", changed_files_fname, MONDO_CACHE);
1208 run_program_and_log_output(tmp, FALSE);
1209 mr_free(tmp);
1210
1211 log_msg(0, "%ld files differed from live filesystem; type less %s or less %s/changed.files to see", diffs, changed_files_fname, MONDO_CACHE);
1212 log_to_screen("See "MONDO_CACHE"/changed.files for a list of nonmatching files.");
1213 log_to_screen("The files probably changed on filesystem, not on backup media.");
1214 }
1215 mr_free(changed_files_fname);
1216 return (retval);
1217}
1218
1219
1220
Note: See TracBrowser for help on using the repository browser.