diff --git a/html/inc/bu-common.php b/html/inc/bu-common.php
index 70a8a0f..de264ca 100644
--- a/html/inc/bu-common.php
+++ b/html/inc/bu-common.php
@@ -1,5 +1,6 @@
exec("update BULIST set BuRunning=$setit_int where BUID=$id");
@@ -44,7 +48,7 @@
*/
function set_bu_error( $buid, $str_errs ){
global $g_database_path;
- $db = new SQLite3( __DIR__."/../$g_database_path" );
+ $db = new SQLite3( __DIR__."/$g_database_path" );
if($str_errs==''){
return $db->exec("update BULIST set BuError = NULL where BUID=$buid");
}
@@ -58,12 +62,10 @@
}
}
-/**
- *
- */
+
function set_last_run_date( $buid, $str_dt ){
global $g_database_path;
- $db = new SQLite3( __DIR__."/../$g_database_path" );
+ $db = new SQLite3( __DIR__."/$g_database_path" );
$p = $db->prepare("update BULIST set LastRunDt=:str_dt where BUID=:buid");
$p->bindValue(':str_dt', $str_dt );
$p->bindValue(':buid', $buid );
@@ -74,6 +76,22 @@
}
}
+function set_sched_date( $buid, $dt_new ){
+
+ global $g_database_path;
+
+ $db = new SQLite3( __DIR__."/$g_database_path" );
+
+ $p = $db->prepare("update BULIST set BU_DATE=:str_dt where BUID=:buid");
+ $p->bindValue(':str_dt', $dt_new );
+ $p->bindValue(':buid', $buid );
+ $p->execute();
+
+ if( $db->lastErrorCode()!==0){
+ return $db->lastErrorCode();
+ }
+}
+
/**
* Run the backup process for the given backup ID.
@@ -116,10 +134,16 @@
return run_backup_F( $bu_test, $buid, $bu_src, $bu_dest, $exFiles );
}
+
+/**
+ * This function is now used directly by the backup service.
+ */
function run_backup_F( $bu_test, $buid, $bu_src, $bu_dest, $exFiles ){
+ global $g_data_dir;
+
if(!set_bu_running( $buid, true, $bu_test )){
- return "Could not set the DB flag";
+ return "Could not set the DB flag ";//.SQLite3::lastErrorMsg();
}
if($bu_test){
@@ -127,31 +151,31 @@
}else{
$flags = '-av';
set_bu_error( $buid, '' ); //clear any previous error
- set_last_run_date( $buid, gmdate("Y-m-d H:i:s") );
+ //set_last_run_date( $buid, gmdate("Y-m-d H:i:s") );
}
$fn_o = getFilename_out( $buid, $bu_test, false );
$fn_e = getFilename_out( $buid, $bu_test, true );
// create the output files with the ID in the first line
- file_put_contents("data/$fn_o","ID: $buid");
- file_put_contents("data/$fn_e","ID: $buid");
+ file_put_contents("$g_data_dir/$fn_o","ID: $buid");
+ file_put_contents("$g_data_dir/$fn_e","ID: $buid");
- if( !file_exists( "data/$fn_e" )){
+ if( !file_exists( "$g_data_dir/$fn_e" )){
return "exec failed to create file $fn_e";
}
$str_exPaths = '';
if(trim( $exFiles )!=''){
$fn_x = getFilename_tmp( $buid, 'x' );
- file_put_contents( "data/$fn_x", $exFiles );
- $str_exPaths = "--exclude-from=data/$fn_x";
+ file_put_contents( "$g_data_dir/$fn_x", $exFiles );
+ $str_exPaths = "--exclude-from=$g_data_dir/$fn_x";
}
// bash command
//rsync -a --exclude-from=to-exclude.txt $PATH_SRC $BKUP_DEST
//rsync -anv --exclude-from=to-exclude.txt $PATH_SRC $BKUP_DEST <-- for testing
- $command = "rsync $flags $str_exPaths $bu_src $bu_dest 2>> data/$fn_e 1>> data/$fn_o";
+ $command = "rsync $flags $str_exPaths $bu_src $bu_dest 2>> $g_data_dir/$fn_e 1>> $g_data_dir/$fn_o";
$output = array();
$result_code = null;
@@ -162,7 +186,7 @@
set_bu_running( $buid, false, $bu_test );
// can we find any error strings in the error file?
- $str_errs = file_get_contents( "data/$fn_e" );
+ $str_errs = file_get_contents( "$g_data_dir/$fn_e" );
$pos = strpos($str_errs, 'error' );
if($pos===FALSE){
$pos = strpos($str_errs, 'failed' );
@@ -176,10 +200,12 @@
/**
- * Very similar to the file version. The common code is running the bash script.
+ * This function is now used directly by the backup service.
*/
function run_backup_DB( $bu_test, $buid, $bu_src, $bu_dest ){
+ global $g_data_dir;
+
if(!set_bu_running( $buid, true, $bu_test )){
return "Could not set the DB flag";
}
@@ -190,21 +216,21 @@
if($bu_test){
$fn_o = getFilename_out( $buid, $bu_test, false );
- $bu_dest = "data";
+ $bu_dest = "$g_data_dir";
}else{
$fn_o = "$bu_src.sql";
set_bu_error( $buid, '' ); //clear any previous error
- set_last_run_date( $buid, gmdate("Y-m-d H:i:s") );
+ //set_last_run_date( $buid, gmdate("Y-m-d H:i:s") );
}
// create the error files with the ID in the first line
$fn_e = getFilename_out( $buid, $bu_test, true );
- exec("echo 'ID: $buid' > data/$fn_e");
+ exec("echo 'ID: $buid' > $g_data_dir/$fn_e");
// bash command
//mysqldump johntest > /home/johnp/tmp/dbs/johntest.sql
- $command = "mysqldump $bu_src 2>> data/$fn_e 1>> $bu_dest/$fn_o";
+ $command = "mysqldump $bu_src 2>> $g_data_dir/$fn_e 1>> $bu_dest/$fn_o";
$output = array();
$result_code = null;
@@ -215,7 +241,7 @@
set_bu_running( $buid, false, $bu_test );
// can we find any error strings in the error file?
- $str_errs = file_get_contents( "data/$fn_e" );
+ $str_errs = file_get_contents( "$g_data_dir/$fn_e" );
$pos = strpos($str_errs, 'error' );
if($pos===FALSE){
$pos = strpos($str_errs, 'failed' );
diff --git a/html/inc/bu_list_content.php b/html/inc/bu_list_content.php
index 2af9546..d48f5e9 100644
--- a/html/inc/bu_list_content.php
+++ b/html/inc/bu_list_content.php
@@ -22,6 +22,54 @@
/**
+ * Retrieve all database rows ordered by the next run time in ascending order. Note that the null date/times will
+ * be listed first.
+ */
+function getbu_list_all( &$allRows, &$colIdxs=null ){
+
+ global $g_database_path;
+
+ $db = new SQLite3($g_database_path, SQLITE3_OPEN_READONLY );
+
+ if($colIdxs!==null){
+ $i=0;
+ $colIdxs = array();
+ $colIdxs['BUID'] = $i++;
+ $colIdxs['BUName'] = $i++;
+ $colIdxs['Dir_Src'] = $i++;
+ $colIdxs['Dir_Dest'] = $i++;
+ $colIdxs['Files_Ex'] = $i++;
+ $colIdxs['BuType'] = $i++;
+ $colIdxs['BuRunning'] = $i++;
+ $colIdxs['BU_DATE'] = $i++;
+ $colIdxs['BU_TIME'] = $i++;
+ $colIdxs['BU_REPEAT'] = $i++;
+ $colIdxs['BuError'] = $i++;
+ $colIdxs['LastRunDt'] = $i++;
+ }
+
+ $html_rows='';
+ $results = $db->query('SELECT BUID, BUName, Dir_Src, Dir_Dest, Files_Ex, BuType, BuRunning, BU_DATE, BU_TIME, BU_REPEAT, BuError, LastRunDt FROM BULIST order by BU_DATE desc, BU_TIME desc');
+ while ($row = $results->fetchArray()) {
+ $allRows[ $row['BUID'] ] = array(
+ $row['BUID'],
+ $row['BUName'],
+ $row['Dir_Src'],
+ $row['Dir_Dest'],
+ $row['Files_Ex'],
+ $row['BuType'],
+ $row['BuRunning'],
+ $row['BU_DATE'],
+ $row['BU_TIME'],
+ $row['BU_REPEAT'],
+ $row['BuError'],
+ $row['LastRunDt']
+ );
+ }
+
+}
+
+/**
* Returns the main backup list page.
*/
function getbu_list_content(){
diff --git a/html/inc/pagemap.php b/html/inc/pagemap.php
index 4b79a47..3ea3132 100644
--- a/html/inc/pagemap.php
+++ b/html/inc/pagemap.php
@@ -14,8 +14,7 @@
if( $cmd=='btn_test_1' ){
include_once __DIR__ . "/service_calls.php";
- $rtn_arr = rpc_test( "Hello" );
- sendHtmlOk_WithData( ['done', $rtn_arr] );
+ sendHtmlOk_WithData( rpc_test( "Hello" ) );
return true;
}
diff --git a/html/inc/service_calls.php b/html/inc/service_calls.php
index b5e1bc5..7b0d4e3 100644
--- a/html/inc/service_calls.php
+++ b/html/inc/service_calls.php
@@ -1,5 +1,7 @@
new DateTime('now', new DateTimeZone("UTC") ) ){
+ //...no it's not
+ return;
+ }
+
+ kickoff_backup( $idfound );
+
+ print( "check after forked: running = ". $g_bu_table[$idfound][ $g_bu_colIdxs['BuRunning'] ] . "\n");
+
+ return true;
+}
+
+/**
+ * Kicks off a back up. Returns immediately. Deligates the work to a client fork.
+ *
+ * $scheduled:
+ * true if it is run according to the $schedule info in the db
+ * false if it has been manually initiated
+ */
+function kickoff_backup( $buid, $scheduled = true ){
+
+ global $g_bu_table;
+ global $g_bu_colIdxs;
+
+
+ // we should be able to use pcntl_fork()
+ $pid = pcntl_fork();
+ if ( $pid == -1 ) {
+ print("fork failed");
+ return;
+ }
+
+ $bu_test = false;
+ $bu_type = $g_bu_table[$buid][ $g_bu_colIdxs['BuType'] ];
+ $bu_src = $g_bu_table[$buid][ $g_bu_colIdxs['Dir_Src'] ];
+ $bu_dest = $g_bu_table[$buid][ $g_bu_colIdxs['Dir_Dest'] ];
+ $exFiles = $g_bu_table[$buid][ $g_bu_colIdxs['Files_Ex'] ];
+
+
+
+ if ( $pid ) {
+ // parent process
+ print( "parentpid = ". getmypid() . "\n" );
+ $g_bu_table[$buid][ $g_bu_colIdxs['BuRunning'] ] = 1;
+ return;
+
+ } else {
+
+ // child process
+ $pid = getmypid();
+ print( "childpid = $pid\n" );
+
+ print( "kickoff_backup for $buid\n" );
+ include_once __DIR__."/../inc/bu-common.php";
+ $bu_result = '';
+ global $g_data_dir;
+ $g_data_dir = __DIR__."/../data";
+
+ if($bu_type==1 ){
+ $bu_result = run_backup_DB( $bu_test, $buid, $bu_src, $bu_dest );
+ }else{
+ $bu_result = run_backup_F( $bu_test, $buid, $bu_src, $bu_dest, $exFiles );
+ }
+
+ print( "backup ended for $buid, result = $bu_result\n" );
+ $obj = rpc( 'm:fork-complete', $pid, "backup-complete", $buid, $scheduled ); //we use our rpc mechanism to notify parent
+ //print_r( $obj );
+ //print( "\n" );
+ exit(0);
+ }
+
+}
+
+
$msgArr = null;
-while(true){
+/**
+ * Return true if a request was found and handled
+ */
+function check_rpc_clients(){
$caller_id = 0;
- $obj = rpc_listen( $caller_id, $msgArr );
+ $obj = rpc_listen( $caller_id, $msgArr, false );
- //print_r( $obj );
+ if($caller_id==0){
+ //nothing to do
+ return false;
+ }
- //do something with the data
- array_unshift( $obj, "Greetings" );
-
+ $obj = handle_rpc_req( $obj );
+
//send msg back
rpc_reply( $caller_id, $obj );
//done with the message
unset( $msgArr[$caller_id] );
+ if( $obj[0] == 'm:fork-complete' ){
+ // this is required to clean up the child process
+ $status;
+ pcntl_waitpid( $obj[1], $status );
+
+ if( $obj[2]="backup-complete"){
+ backupComplete( $obj[3], $obj[4] );
+ }
+ }
+
+ return true;
+
+}
+
+/**
+ * Called by the parent after a client notified that a backup completed.
+ */
+function backupComplete( $buid, $scheduled ){
+
+ //reload the table data - client updates the error field
+ global $g_bu_table;
+ global $g_bu_colIdxs;
+
+ $g_bu_table = array();
+ getbu_list_all( $g_bu_table );
+
+ include_once __DIR__."/../inc/bu-common.php";
+
+ if($scheduled){
+ //if DB error, do nothing
+ $err = $g_bu_table[$buid][ $g_bu_colIdxs['BuError'] ];
+ if($err==''){
+ //update date and time according to the repeat field.
+ $date = date_create( $g_bu_table[$buid][ $g_bu_colIdxs['BU_DATE'] ] );
+ $dt_new = null;
+
+ switch( $g_bu_table[$buid][ $g_bu_colIdxs['BU_REPEAT'] ] ){
+ case 'M':
+ //monthly
+ date_add( $date, new DateInterval('P1M') );
+ $dt_new = date_format( $date, "Y-m-d");
+ break;
+
+ case 'W':
+ //weekly
+ date_add( $date, new DateInterval('P1W') );
+ $dt_new = date_format( $date, "Y-m-d");
+ break;
+
+ case 'D':
+ //daily
+ date_add( $date, new DateInterval('P1D') );
+ $dt_new = date_format( $date, "Y-m-d");
+ break;
+
+ }
+ $g_bu_table[$buid][ $g_bu_colIdxs['BU_DATE'] ] = $dt_new;
+
+ set_sched_date( $buid, $dt_new );
+
+ }
+ }//if manually kicked off - nothing to do
+
+ //TODO: remove the outputfiles
+
+ $dt = gmdate("Y-m-d H:i:s");
+ set_last_run_date( $buid, $dt );
+ $g_bu_table[$buid][ $g_bu_colIdxs['LastRunDt'] ] = $dt;
+
+}
+
+function handle_rpc_req( $obj ){
+
+
+ switch( $obj[0] ){
+ case 'm:fork-complete':
+ //send the same message back to the caller
+ return $obj;
+ }
+
+ //do something with the data
+ print_r( $obj );
+ array_unshift( $obj, "Greetings" );
+ return $obj;
+
}
?>