From 88ec863d5fb2a6d457a4af457eca398ee242dd48 Mon Sep 17 00:00:00 2001 From: Kern Sibbald Date: Fri, 9 Apr 2010 17:36:39 +0200 Subject: [PATCH] Create db_create_restore_object_record and code to insert it --- bacula/src/cats/cats.h | 15 +++++++++ bacula/src/cats/make_mysql_tables.in | 23 ++++++++++--- bacula/src/cats/protos.h | 1 + bacula/src/cats/sql_create.c | 50 ++++++++++++++++++++++++++-- bacula/src/dird/catreq.c | 38 +++++++++++++++++++-- 5 files changed, 118 insertions(+), 9 deletions(-) diff --git a/bacula/src/cats/cats.h b/bacula/src/cats/cats.h index 6058c56a3f..e1dce822fe 100644 --- a/bacula/src/cats/cats.h +++ b/bacula/src/cats/cats.h @@ -939,6 +939,21 @@ struct ATTR_DBR { int DigestType; }; +struct ROBJECT_DBR { + char *full_fname; + char *fname; + char *path; + char *plugin_name; + char *object; + uint32_t object_len; + uint32_t ObjectIndex; + uint32_t FileIndex; + uint32_t Stream; + uint32_t FileType; + JobId_t JobId; + DBId_t RestoreObjectId; +}; + /* File record -- same format as database */ struct FILE_DBR { diff --git a/bacula/src/cats/make_mysql_tables.in b/bacula/src/cats/make_mysql_tables.in index 37a10d235b..ef2efffa41 100644 --- a/bacula/src/cats/make_mysql_tables.in +++ b/bacula/src/cats/make_mysql_tables.in @@ -45,6 +45,21 @@ CREATE TABLE File ( INDEX (JobId, PathId, FilenameId) ); +CREATE TABLE RestoreObject ( + RestoreObjectId INTEGER UNSIGNED NOT NULL AUTO_INCREMENT; + Fname BLOB NOT NULL, + Path BLOB NOT NULL, + RestoreObject BLOB NOT NULL, + PluginName TINYBLOB NOT NULL, + ObjectIndex INTEGER DEFAULT 0, + ObjectType INTEGER DEFAULT 0, + FileIndex INTEGER UNSIGNED DEFAULT 0, + JobId INTEGER UNSIGNED NOT NULL REFERENCES Job, + PRIMARY KEY(RestoreObjectId), + INDEX (JobId) + ); + + # # Possibly add one or more of the following indexes # to the above File table if your Verifies are @@ -224,7 +239,7 @@ CREATE TABLE Media ( 'Read-Only', 'Disabled', 'Error', 'Busy', 'Used', 'Cleaning') NOT NULL, Enabled TINYINT DEFAULT 1, Recycle TINYINT DEFAULT 0, - ActionOnPurge TINYINT DEFAULT 0, + ActionOnPurge TINYINT DEFAULT 0, VolRetention BIGINT UNSIGNED DEFAULT 0, VolUseDuration BIGINT UNSIGNED DEFAULT 0, MaxVolJobs INTEGER UNSIGNED DEFAULT 0, @@ -264,7 +279,7 @@ CREATE TABLE Pool ( MaxVolBytes BIGINT UNSIGNED DEFAULT 0, AutoPrune TINYINT DEFAULT 0, Recycle TINYINT DEFAULT 0, - ActionOnPurge TINYINT DEFAULT 0, + ActionOnPurge TINYINT DEFAULT 0, PoolType ENUM('Backup', 'Copy', 'Cloned', 'Archive', 'Migration', 'Scratch') NOT NULL, LabelType TINYINT DEFAULT 0, LabelFormat TINYBLOB, @@ -375,7 +390,7 @@ CREATE TABLE PathHierarchy ); CREATE INDEX pathhierarchy_ppathid - ON PathHierarchy (PPathId); + ON PathHierarchy (PPathId); CREATE TABLE PathVisibility ( @@ -386,7 +401,7 @@ CREATE TABLE PathVisibility CONSTRAINT pathvisibility_pkey PRIMARY KEY (JobId, PathId) ); CREATE INDEX pathvisibility_jobid - ON PathVisibility (JobId); + ON PathVisibility (JobId); CREATE TABLE Version ( VersionId INTEGER UNSIGNED NOT NULL diff --git a/bacula/src/cats/protos.h b/bacula/src/cats/protos.h index 75753db356..35b8d84953 100644 --- a/bacula/src/cats/protos.h +++ b/bacula/src/cats/protos.h @@ -81,6 +81,7 @@ bool my_batch_start(JCR *jcr, B_DB *mdb); bool my_batch_end(JCR *jcr, B_DB *mdb, const char *error); bool my_batch_insert(JCR *jcr, B_DB *mdb, ATTR_DBR *ar); bool db_create_attributes_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar); +bool db_create_restore_object_record(JCR *jcr, B_DB *mdb, ROBJECT_DBR *ar); bool db_create_base_file_attributes_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar); bool db_commit_base_file_attributes_record(JCR *jcr, B_DB *mdb); bool db_create_base_file_list(JCR *jcr, B_DB *mdb, char *jobids); diff --git a/bacula/src/cats/sql_create.c b/bacula/src/cats/sql_create.c index 218725e5a8..877726670d 100644 --- a/bacula/src/cats/sql_create.c +++ b/bacula/src/cats/sql_create.c @@ -1,7 +1,7 @@ /* Bacula® - The Network Backup Solution - Copyright (C) 2000-2008 Free Software Foundation Europe e.V. + Copyright (C) 2000-2010 Free Software Foundation Europe e.V. The main author of Bacula is Kern Sibbald, with contributions from many others, a complete list can be found in the file AUTHORS. @@ -30,7 +30,6 @@ * * Kern Sibbald, March 2000 * - * Version $Id: sql_create.c 8407 2009-01-28 10:47:21Z ricozz $ */ /* The following is necessary so that we do not include @@ -1261,4 +1260,51 @@ bail_out: return ret; } + +/* + * Create Restore Object record in B_DB + * + */ +bool db_create_restore_object_record(JCR *jcr, B_DB *mdb, ROBJECT_DBR *ro) +{ + bool stat; + POOLMEM *esc_obj = get_pool_memory(PM_MESSAGE); + db_lock(mdb); + + Dmsg1(dbglevel, "Fname=%s\n", ro->fname); + Dmsg0(dbglevel, "put_object_into_catalog\n"); + + split_path_and_file(jcr, mdb, ro->fname); + + mdb->esc_name = check_pool_memory_size(mdb->esc_name, mdb->fnl*2+1); + db_escape_string(jcr, mdb, mdb->esc_name, mdb->fname, mdb->fnl); + + mdb->esc_path = check_pool_memory_size(mdb->esc_path, mdb->pnl*2+1); + db_escape_string(jcr, mdb, mdb->esc_path, mdb->path, mdb->pnl); + + esc_obj = check_pool_memory_size(esc_obj, ro->object_len*2+1); + db_escape_string(jcr, mdb, esc_obj, ro->object, ro->object_len); + + Mmsg(mdb->cmd, + "INSERT INTO RestoreObject (Fname,Path,PluginName,RestoreObject" + "ObjectIndex,ObjectType,FileIndex,JobId) VALUES" + "('%s','%s','%s','%s',%d,%d,%d,%u)", + ro->fname, ro->path, ro->plugin_name, esc_obj, ro->object_len, + ro->ObjectIndex, FT_RESTORE_FIRST, ro->FileIndex, ro->JobId); + + ro->RestoreObjectId = sql_insert_id(mdb, mdb->cmd, NT_("RestoreObject")); + if (ro->RestoreObjectId == 0) { + Mmsg2(&mdb->errmsg, _("Create db Object record %s failed. ERR=%s"), + mdb->cmd, sql_strerror(mdb)); + Jmsg(jcr, M_FATAL, 0, "%s", mdb->errmsg); + stat = false; + } else { + stat = true; + } + db_unlock(mdb); + free_pool_memory(esc_obj); + return stat; +} + + #endif /* HAVE_SQLITE3 || HAVE_MYSQL || HAVE_SQLITE || HAVE_POSTGRESQL || HAVE_INGRES || HAVE_DBI */ diff --git a/bacula/src/dird/catreq.c b/bacula/src/dird/catreq.c index 573a279520..7d9c2f452d 100644 --- a/bacula/src/dird/catreq.c +++ b/bacula/src/dird/catreq.c @@ -418,6 +418,7 @@ static void update_attribute(JCR *jcr, char *msg, int32_t msglen) if (!db_create_attributes_record(jcr, jcr->db, ar)) { Jmsg1(jcr, M_FATAL, 0, _("Attribute create error. %s"), db_strerror(jcr->db)); } + jcr->cached_attribute = false; } /* Any cached attr is flushed so we can reuse jcr->attr and jcr->ar */ jcr->attr = check_pool_memory_size(jcr->attr, msglen); @@ -448,9 +449,40 @@ static void update_attribute(JCR *jcr, char *msg, int32_t msglen) } else { ar->JobId = jcr->JobId; } - ar->Digest = NULL; - ar->DigestType = CRYPTO_DIGEST_NONE; - jcr->cached_attribute = true; + /* + * Restore object */ + if (ar->FileType == FT_RESTORE_FIRST) { + ROBJECT_DBR ro; + POOLMEM *attrEx = get_pool_memory(PM_MESSAGE); + char *p; + ro.full_fname = fname; + ro.Stream = Stream; + ro.FileType = ar->FileType; + ro.FileIndex = FileIndex; + ro.JobId = ar->JobId; + p = ar->attr; /* point to attributes */ + while (*p++ != 0) /* skip attributes */ + { } + while (*p++ != 0) /* skip link */ + { } + /* We have an object, so do a binary copy */ + ro.object_len = msglen + ar->attr - p; + attrEx = check_pool_memory_size(attrEx, ro.object_len + 1); + memcpy(attrEx, p, ro.object_len); + ro.object = attrEx; + /* Add a EOS for those who attempt to print the object */ + p = attrEx + ro.object_len; + *p = 0; + /* Send it */ + if (!db_create_restore_object_record(jcr, jcr->db, &ro)) { + Jmsg1(jcr, M_FATAL, 0, _("Restore object create error. %s"), db_strerror(jcr->db)); + } + free_pool_memory(attrEx); + } else { + ar->Digest = NULL; + ar->DigestType = CRYPTO_DIGEST_NONE; + jcr->cached_attribute = true; + } Dmsg2(400, "dird