Print this page
NEX-5801 Snapshots left over after failed backups
Reviewed by: Rick Mesta <rick.mesta@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Revert "NEX-5801 Snapshots left over after failed backups"
This reverts commit f182fb95f09036db71fbfc6f0a6b90469b761f21.
NEX-5801 Snapshots left over after failed backups
Reviewed by: Rick Mesta <rick.mesta@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
NEX-2911 NDMP logging should use syslog and is too chatty
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/cmd/ndmpd/include/tlm.h
+++ new/usr/src/cmd/ndmpd/include/tlm.h
1 1 /*
2 2 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
3 3 * Copyright (c) 2015 by Delphix. All rights reserved.
4 + * Copyright 2016 Nexenta Systems, Inc. All rights reserved.
4 5 */
5 6
6 7 /*
7 8 * BSD 3 Clause License
8 9 *
9 10 * Copyright (c) 2007, The Storage Networking Industry Association.
10 11 *
11 12 * Redistribution and use in source and binary forms, with or without
12 13 * modification, are permitted provided that the following conditions
13 14 * are met:
14 15 * - Redistributions of source code must retain the above copyright
15 16 * notice, this list of conditions and the following disclaimer.
16 17 *
17 18 * - Redistributions in binary form must reproduce the above copyright
18 19 * notice, this list of conditions and the following disclaimer in
19 20 * the documentation and/or other materials provided with the
20 21 * distribution.
21 22 *
22 23 * - Neither the name of The Storage Networking Industry Association (SNIA)
23 24 * nor the names of its contributors may be used to endorse or promote
24 25 * products derived from this software without specific prior written
25 26 * permission.
26 27 *
27 28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
28 29 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 30 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30 31 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
31 32 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32 33 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33 34 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34 35 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35 36 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36 37 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37 38 * POSSIBILITY OF SUCH DAMAGE.
38 39 */
39 40 #ifndef _TLM_H_
40 41 #define _TLM_H_
41 42
42 43 #include <sys/types.h>
43 44 #include <synch.h>
44 45 #include <limits.h>
45 46 #include <cstack.h>
46 47 #include <sys/acl.h>
47 48 #include <stdio.h>
48 49 #include <errno.h>
|
↓ open down ↓ |
35 lines elided |
↑ open up ↑ |
49 50 #include <fcntl.h>
50 51 #include <strings.h>
51 52 #include <sys/stat.h>
52 53 #include <time.h>
53 54 #include <sys/queue.h>
54 55 #include <sys/fs/zfs.h>
55 56 #include <libzfs.h>
56 57
57 58 #define IS_SET(f, m) (((f) & (m)) != 0)
58 59
59 -#define TLM_MAX_BACKUP_JOB_NAME 32 /* max size of a job's name */
60 +#define TLM_MAX_BACKUP_JOB_NAME 16 /* format is 'NdmpBackup.nnnn\0' */
60 61 #define TLM_TAPE_BUFFERS 10 /* number of rotating tape buffers */
61 62 #define TLM_LINE_SIZE 128 /* size of text messages */
62 63
63 64
64 65 #define TLM_BACKUP_RUN 0x00000001
65 66 #define TLM_RESTORE_RUN 0x00000002
66 67 #define TLM_STOP 0x00000009 /* graceful stop */
67 68 #define TLM_ABORT 0x99999999 /* abandon the run */
68 69
69 70 #define TLM_EXTRA_SPACE 64
70 71 #define TLM_MAX_PATH_NAME (PATH_MAX + TLM_EXTRA_SPACE)
71 72
72 73 #define ENTRYTYPELEN 14
73 74 #define PERMS 4
74 75 #define ID_STR_MAX 20
75 76 #define APPENDED_ID_MAX (ID_STR_MAX + 1)
76 77 #define ACL_ENTRY_SIZE (ENTRYTYPELEN + ID_STR_MAX + PERMS + APPENDED_ID_MAX)
77 78 #define TLM_MAX_ACL_TXT MAX_ACL_ENTRIES * ACL_ENTRY_SIZE
78 79
79 80
80 81 /* operation flags */
81 82 #define TLM_OP_CHOOSE_ARCHIVE 0x00000001 /* look for archive bit */
82 83
83 84 /*
84 85 * Synchronization flags used when launching the TLM threads.
85 86 */
86 87 #define TLM_TAPE_READER 0x00000001
87 88 #define TLM_TAPE_WRITER 0x00000002
88 89 #define TLM_SOCK_READER 0x00000004
89 90 #define TLM_SOCK_WRITER 0x00000008
90 91 #define TLM_BUF_READER 0x00000010
91 92 #define TLM_BUF_WRITER 0x00000020
92 93 #define TLM_TAR_READER 0x00000040
93 94 #define TLM_TAR_WRITER 0x00000080
94 95
95 96 #define SCSI_SERIAL_PAGE 0x80
96 97 #define SCSI_DEVICE_IDENT_PAGE 0x83
97 98 #define SCMD_READ_ELEMENT_STATUS 0xB8
98 99
99 100 #define OCTAL7CHAR 07777777
100 101 #define SYSATTR_RDONLY "SUNWattr_ro"
101 102 #define SYSATTR_RW "SUNWattr_rw"
102 103
103 104 typedef int (*func_t)();
104 105
105 106 typedef struct scsi_serial {
106 107 int sr_flags;
107 108 char sr_num[16];
108 109 } scsi_serial_t;
109 110
110 111 typedef struct fs_fhandle {
111 112 int fh_fid;
112 113 char *fh_fpath;
113 114 } fs_fhandle_t;
114 115
115 116 typedef struct scsi_link {
116 117 struct scsi_link *sl_next;
117 118 struct scsi_link *sl_prev;
118 119 struct scsi_adapter *sl_sa;
119 120 unsigned int sl_sid;
120 121 unsigned int sl_lun;
121 122 unsigned int sl_requested_max_active;
122 123 unsigned int sl_granted_max_active;
123 124 unsigned int sl_n_active;
124 125 unsigned int sl_type; /* SCSI device type */
125 126 } scsi_link_t;
126 127
127 128 typedef struct scsi_adapter {
128 129 struct scsi_adapter *sa_next;
129 130 char sa_name[16];
130 131 struct scsi_link sa_link_head;
131 132 } scsi_adapter_t;
132 133
133 134 typedef struct sasd_drive {
134 135 char sd_name[256];
135 136 char sd_vendor[8 + 1];
136 137 char sd_id[16 + 1];
137 138 char sd_rev[4 + 1];
138 139 char sd_serial[16 + 1];
139 140 char sd_wwn[32 + 1];
140 141 } sasd_drive_t;
141 142
142 143 typedef struct scsi_sasd_drive {
143 144 sasd_drive_t ss_sd;
144 145 scsi_link_t ss_slink;
145 146 } scsi_sasd_drive_t;
146 147
147 148
148 149 #define DEFAULT_SLINK_MAX_XFER (64*1024)
149 150
150 151 typedef struct tlm_info {
151 152 int ti_init_done; /* initialization done ? */
152 153 int ti_library_count; /* number of libraries */
153 154 struct tlm_library *ti_library; /* first in chain */
154 155 struct tlm_chain_link *ti_job_stats; /* chain of job statistics */
155 156 } tlm_info_t;
156 157
157 158 typedef struct tlm_chain_link {
158 159 struct tlm_chain_link *tc_next; /* next blob of statistics */
159 160 struct tlm_chain_link *tc_prev; /* previous blob in the chain */
160 161 int tc_ref_count; /* number of routines */
161 162 void *tc_data; /* the data blob */
162 163 } tlm_chain_link_t;
163 164
164 165 typedef struct tlm_robot {
165 166 struct tlm_robot *tr_next;
166 167 struct tlm_library *tr_library;
167 168 int tr_number;
168 169 } tlm_robot_t;
169 170
170 171 typedef struct tlm_drive {
171 172 struct tlm_drive *td_next;
172 173 struct tlm_library *td_library;
173 174 char td_job_name[TLM_MAX_BACKUP_JOB_NAME];
174 175 int td_number; /* number of this tape drive */
175 176 int td_element; /* the library's number for the drive */
176 177 struct scsi_link *td_slink; /* because the drive may be connected */
177 178 /* to a different SCSI card than the */
178 179 /* library */
179 180 short td_scsi_id;
180 181 short td_lun;
181 182 short td_volume_number; /* for current job */
182 183 /* an index into the tape set */
183 184 int td_fd; /* I/O file descriptor */
184 185 int td_errno; /* system error number */
185 186 long td_exists : 1;
186 187
187 188 } tlm_drive_t;
188 189
189 190 typedef struct tlm_slot {
190 191 struct tlm_slot *ts_next;
191 192 struct tlm_library *ts_library;
192 193 int ts_number; /* number of this slot */
193 194 int ts_element;
194 195 short ts_use_count; /* number of times used since loaded */
195 196 long ts_status_full : 1;
196 197 } tlm_slot_t;
197 198
198 199 typedef struct tlm_library {
199 200 struct tlm_library *tl_next;
200 201 int tl_number; /* number of this tape library */
201 202 long tl_capability_robot : 1,
202 203 tl_capability_door : 1,
203 204 tl_capability_lock : 1,
204 205 tl_capability_slots : 1,
205 206 tl_capability_export : 1,
206 207 tl_capability_drives : 1,
207 208 tl_capability_barcodes : 1,
208 209 tl_ghost_drives : 1;
209 210 /*
210 211 * "ghost_drives" is used to make sure that
211 212 * all drives claimed by the library really
212 213 * exist ... libraries have been known to lie.
213 214 */
214 215 struct scsi_link *tl_slink;
215 216
216 217 int tl_robot_count;
217 218 tlm_robot_t *tl_robot;
218 219 int tl_drive_count;
219 220 tlm_drive_t *tl_drive;
220 221 int tl_slot_count;
221 222 tlm_slot_t *tl_slot;
222 223 } tlm_library_t;
223 224
224 225 typedef struct {
225 226 #ifdef _BIG_ENDIAN
226 227 uint8_t di_peripheral_qual : 3,
227 228 di_peripheral_dev_type : 5;
228 229 uint8_t di_page_code;
229 230 uint16_t di_page_length;
230 231 #else
231 232 uint8_t di_peripheral_dev_type : 5,
232 233 di_peripheral_qual : 3;
233 234 uint8_t di_page_code;
234 235 uint16_t di_page_length;
235 236 #endif
236 237 } device_ident_header_t;
237 238
238 239 typedef struct {
239 240 #ifdef _BIG_ENDIAN
240 241 uint8_t ni_proto_ident : 4,
241 242 ni_code_set : 4;
242 243
243 244 uint8_t ni_PIV : 1,
244 245 : 1,
245 246 ni_asso : 2,
246 247 ni_ident_type : 4;
247 248
248 249 uint8_t ni_reserved;
249 250 uint8_t ni_ident_length;
250 251 #else
251 252 uint8_t ni_code_set : 4,
252 253 ni_proto_ident : 4;
253 254
254 255 uint8_t ni_ident_type : 4,
255 256 ni_asso : 2,
256 257 : 1,
257 258 ni_PIV : 1;
258 259 uint8_t ni_reserved;
259 260 uint8_t ni_ident_length;
260 261 #endif
261 262 } name_ident_t;
262 263
263 264 #define TLM_NO_ERRORS 0x00000000
264 265 #define TLM_ERROR_BUSY 0x00000001
265 266 #define TLM_ERROR_INTERNAL 0x00000002
266 267 #define TLM_ERROR_NO_ROBOTS 0x00000003
267 268 #define TLM_TIMEOUT 0x00000004
268 269 #define TLM_ERROR_RANGE 0x00000005
269 270 #define TLM_EMPTY 0x00000006
270 271 #define TLM_DRIVE_NOT_ASSIGNED 0x00000007
271 272 #define TLM_NO_TAPE_NAME 0x00000008
272 273 #define TLM_NO_BACKUP_DIR 0x00000009
273 274 #define TLM_NO_BACKUP_HARDWARE 0x0000000a
274 275 #define TLM_NO_SOURCE_FILE 0x0000000b
275 276 #define TLM_NO_FREE_TAPES 0x0000000c
276 277 #define TLM_EOT 0x0000000d
277 278 #define TLM_SERIAL_NOT_FOUND 0x0000000e
278 279 #define TLM_SMALL_READ 0x0000000f
279 280 #define TLM_NO_RESTORE_FILE 0x00000010
280 281 #define TLM_EOF 0x00000011
281 282 #define TLM_NO_DIRECTORY 0x00000012
282 283 #define TLM_NO_MEMORY 0x00000013
283 284 #define TLM_WRITE_ERROR 0x00000014
284 285 #define TLM_NO_SCRATCH_SPACE 0x00000015
285 286 #define TLM_INVALID 0x00000016
286 287 #define TLM_MOVE 0x00000017
287 288 #define TLM_SKIP 0x00000018
288 289 #define TLM_OPEN_ERR 0x00000019
289 290
290 291
291 292 #define TLM_MAX_TAPE_DRIVES 16
292 293 #define TLM_NAME_SIZE 100
293 294 #define TLM_MAX_TAR_IMAGE 017777777770
294 295
295 296 #define TLM_VOLNAME_MAX_LENGTH 255
296 297 #define NAME_MAX 255
297 298
298 299 #define TLM_MAGIC "ustar "
299 300 #define TLM_SNAPSHOT_PREFIX ".zfs"
300 301 #define TLM_SNAPSHOT_DIR ".zfs/snapshot"
301 302
302 303 #define RECORDSIZE 512
303 304 #define NAMSIZ 100
304 305
305 306 typedef struct tlm_tar_hdr {
306 307 char th_name[TLM_NAME_SIZE];
307 308 char th_mode[8];
308 309 char th_uid[8];
309 310 char th_gid[8];
310 311 char th_size[12];
311 312 char th_mtime[12];
312 313 char th_chksum[8];
313 314 char th_linkflag;
314 315 char th_linkname[TLM_NAME_SIZE];
315 316 char th_magic[8];
316 317 char th_uname[32];
317 318 char th_gname[32];
318 319 union {
319 320 struct {
320 321 char th_devmajor[8];
321 322 char th_devminor[8];
322 323 } th_dev;
323 324 char th_hlink_ino[12];
324 325 } th_shared;
325 326 } tlm_tar_hdr_t;
326 327
327 328
328 329
329 330 /*
330 331 * The linkflag defines the type of file
331 332 */
332 333 #define LF_OLDNORMAL '\0' /* Normal disk file, Unix compat */
333 334 #define LF_NORMAL '0' /* Normal disk file */
334 335 #define LF_LINK '1' /* Link to previously dumped file */
335 336 #define LF_SYMLINK '2' /* Symbolic link */
336 337 #define LF_CHR '3' /* Character special file */
337 338 #define LF_BLK '4' /* Block special file */
338 339 #define LF_DIR '5' /* Directory */
339 340 #define LF_FIFO '6' /* FIFO special file */
340 341 #define LF_CONTIG '7' /* Contiguous file */
341 342 /* Further link types may be defined later. */
342 343
343 344 #define LF_DUMPDIR 'D'
344 345 /*
345 346 * This is a dir entry that contains
346 347 * the names of files that were in
347 348 * the dir at the time the dump
348 349 * was made
349 350 */
350 351 #define LF_HUMONGUS 'H'
351 352 /*
352 353 * Identifies the NEXT file on the tape
353 354 * as a HUGE file
354 355 */
355 356 #define LF_LONGLINK 'K'
356 357 /*
357 358 * Identifies the NEXT file on the tape
358 359 * as having a long linkname
359 360 */
360 361 #define LF_LONGNAME 'L'
361 362 /*
362 363 * Identifies the NEXT file on the tape
363 364 * as having a long name.
364 365 */
365 366 #define LF_MULTIVOL 'M'
366 367 /*
367 368 * This is the continuation
368 369 * of a file that began on another
369 370 * volume
370 371 */
371 372
372 373 #define LF_VOLHDR 'V' /* This file is a tape/volume header */
373 374 /* Ignore it on extraction */
374 375
375 376 #define LF_ACL 'A' /* Access Control List */
376 377
377 378 #define LF_XATTR 'E' /* Extended attribute */
378 379
379 380 #define KILOBYTE 1024
380 381
381 382
382 383 /*
383 384 * ACL support structure
384 385 */
385 386 typedef struct sec_attr {
386 387 char attr_type;
387 388 char attr_len[7];
388 389 char attr_info[TLM_MAX_ACL_TXT];
389 390 } sec_attr_t;
390 391
391 392 typedef struct tlm_acls {
392 393 int acl_checkpointed : 1, /* are checkpoints active ? */
393 394 acl_clear_archive : 1, /* clear archive bit ? */
394 395 acl_overwrite : 1, /* always overwrite ? */
395 396 acl_update : 1, /* only update ? */
396 397 acl_non_trivial : 1; /* real ACLs? */
397 398 /*
398 399 * The following fields are here to allow
399 400 * the backup reader to open a file one time
400 401 * and keep the information for ACL, ATTRs,
401 402 * and reading the file.
402 403 */
403 404 sec_attr_t acl_info;
404 405
405 406 char acl_root_dir[TLM_VOLNAME_MAX_LENGTH]; /* name of root filesystem */
406 407 fs_fhandle_t acl_dir_fh; /* parent dir's info */
407 408 fs_fhandle_t acl_fil_fh; /* file's info */
408 409 struct stat64 acl_attr; /* file system attributes */
409 410 char uname[32];
410 411 char gname[32];
411 412 } tlm_acls_t;
412 413
413 414
414 415 /*
415 416 * Tape manager's data archiving ops vector
416 417 *
417 418 * This vector represents the granular operations for
418 419 * performing backup/restore. Each backend should provide
419 420 * such a vector interface in order to be invoked by NDMP
420 421 * server.
421 422 * The reserved callbacks are kept for different backup
422 423 * types which are volume-based rather than file-based
423 424 * e.g. zfs send.
424 425 */
425 426 typedef struct tm_ops {
426 427 char *tm_name;
427 428 int (*tm_putfile)();
428 429 int (*tm_putdir)();
|
↓ open down ↓ |
359 lines elided |
↑ open up ↑ |
429 430 int (*tm_putvol)(); /* Reserved */
430 431 int (*tm_getfile)();
431 432 int (*tm_getdir)();
432 433 int (*tm_getvol)(); /* Reserved */
433 434 } tm_ops_t;
434 435
435 436 /* The checksum field is filled with this while the checksum is computed. */
436 437 #define CHKBLANKS " " /* 8 blanks, no null */
437 438
438 439 #define LONGNAME_PREFIX "././_LoNg_NaMe_"
439 -extern void ndmp_log(ulong_t, char *, char *, ...);
440 -char ndmp_log_info[256];
441 -#define NDMP_LOG(p, ...) { \
442 - (void) snprintf(ndmp_log_info, \
443 - sizeof (ndmp_log_info), \
444 - "[%d][%s:%d]", \
445 - (int)pthread_self(), __func__, __LINE__); \
446 - ndmp_log(p, ndmp_log_info, __VA_ARGS__); \
447 - }
448 440 extern void *ndmp_malloc(size_t size);
449 441
450 442 /*
451 443 * ZFS metadata plug-in module structures
452 444 */
453 445 #define ZFS_MAX_PROPS 100
454 446 #define ZFS_META_MAGIC "ZFSMETA"
455 447 #define ZFS_META_MAGIC_EXT "ZFSMETA2"
456 448
457 449 /* Add new major/minor for header changes */
458 450 typedef enum {
459 451 META_HDR_MAJOR_0, /* Original format */
460 452 META_HDR_MAJOR_1, /* Extended format */
461 453 } ndmp_metadata_header_major_t;
462 454
463 455 #define META_HDR_MAJOR_VERSION META_HDR_MAJOR_1
464 456
465 457 typedef enum {
466 458 META_HDR_MINOR_0,
467 459 } ndmp_metadata_header_minor_t;
468 460
469 461 #define META_HDR_MINOR_VERSION META_HDR_MINOR_0
470 462
471 463 /* To support older backups */
472 464 typedef struct ndmp_metadata_property {
473 465 char mp_name[NAME_MAX];
474 466 char mp_value[NAME_MAX];
475 467 char mp_source[NAME_MAX];
476 468 } ndmp_metadata_property_t;
477 469
478 470 typedef struct ndmp_metadata_property_ext {
479 471 char mp_name[ZFS_MAX_DATASET_NAME_LEN];
480 472 char mp_value[ZFS_MAXPROPLEN];
481 473 char mp_source[ZFS_MAXPROPLEN];
482 474 } ndmp_metadata_property_ext_t;
483 475
484 476 typedef struct ndmp_metadata_top_header {
485 477 char th_plname[100];
486 478 uint_t th_plversion;
487 479 char th_magic[10];
488 480 void *th_reserved_1;
489 481 int th_count;
490 482 } ndmp_metadata_top_header_t;
491 483
492 484 /* Original metadata format */
493 485 typedef struct ndmp_metadata_header {
494 486 ndmp_metadata_top_header_t nh_hdr;
495 487 char nh_dataset[NAME_MAX];
496 488 ndmp_metadata_property_t nh_property[1];
497 489 } ndmp_metadata_header_t;
498 490
499 491 /* Extended metadata format */
500 492 typedef struct ndmp_metadata_header_ext {
501 493 ndmp_metadata_top_header_t nh_hdr;
502 494 char nh_dataset[ZFS_MAX_DATASET_NAME_LEN];
503 495 int32_t nh_total_bytes;
504 496 int32_t nh_major;
505 497 int32_t nh_minor;
506 498 ndmp_metadata_property_ext_t nh_property[1];
507 499 } ndmp_metadata_header_ext_t;
508 500
509 501 #define nh_plname nh_hdr.th_plname
510 502 #define nh_plversion nh_hdr.th_plversion
511 503 #define nh_magic nh_hdr.th_magic
512 504 #define nh_count nh_hdr.th_count
513 505
514 506 typedef struct ndmp_metadata_handle {
515 507 void *ml_handle;
516 508 int32_t ml_quota_prop;
517 509 union {
518 510 ndmp_metadata_header_t *u_hdr;
519 511 ndmp_metadata_header_ext_t *u_xhdr;
520 512 } ml_hdr_u;
521 513 } ndmp_metadata_handle_t;
522 514
523 515 #define ml_hdr ml_hdr_u.u_hdr
524 516 #define ml_xhdr ml_hdr_u.u_xhdr
525 517
526 518 /*
527 519 * Node in struct hardlink_q
528 520 *
529 521 * inode: the inode of the hardlink
530 522 * path: the name of the hardlink, used during restore
531 523 * offset: tape offset of the data records for the hardlink, used during backup
532 524 * is_tmp: indicate whether the file was created temporarily for restoring
533 525 * other links during a non-DAR partial restore
534 526 */
535 527 struct hardlink_node {
536 528 unsigned long inode;
537 529 char *path;
538 530 unsigned long long offset;
539 531 int is_tmp;
540 532 SLIST_ENTRY(hardlink_node) next_hardlink;
541 533 };
542 534
543 535 /*
544 536 * Hardlinks that have been backed up or restored.
545 537 *
546 538 * During backup, each node represents a file whose
547 539 * (1) inode has multiple links
548 540 * (2) data has been backed up
549 541 *
550 542 * When we run into a file with multiple links during backup,
551 543 * we first check the list to see whether a file with the same inode
552 544 * has been backed up. If yes, we backup an empty record, while
553 545 * making the file history of this file contain the data offset
554 546 * of the offset of the file that has been backed up. If no,
555 547 * we backup this file, and add an entry to the list.
556 548 *
557 549 * During restore, each node represents an LF_LINK type record whose
558 550 * data has been restored (v.s. a hard link has been created).
559 551 *
560 552 * During restore, when we run into a record of LF_LINK type, we
561 553 * first check the queue to see whether a file with the same inode
562 554 * has been restored. If yes, we create a hardlink to it.
563 555 * If no, we restore the data, and add an entry to the list.
564 556 */
565 557 struct hardlink_q {
566 558 struct hardlink_node *slh_first;
567 559 };
568 560
569 561 /* Utility functions from handling hardlink */
570 562 extern struct hardlink_q *hardlink_q_init();
571 563 extern void hardlink_q_cleanup(struct hardlink_q *qhead);
572 564 extern int hardlink_q_get(struct hardlink_q *qhead, unsigned long inode,
573 565 unsigned long long *offset, char **path);
574 566 extern int hardlink_q_add(struct hardlink_q *qhead, unsigned long inode,
575 567 unsigned long long offset, char *path, int is_tmp);
576 568
577 569 #endif /* !_TLM_H_ */
|
↓ open down ↓ |
120 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX