~drizzle-trunk/drizzle/development

1548.2.1 by Barry.Leslie at PrimeBase
Added the PBMS daemon plugin.
1
/* Copyright (c) 2009 PrimeBase Technologies GmbH, Germany
2
 *
3
 * PrimeBase Media Stream for MySQL
4
 *
5
 * This program is free software; you can redistribute it and/or modify
6
 * it under the terms of the GNU General Public License as published by
7
 * the Free Software Foundation; either version 2 of the License, or
8
 * (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
 *
19
 * Barry Leslie
20
 *
21
 * System dump table.
22
 *
23
 */
1548.2.2 by Barry.Leslie at PrimeBase
A lot of minor changes to clean up the code and to get it to build with Drizzle.
24
#ifdef DRIZZLED
25
#include "config.h"
26
#include <drizzled/common.h>
27
#include <drizzled/session.h>
28
#include <drizzled/field/blob.h>
29
#endif
30
31
#include "cslib/CSConfig.h"
1548.2.1 by Barry.Leslie at PrimeBase
Added the PBMS daemon plugin.
32
33
#include <sys/types.h>
34
#include <sys/stat.h>
35
#include <stdlib.h>
36
#include <time.h>
37
38
39
//#include "mysql_priv.h"
1548.2.2 by Barry.Leslie at PrimeBase
A lot of minor changes to clean up the code and to get it to build with Drizzle.
40
#include "cslib/CSGlobal.h"
41
#include "cslib/CSStrUtil.h"
1548.2.1 by Barry.Leslie at PrimeBase
Added the PBMS daemon plugin.
42
43
#include "ha_pbms.h"
44
//#include <plugin.h>
45
1548.2.10 by Barry.Leslie at PrimeBase
Merge from trunk.
46
#include "mysql_ms.h"
47
#include "repository_ms.h"
48
#include "database_ms.h"
49
#include "compactor_ms.h"
50
#include "open_table_ms.h"
51
#include "discover_ms.h"
52
#include "transaction_ms.h"
53
#include "systab_variable_ms.h"
1548.2.1 by Barry.Leslie at PrimeBase
Added the PBMS daemon plugin.
54
#include "backup_ms.h"
55
56
1548.2.10 by Barry.Leslie at PrimeBase
Merge from trunk.
57
#include "systab_dump_ms.h"
1548.2.1 by Barry.Leslie at PrimeBase
Added the PBMS daemon plugin.
58
59
60
DT_FIELD_INFO pbms_dump_info[]=
61
{
62
	{"Data",			NULL, NULL, MYSQL_TYPE_LONG_BLOB,	&my_charset_bin,	NOT_NULL_FLAG,	"A BLOB repository record"},
63
	{NULL,NULL, NULL, MYSQL_TYPE_STRING,NULL, 0, NULL}
64
};
65
66
DT_KEY_INFO pbms_dump_keys[]=
67
{
68
	{NULL, 0, {NULL}}
69
};
70
71
72
/*
73
 * -------------------------------------------------------------------------
74
 * DUMP TABLE
75
 */
76
//-----------------------
77
MSDumpTable::MSDumpTable(MSSystemTableShare *share, TABLE *table):
78
	MSRepositoryTable(share, table)
79
{
80
}
81
82
//-----------------------
83
MSDumpTable::~MSDumpTable()
84
{
85
}
86
87
//-----------------------
88
void MSDumpTable::use()
89
{	
90
	dt_hasInfo = dt_hasCompleted = dt_haveCloudInfo = false;
91
	dt_headerSize = 0;
92
	
93
	// Suspend the transaction writer while the dump is running.
94
	MSTransactionManager::suspend(true);
95
96
	MSRepositoryTable::use();
97
}
98
99
//-----------------------
100
void MSDumpTable::unuse()
101
{
102
	MSBackupInfo *backupInfo;
103
	
104
	backupInfo = myShare->mySysDatabase->myBlobCloud->cl_getBackupInfo();
105
	if (backupInfo) {
106
		enter_();
107
		push_(backupInfo);
108
		myShare->mySysDatabase->myBlobCloud->cl_clearBackupInfo();
109
		if (backupInfo->isBackupRunning()) {
110
			if (dt_hasCompleted) 
111
				backupInfo->backupCompleted(RETAIN(myShare->mySysDatabase));
112
			else
113
				backupInfo->backupTerminated(RETAIN(myShare->mySysDatabase));
114
		}
115
		release_(backupInfo);
116
		outer_();
117
	}
118
	
119
	MSTransactionManager::resume();
120
	MSRepositoryTable::unuse();
121
}
122
123
//-----------------------
124
void MSDumpTable::seqScanInit()
125
{
126
	dt_hasInfo = dt_hasCompleted = false;
127
	return MSRepositoryTable::seqScanInit();
128
}
129
//-----------------------
130
bool MSDumpTable::seqScanNext(char *buf)
131
{
132
	if (!dt_hasInfo) {
133
		dt_hasInfo = true;
134
		return returnInfoRow(buf);
135
	}
136
	// Reset the position
137
	if (!MSRepositoryTable::seqScanNext(buf)) 
138
		dt_hasCompleted = true;
139
	
140
	return !dt_hasCompleted;
141
}
142
143
//-----------------------
144
bool MSDumpTable::returnDumpRow(char *record, uint64_t record_size, char *buf)
145
{
146
	TABLE		*table = mySQLTable;
147
	Field		*curr_field;
148
	byte		*save;
149
	MY_BITMAP	*save_write_set;
150
151
152
153
154
	/* ASSERT_COLUMN_MARKED_FOR_WRITE is failing when
155
	 * I use store()!??
156
	 * But I want to use it! :(
157
	 */
158
	save_write_set = table->write_set;
159
	table->write_set = NULL;
160
	memset(buf, 0xFF, table->s->null_bytes);
161
	
1548.2.11 by Barry.Leslie at PrimeBase
Removed libxml reqirement by using a home grown xml parser.
162
 	for (Field **field=GET_TABLE_FIELDS(table) ; *field ; field++) {
1548.2.1 by Barry.Leslie at PrimeBase
Added the PBMS daemon plugin.
163
 		curr_field = *field;
164
165
		save = curr_field->ptr;
166
#if MYSQL_VERSION_ID < 50114
167
		curr_field->ptr = (byte *) buf + curr_field->offset();
168
#else
1672.3.6 by Brian Aker
First pass in encapsulating row
169
		curr_field->ptr = (byte *) buf + curr_field->offset(curr_field->getTable()->getInsertRecord());
1548.2.1 by Barry.Leslie at PrimeBase
Added the PBMS daemon plugin.
170
#endif
171
		switch (curr_field->field_name[0]) {
172
			case 'D':
173
			case 'd':
174
				// Data         LONGBLOB
175
				ASSERT(strcmp(curr_field->field_name, "Data") == 0);
176
				if (record_size <= 0xFFFFFFF) {
177
					((Field_blob *) curr_field)->set_ptr(record_size, (byte *) record);
1548.2.2 by Barry.Leslie at PrimeBase
A lot of minor changes to clean up the code and to get it to build with Drizzle.
178
					setNotNullInRecord(curr_field, buf);
1548.2.1 by Barry.Leslie at PrimeBase
Added the PBMS daemon plugin.
179
				}
180
				break;
181
		}
182
		curr_field->ptr = save;
183
	}
184
185
	table->write_set = save_write_set;
186
	return true;
187
}
188
189
//-----------------------
190
bool MSDumpTable::returnRow(MSBlobHeadPtr blob, char *buf)
191
{
192
	uint64_t		record_size, blob_repo_size;
193
	uint16_t		ref_size, ref_count, refs = 0, table_refs = 0, header_size;
194
	uint8_t		blob_storage_type;
195
	MSRepoPointersRec	ptr;
196
	MSDatabase *myDB = myShare->mySysDatabase;
197
	enter_();
198
199
	// Reset the references for the BLOB and recreate
200
	// the temp log references.
201
	ref_count = CS_GET_DISK_2(blob->rb_ref_count_2);
202
	ref_size = CS_GET_DISK_1(blob->rb_ref_size_1);
203
204
	blob_storage_type = CS_GET_DISK_1(blob->rb_storage_type_1);
205
206
	header_size = CS_GET_DISK_2(blob->rb_head_size_2);
207
	blob_repo_size = CS_GET_DISK_6(blob->rb_blob_repo_size_6);
208
	
209
	iBlobBuffer->setLength(header_size);
210
	iRepoFile->read(iBlobBuffer->getBuffer(0), iRepoOffset, (size_t) header_size, header_size);
211
212
	// First check to see if the BLOB is referenced
213
	ptr.rp_chars = iBlobBuffer->getBuffer(0) + dt_headerSize;
214
	for (int count = 0; count < ref_count; count++) {
215
		int ref_type = CS_GET_DISK_2(ptr.rp_ref->rr_type_2);
216
		
217
		switch (ref_type) {
218
			case MS_BLOB_TABLE_REF:
219
				table_refs++;
220
				break;
221
				
222
			case MS_BLOB_FREE_REF:
223
			case MS_BLOB_DELETE_REF:
224
				break;
225
		
226
			default: // Assumed to be a MSRepoBlobRefRec.
227
				// Only committed references are backed up.
228
				if (IS_COMMITTED(CS_GET_DISK_8(ptr.rp_blob_ref->er_blob_ref_id_8))) {
229
					refs++;
230
				} else {
231
					CS_SET_DISK_2(ptr.rp_ref->rr_type_2, MS_BLOB_FREE_REF);
232
				}
233
				
234
				break;
235
		}
236
		
237
		ptr.rp_chars += ref_size;		
238
	}
239
	
240
	
241
	if (refs && table_refs) { // Unreferenced BLOBs are ignored.
242
		if (blob_storage_type == MS_CLOUD_STORAGE) {
243
			CloudKeyRec	cloud_key;
244
			MSRepoFile::getBlobKey(blob, &cloud_key);
245
			myDB->myBlobCloud->cl_backupBLOB(&cloud_key);
246
			record_size = header_size;
247
		} else {
248
			record_size = header_size + blob_repo_size;
249
			iBlobBuffer->setLength(record_size);
250
			iRepoFile->read(iBlobBuffer->getBuffer(header_size), iRepoOffset + header_size, (size_t) blob_repo_size, blob_repo_size);
251
		}
252
	} else {
253
		record_size = 0; // An empty record is returned for unreferenced BLOBs.
254
	}
255
256
257
	return returnDumpRow(iBlobBuffer->getBuffer(0), record_size, buf);
258
}
259
260
//-----------------------
261
#define INC_INFO_SPACE(i) record_size+=i; space-=i;ptr+=i;
262
#define MS_DUMP_MAGIC 0x5A74C1EB
263
typedef struct {
264
	CSDiskValue4 ti_table_id_4;
265
	char		 ti_name[1]; // variable length buffer
266
} TabInfoRec, *TabInfoPtr;
267
268
typedef struct {
269
	CSDiskValue4 di_magic_4;
270
	CSDiskValue2 di_header_size_2;
271
}	RepInfoRec, *RepInfoPtr;
272
273
// Repository DUMP info record format: 
274
// <Dump magic><BLOB header size><database ID><backup number><sysTables size><sysTables dump>[<table ID><table name>]...
275
bool MSDumpTable::returnInfoRow(char *buf)
276
{
277
	uint64_t		record_size = 0, space = 1024;
278
	char		*ptr;
279
	MSTable		*tab;
280
	uint32_t		space_needed, next_tab = 0, cloudRef, cloudbackupNo, backupRef;
281
	RepInfoPtr	rep_info;
282
	TabInfoPtr	tab_info;
283
	CSStringBuffer *sysTablesDump;
284
	MSBackupInfo *backupInfo;
285
	CSDiskData	d;
286
	enter_();
287
288
	// Setup the sysvar table with the cloud backup number then dump it.
289
	if (myShare->mySysDatabase->myBlobType == MS_CLOUD_STORAGE) {
290
		cloudbackupNo = myShare->mySysDatabase->myBlobCloud->cl_getNextBackupNumber();
291
		cloudRef = myShare->mySysDatabase->myBlobCloud->cl_getDefaultCloudRef();
292
	} else {
293
		// It is still possible that the database contains BLOBs in cloud storage
294
		// even if it isn't currently flaged to use cloud storage.
295
		cloudbackupNo = cloudRef = 0;
296
	}
297
298
	backupInfo = MSBackupInfo::startDump(RETAIN(myShare->mySysDatabase), cloudRef, cloudbackupNo);
299
	backupRef = backupInfo->getBackupRefId();
300
	myShare->mySysDatabase->myBlobCloud->cl_setBackupInfo(backupInfo);	
301
	
302
	dt_cloudbackupDBID = myShare->mySysDatabase->myDatabaseID;
303
	
1548.2.2 by Barry.Leslie at PrimeBase
A lot of minor changes to clean up the code and to get it to build with Drizzle.
304
	sysTablesDump = PBMSSystemTables::dumpSystemTables(RETAIN(myShare->mySysDatabase));
1548.2.1 by Barry.Leslie at PrimeBase
Added the PBMS daemon plugin.
305
	push_(sysTablesDump);
306
	
307
	iBlobBuffer->setLength(space + sysTablesDump->length() + 4 + 4);
308
	ptr = iBlobBuffer->getBuffer(0);
309
	rep_info = (RepInfoPtr) iBlobBuffer->getBuffer(0);
310
	dt_headerSize = sizeof(MSBlobHeadRec);
311
	
312
	
313
	CS_SET_DISK_4(rep_info->di_magic_4, MS_DUMP_MAGIC);
314
	CS_SET_DISK_2(rep_info->di_header_size_2, dt_headerSize);
315
	
316
	INC_INFO_SPACE(sizeof(RepInfoRec));
317
	
318
	d.rec_chars = ptr;
319
	CS_SET_DISK_4(d.int_val->val_4, dt_cloudbackupDBID);
320
	INC_INFO_SPACE(4);
321
	
322
	d.rec_chars = ptr;
323
	CS_SET_DISK_4(d.int_val->val_4, backupRef);
324
	INC_INFO_SPACE(4);
325
	
326
	// Add the system tables to the dump
327
	d.rec_chars = ptr;
328
	CS_SET_DISK_4(d.int_val->val_4, sysTablesDump->length());
329
	INC_INFO_SPACE(4);
330
	memcpy(ptr, sysTablesDump->getBuffer(0), sysTablesDump->length());
331
	INC_INFO_SPACE(sysTablesDump->length());
332
	sysTablesDump->release();
333
	sysTablesDump = NULL;
334
			
335
	tab_info = (TabInfoPtr)ptr;
336
	
337
	// Get a list of the tables containing BLOB references. 
338
	while ((tab = myShare->mySysDatabase->getNextTable(&next_tab))) {
339
		push_(tab);
340
		space_needed = tab->myTableName->length() + 5;
341
		if (space < space_needed) {
342
			space += 1024;
343
			iBlobBuffer->setLength(space);
344
			ptr = iBlobBuffer->getBuffer(0) + record_size;
345
		}
346
		
347
		tab_info = (TabInfoPtr)ptr;
348
		CS_SET_DISK_4(tab_info->ti_table_id_4, tab->myTableID);
349
		strcpy(tab_info->ti_name, tab->myTableName->getCString());
350
		INC_INFO_SPACE(space_needed);
351
		
352
		release_(tab);
353
	}
354
	
355
	return_(returnDumpRow(iBlobBuffer->getBuffer(0), record_size, buf));
356
}
357
358
#define INC_INFO_REC(i) info_buffer+=i; length-=i; tab_info = (TabInfoPtr) info_buffer;
359
//-----------------------
360
void MSDumpTable::setUpRepository(const char *info_buffer, uint32_t length)
361
{
362
	uint32_t tab_id, magic;
363
	MSDatabase *myDB = myShare->mySysDatabase;
364
	RepInfoPtr	rep_info = (RepInfoPtr) info_buffer;
365
	TabInfoPtr	tab_info;
366
	uint32_t		sys_size, backupRefID;
367
	MSBackupInfo *backupInfo;	
368
	CSDiskData	d;
369
	
370
	if (length < sizeof(RepInfoRec)) {
371
		CSException::throwException(CS_CONTEXT, CS_ERR_INVALID_RECORD, "Invalid repository info record.");
372
	}
373
374
	magic = CS_GET_DISK_4(rep_info->di_magic_4);
375
	if (CS_GET_DISK_4(rep_info->di_magic_4) != MS_DUMP_MAGIC) {
376
		CSException::throwException(CS_CONTEXT, CS_ERR_BAD_HEADER_MAGIC, "Invalid repository info record.");
377
	}
378
	
379
	dt_headerSize = CS_GET_DISK_2(rep_info->di_header_size_2);
380
	INC_INFO_REC(sizeof(RepInfoRec));
381
	
382
	d.rec_cchars = info_buffer;
383
	dt_cloudbackupDBID = CS_GET_DISK_4(d.int_val->val_4);
384
	INC_INFO_REC(4);
385
	
386
	// Get the backup information
387
	d.rec_cchars = info_buffer;
388
	backupRefID = CS_GET_DISK_4(d.int_val->val_4);
389
	INC_INFO_REC(4);
390
	
391
	// If the backup information is missing then the restore may still
392
	// be able to complete so long as cloud storage was not used.
393
	backupInfo = MSBackupInfo::findBackupInfo(backupRefID);
394
	if (backupInfo)  {
395
		myShare->mySysDatabase->myBlobCloud->cl_setBackupInfo(backupInfo);
396
		dt_haveCloudInfo = true;
397
	}
398
	
399
	// Restore the System table.
400
	d.rec_cchars = info_buffer;
401
	sys_size = CS_GET_DISK_4(d.int_val->val_4);
402
	INC_INFO_REC(4);
403
	
1548.2.2 by Barry.Leslie at PrimeBase
A lot of minor changes to clean up the code and to get it to build with Drizzle.
404
	PBMSSystemTables::restoreSystemTables(RETAIN(myDB), info_buffer, sys_size);
1548.2.1 by Barry.Leslie at PrimeBase
Added the PBMS daemon plugin.
405
	INC_INFO_REC(sys_size);
406
407
	while (length > 5) {
408
		tab_id = CS_GET_DISK_4(tab_info->ti_table_id_4);
409
		myDB->addTable(tab_id, tab_info->ti_name, 0, false);
410
		INC_INFO_REC(strlen(tab_info->ti_name) +5);
411
	}
412
	
413
	if (length)
414
		CSException::throwException(CS_CONTEXT, CS_ERR_INVALID_RECORD, "Invalid repository info record.");		
415
}
416
417
418
//-----------------------
419
void MSDumpTable::insertRow(char *buf)
420
{	
421
	TABLE	*table = mySQLTable;
422
	Field_blob *field;
423
	uint32_t packlength, length;
424
	const char *blob_rec, *blob_ptr;
425
	
1548.2.11 by Barry.Leslie at PrimeBase
Removed libxml reqirement by using a home grown xml parser.
426
	field = (Field_blob *)GET_FIELD(table, 0);
1548.2.1 by Barry.Leslie at PrimeBase
Added the PBMS daemon plugin.
427
	
428
    /* Get the blob record: */
1672.3.6 by Brian Aker
First pass in encapsulating row
429
    blob_rec= buf + field->offset(table->getInsertRecord());
1548.2.1 by Barry.Leslie at PrimeBase
Added the PBMS daemon plugin.
430
    packlength= field->pack_length() - table->s->blob_ptr_size;
431
432
    memcpy(&blob_ptr, blob_rec +packlength, sizeof(char*));
433
    length= field->get_length();
434
	
435
	if (!dt_hasInfo) {
436
		setUpRepository(blob_ptr, length);
437
		dt_hasInfo = true;
438
	} else
439
		insertRepoRow((MSBlobHeadPtr)blob_ptr, length);
440
	
441
}
442
443
//-----------------------
444
void MSDumpTable::insertRepoRow(MSBlobHeadPtr blob, uint32_t length)
445
{	
446
	MSRepository *repo;
447
	MSRepoFile *repo_file;
448
	uint64_t		repo_offset;
449
	uint64_t		blob_data_size;
450
	uint32_t		auth_code;
451
	uint16_t ref_size, ref_count, refs = 0, table_refs = 0;
452
	uint8_t		blob_storage_type;
453
	MSRepoPointersRec	ptr;
454
	MSDatabase *myDB = myShare->mySysDatabase;
455
	CloudKeyRec	cloud_key;
456
	enter_();
457
458
	if (!length)
459
		exit_();
460
	
461
	if (length != (CS_GET_DISK_2(blob->rb_head_size_2) + CS_GET_DISK_6(blob->rb_blob_repo_size_6))) {
462
		CSException::throwException(CS_CONTEXT, MS_ERR_INVALID_RECORD, "Damaged Repository record");
463
	}
464
	
465
	// Get a repository file.
466
	repo = myDB->lockRepo(length);
467
	frompool_(repo);
468
	
469
	repo_file = myDB->getRepoFileFromPool(repo->myRepoID, false);
470
	frompool_(repo_file);
471
472
	repo_offset = repo->myRepoFileSize;
473
	
474
	// Reset the references for the BLOB and recreate
475
	// the temp log references.
476
	auth_code = CS_GET_DISK_4(blob->rb_auth_code_4);
477
	ref_count = CS_GET_DISK_2(blob->rb_ref_count_2);
478
	ref_size = CS_GET_DISK_1(blob->rb_ref_size_1);
479
	blob_data_size = CS_GET_DISK_6(blob->rb_blob_data_size_6);
480
481
	blob_storage_type = CS_GET_DISK_1(blob->rb_storage_type_1);
482
	if (blob_storage_type == MS_CLOUD_STORAGE) {
483
		MSRepoFile::getBlobKey(blob, &cloud_key);
484
	}
485
486
	// First check to see if the BLOB is referenced
487
	ptr.rp_chars = ((char*) blob) + dt_headerSize;
488
	for (int count = 0; count < ref_count; count++) {
489
		int ref_type = CS_GET_DISK_2(ptr.rp_ref->rr_type_2);
490
		
491
		switch (ref_type) {
492
			case MS_BLOB_TABLE_REF:
493
				table_refs++;
494
				break;
495
				
496
			case MS_BLOB_FREE_REF:
497
			case MS_BLOB_DELETE_REF:
498
				break;
499
		
500
			default: // Assumed to be a MSRepoBlobRefRec.
501
				// Only committed references are backed up.
502
				if (IS_COMMITTED(CS_GET_DISK_8(ptr.rp_blob_ref->er_blob_ref_id_8))) {
503
					refs++;
504
				} else {
505
					CS_SET_DISK_2(ptr.rp_ref->rr_type_2, MS_BLOB_FREE_REF);
506
				}
507
				
508
				break;
509
		}
510
		
511
		ptr.rp_chars += ref_size;		
512
	}
513
	
514
	
515
	if (refs && table_refs) { // Unreferenced BLOBs are ignored.
516
	
517
	
518
		// Set table references.
519
		ptr.rp_chars = ((char*) blob) + dt_headerSize;
520
		for (int count = 0; count < ref_count; count++) {
521
			int ref_type = CS_GET_DISK_2(ptr.rp_ref->rr_type_2);
522
			MSOpenTable	*otab;
523
			uint32_t		tab_id;
524
			uint64_t		blob_id;
525
			
526
			switch (ref_type) {
527
				case MS_BLOB_TABLE_REF:
528
					tab_id = CS_GET_DISK_4(ptr.rp_tab_ref->tr_table_id_4);
529
					blob_id = CS_GET_DISK_6(ptr.rp_tab_ref->tr_blob_id_6);
530
					otab = MSTableList::getOpenTableByID(myDB->myDatabaseID, tab_id);
531
			
532
					frompool_(otab);
533
					otab->getDBTable()->setBlobHandle(otab, blob_id, repo->myRepoID, repo_offset, blob_data_size, dt_headerSize, auth_code);
534
					backtopool_(otab);
535
					break;
536
					
537
				case MS_BLOB_DELETE_REF:
538
					break;
539
								
540
				case MS_BLOB_FREE_REF:
541
				default: 
542
					break;
543
			}
544
				
545
			ptr.rp_chars += ref_size;		
546
		}	
547
	
548
		// Write the repository record.
549
		repo_file->write(blob, repo_offset, length);
550
		repo->myRepoFileSize += length;
551
		
552
#ifdef HAVE_ALIAS_SUPPORT
553
		uint16_t alias_offset;
554
		if (alias_offset = CS_GET_DISK_2(blob->rb_alias_offset_2)) { 
555
			myDB->registerBlobAlias(repo->myRepoID, repo_offset, ((char*)blob) + alias_offset);
556
		}
557
#endif		
558
		if (blob_storage_type == MS_CLOUD_STORAGE) {
559
			if (!dt_haveCloudInfo) {
560
				CSException::throwException(CS_CONTEXT, MS_ERR_MISSING_CLOUD_REFFERENCE, "Missing cloud backup information.");
561
			}
562
			myDB->myBlobCloud->cl_restoreBLOB(&cloud_key, dt_cloudbackupDBID);
563
		}
564
	}
565
566
	backtopool_(repo_file);
567
	backtopool_(repo);
568
	exit_();
569
}
570
571
572