Example #1
0
/*
 * See in the tree with selected files what files were selected to be restored.
 */
static inline int set_files_to_restore(JCR *jcr, struct ndm_job_param *job, int32_t FileIndex,
                                       const char *restore_prefix, const char *ndmp_filesystem)
{
   int len;
   int cnt = 0;
   TREE_NODE *node, *parent;
   POOL_MEM restore_pathname, tmp;

   node = first_tree_node(jcr->restore_tree_root);
   while (node) {
      /*
       * See if this is the wanted FileIndex and the user asked to extract it.
       */
      if (node->FileIndex == FileIndex && node->extract) {
         pm_strcpy(restore_pathname, node->fname);

         /*
          * Walk up the parent until we hit the head of the list.
          */
         for (parent = node->parent; parent; parent = parent->parent) {
            pm_strcpy(tmp, restore_pathname.c_str());
            Mmsg(restore_pathname, "%s/%s", parent->fname, tmp.c_str());
         }

         /*
          * We only want to restore the non pseudo NDMP names e.g. not the full backup stream name.
          */
         if (!bstrncmp(restore_pathname.c_str(), "/@NDMP/", 7)) {
            /*
             * See if we need to strip the prefix from the filename.
             */
            len = strlen(ndmp_filesystem);
            if (bstrncmp(restore_pathname.c_str(), ndmp_filesystem, len)) {
               add_to_namelist(job,  restore_pathname.c_str() + len, restore_prefix,
                               (char *)"", (char *)"", NDMP_INVALID_U_QUAD);
            } else {
               add_to_namelist(job,  restore_pathname.c_str(), restore_prefix,
                               (char *)"", (char *)"", NDMP_INVALID_U_QUAD);
            }
            cnt++;
         }
      }

      node = next_tree_node(node);
   }

   return cnt;
}
Example #2
0
static int file_tree_callback(const char *fpath, const struct stat *sb, int typeflag, __unused__ struct FTW *ftwbuf)
{
	if (typeflag == FTW_DNR)
		return FTW_CONTINUE;

	if (typeflag == FTW_NS)
		return FTW_CONTINUE;

	if (ignore_files(fpath))
		return FTW_SKIP_SUBTREE;

	// Check we can read it.
	if (check_stat_file(sb) == -1)
		return FTW_CONTINUE;

	if (shm->exit_reason != STILL_RUNNING)
		return FTW_STOP;

	add_to_namelist(fpath);
	files_in_index++;

	return FTW_CONTINUE;
}
Example #3
0
static void open_fds_from_path(const char *dirpath)
{
	int before = files_in_index;
	/* old declaration int flags = FTW_DEPTH | FTW_ACTIONRETVAL | FTW_MOUNT;
	 * android > 4.4 doesn't support FTW_ACTIONRETVAL anymore
	 */

	int flags = FTW_DEPTH | FTW_MOUNT;

	int ret;

	/* By default, don't follow symlinks so we only get each file once.
	 * But, if we do something like -V /lib, then follow it
	 *
	 * I'm not sure about this, might remove later.
	 */
	if (victim_path == NULL)
		flags |= FTW_PHYS;

	if (victim_dev == NULL) {
	//run normally if no specific dev speficied
		ret = nftw(dirpath, file_tree_callback, 32, flags);
		if (ret != 0) {
			if (shm->exit_reason != EXIT_SIGINT)
				output(0, "Something went wrong during nftw(%s). (%d:%s)\n",
						dirpath, ret, strerror(errno));
			return;
		}
	} else {
		//adding victim dev only! no recursion from file tree callback
		add_to_namelist(victim_dev);
		outputstd ("Adding only victim device: %s", victim_dev);
		files_in_index++;
	}

	output(0, "Added %d filenames from %s\n", files_in_index - before, dirpath);
}
Example #4
0
/*
 * Fill the NDMP restore environment table with the data for the data agent to act on.
 */
static inline bool fill_restore_environment(JCR *jcr,
                                            int32_t current_fi,
                                            struct ndm_job_param *job)
{
   int i;
   char *bp;
   ndmp9_pval pv;
   FILESETRES *fileset;
   char *restore_pathname,
        *ndmp_filesystem,
        *restore_prefix,
        *level;
   POOL_MEM tape_device;
   POOL_MEM destination_path;
   ndmp_backup_format_option *nbf_options;

   /*
    * See if we know this backup format and get it options.
    */
   nbf_options = ndmp_lookup_backup_format_options(job->bu_type);

   /*
    * Lookup the current fileindex and map it to an actual pathname.
    */
   restore_pathname = lookup_fileindex(jcr, current_fi);
   if (!restore_pathname) {
      return false;
   } else {
      /*
       * Skip over the /@NDMP prefix.
       */
      ndmp_filesystem = restore_pathname + 6;
   }

   /*
    * See if there is a level embedded in the pathname.
    */
   bp = strrchr(ndmp_filesystem, '%');
   if (bp) {
      *bp++ = '\0';
      level = bp;
   } else {
      level = NULL;
   }

   /*
    * Lookup the environment stack saved during the backup so we can restore it.
    */
   if (!db_get_ndmp_environment_string(jcr, jcr->db, &jcr->jr,
                                       ndmp_env_handler, &job->env_tab)) {
      /*
       * Fallback code try to build a environment stack that is good enough to
       * restore this NDMP backup. This is used when the data is not available in
       * the database when its either expired or when an old NDMP backup is restored
       * where the whole environment was not saved.
       */

      if (!nbf_options || nbf_options->uses_file_history) {
         /*
          * We asked during the NDMP backup to receive file history info.
          */
         pv.name = ndmp_env_keywords[NDMP_ENV_KW_HIST];
         pv.value = ndmp_env_values[NDMP_ENV_VALUE_YES];
         ndma_store_env_list(&job->env_tab, &pv);
      }

      /*
       * Tell the data agent what type of restore stream to expect.
       */
      pv.name = ndmp_env_keywords[NDMP_ENV_KW_TYPE];
      pv.value = job->bu_type;
      ndma_store_env_list(&job->env_tab, &pv);

      /*
       * Tell the data agent that this is a NDMP backup which uses a level indicator.
       */
      if (level) {
         pv.name = ndmp_env_keywords[NDMP_ENV_KW_LEVEL];
         pv.value = level;
         ndma_store_env_list(&job->env_tab, &pv);
      }

      /*
       * Tell the data engine what was backuped.
       */
      pv.name = ndmp_env_keywords[NDMP_ENV_KW_FILESYSTEM];
      pv.value = ndmp_filesystem;
      ndma_store_env_list(&job->env_tab, &pv);
   }

   /*
    * Lookup any meta tags that need to be added.
    */
   fileset = jcr->res.fileset;
   for (i = 0; i < fileset->num_includes; i++) {
      int j;
      char *item;
      INCEXE *ie = fileset->include_items[i];

      /*
       * Loop over each file = entry of the fileset.
       */
      for (j = 0; j < ie->name_list.size(); j++) {
         item = (char *)ie->name_list.get(j);

         /*
          * See if the original path matches.
          */
         if (bstrcasecmp(item, ndmp_filesystem)) {
            int k, l;
            FOPTS *fo;

            for (k = 0; k < ie->num_opts; k++) {
               fo = ie->opts_list[i];

               /*
                * Parse all specific META tags for this option block.
                */
               for (l = 0; l < fo->meta.size(); l++) {
                  ndmp_parse_meta_tag(&job->env_tab, (char *)fo->meta.get(l));
               }
            }
         }
      }
   }

   /*
    * See where to restore the data.
    */
   restore_prefix = NULL;
   if (jcr->where) {
      restore_prefix = jcr->where;
   } else {
      restore_prefix = jcr->res.job->RestoreWhere;
   }

   if (!restore_prefix) {
      return false;
   }

   /*
    * Tell the data engine where to restore.
    */
   if (nbf_options && nbf_options->restore_prefix_relative) {
      switch (*restore_prefix) {
      case '^':
         /*
          * Use the restore_prefix as an absolute restore prefix.
          * We skip the leading ^ that is the trigger for absolute restores.
          */
         pm_strcpy(destination_path, restore_prefix + 1);
         break;
      default:
         /*
          * Use the restore_prefix as an relative restore prefix.
          */
         if (strlen(restore_prefix) == 1 && *restore_prefix == '/') {
            pm_strcpy(destination_path, ndmp_filesystem);
         } else {
            pm_strcpy(destination_path, ndmp_filesystem);
            pm_strcat(destination_path, restore_prefix);
         }
      }
   } else {
      if (strlen(restore_prefix) == 1 && *restore_prefix == '/') {
         /*
          * Use the original pathname as restore prefix.
          */
         pm_strcpy(destination_path, ndmp_filesystem);
      } else {
         /*
          * Use the restore_prefix as an absolute restore prefix.
          */
         pm_strcpy(destination_path, restore_prefix);
      }
   }

   pv.name = ndmp_env_keywords[NDMP_ENV_KW_PREFIX];
   pv.value = ndmp_filesystem;
   ndma_store_env_list(&job->env_tab, &pv);

   if (!nbf_options || nbf_options->needs_namelist) {
      if (set_files_to_restore(jcr, job, current_fi,
                               destination_path.c_str(), ndmp_filesystem) == 0) {
         /*
          * There is no specific filename selected so restore everything.
          */
         add_to_namelist(job, (char *)"", destination_path.c_str(),
                         (char *)"", (char *)"", NDMP_INVALID_U_QUAD);
      }
   }

   /*
    * If we have a paired storage definition we put the storage daemon
    * auth key and the filesystem into the tape device name of the
    * NDMP session. This way the storage daemon can link the NDMP
    * data and the normal save session together.
    */
   if (jcr->store_bsock) {
      Mmsg(tape_device, "%s@%s", jcr->sd_auth_key, restore_pathname + 6);
      job->tape_device = bstrdup(tape_device.c_str());
   }

   free(restore_pathname);
   return true;
}