Ejemplo n.º 1
0
/*
 * Append global filters on path
 * \param do_display [in] display filters?
 * \param initialized [in/out] indicate if the filter is initialized.
 */
static int mk_path_filter( lmgr_filter_t * filter, int do_display, int * initialized )
{
    filter_value_t fv;
    char path_regexp[RBH_PATH_MAX] = "";
    size_t  len;

    /* is a filter on path specified? */
    if ( !EMPTY_STRING( path_filter ) )
    {
        if ( (initialized != NULL) && !(*initialized) )
        {
            lmgr_simple_filter_init( filter );
            *initialized = TRUE;
        }
        if ( do_display )
            printf("filter path: %s\n", path_filter );

        len = strlen(path_filter);
        if ( path_filter[len-1] != '/' )
        {
            /* ( fullpath LIKE 'path' OR fullpath LIKE 'path/%' ) */
            fv.val_str = path_filter;
            lmgr_simple_filter_add( filter, ATTR_INDEX_fullpath, LIKE, fv,
                                    FILTER_FLAG_BEGIN );

            snprintf( path_regexp, RBH_PATH_MAX, "%s/*", path_filter );
            fv.val_str = path_regexp;
            lmgr_simple_filter_add( filter, ATTR_INDEX_fullpath, LIKE, fv,
                                    FILTER_FLAG_OR | FILTER_FLAG_END );
        }
        else /* ends with slash */
        {
            snprintf( path_regexp, RBH_PATH_MAX, "%s*", path_filter );
            /* directory or directory/% */

            fv.val_str = path_regexp;
            lmgr_simple_filter_add( filter, ATTR_INDEX_fullpath, LIKE, fv,
                                    FILTER_FLAG_BEGIN );
            /* remove last slash */
            path_filter[len-1] = '\0';
            fv.val_str = path_filter;
            lmgr_simple_filter_add( filter, ATTR_INDEX_fullpath, LIKE, fv,
                                    FILTER_FLAG_OR | FILTER_FLAG_END );
        }
    }
    return 0;
}
Ejemplo n.º 2
0
int EntryProc_db_flag_op( struct entry_proc_op_t *p_op, lmgr_t * lmgr )
{
    int            rc;

    /* insert to DB */
    switch ( p_op->db_op_type )
    {
        attr_set_t     attr_chg;
        lmgr_filter_t  filter;
        filter_value_t val;

    case OP_TYPE_UPDATE:
        /* set previous_scan flag */
        ATTR_MASK_INIT( &attr_chg );
        ATTR_MASK_SET( &attr_chg, previous_scan );
        ATTR( &attr_chg, previous_scan ) = TRUE;

        rc = ListMgr_MassUpdate( lmgr, NULL, &attr_chg );
        break;
    case OP_TYPE_REMOVE:
        val.val_bool = TRUE;
        lmgr_simple_filter_init( &filter );
        lmgr_simple_filter_add( &filter, ATTR_INDEX_previous_scan, EQUAL, val );

        /* remove entries with previous_scan flag */
        rc = ListMgr_MassRemove( lmgr, &filter );

        lmgr_simple_filter_free( &filter );
        break;
    default:
        printf( "unhandled\n" );
        rc = -1;
    }
    if ( rc )
        printf( "ERROR: ListMgr mass operation returned %d\n", rc );

    if ( p_op->callback_func )
        p_op->callback_func( lmgr, p_op, p_op->callback_param );

    rc = EntryProcessor_Acknowledge( p_op, 0, TRUE );

    return rc;
}
Ejemplo n.º 3
0
/*
 * Append global filters on path
 * \param do_display [in] display filters?
 * \param initialized [in/out] indicate if the filter is initialized.
 */
static int mk_path_filter( lmgr_filter_t * filter, int do_display, int * initialized )
{
    filter_value_t fv;
    char path_regexp[RBH_PATH_MAX] = "";
    size_t  len;

    /* is a filter on path specified? */
    if ( !EMPTY_STRING( path_filter ) )
    {
        if ( (initialized != NULL) && !(*initialized) )
        {
            lmgr_simple_filter_init( filter );
            *initialized = TRUE;
        }
        if ( do_display )
            printf("filter path: %s\n", path_filter );

        len = strlen(path_filter);
        /* remove last slash */
        if (path_filter[len-1] == '/')
            path_filter[len-1] = '\0';

        /* as this is a RLIKE matching, shell regexp must be replaced by perl:
         * [abc] => OK
         * '*' => '.*'
         * '?' => '.'
         */
        str_replace(path_filter, "*", ".*");
        str_replace(path_filter, "?", ".");

        /* match 'path$' OR 'path/.*' */
        snprintf(path_regexp, RBH_PATH_MAX, "%s($|/.*)", path_filter);
        fv.value.val_str = path_regexp;

        lmgr_simple_filter_add(filter, ATTR_INDEX_fullpath, RLIKE, fv, 0);
    }
    return 0;
}
Ejemplo n.º 4
0
/**
 * Main daemon routine
 */
int main( int argc, char **argv )
{
    int            c, i, option_index = 0;
    char          *bin = basename( argv[0] );

    int            rc;
    char           err_msg[4096];
    robinhood_config_t rh_config;
    int chgd = 0;
    char           badcfg[RBH_PATH_MAX];
    char           tag_name[256] = "";

    start_time = time( NULL );

    zero_options( &options );

    /* parse command line options */
    while ( ( c = getopt_long( argc, argv, SHORT_OPT_STRING, option_tab, &option_index ) ) != -1 )
    {
        switch ( c )
        {
        case 's':
            options.partial_scan = TRUE;
            rh_strncpy(options.partial_scan_path, optarg, RBH_PATH_MAX);
            /* clean final slash */
            if (FINAL_SLASH(options.partial_scan_path))
                REMOVE_FINAL_SLASH(options.partial_scan_path);
            break;

        case 'd':
            if (parse_diff_mask(optarg, &options.diff_mask, err_msg))
            {
                fprintf(stderr,
                        "Invalid argument for --diff: %s\n", err_msg);
                exit( 1 );
            }
            break;

        case 'a':
            if (optarg)
            {
                if (!strcasecmp(optarg,"fs"))
                    options.diff_arg.apply = APPLY_FS;
                else if (!strcasecmp(optarg,"db"))
                    options.diff_arg.apply = APPLY_DB;
                else
                {
                    fprintf(stderr, "Invalid argument for --apply: '%s' (fs or db expected)\n",
                            optarg);
                    exit( 1 );
                }
            }
            else
                options.diff_arg.apply = APPLY_DB;
            break;

        case 'D':
                options.flags |= FLAG_DRY_RUN;
            break;

        case 'f':
            rh_strncpy(options.config_file, optarg, MAX_OPT_LEN);
            break;
#ifdef _HSM_LITE
        case 'b':
            options.diff_arg.recov_from_backend  = 1;
            break;
#endif
#ifdef _HAVE_FID /* only for lustre 2.x */
        case 'o':
            rh_strncpy(options.output_dir, optarg, MAX_OPT_LEN);
            break;
#endif
        case 'l':
            options.force_log_level = TRUE;
            options.log_level = str2debuglevel( optarg );
            if ( options.log_level == -1 )
            {
                fprintf( stderr,
                         "Unsupported log level '%s'. CRIT, MAJOR, EVENT, VERB, DEBUG or FULL expected.\n",
                         optarg );
                exit( 1 );
            }
            break;
        case 'h':
            display_help( bin );
            exit( 0 );
            break;
        case 'V':
            display_version( bin );
            exit( 0 );
            break;
        case ':':
        case '?':
        default:
            fprintf(stderr,"Run '%s --help' for more details.\n", bin);
            exit( 1 );
            break;
        }
    }

    /* check there is no extra arguments */
    if ( optind != argc )
    {
        fprintf( stderr, "Error: unexpected argument on command line: %s\n", argv[optind] );
        exit( 1 );
    }

    /* Initialize global tools */
#ifdef _LUSTRE
    if ( ( rc = Lustre_Init(  ) ) )
    {
        fprintf( stderr, "Error %d initializing liblustreapi\n", rc );
        exit( 1 );
    }
#endif

    /* Initilize uidgid cache */
    if ( InitUidGid_Cache(  ) )
    {
        fprintf( stderr, "Error initializing uid/gid cache\n" );
        exit( 1 );
    }

    /* get default config file, if not specified */
    if (SearchConfig(options.config_file, options.config_file, &chgd,
                      badcfg, MAX_OPT_LEN) != 0)
    {
        fprintf(stderr, "No config file (or too many) found matching %s\n", badcfg);
        exit(2);
    }
    else if (chgd)
    {
        fprintf(stderr, "Using config file '%s'.\n", options.config_file );
    }

    if ( ReadRobinhoodConfig( MODULE_MASK_FS_SCAN | MODULE_MASK_ENTRY_PROCESSOR,
                              options.config_file, err_msg,
                              &rh_config, FALSE ) )
    {
        fprintf( stderr, "Error reading configuration file '%s': %s\n",
                 options.config_file, err_msg );
        exit( 1 );
    }
    process_config_file = options.config_file;

    /* set global configuration */
    global_config = rh_config.global_config;

    /* set policies info */
    policies = rh_config.policies;

    if (options.force_log_level)
        rh_config.log_config.debug_level = options.log_level;
    else
        rh_config.log_config.debug_level = LVL_CRIT; /* no event message */

    /* Set logging to stderr */
    strcpy( rh_config.log_config.log_file, "stderr" );
    strcpy( rh_config.log_config.report_file, "stderr" );
    strcpy( rh_config.log_config.alert_file, "stderr" );

    /* Initialize logging */
    rc = InitializeLogs( bin, &rh_config.log_config );
    if ( rc )
    {
        fprintf( stderr, "Error opening log files: rc=%d, errno=%d: %s\n",
                 rc, errno, strerror( errno ) );
        exit( rc );
    }

    /* Initialize filesystem access */
    rc = InitFS();
    if (rc)
        exit(rc);

#ifdef _HSM_LITE
    rc = Backend_Start( &rh_config.backend_config, options.flags );
    if ( rc )
    {
        DisplayLog( LVL_CRIT, DIFF_TAG, "Error initializing backend" );
        exit( 1 );
    }
#endif

    /* Initialize list manager */
    rc = ListMgr_Init( &rh_config.lmgr_config, FALSE );
    if ( rc )
    {
        DisplayLog( LVL_CRIT, DIFF_TAG, "Error %d initializing list manager", rc );
        exit( rc );
    }
    else
        DisplayLog( LVL_VERB, DIFF_TAG, "ListManager successfully initialized" );


    if ( CheckLastFS(  ) != 0 )
        exit( 1 );

    if (options.diff_mask)
        rh_config.entry_proc_config.diff_mask = options.diff_mask;
    else
    {
        /* parse "all" */
        char tmpstr[] = "all";
        if (parse_diff_mask(tmpstr, &rh_config.entry_proc_config.diff_mask, err_msg))
        {
            DisplayLog(LVL_CRIT, DIFF_TAG, "unexpected error parsing diff mask: %s", err_msg);
            exit(1);
        }
    }

#ifdef LUSTRE_DUMP_FILES
    if (options.diff_arg.apply == APPLY_FS && !(options.flags & FLAG_DRY_RUN))
    {
        /* open the file to write LOV EA and FID remapping */
        if (!EMPTY_STRING(options.output_dir))
        {
            char fname[RBH_PATH_MAX];
            if (mkdir(options.output_dir, 0700) && (errno != EEXIST))
            {
                DisplayLog(LVL_CRIT, DIFF_TAG, "Failed to create directory %s: %s",
                           options.output_dir, strerror(errno));
                exit(1);
            }
            snprintf(fname, RBH_PATH_MAX-1, "%s/"LOVEA_FNAME, options.output_dir);
            options.diff_arg.lovea_file = fopen(fname, "w");
            if (options.diff_arg.lovea_file == NULL)
            {
                DisplayLog(LVL_CRIT, DIFF_TAG, "Failed to open %s for writting: %s",
                           fname, strerror(errno));
                exit(1);
            }
            snprintf(fname, RBH_PATH_MAX-1, "%s/"FIDREMAP_FNAME, options.output_dir);
            options.diff_arg.fid_remap_file = fopen(fname, "w");
            if (options.diff_arg.fid_remap_file == NULL)
            {
                DisplayLog(LVL_CRIT, DIFF_TAG, "Failed to open %s for writting: %s",
                           fname, strerror(errno));
                exit(1);
            }
        }
    }
#endif

    /* if no DB apply action is specified, can't use md_update field for checking
     * removed entries. So, create a special tag for that. */
    if ((options.diff_arg.apply != APPLY_DB) || (options.flags & FLAG_DRY_RUN))
    {
        fprintf(stderr, "Preparing diff table...\n");

        /* create a connexion to the DB. this is safe to use the global lmgr var
         * as statistics thread is not running */
        if (!ensure_db_access())
            exit(1);
        /* create a tag to clear entries after the scan */

        /* There could be several diff running in parallel,
         * so set a suffix to avoid conflicts */
        sprintf(tag_name, "DIFF_%u", (unsigned int) getpid());
        options.diff_arg.db_tag = tag_name;

        /* add filter for partial scan */
        if (options.partial_scan)
        {
            lmgr_filter_t  filter;
            filter_value_t val;
            lmgr_simple_filter_init( &filter );

            char tmp[RBH_PATH_MAX];
            strcpy(tmp, options.partial_scan_path);
            strcat(tmp, "/*");
            val.value.val_str = tmp;
            lmgr_simple_filter_add(&filter, ATTR_INDEX_fullpath, LIKE, val, 0);

            rc = ListMgr_CreateTag(&lmgr, tag_name, &filter, FALSE);
            lmgr_simple_filter_free(&filter);
        }
        else
            rc = ListMgr_CreateTag(&lmgr, tag_name, NULL, FALSE);

        if (rc)
            exit(rc);
    }

    /* Initialise Pipeline */
    rc = EntryProcessor_Init(&rh_config.entry_proc_config, DIFF_PIPELINE,
                             options.flags, &options.diff_arg);
    if ( rc )
    {
        DisplayLog( LVL_CRIT, DIFF_TAG, "Error %d initializing EntryProcessor pipeline", rc );
        goto clean_tag;
    }
    else
        DisplayLog( LVL_VERB, DIFF_TAG, "EntryProcessor successfully initialized" );

    fprintf(stderr, "Starting scan\n");

    /* print header to indicate the content of diff
     * #<diff cmd>
     * ---fs[=/subdir]
     * +++db
     */
    for (i = 0; i < argc; i++)
        printf("%s%s", i==0?"# ":" ", argv[i]);
    printf("\n");
    if (options.diff_arg.apply == APPLY_FS)
    {
        if (options.partial_scan)
            printf("---fs=%s\n",options.partial_scan_path);
        else
            printf("---fs\n");
        printf("+++db\n");
    }
    else
    {
        printf("---db\n");
        if (options.partial_scan)
            printf("+++fs=%s\n",options.partial_scan_path);
        else
            printf("+++fs\n");
    }

    /* Start FS scan */
    if (options.partial_scan)
        rc = FSScan_Start(&rh_config.fs_scan_config, options.flags,
                          options.partial_scan_path);
    else
        rc = FSScan_Start(&rh_config.fs_scan_config, options.flags, NULL);

    if ( rc )
    {
        DisplayLog( LVL_CRIT, DIFF_TAG, "Error %d initializing FS Scan module", rc );
        goto clean_tag;
    }
    else
        DisplayLog( LVL_VERB, DIFF_TAG, "FS Scan module successfully initialized" );

    /* Flush logs now, to have a trace in the logs */
    FlushLogs(  );

    /* both pipeline and scan are now running, can now trap events and display stats */

    /* create signal handling thread */
    rc = pthread_create( &sig_thr, NULL, signal_handler_thr, NULL );
    if ( rc )
    {
        DisplayLog( LVL_CRIT, DIFF_TAG, "Error starting signal handler thread: %s",
                    strerror( errno ) );
        goto clean_tag;
    }
    else
        DisplayLog( LVL_VERB, DIFF_TAG, "Signal handler thread started successfully" );

    pthread_create(&stat_thread, NULL, stats_thr, NULL);

    /* wait for FS scan to end */
    FSScan_Wait(  );
    DisplayLog( LVL_MAJOR, DIFF_TAG, "FS Scan finished" );

    /* Pipeline must be flushed */
    EntryProcessor_Terminate( TRUE );

#ifdef LUSTRE_DUMP_FILES
    /* flush the lovea file */
    if (options.diff_arg.lovea_file)
    {
        fprintf(stderr, " > LOV EA information written to %s/"LOVEA_FNAME"\n", options.output_dir);
        fclose(options.diff_arg.lovea_file);
    }
    if (options.diff_arg.fid_remap_file)
    {
        fprintf(stderr, " > FID remapping written to %s/"FIDREMAP_FNAME"\n", options.output_dir);
        fclose(options.diff_arg.fid_remap_file);
    }
#endif

    fprintf(stderr, "End of scan\n");

    DisplayLog( LVL_MAJOR, DIFF_TAG, "All tasks done! Exiting." );
    rc = 0;

clean_tag:
    /* destroy the tag before exit */
    if (options.diff_arg.db_tag != NULL && ensure_db_access())
    {
        fprintf(stderr, "Cleaning diff table...\n");
        ListMgr_DestroyTag(&lmgr, options.diff_arg.db_tag);
    }

    exit(rc);
    return rc; /* for compiler */
}
Ejemplo n.º 5
0
/* build filters depending on program options */
static int mkfilters(int exclude_dirs)
{
    filter_value_t fv;
    int compflag;

    /* create boolean expression for matching */

    if (prog_options.match_user)
    {
        compare_value_t val;
        strcpy(val.str, prog_options.user);
        if (prog_options.userneg)
            compflag = COMP_UNLIKE;
        else
            compflag = COMP_LIKE;
        if (!is_expr)
            CreateBoolCond(&match_expr, compflag, CRITERIA_OWNER, val);
        else
            AppendBoolCond(&match_expr, compflag, CRITERIA_OWNER, val);
        is_expr = 1;
        query_mask |= ATTR_MASK_owner;
    }

    if (prog_options.match_group)
    {
        compare_value_t val;
        strcpy(val.str, prog_options.group);
        if (prog_options.groupneg)
            compflag = COMP_UNLIKE;
        else
            compflag = COMP_LIKE;
        if (!is_expr)
            CreateBoolCond(&match_expr, compflag, CRITERIA_GROUP, val);
        else
            AppendBoolCond(&match_expr, compflag, CRITERIA_GROUP, val);
        is_expr = 1;
        query_mask |= ATTR_MASK_gr_name;
    }

    if (prog_options.match_name)
    {
        /* this is not converted to DB filter, but will be used in post checking */
        compare_value_t val;
        strcpy(val.str, prog_options.name);
        if (prog_options.nameneg)
            compflag = COMP_UNLIKE;
        else
            compflag = COMP_LIKE;
        if (!is_expr)
            CreateBoolCond(&match_expr, compflag, CRITERIA_FILENAME, val);
        else
            AppendBoolCond(&match_expr, compflag, CRITERIA_FILENAME, val);
        is_expr = 1;
        query_mask |= ATTR_MASK_name;
    }

    if (prog_options.match_size)
    {
        compare_value_t val;
        val.size = prog_options.sz_val;
        if (!is_expr)
            CreateBoolCond(&match_expr, prog_options.sz_compar, CRITERIA_SIZE, val);
        else
            AppendBoolCond(&match_expr, prog_options.sz_compar, CRITERIA_SIZE, val);
        is_expr = 1;
        query_mask |= ATTR_MASK_size;
    }

    if (prog_options.match_crtime)
    {
        compare_value_t val;
        val.duration = prog_options.crt_val;
        if (!is_expr)
            CreateBoolCond(&match_expr, prog_options.crt_compar, CRITERIA_CREATION, val);
        else
            AppendBoolCond(&match_expr, prog_options.crt_compar, CRITERIA_CREATION, val);
        is_expr = 1;
        query_mask |= ATTR_MASK_creation_time;
    }

    if (prog_options.match_mtime)
    {
        compare_value_t val;
        val.duration = prog_options.mod_val;
        if (!is_expr)
            CreateBoolCond(&match_expr, prog_options.mod_compar, CRITERIA_LAST_MOD, val);
        else
            AppendBoolCond(&match_expr, prog_options.mod_compar, CRITERIA_LAST_MOD, val);
        is_expr = 1;
        query_mask |= ATTR_MASK_last_mod;
    }

    if (prog_options.match_atime)
    {
        compare_value_t val;
        val.duration = prog_options.acc_val;
        if (!is_expr)
            CreateBoolCond(&match_expr, prog_options.acc_compar, CRITERIA_LAST_ACCESS, val);
        else
            AppendBoolCond(&match_expr, prog_options.acc_compar, CRITERIA_LAST_ACCESS, val);
        is_expr = 1;
        query_mask |= ATTR_MASK_last_access;
    }
#ifdef _LUSTRE
    if (prog_options.match_ost)
    {
        /* this partially converted to DB filter, and will be fully used in post checking */
        compare_value_t val;
        val.integer = prog_options.ost_idx;
        if (!is_expr)
            CreateBoolCond(&match_expr, COMP_EQUAL, CRITERIA_OST, val);
        else
            AppendBoolCond(&match_expr, COMP_EQUAL, CRITERIA_OST, val);
        is_expr = 1;
        query_mask |= ATTR_MASK_stripe_items;
    }

    if (prog_options.match_pool)
    {
        compare_value_t val;
        strcpy(val.str, prog_options.pool);
        if (!is_expr)
            CreateBoolCond(&match_expr, COMP_LIKE, CRITERIA_POOL, val);
        else
            AppendBoolCond(&match_expr, COMP_LIKE, CRITERIA_POOL, val);
        is_expr = 1;
        query_mask |= ATTR_MASK_stripe_info;
    }
#endif

    /* create DB filters */
    lmgr_simple_filter_init( &entry_filter );

    /* analyze type filter */
    if (prog_options.match_type)
    {
        if (!strcasecmp(prog_options.type, STR_TYPE_DIR))
        {
            /* only match dirs */
            prog_options.dir_only = 1;
            if (!exclude_dirs)
            {
                fv.value.val_str = STR_TYPE_DIR;
                lmgr_simple_filter_add(&entry_filter, ATTR_INDEX_type, EQUAL, fv, 0);
            }
        }
        else
        {
            /* smthg different from dir */
            prog_options.no_dir = 1;
            fv.value.val_str = prog_options.type;
            lmgr_simple_filter_add(&entry_filter, ATTR_INDEX_type, EQUAL, fv, 0);
        }
    }
    else if (exclude_dirs) /* no specific type specified => exclude dirs if required */
    {
        /* filter non directories (directories are handled during recursive DB scan) */
        fv.value.val_str = STR_TYPE_DIR;
        lmgr_simple_filter_add( &entry_filter, ATTR_INDEX_type, NOTEQUAL, fv, 0 );
    }

#ifdef ATTR_INDEX_status
    if (prog_options.match_status)
    {
        if (prog_options.statusneg)
            compflag = NOTEQUAL;
        else
            compflag = EQUAL;
        /* not part of user policies, only add it to DB filter */
        fv.value.val_uint = prog_options.status;
        lmgr_simple_filter_add( &entry_filter, ATTR_INDEX_status, compflag, fv, 0 );
    }
#endif

    if (prog_options.match_name)
    {
        fv.value.val_str = prog_options.name;
        lmgr_simple_filter_add( &entry_filter, ATTR_INDEX_name, LIKE, fv, 0 );
    }

    /* TODO what about pool? */

    if (is_expr)
    {
        char expr[RBH_PATH_MAX];
        /* for debug */
        if (BoolExpr2str(&match_expr, expr, RBH_PATH_MAX)>0)
            DisplayLog(LVL_FULL, FIND_TAG, "Expression matching: %s", expr);

        /* append bool expr to entry filter */
        convert_boolexpr_to_simple_filter( &match_expr, &entry_filter );
    }

    return 0;
}
Ejemplo n.º 6
0
static int recov_start(void)
{
    lmgr_recov_stat_t stats;
    int rc;

    /* is there a filter to be applied? */
    if (ost_list.count > 0 || since_time != 0) {
        lmgr_filter_t filter;
        filter_value_t fv;

        lmgr_simple_filter_init(&filter);

        /* ost filter? */
        if (ost_list.count == 1) {
            printf("only recovering files striped on OST#%u\n",
                   ost_list.values[0].val_uint);
            fv.value.val_uint = ost_list.values[0].val_uint;
            lmgr_simple_filter_add(&filter, ATTR_INDEX_stripe_items, EQUAL, fv,
                                   0);
        } else if (ost_list.count > 1) {
            printf("only recovering files striped on OSTs[%s]\n",
                   ost_range_str);
            fv.list = ost_list;
            lmgr_simple_filter_add(&filter, ATTR_INDEX_stripe_items, IN, fv,
                                   /* allow it to free ost_list->values: */
                                   FILTER_FLAG_ALLOC_LIST);
        }

        /* update time filter */
        if (since_time) {
            char date[128];
            struct tm t;
            strftime(date, 128, "%Y/%m/%d %T", localtime_r(&since_time, &t));
            printf("only recovering files updated after %s (timestamp: %lu)\n",
                   date, since_time);
            fv.value.val_uint = since_time;

            lmgr_simple_filter_add(&filter, ATTR_INDEX_md_update, MORETHAN, fv,
                                   0);
        }

        rc = ListMgr_RecovInit(&lmgr, &filter, &stats);
    } else
        rc = ListMgr_RecovInit(&lmgr, NULL, &stats);

    if (rc == 0) {
        printf("\nRecovery successfully initialized.\n\n");
        printf("It should result in the following state:\n");
        print_recov_stats(true, &stats);
        return 0;
    } else if (rc == DB_ALREADY_EXISTS) {
        printf("\nERROR: a recovery is already in progress, or a previous recovery\n"
               "was not completed properly (see --resume, --complete or --reset option).\n\n");

        unsigned long long total =
            stats.status_count[RS_FILE_OK] + stats.status_count[RS_FILE_DELTA]
            + stats.status_count[RS_NON_FILE] +
            stats.status_count[RS_FILE_EMPTY]
            + stats.status_count[RS_NOBACKUP] + stats.status_count[RS_ERROR];
        printf("The progress of this recovery is %Lu/%Lu entries\n", total,
               stats.total);
        print_recov_stats(false, &stats);

        return -EALREADY;
    } else {    /* other error */

        fprintf(stderr, "ERROR initializing recovery: db error %d\n", rc);
        return rc;
    }
}
Ejemplo n.º 7
0
int undo_rm()
{
    int            rc;
    struct lmgr_rm_list_t * list;
    entry_id_t     id;
    char   last_known_path[RBH_PATH_MAX] = "";
#ifdef _HSM_LITE
    char   bkpath[RBH_PATH_MAX] = "";
#endif
    unsigned long long total_count = 0;
    lmgr_filter_t  filter;

    if (is_fid_filter(&id)) /* 1 single entry */
    {
         rc = ListMgr_GetRmEntry( &lmgr, &id, last_known_path,
#ifdef _HSM_LITE
                            bkpath,
#endif
                            NULL, NULL );
        if (rc == DB_SUCCESS)
        {
            undo_rm_helper( &id, last_known_path,
#ifdef _HSM_LITE
                            bkpath
#endif
                            );
        }
        else if ( rc == DB_NOT_EXISTS )
            fprintf(stderr, DFID": fid not found in deferred removal list\n",
                    PFID(&id));
        else
            fprintf(stderr, "ERROR %d in ListMgr_GetRmEntry("DFID")\n",
                    rc, PFID(&id));
        return rc;
    }
    else /* recover a list of entries */
    {
        lmgr_simple_filter_init( &filter );

        /* append global filters */
        mk_path_filter( &filter, TRUE, NULL );

        /* list files to be recovered */
        list = ListMgr_RmList( &lmgr, FALSE, &filter );

        if ( list == NULL )
        {
            DisplayLog( LVL_CRIT, LOGTAG,
                        "ERROR: Could not retrieve removed entries from database." );
            return -1;
        }

        while ( ( rc = ListMgr_GetNextRmEntry( list, &id, last_known_path,
    #ifdef _HSM_LITE
                            bkpath,
    #endif
                            NULL, NULL )) == DB_SUCCESS )
        {
            total_count++;

            undo_rm_helper( &id, last_known_path,
#ifdef _HSM_LITE
                            bkpath
#endif
                            );
        }
        ListMgr_CloseRmList(list);
    }
    return 0;
}
Ejemplo n.º 8
0
int list_rm()
{
    int            rc, index;
    struct lmgr_rm_list_t * list;
    entry_id_t     id;
    char   last_known_path[RBH_PATH_MAX] = "";
#ifdef _HSM_LITE
    char   bkpath[RBH_PATH_MAX] = "";
#endif

    time_t soft_rm_time = 0;
    time_t expiration_time = 0;

    unsigned long long total_count = 0;
    lmgr_filter_t  filter;

    if (is_fid_filter(&id)) /* 1 single entry */
    {
         rc = ListMgr_GetRmEntry( &lmgr, &id, last_known_path,
#ifdef _HSM_LITE
                            bkpath,
#endif
                            &soft_rm_time, &expiration_time );
        if (rc == DB_SUCCESS)
        {
            display_rm_entry( &id, last_known_path,
#ifdef _HSM_LITE
                            bkpath,
#endif
                            soft_rm_time, expiration_time);
        }
        else if ( rc == DB_NOT_EXISTS )
            fprintf(stderr, DFID": fid not found in deferred removal list\n",
                    PFID(&id));
        else
            fprintf(stderr, "ERROR %d in ListMgr_GetRmEntry("DFID")\n",
                    rc, PFID(&id));
        return rc;
    }
    else /* list of entries */
    {
        lmgr_simple_filter_init( &filter );

        /* append global filters */
        mk_path_filter( &filter, TRUE, NULL );

        /* list all deferred rm, even if non expired */
        list = ListMgr_RmList( &lmgr, FALSE, &filter );

        if ( list == NULL )
        {
            DisplayLog( LVL_CRIT, LOGTAG,
                        "ERROR: Could not retrieve removed entries from database." );
            return -1;
        }

        index = 0;
        while ( ( rc = ListMgr_GetNextRmEntry( list, &id, last_known_path,
    #ifdef _HSM_LITE
                            bkpath,
    #endif
                            &soft_rm_time, &expiration_time )) == DB_SUCCESS )
        {
            total_count++;
            index++;

            printf( "\n" );
            display_rm_entry( &id, last_known_path,
#ifdef _HSM_LITE
                            bkpath,
#endif
                            soft_rm_time, expiration_time );

            /* prepare next call */
            last_known_path[0] = '\0';
#ifdef _HSM_LITE
            bkpath[0] = '\0';
#endif
            soft_rm_time = 0;
            expiration_time = 0;
        }

        ListMgr_CloseRmList(list);
    }
    return 0;
}
Ejemplo n.º 9
0
/** scan sets of directories
 * \param cb_func, callback function for each set of directory
 */
int rbh_scrub(lmgr_t *p_mgr, const wagon_t *id_list,
              unsigned int id_count, attr_mask_t dir_attr_mask,
              scrub_callback_t cb_func, void *arg)
{
    wagon_t *curr_array;
    unsigned int count;
    lmgr_filter_t filter;
    filter_value_t fv;
    int i, rc;
    int last_err = 0;

    rc = add_id_list(id_list, id_count);
    if (rc)
        return rc;

    /* only get subdirs (for scanning) */
    fv.value.val_str = STR_TYPE_DIR;
    lmgr_simple_filter_init(&filter);
    lmgr_simple_filter_add(&filter, ATTR_INDEX_type, EQUAL, fv, 0);

    /* while the array is not empty */
    while (array_used > 0) {
        unsigned int res_count = 0;
        wagon_t *child_ids;
        attr_set_t *child_attrs;

        /* get a set of entry_ids */
        curr_array = &dir_array[array_first];
        if (array_used < LS_CHUNK) {
            /* get all available dirs */
            count = array_used;
        } else {
            /* get a constant chunk */
            count = LS_CHUNK;
        }

#ifdef _DEBUG_ID_LIST
        printf("processing %u-%u\n", array_first, array_first + count - 1);
#endif

        /* read childs */
        res_count = 0;
        child_ids = NULL;
        child_attrs = NULL;

        rc = ListMgr_GetChild(p_mgr, &filter, curr_array, count, dir_attr_mask,
                              &child_ids, &child_attrs, &res_count);

        if (rc) {
            DisplayLog(LVL_CRIT, SCRUB_TAG,
                       "ListMgr_GetChild() terminated with error %d", rc);
            /* @TODO free allocated resources */
            break;
        }

        /* Call the callback func for each listed dir */
        rc = cb_func(child_ids, child_attrs, res_count, arg);
        if (rc)
            /* XXX break the scan? */
            last_err = rc;

        /* can release the list of input ids */
        rbh_scrub_release_list(array_first, count);

        /* copy entry ids before freeing them */
        /* TODO: we could transfer the pathname instead of strdup() them. */
        add_id_list(child_ids, res_count);

        /* attributes no longer needed */
        /* release attrs */
        if (child_attrs) {
            for (i = 0; i < res_count; i++)
                ListMgr_FreeAttrs(&child_attrs[i]);
            MemFree(child_attrs);
            child_attrs = NULL;
        }

        /* free the returned id array */
        if (child_ids) {
            free_wagon(child_ids, 0, res_count);
            MemFree(child_ids);
            child_ids = NULL;
        }
    }
    lmgr_simple_filter_free(&filter);

    return last_err;
}