From dd2137256e781a6bd463c2ad2fa8491251022820 Mon Sep 17 00:00:00 2001 From: Kern Sibbald Date: Sun, 11 Apr 2010 17:24:52 +0200 Subject: [PATCH] Restore object now sent to FD --- bacula/src/dird/fd_cmds.c | 35 ++++++++++++++---- bacula/src/dird/restore.c | 24 ++++++------ bacula/src/filed/fd_plugins.c | 4 +- bacula/src/filed/job.c | 69 +++++++++++++++++++++++++++-------- bacula/src/filed/restore.c | 7 ++++ bacula/src/lib/bsock.c | 24 +++++++++--- 6 files changed, 120 insertions(+), 43 deletions(-) diff --git a/bacula/src/dird/fd_cmds.c b/bacula/src/dird/fd_cmds.c index 340ff606ff..a500840644 100644 --- a/bacula/src/dird/fd_cmds.c +++ b/bacula/src/dird/fd_cmds.c @@ -59,6 +59,7 @@ static char OKjob[] = "2000 OK Job"; static char OKlevel[] = "2000 OK level\n"; static char OKRunScript[] = "2000 OK RunScript\n"; static char OKRunBeforeNow[] = "2000 OK RunBeforeNow\n"; +static char OKRestoreObject[] = "2000 OK ObjectRestored\n"; /* Forward referenced functions */ static bool send_list_item(JCR *jcr, const char *code, char *item, BSOCK *fd); @@ -671,25 +672,37 @@ static int restore_object_handler(void *ctx, int num_fields, char **row) { JCR *jcr = (JCR *)ctx; BSOCK *fd; + POOLMEM *msg_save; fd = jcr->file_bsock; if (jcr->is_job_canceled()) { return 1; } - bash_spaces(row[2]); - bash_spaces(row[3]); - bash_spaces(row[6]); - fd->fsend("RestoreObject JobId=%s ObjLen=%s ObjInx=%s ObjType=%s FI=%s", + fd->fsend("restoreobject JobId=%s ObjLen=%s ObjInx=%s ObjType=%s FI=%s\n", row[0], row[3], row[6], row[7], row[8]); - Dmsg1(000, ">fd: %s\n", fd->msg); + + fd->fsend("%s", row[1]); /* send Fname */ +// Dmsg1(000, "Send obj: %s\n", fd->msg); + + fd->fsend("%s", row[2]); /* send Path */ +// Dmsg1(000, "Send obj: %s\n", fd->msg); + + msg_save = fd->msg; + fd->msg = row[4]; /* object */ + fd->msglen = str_to_uint64(row[3]); /* object length */ + fd->send(); /* send object */ +// Dmsg1(000, "Send obj: %s\n", fd->msg); + fd->msg = msg_save; + return 0; } bool send_restore_objects(JCR *jcr) { -// BSOCK *fd = jcr->file_bsock; POOL_MEM query(PM_MESSAGE); + BSOCK *fd; +// Dmsg0(000, "Enter send_restore_objects\n"); if (!jcr->JobIds || !jcr->JobIds[0]) { return true; } @@ -697,8 +710,16 @@ bool send_restore_objects(JCR *jcr) "PluginName,ObjectIndex,ObjectType,FileIndex " "FROM RestoreObject WHERE JobId IN (%s)", jcr->JobIds); - /* missing_handler is called for each file found */ + /* restore_object_handler is called for each file found */ db_sql_query(jcr->db, query.c_str(), restore_object_handler, (void *)jcr); +// Dmsg0(000, "All restore objects sent, looking for OKRestoreObject\n"); + fd = jcr->file_bsock; + fd->fsend("restoreobject end\n"); + if (!response(jcr, fd, OKRestoreObject, "RestoreObject", DISPLAY_ERROR)) { + Jmsg(jcr, M_FATAL, 0, _("RestoreObject failed.\n")); + return false; + } +// Dmsg0(000, "got for OKRestoreObject\n"); return true; } diff --git a/bacula/src/dird/restore.c b/bacula/src/dird/restore.c index bb4de4710c..ec40ef9f2f 100644 --- a/bacula/src/dird/restore.c +++ b/bacula/src/dird/restore.c @@ -308,12 +308,12 @@ static void close_bootstrap_file(struct bootstrap_info &info) */ bool restore_bootstrap(JCR *jcr) { - BSOCK *fd=NULL, *sd; - bool end_loop=false; - bool first_time=true; + BSOCK *fd = NULL; + BSOCK *sd; + bool first_time = true; struct bootstrap_info info; POOL_MEM restore_cmd(PM_MESSAGE); - bool ret=false; + bool ret = false; /* this command is used for each part */ build_restore_command(jcr, restore_cmd); @@ -323,7 +323,7 @@ bool restore_bootstrap(JCR *jcr) goto bail_out; } /* Read the bootstrap file */ - while (!end_loop && !feof(info.bs)) { + while (!feof(info.bs)) { select_rstore(jcr, info); @@ -399,15 +399,16 @@ bool restore_bootstrap(JCR *jcr) goto bail_out; } + /* Only pass "global" commands to the FD once */ if (first_time) { + first_time = false; if (!send_runscripts_commands(jcr)) { goto bail_out; } - first_time=false; - } - - if (!send_restore_objects(jcr)) { - goto bail_out; + if (!send_restore_objects(jcr)) { + Dmsg0(000, "FAIL: Send restore objects\n"); + goto bail_out; + } } fd->fsend("%s", restore_cmd.c_str()); @@ -417,8 +418,7 @@ bool restore_bootstrap(JCR *jcr) } if (jcr->FDVersion < 2) { /* Old FD */ - end_loop=true; /* we do only one loop */ - + break; /* we do only one loop */ } else { if (!response(jcr, fd, OKstoreend, "Store end", DISPLAY_ERROR)) { goto bail_out; diff --git a/bacula/src/filed/fd_plugins.c b/bacula/src/filed/fd_plugins.c index ca7aad1f2d..ec18c2ca60 100644 --- a/bacula/src/filed/fd_plugins.c +++ b/bacula/src/filed/fd_plugins.c @@ -481,6 +481,7 @@ int plugin_create_file(JCR *jcr, ATTR *attr, BFILE *bfd, int replace) if (!plugin || !plugin_ctx || !set_cmd_plugin(bfd, jcr) || jcr->is_job_canceled()) { return CF_ERROR; } + rp.pkt_size = sizeof(rp); rp.pkt_end = sizeof(rp); rp.stream = attr->stream; @@ -517,9 +518,6 @@ int plugin_create_file(JCR *jcr, ATTR *attr, BFILE *bfd, int replace) if (rp.create_status == CF_CREATED) { return rp.create_status; /* yes, no need to bopen */ } - if (rp.type == FT_RESTORE_FIRST) { - return CF_CREATED; - } flags = O_WRONLY | O_CREAT | O_TRUNC | O_BINARY; Dmsg0(dbglvl, "call bopen\n"); diff --git a/bacula/src/filed/job.c b/bacula/src/filed/job.c index 4fca924320..803a080285 100644 --- a/bacula/src/filed/job.c +++ b/bacula/src/filed/job.c @@ -88,7 +88,7 @@ static int runscript_cmd(JCR *jcr); static int runbefore_cmd(JCR *jcr); static int runafter_cmd(JCR *jcr); static int runbeforenow_cmd(JCR *jcr); -static int restoreobject_cmd(JCR *jcr); +static int restore_object_cmd(JCR *jcr); static void set_options(findFOPTS *fo, const char *opts); static void set_storage_auth_key(JCR *jcr, char *key); @@ -112,7 +112,7 @@ static struct s_cmds cmds[] = { {"fileset", fileset_cmd, 0}, {"JobId=", job_cmd, 0}, {"level = ", level_cmd, 0}, - {"restore", restore_cmd, 0}, + {"restore ", restore_cmd, 0}, {"endrestore", end_restore_cmd, 0}, {"session", session_cmd, 0}, {"status", status_cmd, 1}, @@ -125,7 +125,7 @@ static struct s_cmds cmds[] = { {"RunAfterJob", runafter_cmd, 0}, {"Run", runscript_cmd, 0}, {"accurate", accurate_cmd, 0}, - {"restoreobject", restoreobject_cmd, 0}, + {"restoreobject", restore_object_cmd, 0}, {NULL, NULL} /* list terminator */ }; @@ -137,7 +137,8 @@ static char sessioncmd[] = "session %127s %ld %ld %ld %ld %ld %ld\n"; static char restorecmd[] = "restore replace=%c prelinks=%d where=%s\n"; static char restorecmd1[] = "restore replace=%c prelinks=%d where=\n"; static char restorecmdR[] = "restore replace=%c prelinks=%d regexwhere=%s\n"; -static char restoreobjcmd[] = "RestoreObject JobId=%u ObjLen=%d ObjInx=%d ObjType=%d FI=%d"; +static char restoreobjcmd[] = "restoreobject JobId=%u ObjLen=%d ObjInx=%d ObjType=%d FI=%d\n"; +static char endrestoreobjectcmd[] = "restoreobject end\n"; static char verifycmd[] = "verify level=%30s"; static char estimatecmd[] = "estimate listing=%d"; static char runbefore[] = "RunBeforeJob %s"; @@ -168,6 +169,7 @@ static char OKRunBeforeNow[] = "2000 OK RunBeforeNow\n"; static char OKRunAfter[] = "2000 OK RunAfter\n"; static char OKRunScript[] = "2000 OK RunScript\n"; static char BADcmd[] = "2902 Bad %s\n"; +static char OKRestoreObject[] = "2000 OK ObjectRestored\n"; /* Responses received from Storage Daemon */ @@ -618,25 +620,56 @@ static int runscript_cmd(JCR *jcr) } -static int restoreobject_cmd(JCR *jcr) +static int restore_object_cmd(JCR *jcr) { BSOCK *dir = jcr->dir_bsock; POOLMEM *msg = get_memory(dir->msglen+1); uint32_t JobId; int32_t object_len, object_index, object_type, FileIndex; - Dmsg1(000, "restoreobject_cmd: %s", dir->msg); + Dmsg1(100, "Enter restoreobject_cmd: %s", dir->msg); + if (strcmp(dir->msg, endrestoreobjectcmd) == 0) { + free_memory(msg); + return dir->fsend(OKRestoreObject); + } + if (sscanf(dir->msg, restoreobjcmd, &JobId, &object_len, &object_index, &object_type, &FileIndex) != 5) { + Dmsg0(5, "Bad restore object command\n"); pm_strcpy(jcr->errmsg, dir->msg); Jmsg1(jcr, M_FATAL, 0, _("Bad RestoreObject command: %s\n"), jcr->errmsg); - dir->fsend(_("2909 Bad RestoreObject command.\n")); - free_memory(msg); - return 0; + goto bail_out; + } + +// Dmsg5(000, "Recv object: JobId=%u objlen=%d objinx=%d objtype=%d FI=%d\n", +// JobId, object_len, object_index, object_type, FileIndex); + /* Read Fname */ + if (dir->recv() < 0) { + goto bail_out; + } +// Dmsg2(000, "Recv Fname object: len=%d Fname=%s\n", dir->msglen, dir->msg); + + /* Read Path */ + if (dir->recv() < 0) { + goto bail_out; } - Dmsg5(000, "JobId=%u objlen=%d objinx=%d objtype=%d FI=%d\n", - JobId, object_len, object_index, object_type, FileIndex); +// Dmsg2(000, "Recv Path object: len=%d Path=%s\n", dir->msglen, dir->msg); + + /* Read Object */ + if (dir->recv() < 0) { + goto bail_out; + } +// Dmsg2(000, "Recv Object: len=%d Object=%s\n", dir->msglen, dir->msg); + + free_memory(msg); + Dmsg1(100, "Send: %s", OKRestoreObject); return 1; + +bail_out: + dir->fsend(_("2909 Bad RestoreObject command.\n")); + free_memory(msg); + return 0; + } @@ -1443,7 +1476,8 @@ static void set_storage_auth_key(JCR *jcr, char *key) return; } - /* We can be contacting multiple storage daemons. + /** + * We can be contacting multiple storage daemons. * So, make sure that any old jcr->store_bsock is cleaned up. */ if (jcr->store_bsock) { @@ -1456,7 +1490,8 @@ static void set_storage_auth_key(JCR *jcr, char *key) * So, make sure that any old jcr->sd_auth_key is cleaned up. */ if (jcr->sd_auth_key) { - /* If we already have a Authorization key, director can do multi + /* + * If we already have a Authorization key, director can do multi * storage restore */ Dmsg0(5, "set multi_restore=true\n"); @@ -1465,6 +1500,7 @@ static void set_storage_auth_key(JCR *jcr, char *key) } jcr->sd_auth_key = bstrdup(key); + Dmsg0(5, "set sd auth key\n"); } /** @@ -1846,7 +1882,7 @@ static int restore_cmd(JCR *jcr) /** * Scan WHERE (base directory for restore) from command */ - Dmsg0(150, "restore command\n"); + Dmsg0(100, "restore command\n"); #if defined(WIN32_VSS) /* TODO: this should be given from the director */ @@ -1958,7 +1994,7 @@ static int restore_cmd(JCR *jcr) * Send Close session command to Storage daemon */ sd->fsend(read_close, jcr->Ticket); - Dmsg1(130, "filed>stored: %s", sd->msg); + Dmsg1(100, "filed>stored: %s", sd->msg); bget_msg(sd); /* get OK */ @@ -1996,10 +2032,11 @@ bail_out: set_jcr_job_status(jcr, JS_ErrorTerminated); } - Dmsg0(130, "Done in job.c\n"); + Dmsg0(100, "Done in job.c\n"); int ret; if (jcr->multi_restore) { + Dmsg0(100, OKstoreend); dir->fsend(OKstoreend); ret = 1; /* we continue the loop, waiting for next part */ } else { diff --git a/bacula/src/filed/restore.c b/bacula/src/filed/restore.c index 1893fa551c..d4fffa5625 100644 --- a/bacula/src/filed/restore.c +++ b/bacula/src/filed/restore.c @@ -319,6 +319,13 @@ void do_restore(JCR *jcr) if (rctx.type == FT_DELETED) { /* deleted file */ continue; } + /* + * Restore objects should be ignored here -- they are + * returned at the beginning of the restore. + */ + if (rctx.type == FT_RESTORE_FIRST) { + continue; + } /* * Unpack attributes and do sanity check them diff --git a/bacula/src/lib/bsock.c b/bacula/src/lib/bsock.c index ade5eb678c..6447fcf5eb 100644 --- a/bacula/src/lib/bsock.c +++ b/bacula/src/lib/bsock.c @@ -334,15 +334,29 @@ bool BSOCK::send() int32_t *hdr; bool ok = true; - if (errors || is_terminated() || msglen > 1000000) { + if (errors) { if (!m_suppress_error_msgs) { - Qmsg6(m_jcr, M_ERROR, 0, - _("Socket has errors=%d; is_terminated=%d; or has insane msglen=%d on call to %s:%s:%d\n"), - errors, is_terminated(), msglen, m_who, - m_host, m_port); + Qmsg4(m_jcr, M_ERROR, 0, _("Socket has errors=%d on call to %s:%s:%d\n"), + errors, m_who, m_host, m_port); } return false; } + if (is_terminated()) { + if (!m_suppress_error_msgs) { + Qmsg4(m_jcr, M_ERROR, 0, _("Socket is terminated=%d on call to %s:%s:%d\n"), + is_terminated(), m_who, m_host, m_port); + } + return false; + } + if (msglen > 1000000) { + if (!m_suppress_error_msgs) { + Qmsg4(m_jcr, M_ERROR, 0, + _("Socket has insane msglen=%d on call to %s:%s:%d\n"), + msglen, m_who, m_host, m_port); + } + return false; + } + if (m_use_locking) P(m_mutex); /* Compute total packet length */ if (msglen <= 0) { -- 2.39.5