Print this page
NEX-1348 It takes 23 hours and 37 minutes to run NDMP backup 43.9 GB with10000000 3KB files
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
NEX-13094 Netbackup 8.0 failed to back up files in NDMP certification test
Reviewed by: Alex Deiter <alex.deiter@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
NEX-9532 NDMP: readdir errors when file/directory has special characters
Reviewed by: Peer Dampmann <peer.dampmann@nexenta.com>
Reviewed by: Alexander Eremin <alexander.eremin@nexenta.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
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-2947 Volumes with more than a small fixed about don't traverse properly
NEX-2911 NDMP logging should use syslog and is too chatty
NEX-2692 ndmpd intermittently dumps core due to SIGABRT in umem
SUP-898 nscd is extremely slow when a local file is missing
Reviewed by: Alek Pinchuk <alek.pinchuk@nexenta.com>
Reviewed by: Josef Sipek <josef.sipek@nexenta.com>
NEX-2500 Conflict between NDMP backup job and 'zfs send' leads to NDMP job abort.

*** 33,42 **** --- 33,44 ---- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ + /* Copyright 2017 Nexenta Systems, Inc. All rights reserved. */ + /* * This file implemets the post-order, pre-order and level-order * traversing of the file system. The related macros and constants * are defined in traverse.h. */
*** 78,88 **** /* * Macros on fs_traverse flags. */ #define STOP_ONERR(f) ((f)->ft_flags & FST_STOP_ONERR) #define STOP_ONLONG(f) ((f)->ft_flags & FST_STOP_ONLONG) - #define VERBOSE(f) ((f)->ft_flags & FST_VERBOSE) #define CALLBACK(pp, ep) \ (*(ftp)->ft_callbk)((ftp)->ft_arg, pp, ep) #define NEGATE(rv) ((rv) = -(rv)) --- 80,89 ----
*** 102,135 **** long ts_dpos; /* position in the directory when reading its entries */ fs_fhandle_t ts_fh; struct stat64 ts_st; } traverse_state_t; - /* - * Statistics gathering structure. - */ - typedef struct traverse_statistics { - ulong_t fss_newdirs; - ulong_t fss_readdir_err; - ulong_t fss_longpath_err; - ulong_t fss_lookup_err; - ulong_t fss_nondir_calls; - ulong_t fss_dir_calls; - ulong_t fss_nondir_skipped; - ulong_t fss_dir_skipped; - ulong_t fss_pushes; - ulong_t fss_pops; - ulong_t fss_stack_residue; - } traverse_statistics_t; - - /* - * Global instance of statistics variable. - */ - traverse_statistics_t traverse_stats; - - #define MAX_DENT_BUF_SIZE (8 * 1024) - typedef struct { struct stat64 fd_attr; fs_fhandle_t fd_fh; short fd_len; char fd_name[1]; --- 103,112 ----
*** 140,184 **** int da_end; int da_size; } dent_arg_t; static int traverse_level_nondir(struct fs_traverse *ftp, ! traverse_state_t *tsp, struct fst_node *pnp, ! dent_arg_t *darg); /* - * Gather some directory entry information and return them - */ - static int - fs_populate_dents(void *arg, int namelen, - char *name, long *countp, struct stat64 *attr, - fs_fhandle_t *fh) - { - dent_arg_t *darg = (dent_arg_t *)arg; - int reclen = sizeof (fs_dent_info_t) + namelen; - fs_dent_info_t *dent; - - if ((darg->da_end + reclen) > darg->da_size) - return (-1); - - /* LINTED improper alignment */ - dent = (fs_dent_info_t *)(darg->da_buf + darg->da_end); - - dent->fd_attr = *attr; - dent->fd_fh = *fh; - (void) strcpy(dent->fd_name, name); - - dent->fd_len = reclen; - darg->da_end += reclen; - - if (countp) - (*countp)++; - - return (0); - } - - /* * Creates a new traversing state based on the path passed to it. */ static traverse_state_t * new_tsp(char *path) { --- 117,129 ---- int da_end; int da_size; } dent_arg_t; static int traverse_level_nondir(struct fs_traverse *ftp, ! traverse_state_t *tsp, struct fst_node *pnp); /* * Creates a new traversing state based on the path passed to it. */ static traverse_state_t * new_tsp(char *path) {
*** 200,211 **** * Create a file handle and get stats for the given path */ int fs_getstat(char *path, fs_fhandle_t *fh, struct stat64 *st) { ! if (lstat64(path, st) == -1) return (errno); fh->fh_fid = st->st_ino; if (!S_ISDIR(st->st_mode)) fh->fh_fpath = NULL; --- 145,159 ---- * Create a file handle and get stats for the given path */ int fs_getstat(char *path, fs_fhandle_t *fh, struct stat64 *st) { ! if (lstat64(path, st) == -1) { ! syslog(LOG_INFO, ! "lstat64() says [%s] not found errno=(%d)", path, errno); return (errno); + } fh->fh_fid = st->st_ino; if (!S_ISDIR(st->st_mode)) fh->fh_fpath = NULL;
*** 213,286 **** fh->fh_fpath = strdup(path); return (0); } /* - * Get directory entries info and return in the buffer. Cookie - * will keep the state of each call - */ - static int - fs_getdents(int fildes, struct dirent *buf, size_t *nbyte, - char *pn_path, long *dpos, longlong_t *cookie, - long *n_entries, dent_arg_t *darg) - { - struct dirent *ptr; - char file_path[PATH_MAX + 1]; - fs_fhandle_t fh; - struct stat64 st; - char *p; - int len; - int rv; - - if (*nbyte == 0) { - (void) memset((char *)buf, 0, MAX_DENT_BUF_SIZE); - *nbyte = rv = getdents(fildes, buf, darg->da_size); - *cookie = 0LL; - - if (rv <= 0) - return (rv); - } - - p = (char *)buf + *cookie; - len = *nbyte; - do { - /* LINTED improper alignment */ - ptr = (struct dirent *)p; - *dpos = ptr->d_off; - - if (rootfs_dot_or_dotdot(ptr->d_name)) - goto skip_entry; - - (void) snprintf(file_path, PATH_MAX, "%s/", pn_path); - (void) strlcat(file_path, ptr->d_name, PATH_MAX + 1); - (void) memset(&fh, 0, sizeof (fs_fhandle_t)); - - if (lstat64(file_path, &st) != 0) { - rv = -1; - break; - } - - fh.fh_fid = st.st_ino; - - if (S_ISDIR(st.st_mode)) - goto skip_entry; - - if (fs_populate_dents(darg, strlen(ptr->d_name), - (char *)ptr->d_name, n_entries, &st, &fh) != 0) - break; - - skip_entry: - p = p + ptr->d_reclen; - len -= ptr->d_reclen; - } while (len); - - *cookie = (longlong_t)(p - (char *)buf); - *nbyte = len; - return (rv); - } - - /* * Read the directory entries and return the information about * each entry */ int fs_readdir(fs_fhandle_t *ts_fh, char *path, long *dpos, --- 161,170 ----
*** 336,375 **** struct stat64 pst, est; traverse_state_t *tsp; struct fst_node pn, en; /* parent and entry nodes */ if (!ftp || !ftp->ft_path || !*ftp->ft_path || !ftp->ft_callbk) { - NDMP_LOG(LOG_DEBUG, "Invalid argument"); errno = EINVAL; return (-1); } /* set the default log function if it's not already set */ if (!ftp->ft_logfp) { ftp->ft_logfp = (ft_log_t)syslog; ! NDMP_LOG(LOG_DEBUG, "Log to system log \"%s\"", ftp->ft_path); } /* set the logical path to physical path if it's not already set */ if (!ftp->ft_lpath) { ! NDMP_LOG(LOG_DEBUG, "report the same paths: \"%s\"", ftp->ft_path); ftp->ft_lpath = ftp->ft_path; } pl = strlen(ftp->ft_lpath); if (pl + 1 > PATH_MAX) { /* +1 for the '/' */ ! NDMP_LOG(LOG_DEBUG, "lpath too long \"%s\"", ftp->ft_path); errno = ENAMETOOLONG; return (-1); } (void) strcpy(path, ftp->ft_lpath); (void) memset(&pfh, 0, sizeof (pfh)); rv = fs_getstat(ftp->ft_lpath, &pfh, &pst); if (rv != 0) { ! NDMP_LOG(LOG_DEBUG, "Error %d on fs_getstat(%s)", rv, ftp->ft_path); return (rv); } if (!S_ISDIR(pst.st_mode)) { --- 220,258 ---- struct stat64 pst, est; traverse_state_t *tsp; struct fst_node pn, en; /* parent and entry nodes */ if (!ftp || !ftp->ft_path || !*ftp->ft_path || !ftp->ft_callbk) { errno = EINVAL; return (-1); } /* set the default log function if it's not already set */ if (!ftp->ft_logfp) { ftp->ft_logfp = (ft_log_t)syslog; ! syslog(LOG_DEBUG, "Log to system log \"%s\"", ftp->ft_path); } /* set the logical path to physical path if it's not already set */ if (!ftp->ft_lpath) { ! syslog(LOG_DEBUG, "report the same paths: \"%s\"", ftp->ft_path); ftp->ft_lpath = ftp->ft_path; } pl = strlen(ftp->ft_lpath); if (pl + 1 > PATH_MAX) { /* +1 for the '/' */ ! syslog(LOG_ERR, "lpath too long \"%s\"", ftp->ft_path); errno = ENAMETOOLONG; return (-1); } (void) strcpy(path, ftp->ft_lpath); (void) memset(&pfh, 0, sizeof (pfh)); rv = fs_getstat(ftp->ft_lpath, &pfh, &pst); if (rv != 0) { ! syslog(LOG_ERR, "Error %d on fs_getstat(%s)", rv, ftp->ft_path); return (rv); } if (!S_ISDIR(pst.st_mode)) {
*** 378,389 **** pn.tn_st = &pst; en.tn_path = NULL; en.tn_fh = NULL; en.tn_st = NULL; rv = CALLBACK(&pn, &en); - if (VERBOSE(ftp)) - NDMP_LOG(LOG_DEBUG, "CALLBACK(%s): %d", pn.tn_path, rv); free(pfh.fh_fpath); return (rv); } sp = cstack_new(); --- 261,270 ----
*** 408,422 **** rv = 0; next_dir = 1; do { if (next_dir) { - traverse_stats.fss_newdirs++; - *tsp->ts_end = '\0'; - if (VERBOSE(ftp)) - NDMP_LOG(LOG_DEBUG, "pl %d \"%s\"", pl, path); } next_dir = 0; do { el = NAME_MAX; --- 289,299 ----
*** 423,436 **** rv = fs_readdir(&tsp->ts_fh, pn.tn_path, &tsp->ts_dpos, nm, &el, &efh, &est); if (rv != 0) { ! free(efh.fh_fpath); ! traverse_stats.fss_readdir_err++; ! ! NDMP_LOG(LOG_DEBUG, "Error %d on readdir(%s) pos %d", rv, path, tsp->ts_dpos); if (STOP_ONERR(ftp)) break; rv = SKIP_ENTRY; --- 300,310 ---- rv = fs_readdir(&tsp->ts_fh, pn.tn_path, &tsp->ts_dpos, nm, &el, &efh, &est); if (rv != 0) { ! syslog(LOG_ERR, "Error %d on readdir(%s) pos %d", rv, path, tsp->ts_dpos); if (STOP_ONERR(ftp)) break; rv = SKIP_ENTRY;
*** 438,467 **** continue; } /* done with this directory */ if (el == 0) { - if (VERBOSE(ftp)) - NDMP_LOG(LOG_DEBUG, - "Done(%s)", pn.tn_path); break; } nm[el] = '\0'; if (rootfs_dot_or_dotdot(nm)) { free(efh.fh_fpath); continue; } - if (VERBOSE(ftp)) - NDMP_LOG(LOG_DEBUG, "%u dname: \"%s\"", - tsp->ts_dpos, nm); - if (pl + 1 + el > PATH_MAX) { ! traverse_stats.fss_longpath_err++; ! ! NDMP_LOG(LOG_ERR, "Path %s/%s is too long.", path, nm); if (STOP_ONLONG(ftp)) rv = ENAMETOOLONG; free(efh.fh_fpath); continue; --- 312,332 ---- continue; } /* done with this directory */ if (el == 0) { break; } nm[el] = '\0'; if (rootfs_dot_or_dotdot(nm)) { free(efh.fh_fpath); continue; } if (pl + 1 + el > PATH_MAX) { ! syslog(LOG_ERR, "Path %s/%s is too long.", path, nm); if (STOP_ONLONG(ftp)) rv = ENAMETOOLONG; free(efh.fh_fpath); continue;
*** 477,487 **** if (cstack_push(sp, tsp, 0)) { rv = ENOMEM; free(efh.fh_fpath); break; } - traverse_stats.fss_pushes++; /* * Concatenate the current entry with the * current path. This will be the path of * the new directory to be scanned. --- 342,351 ----
*** 516,537 **** } else { /* * The entry is not a directory so the * callback function must be called. */ - traverse_stats.fss_nondir_calls++; - en.tn_path = nm; en.tn_fh = &efh; en.tn_st = &est; rv = CALLBACK(&pn, &en); free(efh.fh_fpath); - if (VERBOSE(ftp)) - NDMP_LOG(LOG_DEBUG, - "CALLBACK(%s/%s): %d", - pn.tn_path, en.tn_path, rv); - if (rv != 0) break; } } while (rv == 0); --- 380,394 ----
*** 559,586 **** break; assert(tsp != NULL); pl = tsp->ts_end - path; - if (VERBOSE(ftp)) - NDMP_LOG(LOG_DEBUG, "poped pl %d 0x%p \"%s\"", - pl, tsp, path); - - traverse_stats.fss_pops++; - traverse_stats.fss_dir_calls++; - pn.tn_fh = &tsp->ts_fh; pn.tn_st = &tsp->ts_st; en.tn_path = lp + 1; en.tn_fh = &efh; en.tn_st = &est; rv = CALLBACK(&pn, &en); free(efh.fh_fpath); - if (VERBOSE(ftp)) - NDMP_LOG(LOG_DEBUG, "CALLBACK(%s/%s): %d", - pn.tn_path, en.tn_path, rv); /* * Does not need to free tsp here. It will be released * later. */ } --- 416,433 ----
*** 594,621 **** /* * For the 'ftp->ft_path' directory itself. */ if (rv == 0) { - traverse_stats.fss_dir_calls++; - pn.tn_fh = &efh; pn.tn_st = &est; en.tn_path = NULL; en.tn_fh = NULL; en.tn_st = NULL; rv = CALLBACK(&pn, &en); - if (VERBOSE(ftp)) - NDMP_LOG(LOG_DEBUG, "CALLBACK(%s): %d", pn.tn_path, rv); } /* * Pop and free all the remaining entries on the stack. */ while (!cstack_pop(sp, (void **)&tsp, (int *)NULL)) { - traverse_stats.fss_stack_residue++; - free(tsp->ts_fh.fh_fpath); free(tsp); } cstack_delete(sp); --- 441,462 ----
*** 635,741 **** * SKIP_ENTRY: Failed to get the directory entries, so the caller * should skip this entry. */ static int traverse_level_nondir(struct fs_traverse *ftp, ! traverse_state_t *tsp, struct fst_node *pnp, dent_arg_t *darg) { ! int pl; /* path length */ ! int rv; struct fst_node en; /* entry node */ ! longlong_t cookie_verf; ! fs_dent_info_t *dent; ! struct dirent *buf; ! size_t len = 0; ! int fd; ! rv = 0; ! pl = strlen(pnp->tn_path); ! ! buf = ndmp_malloc(MAX_DENT_BUF_SIZE); ! if (buf == NULL) return (errno); ! fd = open(tsp->ts_fh.fh_fpath, O_RDONLY); ! if (fd == -1) { ! free(buf); ! return (errno); } ! while (rv == 0) { ! long i, n_entries; ! ! darg->da_end = 0; ! n_entries = 0; ! rv = fs_getdents(fd, buf, &len, pnp->tn_path, &tsp->ts_dpos, ! &cookie_verf, &n_entries, darg); ! if (rv < 0) { ! traverse_stats.fss_readdir_err++; ! ! NDMP_LOG(LOG_DEBUG, "Error %d on readdir(%s) pos %d", ! rv, pnp->tn_path, tsp->ts_dpos); ! if (STOP_ONERR(ftp)) ! break; ! /* ! * We cannot read the directory entry, we should ! * skip to the next directory. ! */ ! rv = SKIP_ENTRY; continue; - } else { - /* Break at the end of directory */ - if (rv > 0) - rv = 0; - else - break; } ! /* LINTED imporper alignment */ ! dent = (fs_dent_info_t *)darg->da_buf; ! /* LINTED imporper alignment */ ! for (i = 0; i < n_entries; i++, dent = (fs_dent_info_t *) ! ((char *)dent + dent->fd_len)) { ! ! if (VERBOSE(ftp)) ! NDMP_LOG(LOG_DEBUG, "i %u dname: \"%s\"", ! dent->fd_fh.fh_fid, dent->fd_name); ! ! if ((pl + strlen(dent->fd_name)) > PATH_MAX) { ! traverse_stats.fss_longpath_err++; ! ! NDMP_LOG(LOG_ERR, "Path %s/%s is too long.", ! pnp->tn_path, dent->fd_name); ! if (STOP_ONLONG(ftp)) ! rv = -ENAMETOOLONG; ! free(dent->fd_fh.fh_fpath); continue; } /* * The entry is not a directory so the callback * function must be called. */ ! if (!S_ISDIR(dent->fd_attr.st_mode)) { ! traverse_stats.fss_nondir_calls++; ! ! en.tn_path = dent->fd_name; ! en.tn_fh = &dent->fd_fh; ! en.tn_st = &dent->fd_attr; rv = CALLBACK(pnp, &en); ! dent->fd_fh.fh_fpath = NULL; ! if (rv < 0) break; if (rv == FST_SKIP) { ! traverse_stats.fss_nondir_skipped++; break; } } } - } ! free(buf); ! (void) close(fd); return (rv); } /* * Traverse the file system in the level-order way. The description --- 476,546 ---- * SKIP_ENTRY: Failed to get the directory entries, so the caller * should skip this entry. */ static int traverse_level_nondir(struct fs_traverse *ftp, ! traverse_state_t *tsp, struct fst_node *pnp) { ! struct stat64 st; ! fs_fhandle_t fh; ! DIR *dp; ! struct dirent *dirp; struct fst_node en; /* entry node */ ! char path[MAXPATHLEN+MAXNAMELEN+2]; ! int rv = 0; ! if ((dp = opendir(tsp->ts_fh.fh_fpath)) == NULL) { ! syslog(LOG_ERR, ! "traverse_level_nondir: open directory " ! "%s failed: %m", tsp->ts_fh.fh_fpath); return (errno); + } ! while ((dirp = readdir(dp)) != NULL) { ! if ((strcmp(dirp->d_name, ".") == 0) || ! (strcmp(dirp->d_name, "..") == 0)) { ! continue; } ! if (!tlm_cat_path(path, tsp->ts_fh.fh_fpath, ! dirp->d_name)) { continue; } ! if (lstat64(path, &st) != 0) { ! syslog(LOG_ERR, ! "traverse_level_nondir: failed to get file" ! " status for %s skipping: %m", tsp->ts_fh.fh_fpath); continue; } + fh.fh_fid = st.st_ino; /* * The entry is not a directory so the callback * function must be called. */ ! if (!S_ISDIR(st.st_mode)) { ! en.tn_path = dirp->d_name; ! en.tn_fh = &fh; ! en.tn_st = &st; rv = CALLBACK(pnp, &en); ! if (rv < 0) { ! syslog(LOG_DEBUG, ! "traverse_level_nondir: result is %d " ! "with %s", rv, path); break; + } if (rv == FST_SKIP) { ! syslog(LOG_DEBUG, ! "traverse_level_nondir: skipping " ! "%s", path); break; } } } ! (void) closedir(dp); return (rv); } /* * Traverse the file system in the level-order way. The description
*** 753,792 **** cstack_t *sp; fs_fhandle_t pfh, efh; struct stat64 pst, est; traverse_state_t *tsp; struct fst_node pn, en; /* parent and entry nodes */ - dent_arg_t darg; if (!ftp || !ftp->ft_path || !*ftp->ft_path || !ftp->ft_callbk) { - NDMP_LOG(LOG_DEBUG, "Invalid argument"); errno = EINVAL; return (-1); } /* set the default log function if it's not already set */ if (!ftp->ft_logfp) { ftp->ft_logfp = (ft_log_t)syslog; ! NDMP_LOG(LOG_DEBUG, "Log to system log \"%s\"", ftp->ft_path); } if (!ftp->ft_lpath) { ! NDMP_LOG(LOG_DEBUG, "report the same paths \"%s\"", ftp->ft_path); ftp->ft_lpath = ftp->ft_path; } pl = strlen(ftp->ft_lpath); if (pl + 1 > PATH_MAX) { /* +1 for the '/' */ ! NDMP_LOG(LOG_DEBUG, "lpath too long \"%s\"", ftp->ft_path); errno = ENAMETOOLONG; return (-1); } (void) strcpy(path, ftp->ft_lpath); (void) memset(&pfh, 0, sizeof (pfh)); rv = fs_getstat(ftp->ft_lpath, &pfh, &pst); if (rv != 0) { ! NDMP_LOG(LOG_DEBUG, ! "Error %d on fs_getstat(%s)", rv, ftp->ft_path); return (-1); } en.tn_path = NULL; en.tn_fh = NULL; --- 558,595 ---- cstack_t *sp; fs_fhandle_t pfh, efh; struct stat64 pst, est; traverse_state_t *tsp; struct fst_node pn, en; /* parent and entry nodes */ if (!ftp || !ftp->ft_path || !*ftp->ft_path || !ftp->ft_callbk) { errno = EINVAL; return (-1); } /* set the default log function if it's not already set */ if (!ftp->ft_logfp) { ftp->ft_logfp = (ft_log_t)syslog; ! syslog(LOG_DEBUG, "Log to system log \"%s\"", ftp->ft_path); } if (!ftp->ft_lpath) { ! syslog(LOG_DEBUG, "report the same paths \"%s\"", ftp->ft_path); ftp->ft_lpath = ftp->ft_path; } pl = strlen(ftp->ft_lpath); if (pl + 1 > PATH_MAX) { /* +1 for the '/' */ ! syslog(LOG_ERR, "lpath too long \"%s\"", ftp->ft_path); errno = ENAMETOOLONG; return (-1); } (void) strcpy(path, ftp->ft_lpath); (void) memset(&pfh, 0, sizeof (pfh)); rv = fs_getstat(ftp->ft_lpath, &pfh, &pst); if (rv != 0) { ! syslog(LOG_DEBUG, ! "Error %d on fs_getstat(%s)", rv, ftp->ft_lpath); return (-1); } en.tn_path = NULL; en.tn_fh = NULL;
*** 794,806 **** if (!S_ISDIR(pst.st_mode)) { pn.tn_path = ftp->ft_lpath; pn.tn_fh = &pfh; pn.tn_st = &pst; rv = CALLBACK(&pn, &en); - if (VERBOSE(ftp)) - NDMP_LOG(LOG_DEBUG, "CALLBACK(%s): %d", pn.tn_path, rv); - free(pfh.fh_fpath); return (rv); } sp = cstack_new(); --- 597,606 ----
*** 815,866 **** free(pfh.fh_fpath); errno = ENOMEM; return (-1); } - darg.da_buf = ndmp_malloc(MAX_DENT_BUF_SIZE); - if (!darg.da_buf) { - cstack_delete(sp); - free(pfh.fh_fpath); - free(tsp); - errno = ENOMEM; - return (-1); - } - darg.da_size = MAX_DENT_BUF_SIZE; - tsp->ts_ent = tsp->ts_end; tsp->ts_fh = pfh; tsp->ts_st = pst; pn.tn_path = path; pn.tn_fh = &tsp->ts_fh; pn.tn_st = &tsp->ts_st; /* call the callback function on the path itself */ - traverse_stats.fss_dir_calls++; rv = CALLBACK(&pn, &en); if (rv < 0) { free(tsp); goto end; } if (rv == FST_SKIP) { - traverse_stats.fss_dir_skipped++; free(tsp); rv = 0; goto end; } rv = 0; next_dir = 1; do { if (next_dir) { - traverse_stats.fss_newdirs++; - *tsp->ts_end = '\0'; ! if (VERBOSE(ftp)) ! NDMP_LOG(LOG_DEBUG, "pl %d \"%s\"", pl, path); ! ! rv = traverse_level_nondir(ftp, tsp, &pn, &darg); if (rv < 0) { NEGATE(rv); free(tsp->ts_fh.fh_fpath); free(tsp); break; --- 615,649 ---- free(pfh.fh_fpath); errno = ENOMEM; return (-1); } tsp->ts_ent = tsp->ts_end; tsp->ts_fh = pfh; tsp->ts_st = pst; pn.tn_path = path; pn.tn_fh = &tsp->ts_fh; pn.tn_st = &tsp->ts_st; /* call the callback function on the path itself */ rv = CALLBACK(&pn, &en); if (rv < 0) { free(tsp); goto end; } if (rv == FST_SKIP) { free(tsp); rv = 0; goto end; } rv = 0; next_dir = 1; do { if (next_dir) { *tsp->ts_end = '\0'; ! rv = traverse_level_nondir(ftp, tsp, &pn); if (rv < 0) { NEGATE(rv); free(tsp->ts_fh.fh_fpath); free(tsp); break;
*** 891,903 **** el = NAME_MAX; rv = fs_readdir(&tsp->ts_fh, pn.tn_path, &tsp->ts_dpos, nm, &el, &efh, &est); if (rv != 0) { ! traverse_stats.fss_readdir_err++; ! ! NDMP_LOG(LOG_DEBUG, "Error %d on readdir(%s) pos %d", rv, path, tsp->ts_dpos); if (STOP_ONERR(ftp)) break; rv = SKIP_ENTRY; --- 674,684 ---- el = NAME_MAX; rv = fs_readdir(&tsp->ts_fh, pn.tn_path, &tsp->ts_dpos, nm, &el, &efh, &est); if (rv != 0) { ! syslog(LOG_DEBUG, "Error %d on readdir(%s) pos %d", rv, path, tsp->ts_dpos); if (STOP_ONERR(ftp)) break; rv = SKIP_ENTRY;
*** 913,935 **** if (rootfs_dot_or_dotdot(nm)) { free(efh.fh_fpath); continue; } - if (VERBOSE(ftp)) - NDMP_LOG(LOG_DEBUG, "%u dname: \"%s\"", - tsp->ts_dpos, nm); - if (pl + 1 + el > PATH_MAX) { /* * The long paths were already encountered * when processing non-dir entries in. * traverse_level_nondir. * We don't increase fss_longpath_err * counter for them again here. */ ! NDMP_LOG(LOG_ERR, "Path %s/%s is too long.", path, nm); if (STOP_ONLONG(ftp)) rv = ENAMETOOLONG; free(efh.fh_fpath); continue; --- 694,712 ---- if (rootfs_dot_or_dotdot(nm)) { free(efh.fh_fpath); continue; } if (pl + 1 + el > PATH_MAX) { /* * The long paths were already encountered * when processing non-dir entries in. * traverse_level_nondir. * We don't increase fss_longpath_err * counter for them again here. */ ! syslog(LOG_ERR, "Path %s/%s is too long.", path, nm); if (STOP_ONLONG(ftp)) rv = ENAMETOOLONG; free(efh.fh_fpath); continue;
*** 942,952 **** * Call the callback function for the new * directory found, then push the current * directory on to the stack. Then dive * into the entry found. */ - traverse_stats.fss_dir_calls++; en.tn_path = nm; en.tn_fh = &efh; en.tn_st = &est; rv = CALLBACK(&pn, &en); --- 719,728 ----
*** 954,964 **** NEGATE(rv); free(efh.fh_fpath); break; } if (rv == FST_SKIP) { - traverse_stats.fss_dir_skipped++; free(efh.fh_fpath); rv = 0; continue; } --- 730,739 ----
*** 967,978 **** * dive into the entry found. */ if (cstack_push(sp, tsp, 0)) { rv = ENOMEM; } else { - traverse_stats.fss_pushes++; - lp = tsp->ts_end; *tsp->ts_end = '/'; (void) strcpy(tsp->ts_end + 1, nm); tsp = new_tsp(path); --- 742,751 ----
*** 1009,1024 **** if (rv == 0) { if (cstack_pop(sp, (void **)&tsp, (int *)NULL)) break; - traverse_stats.fss_pops++; - - if (VERBOSE(ftp)) - NDMP_LOG(LOG_DEBUG, - "Poped pl %d \"%s\"", pl, path); - *tsp->ts_end = '\0'; pl = tsp->ts_end - path; pn.tn_fh = &tsp->ts_fh; pn.tn_st = &tsp->ts_st; } --- 782,791 ----
*** 1026,1042 **** /* * Pop and free all the remaining entries on the stack. */ while (!cstack_pop(sp, (void **)&tsp, (int *)NULL)) { - traverse_stats.fss_stack_residue++; - free(tsp->ts_fh.fh_fpath); free(tsp); } end: - free(darg.da_buf); cstack_delete(sp); return (rv); } /* --- 793,806 ----