From c3b1332470f9c332f083b8517c65a0fa21fcf4b1 Mon Sep 17 00:00:00 2001 From: Eric Bollengier Date: Fri, 28 Jan 2011 10:50:31 +0100 Subject: [PATCH] Detect mount/junction points and ignore junctions in Windows --- bacula/src/filed/backup.c | 13 ++++++------- bacula/src/filed/estimate.c | 1 + bacula/src/filed/verify.c | 4 +++- bacula/src/findlib/create_file.c | 1 + bacula/src/findlib/find.c | 3 ++- bacula/src/findlib/find_one.c | 22 +++++++++++++++++++++- 6 files changed, 34 insertions(+), 10 deletions(-) diff --git a/bacula/src/filed/backup.c b/bacula/src/filed/backup.c index 72bef802be..78ec13f01e 100644 --- a/bacula/src/filed/backup.c +++ b/bacula/src/filed/backup.c @@ -353,13 +353,8 @@ int save_file(JCR *jcr, FF_PKT *ff_pkt, bool top_level) case FT_NOFSCHG: /* Suppress message for /dev filesystems */ if (!is_in_fileset(ff_pkt)) { -#ifdef HAVE_WIN32 - Jmsg(jcr, M_INFO, 1, _(" %s is a junction point or a different filesystem. Will not descend from %s into it.\n"), - ff_pkt->fname, ff_pkt->top_fname); -#else Jmsg(jcr, M_INFO, 1, _(" %s is a different filesystem. Will not descend from %s into it.\n"), ff_pkt->fname, ff_pkt->top_fname); -#endif } ff_pkt->type = FT_DIREND; /* Backup only the directory entry */ break; @@ -373,6 +368,7 @@ int save_file(JCR *jcr, FF_PKT *ff_pkt, bool top_level) ff_pkt->fname); break; case FT_REPARSE: + case FT_JUNCTION: case FT_DIREND: Dmsg1(130, "FT_DIREND: %s\n", ff_pkt->link); break; @@ -538,7 +534,7 @@ int save_file(JCR *jcr, FF_PKT *ff_pkt, bool top_level) do_read = ff_pkt->statp.st_size > 0; #endif } else if (ff_pkt->type == FT_RAW || ff_pkt->type == FT_FIFO || - ff_pkt->type == FT_REPARSE || + ff_pkt->type == FT_REPARSE || ff_pkt->type == FT_JUNCTION || (!is_portable_backup(&ff_pkt->bfd) && ff_pkt->type == FT_DIREND)) { do_read = true; } @@ -557,7 +553,8 @@ int save_file(JCR *jcr, FF_PKT *ff_pkt, bool top_level) tid = NULL; } int noatime = ff_pkt->flags & FO_NOATIME ? O_NOATIME : 0; - ff_pkt->bfd.reparse_point = ff_pkt->type == FT_REPARSE; + ff_pkt->bfd.reparse_point = (ff_pkt->type == FT_REPARSE || + ff_pkt->type == FT_JUNCTION); if (bopen(&ff_pkt->bfd, ff_pkt->fname, O_RDONLY | O_BINARY | noatime, 0) < 0) { ff_pkt->ff_errno = errno; berrno be; @@ -1197,6 +1194,7 @@ bool encode_and_send_attributes(JCR *jcr, FF_PKT *ff_pkt, int &data_stream) break; case FT_DIREND: case FT_REPARSE: + case FT_JUNCTION: /* Here link is the canonical filename (i.e. with trailing slash) */ stat = sd->fsend("%ld %d %s%c%s%c%c%s%c%u%c", jcr->JobFiles, ff_pkt->type, ff_pkt->link, 0, attribs, 0, 0, @@ -1385,6 +1383,7 @@ static void close_vss_backup_session(JCR *jcr) ff_pkt->object_name = (char *)"job_metadata.xml"; ff_pkt->object = (char *)metadata; ff_pkt->object_len = (wcslen(metadata) + 1) * sizeof(WCHAR); + ff_pkt->object_index = (int)time(NULL); save_file(jcr, ff_pkt, true); } } diff --git a/bacula/src/filed/estimate.c b/bacula/src/filed/estimate.c index 3f6f7dc627..7888bc9ffe 100644 --- a/bacula/src/filed/estimate.c +++ b/bacula/src/filed/estimate.c @@ -82,6 +82,7 @@ static int tally_file(JCR *jcr, FF_PKT *ff_pkt, bool top_level) case FT_INVALIDFS: case FT_INVALIDDT: case FT_REPARSE: + case FT_JUNCTION: case FT_DIREND: case FT_SPEC: case FT_RAW: diff --git a/bacula/src/filed/verify.c b/bacula/src/filed/verify.c index 5f3841d4c5..287f0a4ad3 100644 --- a/bacula/src/filed/verify.c +++ b/bacula/src/filed/verify.c @@ -108,6 +108,7 @@ static int verify_file(JCR *jcr, FF_PKT *ff_pkt, bool top_level) jcr->num_files_examined--; /* correct file count */ return 1; /* ignored */ case FT_REPARSE: + case FT_JUNCTION: case FT_DIREND: Dmsg1(30, "FT_DIR saving: %s\n", ff_pkt->fname); break; @@ -196,7 +197,8 @@ static int verify_file(JCR *jcr, FF_PKT *ff_pkt, bool top_level) stat = dir->fsend("%d %d %s %s%c%s%c%s%c", jcr->JobFiles, STREAM_UNIX_ATTRIBUTES, ff_pkt->VerifyOpts, ff_pkt->fname, 0, attribs, 0, ff_pkt->link, 0); - } else if (ff_pkt->type == FT_DIREND || ff_pkt->type == FT_REPARSE) { + } else if (ff_pkt->type == FT_DIREND || ff_pkt->type == FT_REPARSE || + ff_pkt->type == FT_JUNCTION) { /* Here link is the canonical filename (i.e. with trailing slash) */ stat = dir->fsend("%d %d %s %s%c%s%c%c", jcr->JobFiles, STREAM_UNIX_ATTRIBUTES, ff_pkt->VerifyOpts, ff_pkt->link, diff --git a/bacula/src/findlib/create_file.c b/bacula/src/findlib/create_file.c index 6a4fddd568..ab8afd2ff5 100644 --- a/bacula/src/findlib/create_file.c +++ b/bacula/src/findlib/create_file.c @@ -362,6 +362,7 @@ int create_file(JCR *jcr, ATTR *attr, BFILE *bfd, int replace) } /* End inner switch */ case FT_REPARSE: + case FT_JUNCTION: bfd->reparse_point = true; /* Fall through wanted */ case FT_DIRBEGIN: diff --git a/bacula/src/findlib/find.c b/bacula/src/findlib/find.c index 3c60f95219..77ac196dab 100644 --- a/bacula/src/findlib/find.c +++ b/bacula/src/findlib/find.c @@ -445,7 +445,6 @@ static int our_callback(JCR *jcr, FF_PKT *ff, bool top_level) case FT_INVALIDFS: case FT_INVALIDDT: case FT_NOOPEN: - case FT_REPARSE: // return ff->file_save(jcr, ff, top_level); /* These items can be filtered */ @@ -459,6 +458,8 @@ static int our_callback(JCR *jcr, FF_PKT *ff, bool top_level) case FT_FIFO: case FT_SPEC: case FT_DIRNOCHG: + case FT_REPARSE: + case FT_JUNCTION: if (accept_file(ff)) { return ff->file_save(jcr, ff, top_level); } else { diff --git a/bacula/src/findlib/find_one.c b/bacula/src/findlib/find_one.c index 6cad341518..64a5ec0dd8 100644 --- a/bacula/src/findlib/find_one.c +++ b/bacula/src/findlib/find_one.c @@ -586,8 +586,27 @@ find_one_file(JCR *jcr, FF_PKT *ff_pkt, * if st_rdev is 2, it is a mount point */ #if defined(HAVE_WIN32) + /* + * A reparse point (WIN32_REPARSE_POINT) + * is something special like one of the following: + * IO_REPARSE_TAG_DFS 0x8000000A + * IO_REPARSE_TAG_DFSR 0x80000012 + * IO_REPARSE_TAG_HSM 0xC0000004 + * IO_REPARSE_TAG_HSM2 0x80000006 + * IO_REPARSE_TAG_SIS 0x80000007 + * IO_REPARSE_TAG_SYMLINK 0xA000000C + * + * A junction point is a: + * IO_REPARSE_TAG_MOUNT_POINT 0xA0000003 + * which can be either a link to a Volume (WIN32_MOUNT_POINT) + * or a link to a directory (WIN32_JUNCTION_POINT) + * + * Ignore WIN32_REPARSE_POINT and WIN32_JUNCTION_POINT + */ if (ff_pkt->statp.st_rdev == WIN32_REPARSE_POINT) { ff_pkt->type = FT_REPARSE; + } else if (ff_pkt->statp.st_rdev == WIN32_JUNCTION_POINT) { + ff_pkt->type = FT_JUNCTION; } #endif /* @@ -599,7 +618,8 @@ find_one_file(JCR *jcr, FF_PKT *ff_pkt, * in the directory is seen (i.e. the FT_DIREND). */ rtn_stat = handle_file(jcr, ff_pkt, top_level); - if (rtn_stat < 1 || ff_pkt->type == FT_REPARSE) { /* ignore or error status */ + if (rtn_stat < 1 || ff_pkt->type == FT_REPARSE || + ff_pkt->type == FT_JUNCTION) { /* ignore or error status */ free(link); return rtn_stat; } -- 2.39.5