/* * timecmp * * This callback function is used during backup. It checks * if the object specified by the 'attr' should be backed * up or not. * * Directories are backed up anyways for dump format. * If this function is called, then the directory is * marked in the bitmap vector, it shows that either the * directory itself is modified or there is something below * it that will be backed up. * * Directories for tar format are backed up if and only if * they are modified. * * By setting ndmp_force_bk_dirs global variable to a non-zero * value, directories are backed up anyways. * * Backing up the directories unconditionally, helps * restoring the metadata of directories as well, when one * of the objects below them are being restored. * * For non-directory objects, if the modification or change * time of the object is after the date specified by the * bk_selector_t, the the object must be backed up. * */ static boolean_t timecmp(bk_selector_t *bksp, struct stat64 *attr) { ndmp_lbr_params_t *nlp; nlp = (ndmp_lbr_params_t *)bksp->bs_cookie; if (S_ISDIR(attr->st_mode) && ndmp_force_bk_dirs) { NDMP_LOG(LOG_DEBUG, "d(%lu)", (uint_t)attr->st_ino); return (TRUE); } if (S_ISDIR(attr->st_mode) && dbm_getone(nlp->nlp_bkmap, (u_longlong_t)attr->st_ino) && ((NLP_ISDUMP(nlp) && ndmp_dump_path_node) || (NLP_ISTAR(nlp) && ndmp_tar_path_node))) { /* * If the object is a directory and it leads to a modified * object (that should be backed up) and for that type of * backup the path nodes should be backed up, then return * TRUE. * * This is required by some DMAs like Backup Express, which * needs to receive ADD_NODE (for dump) or ADD_PATH (for tar) * for the intermediate directories of a modified object. * Other DMAs, like net_backup and net_worker, do not have such * requirement. This requirement makes sense for dump format * but for 'tar' format, it does not. In provision to the * NDMP-v4 spec, for 'tar' format the intermediate directories * need not to be reported. */ NDMP_LOG(LOG_DEBUG, "p(%lu)", (u_longlong_t)attr->st_ino); return (TRUE); } if (attr->st_mtime > bksp->bs_ldate) { NDMP_LOG(LOG_DEBUG, "m(%lu): %lu > %lu", (uint_t)attr->st_ino, (uint_t)attr->st_mtime, (uint_t)bksp->bs_ldate); return (TRUE); } if (attr->st_ctime > bksp->bs_ldate) { if (NLP_IGNCTIME(nlp)) { NDMP_LOG(LOG_DEBUG, "ign c(%lu): %lu > %lu", (uint_t)attr->st_ino, (uint_t)attr->st_ctime, (uint_t)bksp->bs_ldate); return (FALSE); } NDMP_LOG(LOG_DEBUG, "c(%lu): %lu > %lu", (uint_t)attr->st_ino, (uint_t)attr->st_ctime, (uint_t)bksp->bs_ldate); return (TRUE); } NDMP_LOG(LOG_DEBUG, "mc(%lu): (%lu,%lu) < %lu", (uint_t)attr->st_ino, (uint_t)attr->st_mtime, (uint_t)attr->st_ctime, (uint_t)bksp->bs_ldate); return (FALSE); }
/* * mark_cb * * The callback function, called by traverse_post to mark bits * in the bitmap. * * Set the bit of the entry if it's been modified (obviously * should be backed up) plus its parent directory. * * If the entry is a directory and is not modified itself, * but it's marked, then there is something below it that * is being backed up. It shows the the path, leads to * an object that will be backed up. So the path should * be marked too. * * The backup path itself is always marked. * * Parameters: * arg (input) - pointer to the mark parameter * pnp (input) - pointer to the path node * enp (input) - pointer to the entry node * * Returns: * 0: as long as traversing should continue * != 0: if traversing should stop */ int mark_cb(void *arg, fst_node_t *pnp, fst_node_t *enp) { int bmd; int rv; u_longlong_t bl; time_t ddate; fs_fhandle_t *pfhp, *efhp; struct stat64 *pstp, *estp; mark_param_t *mpp; ndmp_lbr_params_t *nlp; tlm_acls_t *tacl; rv = 0; mpp = (mark_param_t *)arg; tacl = mpp->mp_tacl; nlp = ndmp_get_nlp(mpp->mp_session); if (!mpp) { syslog(LOG_ERR, "NULL argument passed"); rv = -1; } else if (mpp->mp_session->ns_eof) { syslog(LOG_INFO, "Connection to the client is closed"); rv = -1; } else if (mpp->mp_session->ns_data.dd_abort || (nlp && NLP_ISSET(nlp, NLPF_ABORTED))) { syslog(LOG_INFO, "Processing directories aborted."); rv = -1; } if (rv != 0) return (rv); ddate = mpp->mp_ddate; bmd = mpp->mp_bmd; bl = dbm_getlen(bmd); pfhp = pnp->tn_fh; pstp = pnp->tn_st; /* sanity check on fh and stat of the path passed */ if (pstp->st_ino > bl) { syslog(LOG_ERR, "Invalid path inode #%u", (uint_t)pstp->st_ino); return (-1); } if (pstp->st_ino != pfhp->fh_fid) { syslog(LOG_ERR, "Path ino mismatch %u %u", (uint_t)pstp->st_ino, (uint_t)pfhp->fh_fid); return (-1); } /* * Always mark the backup path inode number. */ if (!enp->tn_path) { (void) dbm_setone(bmd, pstp->st_ino); return (0); } efhp = enp->tn_fh; estp = enp->tn_st; /* sanity check on fh and stat of the entry passed */ if (estp->st_ino > bl) { syslog(LOG_ERR, "Invalid entry inode #%u", (uint_t)estp->st_ino); return (-1); } if (estp->st_ino != efhp->fh_fid) { syslog(LOG_ERR, "Entry ino mismatch %u %u", estp->st_ino, (uint_t)pfhp->fh_fid); return (-1); } /* check the dates and mark the bitmap inode */ if (ddate == 0) { /* base backup */ (void) dbm_setone(bmd, (u_longlong_t)estp->st_ino); (void) dbm_setone(bmd, (u_longlong_t)pstp->st_ino); } else if (estp->st_mtime > ddate) { (void) dbm_setone(bmd, (u_longlong_t)estp->st_ino); (void) dbm_setone(bmd, (u_longlong_t)pstp->st_ino); if (ndmpd_verbose_traverse) { syslog(LOG_DEBUG, "m(%u,%u,%u,%u)", (uint_t)pstp->st_ino, (uint_t)estp->st_ino, (uint_t)estp->st_mtime, (uint_t)ddate); syslog(LOG_DEBUG, "\"%s/%s\"", pnp->tn_path, enp->tn_path); } } else if (iscreated(nlp, NULL, tacl, ddate)) { (void) dbm_setone(bmd, (u_longlong_t)estp->st_ino); (void) dbm_setone(bmd, (u_longlong_t)pstp->st_ino); if (ndmpd_verbose_traverse) { syslog(LOG_DEBUG, "cr(%u,%u,%u,%u)", (uint_t)pstp->st_ino, (uint_t)estp->st_ino, (uint_t)estp->st_mtime, (uint_t)ddate); syslog(LOG_DEBUG, "\"%s/%s\"", pnp->tn_path, enp->tn_path); } } else if (estp->st_ctime > ddate) { if (!NLP_IGNCTIME(nlp)) { (void) dbm_setone(bmd, (u_longlong_t)estp->st_ino); (void) dbm_setone(bmd, (u_longlong_t)pstp->st_ino); } if (ndmpd_verbose_traverse) { if (NLP_IGNCTIME(nlp)) { syslog(LOG_DEBUG, "ign c(%u,%u,%u,%u)", (uint_t)pstp->st_ino, (uint_t)estp->st_ino, (uint_t)estp->st_ctime, (uint_t)ddate); } else { syslog(LOG_DEBUG, "c(%u,%u,%u,%u)", (uint_t)pstp->st_ino, (uint_t)estp->st_ino, (uint_t)estp->st_ctime, (uint_t)ddate); } syslog(LOG_DEBUG, "\"%s/%s\"", pnp->tn_path, enp->tn_path); } } else if (S_ISDIR(estp->st_mode) && dbm_getone(bmd, (u_longlong_t)estp->st_ino)) { (void) dbm_setone(bmd, (u_longlong_t)pstp->st_ino); } return (0); }