/* * mark_common_v2 * * Create the inode bitmap. If last date of the the * backup is epoch, then all the objects should be backed * up; there is no need to traverse the backup hierarchy * and mark the inodes. All the bits should be marked. * * Otherwise, the backup hierarchy should be traversed and * the objects should be marked. * * Parameters: * session (input) - pointer to the session * nlp (input) - pointer to the nlp structure * * Returns: * 0: on success. * != 0: on error. */ static int mark_common_v2(ndmpd_session_t *session, ndmp_lbr_params_t *nlp) { char buf[TLM_MAX_PATH_NAME], *chkpath; int rv; /* * Everything is needed for full backup. */ if (nlp->nlp_ldate == (time_t)0) return (create_allset_bitmap(nlp)); rv = 0; nlp->nlp_bkmap = create_bitmap(nlp->nlp_backup_path, 0); syslog(LOG_DEBUG, "nlp_bkmap %d", nlp->nlp_bkmap); if (nlp->nlp_bkmap < 0) { syslog(LOG_ERR, "Failed to allocate bitmap in mark_common_v2"); rv = -1; } else { if (fs_is_chkpntvol(nlp->nlp_backup_path)) chkpath = nlp->nlp_backup_path; else chkpath = tlm_build_snapshot_name( nlp->nlp_backup_path, buf, nlp->nlp_jstat->js_job_name); rv = mark_inodes_v2(session, nlp, chkpath); (void) dbm_setone(nlp->nlp_bkmap, (u_longlong_t)ROOT_INODE); } return (rv); }
/* * check_backup_dir_validity * * Check if the backup directory is valid. Make sure it exists and * is writable. Check for snapshot and readonly cases. */ static int check_backup_dir_validity(ndmpd_module_params_t *params, char *bkpath) { char *msg; int rv; struct stat64 st; rv = NDMP_NO_ERR; if (stat64(bkpath, &st) < 0) { msg = strerror(errno); MOD_LOG(params, "Error: stat(%s): %s.\n", bkpath, msg); rv = NDMP_ILLEGAL_ARGS_ERR; } else if (!S_ISDIR(st.st_mode)) { MOD_LOG(params, "Error: %s is not a directory.\n", bkpath); rv = NDMP_ILLEGAL_ARGS_ERR; } else if (fs_is_rdonly(bkpath) && !fs_is_chkpntvol(bkpath) && fs_is_chkpnt_enabled(bkpath)) { MOD_LOG(params, "Error: %s is not a checkpointed path.\n", bkpath); rv = NDMP_BAD_FILE_ERR; } return (rv); }
/* * create_bitmap * * Create a dbitmap and return its descriptor. * * Parameters: * path (input) - path for which the bitmap should be created * value (input) - the initial value for the bitmap * * Returns: * the dbitmap descriptor */ static int create_bitmap(char *path, int value) { char bm_fname[PATH_MAX]; char buf[TLM_MAX_PATH_NAME]; char *livepath; ulong_t ninode; syslog(LOG_DEBUG, "path \"%s\"", path); if (fs_is_chkpntvol(path)) livepath = (char *)tlm_remove_checkpoint(path, buf); else livepath = path; ninode = 1024 * 1024 * 1024; if (ninode == 0) return (-1); (void) ndmpd_mk_temp(bm_fname); syslog(LOG_DEBUG, "path \"%s\"ninode %u bm_fname \"%s\"", livepath, ninode, bm_fname); return (dbm_alloc(bm_fname, (u_longlong_t)ninode, value)); }
/* * ndmpd_tar_backup_starter (V2 only) * * The main backup starter function. It creates a snapshot if necessary * and calls ndmp_tar_backup to perform the actual backup. It does the cleanup * and release the snapshot at the end. */ int ndmpd_tar_backup_starter(void *arg) { ndmpd_module_params_t *mod_params = arg; int err; ndmpd_session_t *session; ndmp_lbr_params_t *nlp; session = (ndmpd_session_t *)(mod_params->mp_daemon_cookie); *(mod_params->mp_module_cookie) = nlp = ndmp_get_nlp(session); ndmp_session_ref(session); err = 0; if (fs_is_chkpntvol(nlp->nlp_backup_path) || fs_is_rdonly(nlp->nlp_backup_path) || !fs_is_chkpnt_enabled(nlp->nlp_backup_path)) NLP_SET(nlp, NLPF_CHKPNTED_PATH); else { NLP_UNSET(nlp, NLPF_CHKPNTED_PATH); if (ndmp_create_snapshot(nlp->nlp_backup_path, nlp->nlp_jstat->js_job_name) < 0) { MOD_LOG(mod_params, "Error: creating checkpoint on %s\n", nlp->nlp_backup_path); /* -1 causes halt reason to become internal error. */ err = -1; } } NDMP_LOG(LOG_DEBUG, "NLPF_CHKPNTED_PATH: %c", NDMP_YORN(NLP_ISCHKPNTED(nlp))); NDMP_LOG(LOG_DEBUG, "err: %d, update %c", err, NDMP_YORN(NLP_SHOULD_UPDATE(nlp))); if (err == 0) { err = ndmp_get_cur_bk_time(nlp, &nlp->nlp_cdate, nlp->nlp_jstat->js_job_name); if (err != 0) { NDMP_LOG(LOG_DEBUG, "err %d", err); } else { log_bk_params_v2(session, mod_params, nlp); err = ndmpd_tar_backup(session, mod_params, nlp); } } if (nlp->nlp_bkmap >= 0) { (void) dbm_free(nlp->nlp_bkmap); nlp->nlp_bkmap = -1; } if (!NLP_ISCHKPNTED(nlp)) (void) ndmp_remove_snapshot(nlp->nlp_backup_path, nlp->nlp_jstat->js_job_name); NDMP_LOG(LOG_DEBUG, "err %d, update %c", err, NDMP_YORN(NLP_SHOULD_UPDATE(nlp))); if (err == 0 && NLP_SHOULD_UPDATE(nlp)) { if (ndmpd_put_dumptime(nlp->nlp_backup_path, nlp->nlp_clevel, nlp->nlp_cdate) < 0) { err = EPERM; MOD_LOG(mod_params, "Error: updating the dumpdates file on %s\n", nlp->nlp_backup_path); } } MOD_DONE(mod_params, err); /* nlp_params is allocated in start_backup() */ NDMP_FREE(nlp->nlp_params); NS_DEC(nbk); ndmp_session_unref(session); return (err); }
/* * ndmp_restore_extract_params * * Go through the restore parameters and check them and extract them * by setting NLP flags and other values. * * Parameters: * * Returns: * 0: on success * -1: otherwise */ int ndmp_restore_extract_params(ndmpd_session_t *session, ndmpd_module_params_t *params) { char *bkpath, *rspath; ndmp_lbr_params_t *nlp; if ((nlp = ndmp_get_nlp(session)) == NULL) { NDMP_LOG(LOG_DEBUG, "nlp == NULL"); return (-1); } /* Extract directory from where the backup was made. */ if ((bkpath = get_backup_path_v2(params)) == NULL) return (NDMP_ILLEGAL_ARGS_ERR); nlp->nlp_restore_bk_path = bkpath; /* The number of the selections. */ if ((nlp->nlp_nfiles = get_nfiles(session, params)) == 0) return (NDMP_ILLEGAL_ARGS_ERR); NDMP_LOG(LOG_DEBUG, "nfiles: %d", nlp->nlp_nfiles); if ((rspath = get_restore_dest(params)) == NULL) return (NDMP_ILLEGAL_ARGS_ERR); if (fs_is_rdonly(rspath)) { MOD_LOG(params, "Error: Can't restore to a read-only volume: \"%s\"\n", rspath); return (NDMP_ILLEGAL_ARGS_ERR); } if (fs_is_chkpntvol(rspath)) { MOD_LOG(params, "Error: Can't restore to a checkpoint: \"%s\"\n", rspath); return (NDMP_ILLEGAL_ARGS_ERR); } if (same_path(bkpath, rspath)) rspath = ""; if ((nlp->nlp_restore_path = strdup(rspath)) == NULL) return (NDMP_NO_MEM_ERR); bkpath = trim_name(bkpath); if (correct_ents(params, nlp->nlp_nfiles, bkpath) < 0) { free(nlp->nlp_restore_path); return (NDMP_ILLEGAL_ARGS_ERR); } if (check_restore_paths(params, nlp->nlp_nfiles, rspath) < 0) { free(nlp->nlp_restore_path); return (NDMP_ILLEGAL_ARGS_ERR); } MOD_LOG(params, "Restoring %d files.\n", nlp->nlp_nfiles); MOD_LOG(params, "Restoring to: \"%s\".\n", nlp->nlp_restore_path); MOD_LOG(params, "Record size: %d\n", session->ns_mover.md_record_size); return (NDMP_NO_ERR); }
/* * Check if the volume is read-only */ boolean_t fs_is_rdonly(char *path) { return (fs_is_chkpntvol(path)); }