X-Git-Url: http://git.pjr.cc/?a=blobdiff_plain;f=bin%2Fpbdc.php;h=8c67315e0df10ff4a09d75e31b3b9ca42df7e29b;hb=95682a89442421c2ae8bfbf729c255c993874d7c;hp=8e61a237b6872383ecc30964b012ea6896c2fb4a;hpb=e27b4a5c5cd7502324127aabebf109aa30b323fe;p=php-bacula-disk-changer.git diff --git a/bin/pbdc.php b/bin/pbdc.php index 8e61a23..8c67315 100644 --- a/bin/pbdc.php +++ b/bin/pbdc.php @@ -1,21 +1,371 @@ +Autochanger { + Name = + + Changer Command = "/usr/local/bin/vchanger %c %o %S %a %d" + Changer Device = "" +} + + +Device { + Name = + DriveIndex = + Autochanger = yes; + DeviceType = File + MediaType = File + ArchiveDevice = + RemovableMedia = no; + RandomAccess = yes; +} +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 ($BACULA_USER not $user)\n"; + exit(0); + } + + $changer_name = $argv[1]; + + echo "This command will init the data for $changer_name\n"; + + if(file_exists("$BASE_DATA/$changer_name.db")&&check_init($changer_name)) { + //echo "Daemon is already init'd, are you sure you wish to do this, it will loose all config [y/n]:"; + $r = readline("Daemon is already init'd, are you sure you wish to do this, it will loose all config [y/n]:"); + 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]:"); + $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($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"; +} + +function check_init_and_fail($changer) +{ + $lk = conf_getVal($changer, "automountdir"); + if(!$lk) { + echo "DB not init'd yet, please run init first\n"; + exit(0); + } +} + +function check_init($changer) +{ + $lk = conf_getVal($changer, "automountdir"); + if(!$lk) { + return false; + } + + return true; +} + +function add_disk() +{ + // disks get inited by going to /changer_dir/disk_uuid/ then: + // creating pbdc/changer_name/stuff. + global $BASE_DATA, $BASE_LIB, $BACULA_USER, $argv; + + check_init_and_fail($argv[1]); + + $dh = opendir("/dev/disk/by-uuid"); + + $disk = ""; + $i = 0; + + while(($file = readdir($dh)) !== false) { + if($file != "." && $file != "..") { + $st = stat("/dev/disk/by-uuid/".$file); + $realname = basename(readlink("/dev/disk/by-uuid/".$file)); + + // now get the size + $fh = fopen("/sys/class/block/$realname/size", "r"); + $rl = fgets($fh); + fclose($fh); + $realsize = (int)(((($rl/1024)*512)/1024)/1024); + + 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++; + } + } + + closedir($dh); + + $i = readline("Choose a disk from the list above:"); + if(isset($disk[$i]["real"])) { + echo "you have chosen, ".$disk[$i]["syml"]." (".$disk[$i]["real"].") of size ".$disk[$i]["size"]."gb\n"; + $ans = readline("is this correct? [y/n]:"); + if($ans != "y") { + echo "you said no, i bail\n"; + exit(0); + } + } else { + echo "invalid selection\n"; + exit(0); + } + + // now we try and init the disk + // we have to get automount directory config + $dir = conf_getVal($argv[1], "automountdir"); + if(!is_dir($dir)) { + echo "cant find automount directory, $dir\n"; + } + $mkd = "$dir/".basename($disk[$i]["syml"])."/pbdc/".$argv[1]."/tapes/"; + $k = mkdir($mkd, 0700, true); + + if(!is_dir($mkd)) { + echo "Error, couldn't create directory, check permissions on $mkd?\n"; + } + + $ts = conf_getVal($argv[1], "tapesize"); + $max = (int)($disk[$i]["size"]/$ts); + + $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"])); + + if(!$did) { + echo "Disk already exists, doing nothing\n"; + 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