<?php
-$BASE_LIB="../lib";
-$BASE_DATA="../db";
-$BACULA_USER="paulr";
+$BASE_LIB=$_SERVER["BASE_LIB"];
+$BASE_DIR=$_SERVER["BASE_DIR"];
+$BASE_DATA=$_SERVER["BASE_DATA"];
+$BACULA_USER=$_SERVER["BACULA_USER"];
-global $BASE_DATA, $BASE_LIB, $BACULA_USER;
+global $BASE_DATA, $BASE_LIB, $BACULA_USER, $BASE_DIR;
require_once "$BASE_LIB/lib.php";
function bacula_config()
{
- global $BASE_DATA, $BASE_LIB, $BACULA_USER, $argv;
+ global $BASE_DATA, $BASE_LIB, $BACULA_USER, $argv, $BASE_DIR;
check_init_and_fail($argv[1]);
$changer = $argv[1];
$ntapes = conf_getVal($changer, "ndrives");
$tapeloc = conf_getVal($changer, "drivelocation");
+ $tapesz = conf_getVal($changer, "tapesize");
// TODO: do this bit
// bacula-sd.conf
?>
+-------------------------------- bacula-sd.conf -----------------------------
Autochanger {
Name = <?php echo "$changer\n"?>
- <?php
+<?php
for($i=0; $i<$ntapes; $i++) {
- echo "Device = \"$changer-drive$i\"\n";
+ echo " Device = \"$changer-drive$i\"\n";
}
- ?>
- Changer Command = "/usr/local/bin/vchanger %c %o %S %a %d"
+?>
+ Changer Command = "<?php echo $BASE_DIR."/bin/pbdc-bacula"?> %c %o %S %a %d"
Changer Device = "<?php echo $changer ?>"
}
RemovableMedia = no;
RandomAccess = yes;
}
+
+
<?php
- }
+ }
+?>
+
+
+-------------------------------- bacula-dir.conf -----------------------------
+Storage {
+ Name = <INSERT STORAGE NAME>
+ Address = <ADDRESS OF WHERE SD IS RUNNING>
+ SDPort = 9103
+ Password = "<SD PASSWORD>"
+ Device = <?php echo "\"$changer-drive$i\"\n" ?>
+ Media Type = File
+ Autochanger = yes;
+}
+
+# a pool for our storage
+Pool {
+ Name = <POOL NAME GOES HERE>
+ Pool Type = Backup
+ Recycle = yes # Bacula can automatically recycle Volumes
+ AutoPrune = yes # Prune expired volumes
+ Volume Retention = 50 days # I set this to 50 days, dont ask me why
+ Maximum Volume Bytes = <?php echo "$tapesz"."G"?> # Limit Volume size to something reasonable
+ Maximum Volumes = 1000 # Limit number of Volumes in Pool SET THIS
+}
+
+# add a default job job defs for our pool - modify where necessary
+# i.e. look at the normal jobdefs, or modify that with your backup defs.
+JobDefs {
+ Name = "PBDCJobDefs"
+ Type = Backup
+ Level = Incremental
+ Storage = <INSERT STORAGE NAME>
+ Messages = Standard
+ Pool = <POOL NAME GOES HERE>
+ Priority = 10
+ Write Bootstrap = "/var/lib/bacula/%c.bsr"
+}
+
+
+<?php
+
}
function pbdc_status()
$dh = opendir("$amloc/".$row["disk_name"]."/pbdc/".$argv[1]."/tapes/");
while(($file = readdir($dh)) !== false) {
if(ereg("d[0-9]+_vol[0-9]+", $file)!=false) {
- echo "Tape: $file\n";
+ $sql = "select slot_no from slots where tape_name=='$file'";
+ $res2 = $db->query($sql);
+ if($res2) {
+ foreach($res2 as $row2)
+ $slot = $row2["slot_no"];
+ } else $slot = "none";
+ echo "Tape: $file (slot $slot)\n";
} else {
//echo "didnt match: $file\n";
}
global $BASE_DATA, $BASE_LIB, $BACULA_USER, $argv;
// check if we are the bacula user
- $user = posix_getlogin();
+ //$user = posix_getlogin();
+ $user = $_SERVER["USER"];
if($user != $BACULA_USER) {
- echo "This command must be run as the bacula user\n";
+ echo "This command must be run as the bacula user ($BACULA_USER not $user)\n";
exit(0);
}
if($r == "y") {
echo "Ok, but its your disaster, waiting 5 seconds prior to init'ing the database (hit ctrl-c to exit)\n";
sleep(5);
+ unlink("$BASE_DATA/$changer_name.db");
} else {
echo "Ok, not doing it, so long chum\n";
exit(0);
echo "Creating database\n";
$ra = readline("Directory where automount occurs [/changer/]:");
- $rb = readline("Number of drives [1]:");
+ $rb = readline("Number of drives [2]:");
$rc = readline("Size of tapes [20] (in gb):");
$rd = readline("Where to store drive pointers [/var/run/bacula/]:");
if($ra == "") $ra = "/changer/";
- if($rb == "") $rb = 1;
+ if($rb == "") $rb = 2;
if($rc == "") $rc = 20;
if($rd == "") $rd = "/var/run/bacula/";
conf_setVal($changer_name, "drivelocation", "$rd");
// check if they were set
- echo "got: ".conf_getVal($changer_name, "automountdir").", and ".conf_getVal($changer_name, "tapesize").", and ".conf_getVal($changer_name, "ndrives")."\n";
+ // echo "got: ".conf_getVal($changer_name, "automountdir").", and ".conf_getVal($changer_name, "tapesize").", and ".conf_getVal($changer_name, "ndrives")."\n";
}
function check_init_and_fail($changer)
return true;
}
+function disk_get_size($file, $realname="")
+{
+ global $BASE_DATA, $BASE_LIB, $BACULA_USER, $argv;
+
+ check_init_and_fail($argv[1]);
+
+ $changer = $argv[1];
+
+ error_reporting(E_ALL);
+
+ $dh = opendir("/dev/disk/by-uuid");
+ $amdir = conf_getVal($changer, "automountdir");
+
+ $ts = 0;
+
+ $parsed = false;
+ if(file_exists("/$amdir/$file/.")) {
+ $cmd = "/bin/df -k /$amdir/$file/. |/usr/bin/tail -1 |/usr/bin/awk '{ print $4 }'";
+ $pl = popen($cmd, "r");
+ if($pl) {
+ $f = fread($pl, 1024);
+ //echo "cmd: $cmd\nf: $f\n";
+ $ts = (int)($f);
+ if($ts > 1) $parsed = true;
+ pclose($pl);
+ }
+ }
+
+ if(!$parsed && $realname != "") {
+ $fh = fopen("/sys/class/block/$realname/size", "r");
+ $lk = ((int)(fgets($fh)));
+ $ts = ($lk/1024)*512;
+ fclose($fh);
+
+ }
+
+ $realsize = (int)(($ts/1024)/1024);
+
+ return $realsize;
+}
+
function add_disk()
{
// disks get inited by going to /changer_dir/disk_uuid/ then:
check_init_and_fail($argv[1]);
+ $changer = $argv[1];
+
$dh = opendir("/dev/disk/by-uuid");
+ $amdir = conf_getVal($changer, "automountdir");
$disk = "";
$i = 0;
if($file != "." && $file != "..") {
$st = stat("/dev/disk/by-uuid/".$file);
$realname = basename(readlink("/dev/disk/by-uuid/".$file));
+ $realsize = disk_get_size($file, $realname);
- // now get the size
- $fh = fopen("/sys/class/block/$realname/size", "r");
- $rl = fgets($fh);
- fclose($fh);
- $realsize = (int)(((($rl/1024)*512)/1024)/1024);
-
+ // now get the size, first lets try and parse df output
echo "disk $i: /dev/$realname or /dev/disk/by-uuid/$file of size ".$realsize."gb\n";
$disk[$i]["real"] = "/dev/$realname";
$disk[$i]["syml"] = "/dev/disk/by-uuid/".$file;
$disk[$i]["size"] = $realsize;
$i++;
+
}
}
$max = (int)($disk[$i]["size"]/$ts);
$kt = (int)(readline("No of tapes to create [max:$max] @ ".$ts."gb each:"));
+ if($kt == "") $kt = $max;
+ if($kt < 0) $kt = $max;
if($kt > $max) {
echo "Sorry, max number of tapes is $max, creating $max instead\n";
$kt = $max;
} else {
echo "tape $tid already existed\n";
}
+ add_to_slot($argv[1], $tid, $did);
}
}
+
+function add_to_slot($changer, $tapename, $disk_id)
+{
+ global $BASE_DATA, $BASE_LIB, $BACULA_USER, $argv;
+
+ $db = db_getDB($changer);
+
+ $slot = "";
+ $slots = 0;
+ $max_slot = 0;
+
+ $res = $db->query("select * from slots");
+ foreach($res as $row) {
+ $slot[$row["slot_no"]]["diskid"] = $row["disk_id"];
+ $slot[$row["slot_no"]]["tapename"] = $row["tape_name"];
+ $slots++;
+ if($row["slot_no"] > $max_slot) $max_slot = $row["slot_no"];
+ }
+
+ // first tape, straight in with you
+ if($slots == 0) {
+ $db->query("insert into slots values (NULL, 1, $disk_id, '$tapename')");
+ return;
+ }
+
+ // next hunt thru the slots and see if its filled yet.
+ foreach($slot as $lk) {
+ if($lk["tapename"] == $tapename) {
+ // tape was already there, move along
+ return;
+ }
+ }
+
+ // now we go from 0 to the end looking for a free slot
+ for($i=1; $i < $max_slot; $i++) {
+ if(!isset($slot[$i])) {
+ // we have a free slot, but it shouldnt appear that way like that.. oh well.
+ $db->query("insert into slots values (NULL, $i, $disk_id, '$tapename')");
+ return;
+ }
+ if($slot[$i]["tapename"] == "") {
+ // slot is free
+ $db->query("delete from slots where slot_no='$i'");
+ $db->query("insert into slots values (NULL, $i, $disk_id, '$tapename')");
+ return;
+ }
+ }
+
+ // So much error checking to do.
+ // if we made it here, we need more slots.
+ $ns = $max_slot + 1;
+ $db->query("insert into slots values (NULL, $ns, $disk_id, '$tapename')");
+ return;
+}
?>
\ No newline at end of file