-
Notifications
You must be signed in to change notification settings - Fork 0
/
LocalRsyncBackup.php
105 lines (91 loc) · 3.87 KB
/
LocalRsyncBackup.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#!/usr/bin/php
<?php
require_once 'SystemWrapper.php';
class LocalRsyncBackup extends SystemWrapper {
function __construct($log) {
if($log instanceof SystemWrapper){
$this->folder = $log->folder;
$this->file = $log->file;
$retArr = array();
$retCode = 0;
exec('whoami', $retArr, $retCode);
if ($retArr[0] != 'root') {
throw new Exception('need to be root');
}
} else {
parent::__construct($log);
}
}
function mount($dev, $folder, $readMode, $mountMode) {
$retArr = array();
$retCode = 0;
if ($mountMode == 'remount') {
return ($this->exec("mount -o remount,$readMode $dev $folder") != 0);
} else if ($mountMode == 'mount') {
return ($this->exec("mount -o $readMode $dev $folder") != 0);
} else if ($mountMode == 'umount') {
return ($this->exec("umount $dev") != 0);
}
return false; //$mountMode unknown
}
function backup($FROM, $TO_FOLDER, $TO_DEVICE, $EXLUDELIST) {
$retArr = array();
$retCode = 0;
$MOUNT_RO = true;
#check for presence
$retCode = $this->exec("mount | grep -q $TO_DEVICE");
if ($retCode != 0) {
$this->log("Error: target device not mounted");
return false;
}
# Festplatte rw remounten falls gewünscht!
if ($MOUNT_RO) {
if ($this->mount($TO_DEVICE, $TO_FOLDER, "rw", "remount")) {
$this->log("Error: Could not remount $TO_DEVICE readwrite");
return false;
} else
$this->log("remounted $TO_DEVICE as readwrite");
}
#here the real syncing happens
#use rsync with inplace to make it faster
#print stats to a log file
# safe links ignores links that point out of the syncing folder
$retCode = $this->exec("rsync -a --delete --delete-excluded --exclude-from=$EXLUDELIST --stats -h --inplace $FROM $TO_FOLDER ");
$this->log("Finished rsync backup from $FROM");
if ($retCode == 0 || $retCode == 23) {
$this->log("rsync: success");
} else {
$this->log("error (return code of rsync is $retCode) ");
return false;
}
# write through
$this->exec("sync");
if ($MOUNT_RO) {
if ($this->mount($TO_DEVICE, $TO_FOLDER, "ro", "remount")) {
$this->log("Error: Could not remount $TO_DEVICE readonly");
return false;
} else {
$this->log("remounted $TO_DEVICE as readonly");
# check for max mount count
$mountCount = $this->exec("tune2fs -l $TO_DEVICE | grep \"^Mount count\" | awk 'BEGIN { FS = \" \" } ;{exit $2}' ");
$this->log("$TO_DEVICE has been mounted $mountCount times");
$maxMountCount = $this->exec("tune2fs -l $TO_DEVICE | grep \"^Maximum mount count\" | awk 'BEGIN { FS = \" \" } ;{exit $2}'");
$this->log("maximum is $maxMountCount");
if ($mountCount >= $maxMountCount - 1) {
$this->log("$TO_DEVICE needs to be checked (has been mounted too often)");
$this->mount($TO_DEVICE, $TO_FOLDER, "", "umount");
$retCode = $this->exec("/sbin/e2fsck -p $TO_DEVICE", $retArr, $retCode);
if ($retCode != 0) {
$this->log("could not e2fsck $TO_DEVICE (returned $retCode)");
return false;
}
$this->mount($TO_DEVICE, $TO_FOLDER, "ro", "mount");
$this->log("$TO_DEVICE has been checked");
}
}
}
$this->log("Sync of $FROM completed successfully");
return true;
}
}
?>