Beispiel #1
0
/*
 * 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);
}
Beispiel #2
0
/*
 * 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);
}