X-Git-Url: http://git.pjr.cc/?a=blobdiff_plain;f=bin%2Fpbdc.php;h=0ea159ae7d1e08ed3f96447d7b336f0dcfc072ce;hb=ea59819adbba9ec633cbb39f8c2388b5e392be6a;hp=c1ea23d75fd1cf04802148e9945386465d9898d3;hpb=10b3158464d931ccfa758eb648ca2e9b72aa0a86;p=php-bacula-disk-changer.git diff --git a/bin/pbdc.php b/bin/pbdc.php index c1ea23d..0ea159a 100644 --- a/bin/pbdc.php +++ b/bin/pbdc.php @@ -1,10 +1,11 @@ +-------------------------------- bacula-sd.conf ----------------------------- +Autochanger { + Name = + + Changer Command = " %c %o %S %a %d" + Changer Device = "" +} + + +Device { + Name = + DriveIndex = + Autochanger = yes; + DeviceType = File + MediaType = File + ArchiveDevice = + RemovableMedia = no; + RandomAccess = yes; +} + + + + + +-------------------------------- bacula-dir.conf ----------------------------- +Storage { + Name = + Address =
+ SDPort = 9103 + Password = "" + Device = + Media Type = File + Autochanger = yes; +} + +# a pool for our storage +Pool { + Name = + 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 = # 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 = + Messages = Standard + Pool = + Priority = 10 + Write Bootstrap = "/var/lib/bacula/%c.bsr" +} + + +query("select * from disk_list"); + + $tapeloc = conf_getVal($changer, "drivelocation"); + $amloc = conf_getVal($changer, "automountdir"); + + $ret = false; + foreach($res as $row) { + echo "Listing tapes for disk ".$row["disk_id"].", ".$row["disk_name"]."\n"; + //echo "dir: $amloc/".$row["disk_name"]."/pbdc/".$argv[1]."/tapes/\n"; + //exit(0); + $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) { + $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 $sln)\n"; + } else { + //echo "didnt match: $file\n"; + } + //exit(0); + } + closedir($dh); + } + + $nt = (int)(conf_getVal($changer, "ndrives")); + for($i = 0; $i < $nt; $i++) { + if(file_exists("$tapeloc/$changer-drive$i")) { + $rl = basename(readlink("$tapeloc/$changer-drive$i")); + echo "drive $i points has tape $rl loaded\n"; + } else { + echo "drive $i is unloaded\n"; + } + } +} + +function list_disks() +{ + global $BASE_DATA, $BASE_LIB, $BACULA_USER, $argv; + + check_init_and_fail($argv[1]); + + $db = db_getDB($argv[1]); + + $res = $db->query("select * from disk_list"); + + $ret = false; + foreach($res as $row) { + echo "Disk ".$row["disk_id"].": ".$row["disk_name"]."\n"; + $ret = true; + } + + if(!$ret) { + echo "No disks defined yet for this changer\n"; + } + + + return; +} + function init() { global $BASE_DATA, $BASE_LIB, $BACULA_USER, $argv; // check if we are the bacula user $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); } @@ -58,6 +223,7 @@ function init() 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); @@ -66,16 +232,19 @@ function init() 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, "automountdir", "$ra"); conf_setVal($changer_name, "ndrives", "$rb"); conf_setVal($changer_name, "tapesize", "$rc"); + 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"; @@ -100,6 +269,47 @@ function check_init($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: @@ -108,7 +318,10 @@ function add_disk() check_init_and_fail($argv[1]); + $changer = $argv[1]; + $dh = opendir("/dev/disk/by-uuid"); + $amdir = conf_getVal($changer, "automountdir"); $disk = ""; $i = 0; @@ -117,18 +330,15 @@ function add_disk() 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++; + } } @@ -163,9 +373,10 @@ function add_disk() $ts = conf_getVal($argv[1], "tapesize"); $max = (int)($disk[$i]["size"]/$ts); - $k = (int)(readline("No of tapes to create [max:$max] @ ".$ts."gb each:")); - if($k > $max) { + $kt = (int)(readline("No of tapes to create [max:$max] @ ".$ts."gb each:")); + if($kt > $max) { echo "Sorry, max number of tapes is $max, creating $max instead\n"; + $kt = $max; } $did = add_diskToDB($argv[1], basename($disk[$i]["syml"])); @@ -175,6 +386,73 @@ function add_disk() exit(0); } + // disk names are d.$did_vol0000x //echo "did: $did\n"; + for($ii=0; $ii < $kt; $ii++) { + $tid = sprintf("d%d_vol%04d", $did, $ii); + //echo "would create $tid\n"; + $tp = "$dir/".basename($disk[$i]["syml"])."/pbdc/".$argv[1]."/tapes/$tid"; + if(!file_exists($tp)) { + fopen($tp, "w"); + echo "created tape $tid\n"; + } 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