X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=bacula%2Fsrc%2Fstored%2Ffd_cmds.c;h=8c798a436de9bc1e442ac8e29c117c86b3877267;hb=9cdeafde391bd0c57693398f3b9eac9404892f1b;hp=91714180ab2076fc510a6cea8ba58f6bc8bbd660;hpb=3a5e17c3fb18038b3590abb48e4d47c3c1031e34;p=bacula%2Fbacula diff --git a/bacula/src/stored/fd_cmds.c b/bacula/src/stored/fd_cmds.c index 91714180ab..8c798a436d 100644 --- a/bacula/src/stored/fd_cmds.c +++ b/bacula/src/stored/fd_cmds.c @@ -1,17 +1,19 @@ /* * This file handles commands from the File daemon. * + * Kern Sibbald, MM + * * We get here because the Director has initiated a Job with * the Storage daemon, then done the same with the File daemon, * then when the Storage daemon receives a proper connection from - * the File daemon, control is passed here to handle the + * the File daemon, control is passed here to handle the * subsequent File daemon commands. * * Version $Id$ - * + * */ /* - Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker + Copyright (C) 2000-2005 Kern Sibbald This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -40,28 +42,27 @@ extern STORES *me; static char ferrmsg[] = "3900 Invalid command\n"; /* Imported functions */ -extern int do_append_data(JCR *jcr); -extern int do_read_data(JCR *jcr); - -/* Forward referenced functions */ - +extern bool do_append_data(JCR *jcr); +extern bool do_read_data(JCR *jcr); /* Forward referenced FD commands */ -static int append_open_session(JCR *jcr); -static int append_close_session(JCR *jcr); -static int append_data_cmd(JCR *jcr); -static int append_end_session(JCR *jcr); -static int read_open_session(JCR *jcr); -static int read_data_cmd(JCR *jcr); -static int read_close_session(JCR *jcr); -static int bootstrap_cmd(JCR *jcr); +static bool append_open_session(JCR *jcr); +static bool append_close_session(JCR *jcr); +static bool append_data_cmd(JCR *jcr); +static bool append_end_session(JCR *jcr); +static bool read_open_session(JCR *jcr); +static bool read_data_cmd(JCR *jcr); +static bool read_close_session(JCR *jcr); + +/* Exported function */ +bool bootstrap_cmd(JCR *jcr); struct s_cmds { - char *cmd; - int (*func)(JCR *jcr); + const char *cmd; + bool (*func)(JCR *jcr); }; -/* +/* * The following are the recognized commands from the File daemon */ static struct s_cmds fd_cmds[] = { @@ -73,17 +74,17 @@ static struct s_cmds fd_cmds[] = { {"read data", read_data_cmd}, {"read close", read_close_session}, {"bootstrap", bootstrap_cmd}, - {NULL, NULL} /* list terminator */ + {NULL, NULL} /* list terminator */ }; /* Commands from the File daemon that require additional scanning */ -static char read_open[] = "read open session = %s %ld %ld %ld %ld %ld %ld\n"; +static char read_open[] = "read open session = %127s %ld %ld %ld %ld %ld %ld\n"; /* Responses sent to the File daemon */ static char NO_open[] = "3901 Error session already open\n"; static char NOT_opened[] = "3902 Error session not opened\n"; static char OK_end[] = "3000 OK end\n"; -static char OK_close[] = "3000 OK close Volumes = %d\n"; +static char OK_close[] = "3000 OK close Status = %d\n"; static char OK_open[] = "3000 OK open ticket = %d\n"; static char OK_append[] = "3000 OK append data\n"; static char ERROR_append[] = "3903 Error append data\n"; @@ -92,7 +93,7 @@ static char ERROR_bootstrap[] = "3904 Error bootstrap\n"; /* Information sent to the Director */ static char Job_start[] = "3010 Job %s start\n"; -static char Job_end[] = +static char Job_end[] = "3099 Job %s end JobStatus=%d JobFiles=%d JobBytes=%s\n"; /* @@ -105,231 +106,232 @@ static char Job_end[] = */ void run_job(JCR *jcr) { - int i, found, quit; + int i; + bool found, quit; BSOCK *fd = jcr->file_bsock; BSOCK *dir = jcr->dir_bsock; char ec1[30]; + fd->jcr = jcr; + dir->jcr = jcr; Dmsg1(120, "Start run Job=%s\n", jcr->Job); - bnet_fsend(dir, Job_start, jcr->Job); - time(&jcr->start_time); + bnet_fsend(dir, Job_start, jcr->Job); + jcr->start_time = time(NULL); jcr->run_time = jcr->start_time; - jcr->JobStatus = JS_Running; - dir_send_job_status(jcr); /* update director */ - for (quit=0; !quit;) { + set_jcr_job_status(jcr, JS_Running); + dir_send_job_status(jcr); /* update director */ + for (quit=false; !quit;) { + int stat; /* Read command coming from the File daemon */ - if (bnet_recv(fd) <= 0) { - break; /* connection terminated */ + stat = bnet_recv(fd); + if (is_bnet_stop(fd)) { /* hardeof or error */ + break; /* connection terminated */ + } + if (stat <= 0) { + continue; /* ignore signals and zero length msgs */ } Dmsg1(110, "msg); - found = 0; + found = false; for (i=0; fd_cmds[i].cmd; i++) { - if (strncmp(fd_cmds[i].cmd, fd->msg, strlen(fd_cmds[i].cmd)) == 0) { - found = 1; /* indicate command found */ - if (!fd_cmds[i].func(jcr)) { /* do command */ - jcr->JobStatus = JS_ErrorTerminated; - quit = 1; - } - break; - } + if (strncmp(fd_cmds[i].cmd, fd->msg, strlen(fd_cmds[i].cmd)) == 0) { + found = true; /* indicate command found */ + if (!fd_cmds[i].func(jcr)) { /* do command */ + set_jcr_job_status(jcr, JS_ErrorTerminated); + quit = true; + } + break; + } } - if (!found) { /* command not found */ + if (!found) { /* command not found */ Dmsg1(110, "msg); - bnet_fsend(fd, ferrmsg); - break; + bnet_fsend(fd, ferrmsg); + break; } } - time(&jcr->end_time); - if (!job_cancelled(jcr)) { - jcr->JobStatus = JS_Terminated; - } + bnet_sig(fd, BNET_TERMINATE); /* signal to FD job is done */ + jcr->end_time = time(NULL); + dequeue_messages(jcr); /* send any queued messages */ + set_jcr_job_status(jcr, JS_Terminated); + generate_daemon_event(jcr, "JobEnd"); bnet_fsend(dir, Job_end, jcr->Job, jcr->JobStatus, jcr->JobFiles, edit_uint64(jcr->JobBytes, ec1)); - - bnet_sig(dir, BNET_EOD); /* send EOD to Director daemon */ + bnet_sig(dir, BNET_EOD); /* send EOD to Director daemon */ return; } - + /* * Append Data command * Open Data Channel and receive Data for archiving * Write the Data to the archive device */ -static int append_data_cmd(JCR *jcr) +static bool append_data_cmd(JCR *jcr) { BSOCK *fd = jcr->file_bsock; Dmsg1(120, "Append data: %s", fd->msg); if (jcr->session_opened) { Dmsg1(110, "msg); + jcr->JobType = JT_BACKUP; if (do_append_data(jcr)) { - bnet_fsend(fd, OK_append); - jcr->JobType = JT_BACKUP; - return 1; + return bnet_fsend(fd, OK_append); } else { - bnet_fsend(fd, ERROR_append); - return 0; + bnet_suppress_error_messages(fd, 1); /* ignore errors at this point */ + bnet_fsend(fd, ERROR_append); } } else { bnet_fsend(fd, NOT_opened); - return 0; } + return false; } -static int append_end_session(JCR *jcr) +static bool append_end_session(JCR *jcr) { BSOCK *fd = jcr->file_bsock; Dmsg1(120, "storemsg); if (!jcr->session_opened) { bnet_fsend(fd, NOT_opened); - return 0; + return false; } + set_jcr_job_status(jcr, JS_Terminated); return bnet_fsend(fd, OK_end); } -/* +/* * Append Open session command * */ -static int append_open_session(JCR *jcr) +static bool append_open_session(JCR *jcr) { BSOCK *fd = jcr->file_bsock; Dmsg1(120, "Append open session: %s", fd->msg); if (jcr->session_opened) { bnet_fsend(fd, NO_open); - return 0; + return false; } - Dmsg1(110, "Append open session: %s\n", dev_name(jcr->device->dev)); - jcr->session_opened = TRUE; + jcr->session_opened = true; /* Send "Ticket" to File Daemon */ bnet_fsend(fd, OK_open, jcr->VolSessionId); Dmsg1(110, ">filed: %s", fd->msg); - return 1; + return true; } /* * Append Close session command - * Close the append session and send back Statistics - * (need to fix statistics) + * Close the append session and send back Statistics + * (need to fix statistics) */ -static int append_close_session(JCR *jcr) +static bool append_close_session(JCR *jcr) { BSOCK *fd = jcr->file_bsock; - Dmsg1(120, "msg); + Dmsg1(120, "msg); if (!jcr->session_opened) { bnet_fsend(fd, NOT_opened); - return 0; + return false; } /* Send final statistics to File daemon */ - bnet_fsend(fd, OK_close, jcr->NumVolumes); - Dmsg1(160, ">filed: %s\n", fd->msg); + bnet_fsend(fd, OK_close, jcr->JobStatus); + Dmsg1(120, ">filed: %s", fd->msg); - bnet_sig(fd, BNET_EOD); /* send EOD to File daemon */ - - Dmsg1(110, "Append close session: %s\n", dev_name(jcr->device->dev)); + bnet_sig(fd, BNET_EOD); /* send EOD to File daemon */ - if (jcr->JobStatus != JS_ErrorTerminated) { - jcr->JobStatus = JS_Terminated; - } - jcr->session_opened = FALSE; - return 1; + jcr->session_opened = false; + return true; } /* * Read Data command - * Open Data Channel, read the data from + * Open Data Channel, read the data from * the archive device and send to File * daemon. */ -static int read_data_cmd(JCR *jcr) +static bool read_data_cmd(JCR *jcr) { BSOCK *fd = jcr->file_bsock; - Dmsg1(120, "Read data: %s\n", fd->msg); + Dmsg1(120, "Read data: %s", fd->msg); if (jcr->session_opened) { Dmsg1(120, "msg); return do_read_data(jcr); } else { bnet_fsend(fd, NOT_opened); - return 0; + return false; } } -/* +/* * Read Open session command * * We need to scan for the parameters of the job * to be restored. */ -static int read_open_session(JCR *jcr) +static bool read_open_session(JCR *jcr) { BSOCK *fd = jcr->file_bsock; Dmsg1(120, "%s\n", fd->msg); if (jcr->session_opened) { bnet_fsend(fd, NO_open); - return 0; + return false; } - if (sscanf(fd->msg, read_open, jcr->VolumeName, &jcr->read_VolSessionId, - &jcr->read_VolSessionTime, &jcr->read_StartFile, &jcr->read_EndFile, - &jcr->read_StartBlock, &jcr->read_EndBlock) == 7) { + if (sscanf(fd->msg, read_open, jcr->read_dcr->VolumeName, &jcr->read_VolSessionId, + &jcr->read_VolSessionTime, &jcr->read_StartFile, &jcr->read_EndFile, + &jcr->read_StartBlock, &jcr->read_EndBlock) == 7) { if (jcr->session_opened) { - bnet_fsend(fd, NOT_opened); - return 0; + bnet_fsend(fd, NOT_opened); + return false; } Dmsg4(100, "read_open_session got: JobId=%d Vol=%s VolSessId=%ld VolSessT=%ld\n", - jcr->JobId, jcr->VolumeName, jcr->read_VolSessionId, - jcr->read_VolSessionTime); + jcr->JobId, jcr->read_dcr->VolumeName, jcr->read_VolSessionId, + jcr->read_VolSessionTime); Dmsg4(100, " StartF=%ld EndF=%ld StartB=%ld EndB=%ld\n", - jcr->read_StartFile, jcr->read_EndFile, jcr->read_StartBlock, - jcr->read_EndBlock); + jcr->read_StartFile, jcr->read_EndFile, jcr->read_StartBlock, + jcr->read_EndBlock); } - Dmsg1(110, "Read open session: %s\n", dev_name(jcr->device->dev)); - - jcr->session_opened = TRUE; + jcr->session_opened = true; jcr->JobType = JT_RESTORE; /* Send "Ticket" to File Daemon */ bnet_fsend(fd, OK_open, jcr->VolSessionId); Dmsg1(110, ">filed: %s", fd->msg); - return 1; + return true; } -static int bootstrap_cmd(JCR *jcr) +bool bootstrap_cmd(JCR *jcr) { BSOCK *fd = jcr->file_bsock; POOLMEM *fname = get_pool_memory(PM_FNAME); FILE *bs; + bool ok = false; if (jcr->RestoreBootstrap) { unlink(jcr->RestoreBootstrap); free_pool_memory(jcr->RestoreBootstrap); } - Mmsg(&fname, "%s/%s.%s.bootstrap", me->working_directory, me->hdr.name, + Mmsg(fname, "%s/%s.%s.bootstrap", me->working_directory, me->hdr.name, jcr->Job); Dmsg1(400, "bootstrap=%s\n", fname); jcr->RestoreBootstrap = fname; bs = fopen(fname, "a+"); /* create file */ if (!bs) { Jmsg(jcr, M_FATAL, 0, _("Could not create bootstrap file %s: ERR=%s\n"), - jcr->RestoreBootstrap, strerror(errno)); + jcr->RestoreBootstrap, strerror(errno)); goto bail_out; } - while (bnet_recv(fd) > 0) { - Dmsg1(400, "storedmsg); + while (bnet_recv(fd) >= 0) { + Dmsg1(400, "storedmsg); fputs(fd->msg, bs); } fclose(bs); @@ -339,39 +341,41 @@ static int bootstrap_cmd(JCR *jcr) goto bail_out; } if (debug_level > 20) { - dump_bsr(jcr->bsr); + dump_bsr(jcr->bsr, true); } - return bnet_fsend(fd, OK_bootstrap); + ok = true; bail_out: unlink(jcr->RestoreBootstrap); free_pool_memory(jcr->RestoreBootstrap); jcr->RestoreBootstrap = NULL; - bnet_fsend(fd, ERROR_bootstrap); - return 0; - + if (!ok) { + bnet_fsend(fd, ERROR_bootstrap); + return false; + } + return bnet_fsend(fd, OK_bootstrap); } /* * Read Close session command - * Close the read session + * Close the read session */ -static int read_close_session(JCR *jcr) +static bool read_close_session(JCR *jcr) { BSOCK *fd = jcr->file_bsock; Dmsg1(120, "Read close session: %s\n", fd->msg); if (!jcr->session_opened) { bnet_fsend(fd, NOT_opened); - return 0; + return false; } /* Send final statistics to File daemon */ bnet_fsend(fd, OK_close); Dmsg1(160, ">filed: %s\n", fd->msg); - bnet_sig(fd, BNET_EOD); /* send EOD to File daemon */ - - jcr->session_opened = FALSE; - return 1; + bnet_sig(fd, BNET_EOD); /* send EOD to File daemon */ + + jcr->session_opened = false; + return true; }