#define USE_JOB_LIST
#define COMMAND_LINE_TOOL // See in src/plugin/fd/fd_common.h
+
#define MAX_RETURN_PRUNE 10
+#define RETRY_LOCK 10
+#define ALWAYS_LEVEL 0
+#define CRITICAL_LEVEL 100
+#define STANDARD_LEVEL 300
+#define PROG_NAME "bjoblist"
+
#include "plugins/fd/fd_common.h"
int main(int argc, char *argv[])
{
int opt;
- POOLMEM *tmp = get_pool_memory(PM_FNAME);
+ int lock_return = 1; // Good by default
+ int lock_fd;
+ char lock_name[20]="/tmp/bjoblist.lck";
+ POOL_MEM pool_mem;
+ POOLMEM *lock_poolmem = get_pool_memory(PM_NAME);
alist tmp_list(MAX_RETURN_PRUNE, owned_by_alist);
bool store_return = true;
bool search_return = true;
-
+ char *to_delete_job;
+
// Args to be received by the command line
char *dat_file = NULL;
char *key = NULL;
char *data = NULL;
bool is_store = false;
bool is_search = false;
+ bool use_lock = false;
debug_level = 0;
// Parsing of command line arguments
- while ((opt = getopt(argc, argv, "w:f:k:p:j:l:D:sSd:h")) != -1) {
+ while ((opt = getopt(argc, argv, "w:f:k:p:j:l:D:sSiLd:h")) != -1) {
switch(opt) {
case 'w': // Working dir
working_directory = optarg; // global var
break;
case 'D': // Data
- // TODO is no data put curr job instead
data = optarg;
break;
is_search = true;
break;
+ case 'L': // Use file lock
+ use_lock = true;
+ break;
+
case 'd': // Debug-level
debug_level = atoi(optarg); // global var
break;
case 'h': // help default is help as well
default:
- printf("bjoblist: joblist command line tool : store/search jobs and find deletable ones\n"
+ Dmsg(NULL, ALWAYS_LEVEL,
+ "bjoblist: joblist command line tool : "
+ "store/search jobs and find deletable ones\n"
"USAGE: bjoblist [OPTIONS]\n"
"Options-styles: -option\n\n"
- "\t-w\tWorking directory\n"
- "\t-f\tDat file with job hierarchy info\n"
- "\t-k\tKey (hostname + volume name)\n"
- "\t-p\tPrevious job\n"
- "\t-j\tCurrent job\n"
- "\t-l\tLevel {(F)ull, (D)ifferential, (I)ncremental}\n"
- "\t-D\tData XXX-XXX-XXX-XXX-XXX\n"
- "\t-s\tStore-mode\n"
- "\t-S\tSearch-mode\n"
- "\t-d\tDebug-level\n"
- "\t-h\t display this text\n\n");
+ "\t-w WORK_DIR\t\tWorking directory\n"
+ "\t-f DATA_FILE\t\tDat file with job hierarchy info\n"
+ "\t-k KEY\t\t\tKey host_name:volume_name\n"
+ "\t-p PREVIOUS_JOB\t\tPrevious job\n"
+ "\t-j CURRENT_JOB\t\tCurrent job\n"
+ "\t-l {F,I,D}\t\tLevel {(F)ull, (D)ifferential, (I)ncremental}\n"
+ "\t-D DATA\t\t\tData\n"
+ "\t-d DEBUG_LEVEL\t\tDebug-level\n"
+ "\t-s\t\t\tStore-mode\n"
+ "\t-S\t\t\tSearch-mode\n"
+ "\t-L\t\t\tUse file lock\n"
+ "\t-h\t\t\tDisplay this text\n\n");
exit(EXIT_SUCCESS);
}
// Check for correctly initialized variables
// Prev job can eventually be NULL
if (working_directory == NULL) {
- printf("Working directory not set EXIT\n");
+ Dmsg(NULL, CRITICAL_LEVEL, "Working directory not set EXIT\n");
exit(EXIT_FAILURE);
}
// Check if data_file has been initilaized
if (dat_file == NULL) {
- printf("Data file not set EXIT\n");
+ Dmsg(NULL, CRITICAL_LEVEL, "Data file not set EXIT\n");
exit(EXIT_FAILURE);
}
// Check that current job is not null
if (curr_job == NULL) {
- printf("Current job not sell EXIT\n");
+ Dmsg(NULL, CRITICAL_LEVEL, "Current job not sell EXIT\n");
exit(EXIT_FAILURE);
}
// Check if key = either F/I/D
if (level != 'F' && level != 'I' && level != 'D') {
- printf("Bad key has to be either F/I/D\n");
+ Dmsg(NULL, CRITICAL_LEVEL, "Bad key has to be either F/I/D\n");
exit(EXIT_FAILURE);
}
// Check if there is a search and or store to do
if (!is_store && !is_search) {
- printf("Store or search not called. Nothing to do EXIT\n");
+ Dmsg(NULL, CRITICAL_LEVEL, "Store or search not called. Nothing to do EXIT\n");
exit(EXIT_SUCCESS);
}
+ // If -L is passed try to acquiere lock
+ if (use_lock) {
+ lock_return = create_lock_file(lock_name, PROG_NAME, lock_name, &lock_poolmem, &lock_fd);
+ }
+
+ // If fail to acquiere lock wait and retry
+ if (lock_return != 1) {
+ Dmsg(NULL, STANDARD_LEVEL, "Fail to acquire lock retry\n");
+ bmicrosleep(RETRY_LOCK, 0);
+ lock_return = create_lock_file(lock_name, PROG_NAME, lock_name, &lock_poolmem, &lock_fd);
+
+ // IF lock fail once again just abort
+ if (lock_return != 1) {
+ Dmsg(NULL, CRITICAL_LEVEL, "Fail to acquire lock twice EXIT\n");
+ exit(EXIT_FAILURE);
+ }
+
+ }
+
joblist job_history(NULL, key, curr_job, prev_job, level); // context can be null
job_history.set_base(dat_file);
job_history.prune_jobs(NULL, NULL, &tmp_list); // retrun void
// print all deletable jobs
- char *buf;
- foreach_alist(buf, &tmp_list) {
- printf("%s\n", buf);
+ foreach_alist(to_delete_job, &tmp_list) {
+ Dmsg(NULL, ALWAYS_LEVEL, "%s\n", to_delete_job);
}
}
if (is_search) {
- search_return = job_history.find_job(curr_job, &tmp); // return bool
- printf("Search out %s\n", tmp);
+ search_return = job_history.find_job(curr_job, pool_mem.handle()); // Return bool
+ Dmsg(NULL, ALWAYS_LEVEL, "%s\n", pool_mem.c_str());
}
+ // Unlock file and close
+ //lock_ret = fcntl_lock(dat_file_fd, F_UNLCK);
+ //fclose(dat_file_ptr);
+
// Check that search/store op returned correctly (true if not called)
- if (store_return && search_return) {
+ if (store_return && search_return && lock_return == 1) {
exit(EXIT_SUCCESS);
} else {
- printf("Store return : %d, Search return %d\n", store_return, search_return);
+ Dmsg(NULL, CRITICAL_LEVEL, "Store return : %d, Search return %d Lock return : %d\n",
+ store_return, search_return, lock_return);
+
exit(EXIT_FAILURE);
}
}
bjoblist=${bin}/bjoblist
+result_file=$(mktemp)
+
# Various key setup
key1="netapp:/vol/vol1"
-key2="netapp:/vol/vol2"
-key3="netapp:/vol/vol2xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
-key4="netapp:/vol/vol2xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxz"
#vVarious data setup
data1="ID=704ba403-fa5d-45f9-8681-859eec950723 DATE=1:15f18c5c-3824-40d2-8843-e6d161f77504:15f18c5c-3824-40d2-8843-e6d161f77504"
jobD="Test1.2020-03-12_09.45.31_27"
jobI3="Test1.2020-03-12_09.45.31_28"
-#vData file
+# Data file
data_file="nutanixfiler.dat"
# Working dir
-working_dir="/opt/bacula/working"
+working_dir="/tmp"
+
+start_test
+
+estat=0
+
+# Store jobF with key 1
+print_debug "Store jobF"
+"$bjoblist" -w "$working_dir" -f "$data_file" -k "$key1" -j "$jobF" -l F -D "$data1" -s -L > /dev/null
+
+# See if jobF is stored
+print_debug "Search jobF"
+"$bjoblist" -w "$working_dir" -f "$data_file" -k "$key1" -j "$jobF" -l F -D "$data1" -S > "$result_file"
+grep -e "$data1" "$result_file" > /dev/null
+
+if [ $? != 0 ]; then
+ print_debug "Did not found jobF"
+ $estat=1
+fi
+
+# Empty tmp file
+> "$result_file"
+
+# Store jobI
+print_debug "Store jobI"
+"$bjoblist" -w "$working_dir" -f "$data_file" -k "$key1" -j "$jobI" -p "$jobF" -l I -D "$data2" -s -L > /dev/null
+
+# See if jobI is stored
+print_debug "Search jobI"
+"$bjoblist" -w "$working_dir" -f "$data_file" -k "$key1" -j "$jobI" -l I -D "$data2" -S > "$result_file"
+grep -e "$data2" "$result_file" > /dev/null
+
+if [ $? != 0 ]; then
+ print_debug "Did not find jobI"
+ $estat=1
+fi
+
+# Empty file
+> "$result_file"
+
+# Store jobI2
+print_debug "Store jobI2"
+"$bjoblist" -w "$working_dir" -f "$data_file" -k "$key1" -j "$jobI2" -p "$jobI" -l I -D "$data3" -s -L > /dev/null
+
+# Store jobD
+print_debug "Store jobD"
+"$bjoblist" -w "$working_dir" -f "$data_file" -k "$key1" -j "$jobD" -p "$jobF" -l D -D "$data4" -s -L > /dev/null
+
+# Store job I3 from jobD
+print_debug "Store jobI3"
+"$bjoblist" -w "$working_dir" -f "$data_file" -k "$key1" -j "$jobI3" -p "$jobD" -l I -D "$data5" -s > "$result_file"
+grep -e "$data2" -e "$data3" "$result_file" > /dev/null
+
+if [ $? != 0 ]; then
+ print_debug "Did not received jobI and jobI2 to delete"
+ $estat=1
+fi
+
+# Empty file
+> "$result_file"
+
+# Search jobD
+print_debug "Search jobD"
+"$bjoblist" -w "$working_dir" -f "$data_file" -k "$key1" -j "$jobD" -l D -D "$data4" -S > "$result_file"
+grep -e "$data4" "$result_file" > /dev/null
+
+if [ $? != 0 ]; then
+ print_debug "Error file job differential not found"
+ $estat=1
+fi
+
+# Empty file
+> "$result_file"
+
+# Search jobI2
+print_debug "Search jobI2"
+"$bjoblist" -w "$working_dir" -f "$data_file" -k "$key1" -j "$jobI2" -l I -D "$data3" -S > "$result_file"
+grep -e "$data3" "$result_file" > /dev/null
+
+if [ $? == 0 ]; then
+ print_debug "Error found file that should be deleted"
+ $estat=1
+fi
+
+# Empty file
+> "$result_file"
-"$bjoblist" -h
+# Search jobI3
+print_debug "Search jobI3"
+"$bjoblist" -w "$working_dir" -f "$data_file" -k "$key1" -j "$jobI3" -l I -D "$data5" -S > "$result_file"
+grep -e "$data5" "$result_file" > /dev/null
+if [ $? != 0 ]; then
+ print_debug "Error file incremental job 3 not found"
+ $estat=1
+fi
-exit 1
+rm "$data_file"
+rm "$result_file"
+end_test