Print this page
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/ndmp/ndmpd_dtime.c
+++ new/usr/src/cmd/ndmpd/ndmp/ndmpd_dtime.c
1 1 /*
2 2 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
3 3 * Copyright (c) 2015 by Delphix. All rights reserved.
4 4 */
5 5
6 6 /*
7 7 * BSD 3 Clause License
8 8 *
9 9 * Copyright (c) 2007, The Storage Networking Industry Association.
10 10 *
11 11 * Redistribution and use in source and binary forms, with or without
12 12 * modification, are permitted provided that the following conditions
13 13 * are met:
14 14 * - Redistributions of source code must retain the above copyright
15 15 * notice, this list of conditions and the following disclaimer.
16 16 *
17 17 * - Redistributions in binary form must reproduce the above copyright
18 18 * notice, this list of conditions and the following disclaimer in
19 19 * the documentation and/or other materials provided with the
20 20 * distribution.
21 21 *
22 22 * - Neither the name of The Storage Networking Industry Association (SNIA)
23 23 * nor the names of its contributors may be used to endorse or promote
24 24 * products derived from this software without specific prior written
25 25 * permission.
26 26 *
27 27 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
28 28 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30 30 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
31 31 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
↓ open down ↓ |
31 lines elided |
↑ open up ↑ |
32 32 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33 33 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34 34 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35 35 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36 36 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37 37 * POSSIBILITY OF SUCH DAMAGE.
38 38 */
39 39
40 40 #include <sys/param.h>
41 41 #include <sys/types.h>
42 +#include <syslog.h>
42 43 #include <ctype.h>
43 44 #include <errno.h>
44 45 #include <fcntl.h>
45 46 #include <limits.h>
46 47 #include <stdarg.h>
47 48 #include <stdio.h>
48 49 #include <stdlib.h>
49 50 #include <string.h>
50 51 #include <time.h>
51 52 #include <unistd.h>
52 53 #include <libnvpair.h>
53 -#include "ndmpd_log.h"
54 54 #include "ndmpd.h"
55 55
56 56 /*
57 57 * The dumpdates file on file system.
58 58 */
59 59 #define NDMP_DUMPDATES "dumpdates"
60 60
61 61
62 62 /*
63 63 * Offsets into the ctime string to various parts.
64 64 */
65 65 #define E_MONTH 4
66 66 #define E_DAY 8
67 67 #define E_HOUR 11
68 68 #define E_MINUTE 14
69 69 #define E_SECOND 17
70 70 #define E_YEAR 20
71 71
72 72
73 73 /*
74 74 * The contents of the file dumpdates is maintained on a linked list.
75 75 */
76 76 typedef struct dumpdates {
77 77 char dd_name[TLM_MAX_PATH_NAME];
78 78 char dd_level;
79 79 time_t dd_ddate;
80 80 struct dumpdates *dd_next;
81 81 } dumpdates_t;
82 82
83 83
84 84 /*
85 85 * Month names used in ctime string.
86 86 */
87 87 static char months[] = "JanFebMarAprMayJunJulAugSepOctNovDec";
88 88
89 89
90 90 /*
91 91 * Binary lock for accessing the dumpdates file.
92 92 */
93 93 mutex_t ndmp_dd_lock = DEFAULTMUTEX;
94 94
95 95 int ndmp_isdst = -1;
96 96
97 97 char *zfs_dumpdate_props[] = {
98 98 "dumpdates:level0",
99 99 "dumpdates:level1",
100 100 "dumpdates:level2",
101 101 "dumpdates:level3",
102 102 "dumpdates:level4",
103 103 "dumpdates:level5",
104 104 "dumpdates:level6",
105 105 "dumpdates:level7",
106 106 "dumpdates:level8",
107 107 "dumpdates:level9",
108 108 };
109 109
110 110
111 111 /*
112 112 * lookup
113 113 *
114 114 * Look up the month (3-character) name and return its number.
115 115 *
116 116 * Returns -1 if the months name is not valid.
117 117 */
118 118 static int
119 119 lookup(char *str)
120 120 {
121 121 register char *cp, *cp2;
122 122
123 123 if (!str)
124 124 return (-1);
125 125
126 126 for (cp = months, cp2 = str; *cp != '\0'; cp += 3)
127 127 if (strncmp(cp, cp2, 3) == 0)
128 128 return ((cp-months) / 3);
129 129 return (-1);
130 130 }
131 131
132 132
133 133 /*
134 134 * unctime
135 135 *
136 136 * Convert a ctime(3) format string into a system format date.
137 137 * Return the date thus calculated.
138 138 *
139 139 * Return -1 if the string is not in ctime format.
140 140 */
141 141 static int
142 142 unctime(char *str, time_t *t)
143 143 {
144 144 struct tm then;
145 145 char dbuf[26];
146 146
147 147 if (!str || !t)
148 148 return (-1);
149 149
150 150 (void) memset(&then, 0, sizeof (then));
151 151 (void) strlcpy(dbuf, str, sizeof (dbuf) - 1);
152 152 dbuf[sizeof (dbuf) - 1] = '\0';
153 153 dbuf[E_MONTH+3] = '\0';
|
↓ open down ↓ |
90 lines elided |
↑ open up ↑ |
154 154 if ((then.tm_mon = lookup(&dbuf[E_MONTH])) < 0)
155 155 return (-1);
156 156
157 157 then.tm_mday = atoi(&dbuf[E_DAY]);
158 158 then.tm_hour = atoi(&dbuf[E_HOUR]);
159 159 then.tm_min = atoi(&dbuf[E_MINUTE]);
160 160 then.tm_sec = atoi(&dbuf[E_SECOND]);
161 161 then.tm_year = atoi(&dbuf[E_YEAR]) - 1900;
162 162 then.tm_isdst = ndmp_isdst;
163 163
164 - NDMP_LOG(LOG_DEBUG,
164 + syslog(LOG_DEBUG,
165 165 "yday %d wday %d %d/%d/%d %02d:%02d:%02d",
166 166 then.tm_yday, then.tm_wday, then.tm_year, then.tm_mon,
167 167 then.tm_mday, then.tm_hour, then.tm_min, then.tm_sec);
168 168
169 169 *t = mktime(&then);
170 170
171 171 return (0);
172 172 }
173 173
174 174
175 175 /*
176 176 * ddates_pathname
177 177 *
178 178 * Create the dumpdates file full path name.
179 179 */
180 180 static char *
181 181 ddates_pathname(char *buf)
182 182 {
183 183 return (ndmpd_make_bk_dir_path(buf, NDMP_DUMPDATES));
184 184 }
185 185
186 186
187 187 /*
188 188 * getaline
189 189 *
190 190 * Get a line from the file and handle the continued lines.
191 191 */
192 192 static char *
193 193 getaline(FILE *fp, char *line, int llen)
194 194 {
195 195 char *save;
196 196 int len;
197 197
198 198 if (!fp || !line)
199 199 return (NULL);
200 200
201 201 *(save = line) = '\0';
202 202 do {
203 203 if (fgets(line, llen, fp) != line)
204 204 return (NULL);
205 205
206 206 /* comment line? */
207 207 if (*line == '#')
208 208 continue;
209 209
210 210 len = strlen(line);
211 211 /* short line */
212 212 if (len <= 0)
213 213 continue;
214 214
215 215 line += len-1;
216 216 if (*line != '\n')
217 217 return (NULL);
218 218
219 219 /* trim the trailing new line */
220 220 *line = '\0';
221 221 if (--len <= 0)
222 222 break;
223 223
224 224 if (*(line-1) != '\\')
225 225 break;
226 226
227 227 *(line-1) = '\n';
228 228 llen -= len;
229 229 } while (llen > 0);
230 230
231 231 return (save);
232 232 }
233 233
234 234
235 235 /*
236 236 * get_ddname
237 237 *
238 238 * Get the path name from the buffer passed.
239 239 *
240 240 * Returns the beginning of the path name. The buffer pointer is moved
241 241 * forward to point to where the next field (the dump level) begins.
242 242 */
243 243 static char *
244 244 get_ddname(char **bpp)
245 245 {
246 246 char *h, *t, *save;
247 247
248 248 if (!bpp || !*bpp)
249 249 return (NULL);
250 250
251 251 *bpp += strspn(*bpp, "\t ");
252 252 save = h = t = *bpp;
253 253 while (*t) {
254 254 if (*t == '\t' || *t == ' ') {
255 255 /* consume the '\t' or space character */
256 256 t++;
257 257 break;
258 258 }
259 259
260 260 if (*t == '\\')
261 261 switch (*(t+1)) {
262 262 case '\t':
263 263 case ' ':
264 264 t++; /* skip the '\\' */
265 265 default:
266 266 break; /* nothing */
267 267 }
268 268
269 269 *h++ = *t++;
270 270 }
271 271
272 272 *bpp = t;
273 273 *h++ = '\0';
274 274 return (save);
275 275 }
276 276
277 277
278 278 /*
279 279 * get_ddlevel
280 280 *
281 281 * Get the dump level from the buffer passed.
282 282 *
283 283 * Returns the dump level found. The buffer pointer is moved
284 284 * forward to point to where the next field (the dump date) begins.
285 285 */
286 286 static int
287 287 get_ddlevel(char **bpp)
288 288 {
289 289 char *t, *save;
290 290
|
↓ open down ↓ |
116 lines elided |
↑ open up ↑ |
291 291 if (!bpp || !*bpp)
292 292 return (-1);
293 293
294 294 *bpp += strspn(*bpp, "\t ");
295 295 save = t = *bpp;
296 296
297 297 /*
298 298 * For 'F', 'A', 'I', and 'D' return the character itself.
299 299 */
300 300 if (IS_LBR_BKTYPE(*t)) {
301 - NDMP_LOG(LOG_DEBUG, "Lbr bk type %c", *t);
301 + syslog(LOG_DEBUG, "Lbr bk type %c", *t);
302 302 /*
303 303 * Skip the backup type character and null terminate the
304 304 * string.
305 305 */
306 306 *++t = '\0';
307 307 *bpp = ++t;
308 308 return (toupper(*save));
309 309 }
310 310
311 311 while (isdigit(*t))
312 312 t++;
313 313
314 314 *t++ = '\0';
315 315 *bpp = t;
316 316 return (atoi(save));
317 317 }
318 318
319 319
320 320 /*
321 321 * get_ddate
322 322 *
323 323 * Get the dump date from the buffer passed.
324 324 *
325 325 * Returns the dump date string. The buffer pointer is moved
326 326 * forward. It points to the end of the buffer now.
327 327 */
328 328 static char *
329 329 get_ddate(char **bpp)
330 330 {
331 331 char *save;
332 332
333 333 if (!bpp || !*bpp)
334 334 return (NULL);
335 335
336 336 *bpp += strspn(*bpp, "\t ");
337 337 save = *bpp;
338 338 *bpp += strlen(*bpp);
339 339 return (save);
340 340 }
341 341
342 342
343 343 /*
344 344 * put_ddname
345 345 *
346 346 * Print the dump path name to the dumpdates file. It escapes the space,
347 347 * '\t' and new line characters in the path name. The same characters are
348 348 * considered in the get_ddname().
349 349 */
350 350 static void
351 351 put_ddname(FILE *fp, char *nm)
352 352 {
353 353 if (!nm)
354 354 return;
355 355
356 356 while (*nm)
357 357 switch (*nm) {
358 358 case ' ':
359 359 case '\n':
360 360 case '\t':
361 361 (void) fputc('\\', fp);
362 362 /* FALLTHROUGH */
363 363 default:
364 364 (void) fputc(*nm++, fp);
365 365 }
366 366 }
367 367
368 368
369 369 /*
370 370 * put_ddlevel
371 371 *
372 372 * Print the dump level into the dumpdates file.
373 373 */
374 374 static void
375 375 put_ddlevel(FILE *fp, int level)
376 376 {
377 377 if (!fp)
378 378 return;
379 379
380 380 (void) fprintf(fp, IS_LBR_BKTYPE(level) ? "%c" : "%d", level);
381 381 }
382 382
383 383
384 384 /*
385 385 * put_ddate
386 386 *
|
↓ open down ↓ |
75 lines elided |
↑ open up ↑ |
387 387 * Print the dump date into the dumpdates file.
388 388 */
389 389 static void put_ddate(FILE *fp,
390 390 time_t t)
391 391 {
392 392 char tbuf[64];
393 393
394 394 if (!fp)
395 395 return;
396 396
397 - NDMP_LOG(LOG_DEBUG, "[%u]", t);
398 -
399 397 (void) ctime_r(&t, tbuf, sizeof (tbuf));
400 398 /* LINTED variable format specifier */
401 399 (void) fprintf(fp, tbuf);
402 400 }
403 401
404 402
405 403 /*
406 404 * dd_free
407 405 *
408 406 * Free the linked list of dumpdates entries.
409 407 */
410 408 static void
411 409 dd_free(dumpdates_t *ddheadp)
412 410 {
413 411 dumpdates_t *save;
414 412
415 413 if (!ddheadp)
416 414 return;
417 415
418 416 ddheadp = ddheadp->dd_next;
419 417 while (ddheadp) {
420 418 save = ddheadp->dd_next;
421 419 free(ddheadp);
422 420 ddheadp = save;
423 421 }
424 422 }
425 423
426 424
427 425 /*
428 426 * makedumpdate
429 427 *
430 428 * Make the dumpdate node based on the string buffer passed to it.
431 429 */
432 430 static int
433 431 makedumpdate(dumpdates_t *ddp, char *tbuf)
434 432 {
435 433 char *nmp, *un_buf;
436 434 int rv;
437 435
438 436 /*
|
↓ open down ↓ |
30 lines elided |
↑ open up ↑ |
439 437 * While parsing each line, if a line contains one of the
440 438 * LBR-type levels, then checking the return value of
441 439 * get_ddlevel() against negative values, it OK. Because
442 440 * neither of the 'F', 'A', 'I' nor 'D' have negative
443 441 * ASCII value.
444 442 */
445 443 if (!ddp || !tbuf)
446 444 rv = -1;
447 445 else if (!(nmp = get_ddname(&tbuf))) {
448 446 rv = -1;
449 - NDMP_LOG(LOG_DEBUG, "get_ddname failed 0x%p", nmp);
447 + syslog(LOG_ERR, "get_ddname failed 0x%p", nmp);
450 448 } else if ((ddp->dd_level = get_ddlevel(&tbuf)) < 0) {
451 449 rv = -1;
452 - NDMP_LOG(LOG_DEBUG, "dd_level < 0 %d", ddp->dd_level);
450 + syslog(LOG_ERR, "dd_level < 0 %d", ddp->dd_level);
453 451 } else if (!(un_buf = get_ddate(&tbuf))) {
454 452 rv = -1;
455 - NDMP_LOG(LOG_DEBUG, "get_ddate failed 0x%p", un_buf);
453 + syslog(LOG_ERR, "get_ddate failed 0x%p", un_buf);
456 454 } else if (unctime(un_buf, &ddp->dd_ddate) < 0) {
457 455 rv = -1;
458 - NDMP_LOG(LOG_DEBUG, "unctime failed \"%s\"", un_buf);
456 + syslog(LOG_ERR, "unctime failed \"%s\"", un_buf);
459 457 } else {
460 458 (void) strlcpy(ddp->dd_name, nmp, TLM_MAX_PATH_NAME);
461 459 rv = 0;
462 460 }
463 461
464 462 return (rv);
465 463 }
466 464
467 465
468 466 /*
469 467 * getrecord
470 468 *
471 469 * Read a record of dumpdates file and parse it.
472 470 * The records that span multiple lines are covered.
473 471 *
474 472 * Returns:
475 473 * 0 on success
476 474 * < 0 on error
477 475 */
478 476 static int
479 477 getrecord(FILE *fp, dumpdates_t *ddatep, int *recno)
480 478 {
481 479 char tbuf[BUFSIZ];
|
↓ open down ↓ |
13 lines elided |
↑ open up ↑ |
482 480
483 481 if (!fp || !ddatep || !recno)
484 482 return (-1);
485 483
486 484 do {
487 485 if (getaline(fp, tbuf, sizeof (tbuf)) != tbuf)
488 486 return (-1);
489 487 } while (!*tbuf);
490 488
491 489 if (makedumpdate(ddatep, tbuf) < 0)
492 - NDMP_LOG(LOG_DEBUG,
490 + syslog(LOG_ERR,
493 491 "Unknown intermediate format in %s, line %d", tbuf, *recno);
494 492
495 493 (*recno)++;
496 494
497 - if (IS_LBR_BKTYPE(ddatep->dd_level & 0xff)) {
498 - NDMP_LOG(LOG_DEBUG, "Lbr: [%s][%c][%u]",
499 - ddatep->dd_name, ddatep->dd_level, ddatep->dd_ddate);
500 - } else
501 - NDMP_LOG(LOG_DEBUG, "[%s][%d][%u]",
502 - ddatep->dd_name, ddatep->dd_level, ddatep->dd_ddate);
503 -
504 495 return (0);
505 496 }
506 497
507 498
508 499 /*
509 500 * readdumptimes
510 501 *
511 502 * Read the dumpdates file and make a linked list of its entries.
512 503 *
513 504 * Returns:
514 505 * 0 on success
515 506 * < 0 on error
516 507 */
517 508 static int
518 509 readdumptimes(FILE *fp, dumpdates_t *ddheadp)
519 510 {
520 511 int recno;
521 512 register struct dumpdates *ddwalk;
522 513
523 514 if (!fp || !ddheadp)
524 515 return (-1);
525 516
526 517 recno = 1;
527 518 (void) memset((void *)ddheadp, 0, sizeof (*ddheadp));
528 519 for (; ; ) {
529 520 ddwalk = ndmp_malloc(sizeof (*ddwalk));
530 521 if (!ddwalk)
531 522 return (-1);
532 523
533 524 if (getrecord(fp, ddwalk, &recno) < 0) {
534 525 free(ddwalk);
535 526 break;
536 527 }
537 528
538 529 ddwalk->dd_next = ddheadp->dd_next;
539 530 ddheadp->dd_next = ddwalk;
540 531 ddheadp = ddwalk;
541 532 }
542 533
543 534 return (0);
544 535 }
545 536
546 537
547 538 /*
|
↓ open down ↓ |
34 lines elided |
↑ open up ↑ |
548 539 * dumprecout
549 540 *
550 541 * Print a record into the dumpdates file.
551 542 */
552 543 static void
553 544 dumprecout(FILE *fp, dumpdates_t *ddp)
554 545 {
555 546 if (!ddp)
556 547 return;
557 548
558 - if (IS_LBR_BKTYPE(ddp->dd_level)) {
559 - NDMP_LOG(LOG_DEBUG, "Lbr: [%s][%c][%u]",
560 - ddp->dd_name, ddp->dd_level, ddp->dd_ddate);
561 - } else
562 - NDMP_LOG(LOG_DEBUG, "[%s][%d][%u]",
563 - ddp->dd_name, ddp->dd_level, ddp->dd_ddate);
564 -
565 549 put_ddname(fp, ddp->dd_name);
566 550 (void) fputc('\t', fp);
567 551 put_ddlevel(fp, ddp->dd_level);
568 552 (void) fputc('\t', fp);
569 553 put_ddate(fp, ddp->dd_ddate);
570 554 }
571 555
572 556
573 557 /*
574 558 * initdumptimes
575 559 *
576 560 * Open the dumpdates file and read it into memory.
577 561 *
578 562 * Returns:
579 563 * 0 on success
580 564 * < 0 on error
581 565 *
582 566 */
583 567 static int
584 568 initdumptimes(dumpdates_t *ddheadp)
585 569 {
586 570 char fname[PATH_MAX];
587 571 int rv;
588 572 FILE *fp;
|
↓ open down ↓ |
14 lines elided |
↑ open up ↑ |
589 573
590 574 if (!ddheadp)
591 575 return (-1);
592 576
593 577 if (!ddates_pathname(fname))
594 578 return (-1);
595 579
596 580 fp = fopen(fname, "r");
597 581 if (!fp) {
598 582 if (errno != ENOENT) {
599 - NDMP_LOG(LOG_ERR, "Cannot read %s: %m.", fname);
583 + syslog(LOG_ERR, "Cannot read %s: %m.", fname);
600 584 return (-1);
601 585 }
602 586 /*
603 587 * Dumpdates does not exist, make an empty one.
604 588 */
605 - NDMP_LOG(LOG_DEBUG,
589 + syslog(LOG_DEBUG,
606 590 "No file `%s', making an empty one", fname);
607 591
608 592 fp = fopen(fname, "w");
609 593 if (!fp) {
610 - NDMP_LOG(LOG_ERR, "Cannot create %s: %m.", fname);
594 + syslog(LOG_ERR, "Cannot create %s: %m.", fname);
611 595 return (-1);
612 596 }
613 597 (void) fclose(fp);
614 598
615 599 fp = fopen(fname, "r");
616 600 if (!fp) {
617 - NDMP_LOG(LOG_ERR,
601 + syslog(LOG_ERR,
618 602 "Cannot read %s after creating it. %m.", fname);
619 603 return (-1);
620 604 }
621 605 }
622 606
623 607 rv = readdumptimes(fp, ddheadp);
624 608 (void) fclose(fp);
625 609
626 610 return (rv);
627 611 }
628 612
629 613
630 614 /*
631 615 * putdumptime
632 616 *
633 617 * Put the record specified by path, level and backup date to the file.
634 618 * Update the record if such entry already exists; append if not.
635 619 *
636 620 * Returns:
637 621 * 0 on success
638 622 * < 0 on error
639 623 */
640 624 static int
641 625 putdumptime(char *path, int level, time_t ddate)
642 626 {
643 627 int found;
|
↓ open down ↓ |
16 lines elided |
↑ open up ↑ |
644 628 char fname[PATH_MAX], bakfname[PATH_MAX];
645 629 FILE *rfp, *wfp;
646 630 dumpdates_t ddhead, tmpdd;
647 631 register dumpdates_t *ddp;
648 632 int rv;
649 633
650 634 if (!path)
651 635 return (-1);
652 636
653 637 if (IS_LBR_BKTYPE(level)) {
654 - NDMP_LOG(LOG_DEBUG, "Lbr: [%s][%c][%u]", path, level, ddate);
638 + syslog(LOG_DEBUG, "Lbr: [%s][%c][%u]", path, level, ddate);
655 639 } else {
656 - NDMP_LOG(LOG_DEBUG, "[%s][%d][%u]", path, level, ddate);
640 + syslog(LOG_DEBUG, "[%s][%d][%u]", path, level, ddate);
657 641 }
658 642
659 643 if (!ddates_pathname(fname)) {
660 - NDMP_LOG(LOG_ERR, "Cannot get dumpdate file path name.");
644 + syslog(LOG_ERR, "Cannot get dumpdate file path name.");
661 645 return (-1);
662 646 }
663 647
664 648 rfp = fopen(fname, "r");
665 649 if (!rfp) {
666 - NDMP_LOG(LOG_DEBUG, "Creating %s.", fname);
650 + syslog(LOG_DEBUG, "Creating %s.", fname);
667 651 (void) memset((void *)&ddhead, 0, sizeof (ddhead));
668 652 if (initdumptimes(&ddhead) < 0) {
669 - NDMP_LOG(LOG_ERR, "Could not initialize %s.",
653 + syslog(LOG_ERR, "Could not initialize %s.",
670 654 NDMP_DUMPDATES);
671 655 dd_free(&ddhead);
672 656 return (-1);
673 657 }
674 658 } else {
675 659 rv = readdumptimes(rfp, &ddhead);
676 660
677 661 if (rv < 0) {
678 - NDMP_LOG(LOG_ERR, "Error reading dumpdates file.");
662 + syslog(LOG_ERR, "Error reading dumpdates file.");
679 663 (void) fclose(rfp);
680 664 dd_free(&ddhead);
681 665 return (-1);
682 666 }
683 667 (void) fclose(rfp);
684 668 }
685 669
686 670 (void) snprintf(bakfname, PATH_MAX, "%s.bak", fname);
687 671 wfp = fopen(bakfname, "w");
688 672 if (!wfp) {
689 - NDMP_LOG(LOG_ERR, "Cannot open %s: %m.", bakfname);
673 + syslog(LOG_ERR, "Cannot open %s: %m.", bakfname);
690 674 dd_free(&ddhead);
691 675 return (-1);
692 676 }
693 677
694 - NDMP_LOG(LOG_DEBUG, "[%s][%s]", fname, bakfname);
678 + syslog(LOG_DEBUG, "[%s][%s]", fname, bakfname);
695 679
696 680 /* try to locate the entry in the file */
697 681 found = 0;
698 682 for (ddp = ddhead.dd_next; ddp; ddp = ddp->dd_next) {
699 683 if (ddp->dd_level != level)
700 684 continue;
701 685 if (strcmp(path, ddp->dd_name))
702 686 continue;
703 687
704 - NDMP_LOG(LOG_DEBUG, "Found: [%s][%d][%u]",
688 + syslog(LOG_DEBUG, "Found: [%s][%d][%u]",
705 689 ddp->dd_name, ddp->dd_level, ddp->dd_ddate);
706 690
707 691 /* update the record for the entry */
708 692 found = 1;
709 693 ddp->dd_ddate = ddate;
710 694
711 - NDMP_LOG(LOG_DEBUG,
695 + syslog(LOG_DEBUG,
712 696 "Updated to: [%s][%d][%u]",
713 697 ddp->dd_name, ddp->dd_level, ddp->dd_ddate);
714 698 }
715 699
716 700 /* dump all the read records */
717 701 for (ddp = ddhead.dd_next; ddp; ddp = ddp->dd_next)
718 702 dumprecout(wfp, ddp);
719 703
720 704 dd_free(&ddhead);
721 705
722 706 /* append a new record */
723 707 if (!found) {
724 708 (void) strlcpy(tmpdd.dd_name, path, TLM_MAX_PATH_NAME);
725 709 tmpdd.dd_level = level;
726 710 tmpdd.dd_ddate = ddate;
727 711 dumprecout(wfp, &tmpdd);
728 712 }
729 713
730 714 (void) fclose(wfp);
731 715 (void) rename(bakfname, fname);
732 716
733 717 return (0);
734 718 }
735 719
736 720
737 721 /*
738 722 * append_dumptime
739 723 *
740 724 * Append the record specified by path, level and backup date to the file.
741 725 */
742 726 static int
|
↓ open down ↓ |
21 lines elided |
↑ open up ↑ |
743 727 append_dumptime(char *fname, char *path, int level, time_t ddate)
744 728 {
745 729 char fpath[PATH_MAX], bakfpath[PATH_MAX];
746 730 FILE *fp;
747 731 dumpdates_t tmpdd;
748 732
749 733 if (!fname || !*fname || !path || !*path)
750 734 return (-1);
751 735
752 736 if (IS_LBR_BKTYPE(level & 0xff)) {
753 - NDMP_LOG(LOG_DEBUG,
737 + syslog(LOG_DEBUG,
754 738 "Lbr: [%s][%s][%c][%u]",
755 739 fname, path, level, ddate);
756 740 } else
757 - NDMP_LOG(LOG_DEBUG, "[%s][%s][%d][%u]",
741 + syslog(LOG_DEBUG, "[%s][%s][%d][%u]",
758 742 fname, path, level, ddate);
759 743
760 744 if (!ndmpd_make_bk_dir_path(fpath, fname)) {
761 - NDMP_LOG(LOG_ERR, "Cannot get dumpdate file path name %s.",
745 + syslog(LOG_ERR, "Cannot get dumpdate file path name %s.",
762 746 fname);
763 747 return (-1);
764 748 }
765 749
766 750 (void) snprintf(bakfpath, PATH_MAX, "%s.bak", fpath);
767 751
768 752 /*
769 753 * If the file is there and can be opened then make a
770 754 * backup copy it.
771 755 */
772 756 fp = fopen(fpath, "r");
773 757 if (fp) {
774 758 (void) fclose(fp);
775 759 if (filecopy(bakfpath, fpath) != 0) {
776 - NDMP_LOG(LOG_ERR, "Cannot copy %s to %s: %m.",
760 + syslog(LOG_ERR, "Cannot copy %s to %s: %m.",
777 761 fpath, bakfpath);
778 762 return (-1);
779 763 }
780 764 }
781 765
782 766 /* open the new copy to append the record to it */
783 767 fp = fopen(bakfpath, "a");
784 768 if (!fp) {
785 - NDMP_LOG(LOG_ERR, "Cannot open %s: %m.", bakfpath);
769 + syslog(LOG_ERR, "Cannot open %s: %m.", bakfpath);
786 770 return (-1);
787 771 }
788 772
789 - NDMP_LOG(LOG_DEBUG, "[%s][%s]", fpath, bakfpath);
773 + syslog(LOG_DEBUG, "[%s][%s]", fpath, bakfpath);
790 774
791 775 /* append a new record */
792 776 (void) strlcpy(tmpdd.dd_name, path, TLM_MAX_PATH_NAME);
793 777 tmpdd.dd_level = level;
794 778 tmpdd.dd_ddate = ddate;
795 779 dumprecout(fp, &tmpdd);
796 780
797 781 (void) fclose(fp);
798 782 (void) rename(bakfpath, fpath);
799 783
800 784 return (0);
801 785 }
802 786
803 787
804 788 /*
805 789 * find_date
806 790 *
807 791 * Find the specified date
808 792 */
809 793 static dumpdates_t *
810 794 find_date(dumpdates_t *ddp, char *path, int level, time_t t)
811 795 {
812 796 for (; ddp; ddp = ddp->dd_next)
813 797 if (ddp->dd_level == level && ddp->dd_ddate > t &&
814 798 strcmp(path, ddp->dd_name) == 0)
815 799 break;
816 800
817 801 return (ddp);
818 802 }
819 803
820 804
821 805 /*
822 806 * Get the dumpdate of the last level backup done on the path.
823 807 * The last level normally is (level - 1) in case of NetBackup
824 808 * but some DMAs allow that previous level could be anything
825 809 * between 0 and the current level.
826 810 *
827 811 * Returns:
828 812 * 0 on success
829 813 * < 0 on error
830 814 */
831 815 int
832 816 ndmpd_get_dumptime(char *path, int *level, time_t *ddate)
833 817 {
834 818 int i;
|
↓ open down ↓ |
35 lines elided |
↑ open up ↑ |
835 819 dumpdates_t ddhead, *ddp, *save;
836 820 char vol[ZFS_MAX_DATASET_NAME_LEN];
837 821 nvlist_t *userprops;
838 822 zfs_handle_t *zhp;
839 823 nvlist_t *propval = NULL;
840 824 char *strval = NULL;
841 825
842 826 if (!path || !level || !ddate)
843 827 return (-1);
844 828
845 - NDMP_LOG(LOG_DEBUG, "[%s] level %d",
829 + syslog(LOG_DEBUG, "[%s] level %d",
846 830 path, *level);
847 831
848 832 if (*level == 0) {
849 833 *ddate = (time_t)0;
850 834 return (0);
851 835 }
852 836
853 837 (void) mutex_lock(&zlib_mtx);
854 838 /* Check if this is a ZFS dataset */
855 839 if ((zlibh != NULL) &&
856 840 (get_zfsvolname(vol, sizeof (vol), path) == 0) &&
857 841 ((zhp = zfs_open(zlibh, vol, ZFS_TYPE_DATASET)) != NULL)) {
858 842 if ((userprops = zfs_get_user_props(zhp)) == NULL) {
859 843 *level = 0;
860 844 *ddate = (time_t)0;
861 845 zfs_close(zhp);
862 846 (void) mutex_unlock(&zlib_mtx);
863 847 return (0);
864 848 }
865 849 for (i = *level - 1; i >= 0; i--) {
866 850 if (nvlist_lookup_nvlist(userprops,
867 851 zfs_dumpdate_props[i], &propval) == 0) {
868 852 *level = i;
869 853 break;
870 854 }
871 855 }
872 856 if (propval == NULL ||
873 857 nvlist_lookup_string(propval, ZPROP_VALUE,
874 858 &strval) != 0) {
875 859 *level = 0;
876 860 *ddate = (time_t)0;
877 861 zfs_close(zhp);
878 862 (void) mutex_unlock(&zlib_mtx);
879 863 return (0);
880 864 }
881 865 if (unctime(strval, ddate) < 0) {
882 866 zfs_close(zhp);
883 867 (void) mutex_unlock(&zlib_mtx);
884 868 return (-1);
885 869 }
886 870
887 871 zfs_close(zhp);
888 872 (void) mutex_unlock(&zlib_mtx);
889 873 return (0);
890 874 }
891 875 (void) mutex_unlock(&zlib_mtx);
892 876
893 877 (void) memset((void *)&ddhead, 0, sizeof (ddhead));
894 878 if (initdumptimes(&ddhead) < 0) {
895 879 dd_free(&ddhead);
896 880 return (-1);
897 881 }
898 882
899 883 /*
900 884 * Empty dumpdates file means level 0 for all paths.
901 885 */
902 886 if ((ddp = ddhead.dd_next) == 0) {
903 887 if (!IS_LBR_BKTYPE(*level & 0xff))
904 888 *level = 0;
905 889 *ddate = 0;
|
↓ open down ↓ |
50 lines elided |
↑ open up ↑ |
906 890 return (0);
907 891 }
908 892
909 893 /*
910 894 * If it's not level backup, then find the exact record
911 895 * type.
912 896 */
913 897 if (IS_LBR_BKTYPE(*level & 0xff)) {
914 898 save = find_date(ddp, path, *level, *ddate);
915 899
916 - NDMP_LOG(LOG_DEBUG,
900 + syslog(LOG_DEBUG,
917 901 "LBR_BKTYPE save 0x%p", save);
918 902
919 903 *ddate = save ? save->dd_ddate : (time_t)0;
920 904 } else {
921 905 /*
922 906 * Go find the entry with the same name for a maximum of a
923 907 * lower increment and older date.
924 908 */
925 909 save = NULL;
926 910 for (i = *level - 1; i >= 0; i--) {
927 911 save = find_date(ddp, path, i, *ddate);
928 912 if (save) {
929 913 *level = save->dd_level;
930 914 *ddate = save->dd_ddate;
931 915 break;
932 916 }
933 917 }
934 918
935 919 if (!save) {
936 920 *level = 0;
937 921 *ddate = (time_t)0;
938 922 }
939 923 }
940 924
941 925 dd_free(&ddhead);
942 926
943 927 return (0);
944 928 }
945 929
946 930
947 931 /*
948 932 * Put the date and the level of the back up for the
949 933 * specified path in the dumpdates file. If there is a line
950 934 * for the same path and the same level, the date is updated.
951 935 * Otherwise, a line is appended to the file.
952 936 *
953 937 * Returns:
954 938 * 0 on success
|
↓ open down ↓ |
28 lines elided |
↑ open up ↑ |
955 939 * < 0 on error
956 940 */
957 941 int
958 942 ndmpd_put_dumptime(char *path, int level, time_t ddate)
959 943 {
960 944 char vol[ZFS_MAX_DATASET_NAME_LEN];
961 945 zfs_handle_t *zhp;
962 946 char tbuf[64];
963 947 int rv;
964 948
965 - NDMP_LOG(LOG_DEBUG, "[%s][%d][%u]", path, level,
949 + syslog(LOG_DEBUG, "[%s][%d][%u]", path, level,
966 950 ddate);
967 951
968 952 /* Check if this is a ZFS dataset */
969 953 (void) mutex_lock(&zlib_mtx);
970 954 if ((zlibh != NULL) &&
971 955 (get_zfsvolname(vol, sizeof (vol), path) == 0) &&
972 956 ((zhp = zfs_open(zlibh, vol, ZFS_TYPE_DATASET)) != NULL)) {
973 957
974 958 (void) ctime_r(&ddate, tbuf, sizeof (tbuf));
975 959 rv = zfs_prop_set(zhp, zfs_dumpdate_props[level], tbuf);
976 960 zfs_close(zhp);
977 961
978 962 (void) mutex_unlock(&zlib_mtx);
979 963 return (rv);
980 964 }
981 965 (void) mutex_unlock(&zlib_mtx);
982 966
983 967 (void) mutex_lock(&ndmp_dd_lock);
984 968 rv = putdumptime(path, level, ddate);
985 969 (void) mutex_unlock(&ndmp_dd_lock);
986 970
987 971 return (rv);
988 972 }
989 973
990 974
991 975 /*
|
↓ open down ↓ |
16 lines elided |
↑ open up ↑ |
992 976 * Append a backup date record to the specified file.
993 977 */
994 978 int
995 979 ndmpd_append_dumptime(char *fname, char *path, int level, time_t ddate)
996 980 {
997 981 char vol[ZFS_MAX_DATASET_NAME_LEN];
998 982 zfs_handle_t *zhp;
999 983 char tbuf[64];
1000 984 int rv;
1001 985
1002 - NDMP_LOG(LOG_DEBUG, "[%s][%s][%d][%u]", fname,
986 + syslog(LOG_DEBUG, "[%s][%s][%d][%u]", fname,
1003 987 path, level, ddate);
1004 988
1005 989 /* Check if this is a ZFS dataset */
1006 990 (void) mutex_lock(&zlib_mtx);
1007 991 if ((zlibh != NULL) &&
1008 992 (get_zfsvolname(vol, sizeof (vol), path) == 0) &&
1009 993 ((zhp = zfs_open(zlibh, vol, ZFS_TYPE_DATASET)) != NULL)) {
1010 994
1011 995 (void) ctime_r(&ddate, tbuf, sizeof (tbuf));
1012 996 rv = zfs_prop_set(zhp, zfs_dumpdate_props[level], tbuf);
1013 997 zfs_close(zhp);
1014 998
1015 999 (void) mutex_unlock(&zlib_mtx);
1016 1000 return (rv);
1017 1001 }
1018 1002 (void) mutex_unlock(&zlib_mtx);
1019 1003
1020 1004 (void) mutex_lock(&ndmp_dd_lock);
1021 1005 rv = append_dumptime(fname, path, level, ddate);
1022 1006 (void) mutex_unlock(&ndmp_dd_lock);
1023 1007
1024 1008 return (rv);
1025 1009 }
|
↓ open down ↓ |
13 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX