Example #1
0
static void log_cfg_set_default(void *module_config)
{
    log_config_t *conf = (log_config_t *) module_config;

    conf->debug_level = LVL_EVENT;
    rh_strncpy(conf->log_file, "/var/log/robinhood.log", RBH_PATH_MAX);
    rh_strncpy(conf->report_file, "/var/log/robinhood_actions.log",
               RBH_PATH_MAX);

    rh_strncpy(conf->alert_file, "/var/log/robinhood_alerts.log", 1024);
    conf->alert_mail[0] = '\0';

#ifdef HAVE_CHANGELOGS
    conf->changelogs_file[0] = '\0';
#endif

    conf->syslog_facility = LOG_LOCAL1;
    conf->syslog_priority = LOG_INFO;

    conf->batch_alert_max = 1;  /* no batching */
    conf->alert_show_attrs = false;

    conf->stats_interval = 900; /* 15min */

    conf->log_process = 0;
    conf->log_host = 0;
}
Example #2
0
static int log_cfg_set(void *cfg, bool reload)
{
    log_config_t *config = (log_config_t *) cfg;
    char old_log_file[RBH_PATH_MAX] = "";
    int old_level = -1;

    if (reload)
        return log_cfg_reload(config);

    /* keep previous values in case log level is forced */
    if (log_config.force_debug_level)
        old_level = log_config.debug_level;

    if (log_config.force_log_file)
        rh_strncpy(old_log_file, log_config.log_file, sizeof(old_log_file));

    log_config = *config;

    /* restore previous values */
    if (old_level != -1) {
        log_config.force_debug_level = true;
        log_config.debug_level = old_level;
    }
    if (!EMPTY_STRING(old_log_file)) {
        log_config.force_log_file = true;
        rh_strncpy(log_config.log_file, old_log_file,
                   sizeof(log_config.log_file));
    }

    return 0;
}
Example #3
0
int InitializeLogs(const char *program_name)
{
    struct utsname uts;
    char          *tmp;
    int            rc;

    /* get node name */
    if (uname(&uts) == -1)
        strcpy(machine_name, "???");
    else
        rh_strncpy(machine_name, uts.nodename, RBH_PATH_MAX);

    /* if the name is the full machine name (node.subnet.domain.ext),
     * only kief the brief name */
    if ((tmp = strchr(machine_name, '.')) != NULL)
        *tmp = '\0';

    if (program_name == NULL)
        strcpy(prog_name, "???");
    else
        rh_strncpy(prog_name, program_name, RBH_PATH_MAX);

    /* open log files */
    rc = init_log_descr(log_config.log_file, &log);
    if (rc)
        return rc;

    rc = init_log_descr(log_config.report_file, &report);
    if (rc)
        return rc;

    if (!EMPTY_STRING(log_config.alert_file)) {
        rc = init_log_descr(log_config.alert_file, &alert);
        if (rc)
            return rc;
    }
#ifdef HAVE_CHANGELOGS
    if (!EMPTY_STRING(log_config.changelogs_file)) {
        rc = init_log_descr(log_config.changelogs_file, &chglogs);
        if (rc)
            return rc;
    }
#endif

    /* Update log level for external components we get logs from (LLAPI...) */
    rbh_adjust_log_level_external();

    last_time_test = time(NULL);
    log_initialized = true;

    return 0;

}   /* InitializeLogs */
Example #4
0
static int parse_bk_id(attr_set_t *attrs, const char *str, entry_id_t *id,
                       bool *id_set)
{
    char attr[128];
    char *val;
    int rc;

    val = strchr(str, '=');
    if (!val) {
        fprintf(stderr, "Invalid attr format '%s': expected <attr>=<value>\n",
                str);
        return -EINVAL;
    }
    rh_strncpy(attr, str, MIN2(val - str + 1, sizeof(attr)));
    val++;

    if (!strcasecmp(attr, "id") || !strcasecmp(attr, "fid")) {
        rc = read_fid(val, id);
        if (rc == 0 && id_set)
            *id_set = true;
        return rc;
    }

    rc = set_attr_value_from_strings(attr, val, attrs, smi);

    return rc;
}
Example #5
0
/* This code is an adaptation of llapi_mds_getfileinfo() in liblustreapi.
 * It is unused for now, but could be useful when SOM will be implemented.
 */
int lustre_mds_stat(char *fullpath, int parentfd, struct stat *inode)
{
    /* this buffer must be large enough for handling filename */
    char           buffer[1024];
    struct lov_user_mds_data *lmd = ( struct lov_user_mds_data * ) buffer;
    char          *filename;
    int            rc;

    /* sanity checks */
    if ((fullpath == NULL) || (inode == NULL))
        return EINVAL;

    filename = basename( fullpath );

    if ( filename == NULL )
        filename = fullpath;

    memset(lmd, 0, sizeof(buffer));
    rh_strncpy(buffer, filename, strlen(filename) + 1);
    rc = ioctl(parentfd, IOC_MDC_GETFILEINFO, (void *)lmd);

    if ( rc )
    {
        if ( errno == ENOTTY )
        {
            /* ioctl is not supported, it is not a lustre fs.
             * Do the regular lstat(2) instead. */
            rc = lstat( fullpath, inode );
            if ( rc )
            {
                DisplayLog( LVL_CRIT, TAG_MDSSTAT, "Error: %s: lstat failed for %s",
                            __FUNCTION__, fullpath );
                return rc;
            }
        }
        else if ( ( errno == ENOENT ) || ( errno == ESTALE ) )
        {
            DisplayLog( LVL_MAJOR, TAG_MDSSTAT, "Warning: %s: %s does not exist",
                        __FUNCTION__, fullpath );
            return ENOENT;
        }
        else
        {
            DisplayLog(LVL_CRIT, TAG_MDSSTAT,
                       "Error: %s: IOC_MDC_GETFILEINFO failed for %s: rc=%d, errno=%d",
                       __FUNCTION__, fullpath, rc, errno);
            return rc;
        }
    }
    else
        *inode = lmd->lmd_st;

    return 0;

}
Example #6
0
int SetDefaultGlobalConfig( void *module_config, char *msg_out )
{
    global_config_t *conf = ( global_config_t * ) module_config;
    msg_out[0] = '\0';

    rh_strncpy(conf->fs_path, "", RBH_PATH_MAX);
#ifdef _HAVE_FID
    rh_strncpy(conf->fs_type, "lustre", FILENAME_MAX);
#else
    rh_strncpy(conf->fs_type, "", FILENAME_MAX);
#endif
    rh_strncpy(conf->lock_file, "/var/locks/robinhood.lock", RBH_PATH_MAX);
    conf->stay_in_fs = TRUE;
    conf->check_mounted = TRUE;
    conf->fs_key = FSKEY_FSNAME;

#if defined( _LUSTRE ) && defined( _MDS_STAT_SUPPORT )
    conf->direct_mds_stat = FALSE;
#endif


    return 0;
}
Example #7
0
/* retrieve error message */
char          *db_errmsg( db_conn_t * conn, char *errmsg, unsigned int buflen )
{
    if ( *conn == NULL )
    {
        strcpy( errmsg, "Connection not initialized" );
        return errmsg;
    }

    if ( strlen( sqlite3_errmsg( *conn ) ) + 1 > buflen )
        rh_strncpy(errmsg, sqlite3_errmsg(*conn), buflen);
    else
        strcpy( errmsg, sqlite3_errmsg( *conn ) );

    return errmsg;
}
Example #8
0
static void no_name_warning(PK_PARG_T pk, attr_set_t *p_attrs, unsigned int count)
{
    DEF_PK(ppk);
    char msg[256];

    entry_id2pk(&ATTR(p_attrs, parent_id), PTR_PK(ppk));

    if (count > 1)
        snprintf(msg, sizeof(msg), "%u entries", count);
    else
        rh_strncpy(msg, "entry", sizeof(msg));

    DisplayLog(LVL_MAJOR, LISTMGR_TAG, "WARNING: %s created without"
               " name or parent information: pk="DPK", name='%s', parent='%s'",
               msg, pk, ATTR_MASK_TEST(p_attrs, name) ? ATTR(p_attrs, name) : "",
               ATTR_MASK_TEST(p_attrs, parent_id) ? ppk : "");
}
Example #9
0
/* check syslog facility name.
 * keep p_level unchanged if not specified.
 */
static int check_syslog_facility(const char *descriptor, int *p_fac,
                                 int *p_level)
{
    char  descr_cp[256];
    char *curr;
    int   i;
    bool  match;

    rh_strncpy(descr_cp, descriptor, 256);
    curr = strchr(descr_cp, '.');
    if (curr != NULL) {
        curr[0] = '\0';
        curr++; /* location of syslog level */
    }

    match = false;
    for (i = 0; facilitynames[i].c_name != NULL; i++) {
        if (!strcasecmp(facilitynames[i].c_name, descr_cp)) {
            if (p_fac)
                *p_fac = facilitynames[i].c_val;
            match = true;
            break;
        }
    }
    if (!match)
        return ENOENT;

    if (curr != NULL) {
        /* now doing the same for priority */
        match = false;
        for (i = 0; prioritynames[i].c_name != NULL; i++) {
            if (!strcasecmp(prioritynames[i].c_name, curr)) {
                if (p_level)
                    *p_level = prioritynames[i].c_val;
                match = true;
                break;
            }
        }
        if (!match)
            return ENOENT;
    }

    return 0;
}
Example #10
0
/* Helper function to parse int escape codes (\NNN octal or \xHH hex)
 * return the number of bytes read in str, or -1 if need a go-again for 0 */
static int parse_escaped_int(const char *str, struct fchunk *chunk, int base)
{
    long int print_val;
    char value_string[4], *endptr;
    int numread;

    if (base == 8) {
        numread = 3;
    } else if (base == 16) {
        numread = 2;
    } else {
        RBH_BUG("Error: invalid base");
    }

    /* copy next few chars and try to read as int */
    rh_strncpy(value_string, str, numread+1); /* +1 for final '\0' */
    print_val = strtol(value_string, &endptr, base);
    if (endptr == value_string) {
        /* invalid hex */
        return 0;
    }

    /* printf will copy any byte we put in format string unchanged,
     * except for '\0' and '%'.
     * '\0' is handled as a directive since printf will stop on a 0-byte
     * even with a length specifier */
    if (print_val == 0) {
        /* if chunk->directive is already set, request a new chunk and
         * parse this again */
        if (chunk->directive)
            return -1;
        g_string_append(chunk->format, "%c");
        chunk->directive = 'z';
    } else if ((char)print_val == '%') {
        g_string_append(chunk->format, "%%");
    } else {
        /* printf-agnostic character */
        g_string_append_c(chunk->format, (char)print_val);
    }

    return endptr - value_string;
}
Example #11
0
int update_stripe_info(lmgr_t *p_mgr, PK_ARG_T pk, int validator,
                       const stripe_info_t *p_stripe,
                       const stripe_items_t *p_items, bool insert_if_absent)
{
    attr_set_t fake_attr;
    attr_set_t *p_attr = &fake_attr;
    pktype list[1];

    rh_strncpy(list[0], pk, sizeof(*list));

    ATTR_MASK_INIT(&fake_attr);
    if (p_stripe) {
        ATTR_MASK_SET(&fake_attr, stripe_info);
        ATTR(&fake_attr, stripe_info) = *p_stripe;
    }
    if (p_items) {
        ATTR_MASK_SET(&fake_attr, stripe_items);
        ATTR(&fake_attr, stripe_items) = *p_items;
    }

    return batch_insert_stripe_info(p_mgr, list, &validator, &p_attr, 1, true);
}
Example #12
0
char *FormatStripeList(char *buff, size_t sz, const stripe_items_t *p_stripe_items, bool brief)
{
    unsigned int   i;
    size_t         written = 0;
    const char * format;

    if ( !p_stripe_items || ( p_stripe_items->count == 0 ) )
    {
        rh_strncpy(buff, "(none)", sz);
        return buff;
    }

    buff[0] = '\0';

    for ( i = 0; i < p_stripe_items->count; i++ )
    {
        if ( i != p_stripe_items->count - 1 ) {
            if (brief)
                format = "ost#%u:%u, ";
            else
                format = "ost#%u: %u, ";
        } else {
            if (brief)
                format = "ost#%u:%u";
            else
                format = "ost#%u: %u";
        }
        written +=
            snprintf( ( char * ) ( buff + written ), sz - written, format,
                      p_stripe_items->stripe[i].ost_idx,
                      p_stripe_items->stripe[i].obj_id );
    }

    buff[sz-1] = '\0';

    return buff;
}
Example #13
0
/**
 * Main daemon routine
 */
int main( int argc, char **argv )
{
    int            c, option_index = 0;
    char          *bin = basename( argv[0] );

    char           config_file[MAX_OPT_LEN] = "";
    int            force_log_level = FALSE;
    int            log_level = 0;
    int            rc;
    int            chgd = 0;
    char           err_msg[4096];
    int            neg = 0;
    char           badcfg[RBH_PATH_MAX];

    /* parse command line options */
    while ((c = getopt_long_only(argc, argv, SHORT_OPT_STRING, option_tab,
                            &option_index )) != -1)
    {
        switch ( c )
        {
        case '!':
            neg = 1;
            break;
        case 'u':
            toggle_option(match_user, "user");
            prog_options.user = optarg;
            prog_options.userneg = neg;
            neg = 0;
            break;
        case 'g':
            toggle_option(match_group, "group");
            prog_options.group = optarg;
            prog_options.groupneg = neg;
            neg = 0;
            break;
        case 'U': /* match numerical (non resolved) users */
            toggle_option(match_user, "user");
            prog_options.user = "******";
            prog_options.userneg = neg;
            neg = 0;
            break;
        case 'G': /* match numerical (non resolved) groups */
            toggle_option(match_group, "group");
            prog_options.group = "[0-9]*";
            prog_options.groupneg = neg;
            neg = 0;
            break;
        case 'n':
            toggle_option(match_name, "name");
            prog_options.name = optarg;
            prog_options.nameneg = neg;
            neg = 0;
            break;
#ifdef _LUSTRE
        case 'o':
            toggle_option(match_ost, "ost");
            prog_options.ost_idx = str2int(optarg);
            if (prog_options.ost_idx == (unsigned int)-1)
            {
                fprintf(stderr, "invalid ost index '%s': unsigned integer expected\n", optarg);
                exit(1);
            }
            if (neg) {
                fprintf(stderr, "! () is not supported for ost criteria\n");
                exit(1);
            }
            break;
        case 'P':
            toggle_option(match_pool, "pool");
            prog_options.pool = optarg;
            break;
        case 'O':
            prog_options.lsost = 1;
            prog_options.print = 0;
            disp_mask |= LSOST_DISPLAY_MASK;
            if (neg) {
                fprintf(stderr, "! (-not) unexpected before -lsost option\n");
                exit(1);
            }
            break;
#endif
        case 't':
            toggle_option(match_type, "type");
            prog_options.type = opt2type(optarg);
            if (prog_options.type == NULL)
            {
                fprintf(stderr, "invalid type '%s': expected types: "TYPE_HELP".\n", optarg);
                exit(1);
            }
            if (neg) {
                fprintf(stderr, "! (-not) is not supported for type criteria\n");
                exit(1);
            }
            break;
        case 's':
            toggle_option(match_size, "size");
            if (set_size_filter(optarg))
                exit(1);
            if (neg) {
                fprintf(stderr, "! (-not) is not supported for size criteria\n");
                exit(1);
            }
            break;

        case 'A':
            toggle_option(match_atime, "atime/amin");
            if (set_time_filter(optarg, 0, TRUE, atime))
                exit(1);
            if (neg) {
                fprintf(stderr, "! (-not) is not supported for time criteria\n");
                exit(1);
            }
            break;

        case 'a':
            toggle_option(match_atime, "atime/amin");
            if (set_time_filter(optarg, 60, TRUE, atime))
                exit(1);
            if (neg) {
                fprintf(stderr, "! (-not) is not supported for time criteria\n");
                exit(1);
            }
            break;

        case 'C':
            toggle_option(match_crtime, "crtime");
            if (set_time_filter(optarg, 0, TRUE, rh_crtime))
                exit(1);
            if (neg) {
                fprintf(stderr, "! (-not) is not supported for time criteria\n");
                exit(1);
            }
            break;

        case 'M':
            toggle_option(match_mtime, "mtime/mmin/msec");
            if (set_time_filter(optarg, 0, TRUE, mtime))
                exit(1);
            if (neg) {
                fprintf(stderr, "! (-not) is not supported for time criteria\n");
                exit(1);
            }
            break;

        case 'm':
            toggle_option(match_mtime, "mtime/mmin/msec");
            if (set_time_filter(optarg, 60, FALSE, mtime)) /* don't allow suffix (multiplier is 1min) */
                exit(1);
            if (neg) {
                fprintf(stderr, "! (-not) is not supported for time criteria\n");
                exit(1);
            }
            break;

        case 'z':
            toggle_option(match_mtime, "mtime/mmin/msec");
            if (set_time_filter(optarg, 1, FALSE, mtime)) /* don't allow suffix (multiplier is 1sec) */
                exit(1);
            if (neg) {
                fprintf(stderr, "! (-not) is not supported for time criteria\n");
                exit(1);
            }
            break;


#ifdef ATTR_INDEX_status
        case 'S':
            toggle_option(match_status, "status");
            prog_options.status = status2dbval(optarg);
            if ( prog_options.status == (file_status_t)-1 )
            {
                fprintf(stderr, "Unknown status '%s'. Allowed status: %s.\n", optarg,
                        allowed_status());
                exit(1);
            }
            prog_options.statusneg = neg;
            neg = 0;
            break;
#endif
        case 'l':
            prog_options.ls = 1;
            prog_options.print = 0;
            disp_mask |= LS_DISPLAY_MASK;
            if (neg) {
                fprintf(stderr, "! (-not) unexpected before -ls option\n");
                exit(1);
            }
            break;
        case 'p':
            prog_options.print = 1;
            disp_mask |= LS_DISPLAY_MASK;
            if (neg) {
                fprintf(stderr, "! (-not) unexpected before -ls option\n");
                exit(1);
            }
            break;

        case 'E':
            toggle_option(exec, "exec");
            prog_options.exec_cmd = optarg;
            prog_options.print = 0;
            break;
        case 'f':
            rh_strncpy(config_file, optarg, MAX_OPT_LEN);
            if (neg) {
                fprintf(stderr, "! (-not) unexpected before -f option\n");
                exit(1);
            }
            break;
        case 'd':
            force_log_level = TRUE;
            log_level = str2debuglevel( optarg );
            if ( log_level == -1 )
            {
                fprintf(stderr,
                        "Unsupported log level '%s'. CRIT, MAJOR, EVENT, VERB, DEBUG or FULL expected.\n",
                        optarg);
                exit(1);
            }
            if (neg) {
                fprintf(stderr, "! (-not) unexpected before -d option\n");
                exit(1);
            }
            break;
        case 'b':
            prog_options.bulk = force_nobulk;
            break;
        case 'h':
            display_help( bin );
            exit( 0 );
            break;
        case 'V':
            display_version( bin );
            exit( 0 );
            break;
        case ':':
        case '?':
        default:
            display_help( bin );
            exit( 1 );
            break;
        }
    }

    /* get default config file, if not specified */
    if (SearchConfig(config_file, 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", config_file );
    }

    /* only read ListMgr config */

    if ( ReadRobinhoodConfig( 0, config_file, err_msg, &config, FALSE ) )
    {
        fprintf( stderr, "Error reading configuration file '%s': %s\n", config_file, err_msg );
        exit( 1 );
    }
    process_config_file = config_file;

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

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

    if ( force_log_level )
        config.log_config.debug_level = log_level;
    else
        config.log_config.debug_level = LVL_MAJOR; /* no event message */

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

    /* Initialize logging */
    rc = InitializeLogs( bin, &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);

    /* Initialize list manager */
    rc = ListMgr_Init( &config.lmgr_config, TRUE );
    if ( rc )
    {
        DisplayLog( LVL_CRIT, FIND_TAG, "Error %d initializing list manager", rc );
        exit( rc );
    }
    else
        DisplayLog( LVL_DEBUG, FIND_TAG, "ListManager successfully initialized" );

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

    /* Create database access */
    rc = ListMgr_InitAccess(&lmgr);
    if (rc)
    {
        DisplayLog( LVL_CRIT, FIND_TAG, "Error %d: cannot connect to database", rc );
        exit(rc);
    }

    if (argc == optind)
    {
        /* no argument: default is root
         * => switch to bulk mode (unless nobulk is specified)
         */
        if (prog_options.bulk != force_nobulk)
        {
            DisplayLog(LVL_DEBUG, FIND_TAG, "Optimization: switching to bulk DB request mode");
            mkfilters(FALSE); /* keep dirs */
            return list_bulk();
        }
        else
        {
            char *id = config.global_config.fs_path;
            mkfilters(TRUE); /* exclude dirs */
            /* no path specified, list all entries */
            rc = list_contents(&id, 1);
        }
    }
    else
    {
        mkfilters(TRUE); /* exclude dirs */
        rc = list_contents(argv+optind, argc-optind);
    }

    ListMgr_CloseAccess( &lmgr );

    return rc;
}
Example #14
0
/**
 * Main daemon routine
 */
int main(int argc, char **argv)
{
    int            c, option_index = 0;
    const char    *bin;

    char           config_file[MAX_OPT_LEN] = "";

    bool           do_start = false;
    bool           do_reset = false;
    bool           do_resume = false;
    bool           do_complete = false;
    bool           do_status = false;

    int            list_state = -1;
    int            local_flags = 0;

    int            rc;
    char           err_msg[4096];
    robinhood_config_t config;
    struct sigaction act_sigterm;
    int             chgd = 0;
    char            badcfg[RBH_PATH_MAX];

    bin = rh_basename(argv[0]); /* supports NULL argument */

    /* parse command line options */
    while ((c =
            getopt_long(argc, argv, SHORT_OPT_STRING, option_tab,
                        &option_index)) != -1) {
        switch (c) {
        case 'S':
            do_start = true;
            break;
        case 's':
            do_status = true;
            break;
        case 'Z':
            do_reset = true;
            break;
        case 'c':
            do_complete = true;
            break;
        case 'r':
            do_resume = true;
            break;
        case 'L':
            if (!strcasecmp(optarg, "all"))
                list_state = RT_ALL;
            else if (!strcasecmp(optarg, "done"))
                list_state = RT_DONE;
            else if (!strcasecmp(optarg, "failed"))
                list_state = RT_FAILED;
            else if (!strcasecmp(optarg, "todo"))
                list_state = RT_TODO;
            else {
                fprintf(stderr,
                        "Invalid parameter for option --list: all, done, failed or todo expected.\n");
                exit(1);
            }
            break;
        case 'e':
            local_flags |= RETRY_ERRORS;
            break;
        case 'y':
            local_flags |= NO_CONFIRM;
            break;
        case 'f':
            rh_strncpy(config_file, optarg, MAX_OPT_LEN);
            break;
        case 'D':
            if (!optarg) {
                fprintf(stderr,
                        "Missing mandatory argument <path> for --dir\n");
                exit(1);
            } else {
                rh_strncpy(path_buff, optarg, MAX_OPT_LEN);
                path_filter = path_buff;
            }
            break;
        case 'o':
            if (!optarg) {
                fprintf(stderr,
                        "Missing mandatory argument <ost_index> for --ost\n");
                exit(1);
            }
            /* parse it as a set */
            if (lmgr_range2list(optarg, DB_UINT, &ost_list)) {
                fprintf(stderr,
                        "Invalid value '%s' for --ost option: integer or set expected (e.g. 2 or 3,5-8,10-12).\n",
                        optarg);
                exit(1);
            }
            /* copy arg to display it */
            rh_strncpy(ost_range_str, optarg, sizeof(ost_range_str));
            break;
        case 'b':
            if (!optarg) {
                fprintf(stderr,
                        "Missing mandatory argument <date_time> for --since\n");
                exit(1);
            }
            since_time = str2date(optarg);
            if (since_time == (time_t)-1) {
                fprintf(stderr,
                        "Invalid date format: yyyymmdd[HH[MM[SS]]] expected\n");
                exit(1);
            }
            break;
        case 'l':
        {
            int log_level = str2debuglevel(optarg);

            if (log_level == -1) {
                fprintf(stderr,
                        "Unsupported log level '%s'. CRIT, MAJOR, EVENT, VERB, DEBUG or FULL expected.\n",
                        optarg);
                exit(1);
            }
            force_debug_level(log_level);
            break;
        }
        case 'h':
            display_help(bin);
            exit(0);
            break;
        case 'V':
            display_version(bin);
            exit(0);
            break;
        case ':':
        case '?':
        default:
            display_help(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);
    }

    rc = rbh_init_internals();
    if (rc != 0)
        exit(rc);

    /* get default config file, if not specified */
    if (SearchConfig(config_file, 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", config_file);
    }

    /* only read ListMgr config */

    if (ReadRobinhoodConfig(0, config_file, err_msg, &config, false)) {
        fprintf(stderr, "Error reading configuration file '%s': %s\n",
                config_file, err_msg);
        exit(1);
    }

    /* XXX HOOK: Set logging to stderr */
    strcpy(config.log_config.log_file, "stderr");
    strcpy(config.log_config.report_file, "stderr");
    strcpy(config.log_config.alert_file, "stderr");

    /* Initialize logging */
    rc = InitializeLogs(bin, &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);

    /* Initialize status managers (XXX all or just the one used for
     * recovery?) */
    rc = smi_init_all(options.flags);
    if (rc)
        exit(rc);

    /* Initialize list manager */
    rc = ListMgr_Init(0);
    if (rc) {
        DisplayLog(LVL_CRIT, RECOV_TAG,
                   "Error initializing list manager: %s (%d)", lmgr_err2str(rc),
                   rc);
        exit(rc);
    } else
        DisplayLog(LVL_DEBUG, RECOV_TAG,
                   "ListManager successfully initialized");

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

    /* Create database access */
    rc = ListMgr_InitAccess(&lmgr);
    if (rc) {
        DisplayLog(LVL_CRIT, RECOV_TAG, "Error %d: cannot connect to database",
                   rc);
        exit(rc);
    }
#ifdef _HSM_LITE
    rc = Backend_Start(&config.backend_config, 0);
    if (rc) {
        DisplayLog(LVL_CRIT, RECOV_TAG, "Error initializing backend");
        exit(1);
    }
#endif

    /* create signal handlers */
    memset(&act_sigterm, 0, sizeof(act_sigterm));
    act_sigterm.sa_flags = 0;
    act_sigterm.sa_handler = terminate_handler;
    if (sigaction(SIGTERM, &act_sigterm, NULL) == -1
        || sigaction(SIGINT, &act_sigterm, NULL) == -1) {
        DisplayLog(LVL_CRIT, RECOV_TAG,
                   "Error while setting signal handlers for SIGTERM and SIGINT: %s",
                   strerror(errno));
        exit(1);
    } else
        DisplayLog(LVL_VERB, RECOV_TAG,
                   "Signals SIGTERM and SIGINT (abort command) are ready to be used");

    if (do_status)
        rc = recov_status();
    else if (list_state != -1)
        rc = recov_list(list_state);
    else if (do_start)
        rc = recov_start();
    else if (do_reset)
        rc = recov_reset(local_flags & NO_CONFIRM);
    else if (do_resume)
        rc = recov_resume(local_flags & RETRY_ERRORS);
    else if (do_complete)
        rc = recov_complete();
    else {
        display_help(bin);
        rc = 1;
    }

    ListMgr_CloseAccess(&lmgr);

    return rc;
}
Example #15
0
/**
 * Main daemon routine
 */
int main(int argc, char **argv)
{
    int c, option_index = 0;
    const char *bin;
    char config_file[MAX_OPT_LEN] = "";

    int rc;
    char err_msg[4096];
    robinhood_config_t config;
    int chgd = 0;
    char badcfg[RBH_PATH_MAX];

    bin = rh_basename(argv[0]);

    /* parse command line options */
    while ((c = getopt_long(argc, argv, SHORT_OPT_STRING, option_tab,
                            &option_index)) != -1) {
        switch (c) {
        case 'f':
            rh_strncpy(config_file, optarg, MAX_OPT_LEN);
            break;
        case 'l':
        {
            int log_level = str2debuglevel(optarg);

            if (log_level == -1) {
                fprintf(stderr,
                        "Unsupported log level '%s'. CRIT, MAJOR, EVENT, VERB, DEBUG or FULL expected.\n",
                        optarg);
                exit(1);
            }
            force_debug_level(log_level);
            break;
        }
        case 'h':
            display_help(bin);
            exit(0);
            break;
        case 'V':
            display_version(bin);
            exit(0);
            break;
        case ':':
        case '?':
        default:
            display_help(bin);
            exit(1);
            break;
        }
    }

    /* 2 expected argument: old backend path, new path is FS */
    if (optind > argc - 2) {
        fprintf(stderr, "Error: missing arguments on command line.\n");
        display_help(bin);
        exit(1);
    } else if (optind < argc - 3) {
        fprintf(stderr, "Error: too many arguments on command line.\n");
        display_help(bin);
        exit(1);
    }

    /* get default config file, if not specified */
    if (SearchConfig(config_file, 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", config_file);
    }

    rc = rbh_init_internals();
    if (rc != 0)
        exit(rc);

    /* only read ListMgr config */
    if (ReadRobinhoodConfig(0, config_file, err_msg, &config, false)) {
        fprintf(stderr, "Error reading configuration file '%s': %s\n",
                config_file, err_msg);
        exit(1);
    }

    /* XXX HOOK: Set logging to stderr */
    strcpy(config.log_config.log_file, "stderr");
    strcpy(config.log_config.report_file, "stderr");
    strcpy(config.log_config.alert_file, "stderr");

    /* Initialize logging */
    rc = InitializeLogs(bin, &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);

    /* Initialize status managers (XXX all or just the one used for rebind?) */
    rc = smi_init_all(options.flags);
    if (rc)
        exit(rc);

#ifdef _HSM_LITE
    rc = Backend_Start(&config.backend_config, 0);
    if (rc) {
        DisplayLog(LVL_CRIT, LOGTAG, "Error initializing backend");
        exit(1);
    }
#endif

    if (optind == argc - 2)
        rc = rebind_helper(argv[optind], argv[optind + 1], NULL);
    else if (optind == argc - 3)
        rc = rebind_helper(argv[optind], argv[optind + 1], argv[optind + 2]);

    return rc;
}
Example #16
0
int ReadLmgrConfig( config_file_t config, void *module_config, char *msg_out, int for_reload )
{
    int            rc;
    lmgr_config_t *conf = ( lmgr_config_t * ) module_config;
    char         **options = NULL;
    unsigned int   nb_options = 0;
    char           tmpstr[1024];

    config_item_t  db_block;

    static const char *lmgr_allowed[] = {
        "commit_behavior",
        "connect_retry_interval_min",
        "connect_retry_interval_max",
        "user_acct",
        "group_acct",
        MYSQL_CONFIG_BLOCK,
        SQLITE_CONFIG_BLOCK,
        NULL
    };


#ifdef _MYSQL
    static const char *db_allowed[] = {
        "server", "db", "user", "password", "password_file", "port", "socket",
        "innodb", NULL
    };
#elif defined (_SQLITE)
    static const char *db_allowed[] = {
        "db_file", "retry_delay_microsec",
        NULL
    };
#endif

    /* get ListManager block */

    config_item_t  lmgr_block = rh_config_FindItemByName( config, LMGR_CONFIG_BLOCK );

    if ( lmgr_block == NULL )
    {
        strcpy( msg_out, "Missing configuration block '" LMGR_CONFIG_BLOCK "'" );
        return ENOENT;
    }

    if ( rh_config_ItemType( lmgr_block ) != CONFIG_ITEM_BLOCK )
    {
        strcpy( msg_out, "A block is expected for '" LMGR_CONFIG_BLOCK "' item" );
        return EINVAL;
    }

    /* retrieve parameters */

    /* 1) commit_behavior */

    rc = GetStringParam( lmgr_block, LMGR_CONFIG_BLOCK, "commit_behavior",
                         STR_PARAM_NO_WILDCARDS, tmpstr, 1024, &options, &nb_options, msg_out );
    if ( ( rc != 0 ) && ( rc != ENOENT ) )
        return rc;
    else if ( rc != ENOENT )
    {
        if ( !strcasecmp( tmpstr, "autocommit" ) )
            conf->commit_behavior = 0;
        else if ( !strcasecmp( tmpstr, "transaction" ) )
            conf->commit_behavior = 1;
        else if ( !strcasecmp( tmpstr, "periodical" )  /* for backward compatibility */
                  || !strcasecmp( tmpstr, "periodic" ) )
        {
            if ( ( nb_options != 1 ) || !options || !options[0] )
            {
                strcpy( msg_out,
                        "A single argument is expected for periodic commit behavior. Eg: commit_behavior = periodic(1000)" );
                return EINVAL;
            }

            conf->commit_behavior = atoi( options[0] );
            if ( conf->commit_behavior == 0 )
            {
                strcpy( msg_out,
                        "The argument for \"" LMGR_CONFIG_BLOCK
                        "::commit_behavior = periodical\" must be a positive integer. Eg: commit_behavior = periodic(1000)" );
                return EINVAL;
            }
        }
        else
        {
            sprintf( msg_out, "Invalid commit behavior '%s' (expected: autocommit, "
                     "transaction, periodic(<count>))", tmpstr );
            return EINVAL;
        }
    }

    /* 2) connect_retry_interval_min  and connect_retry_interval_max */

    rc = GetDurationParam( lmgr_block, LMGR_CONFIG_BLOCK,
                           "connect_retry_interval_min",
                           INT_PARAM_POSITIVE | INT_PARAM_NOT_NULL,
                           ( int * ) &conf->connect_retry_min, NULL, NULL, msg_out );
    if ( ( rc != 0 ) && ( rc != ENOENT ) )
        return rc;

    rc = GetDurationParam( lmgr_block, LMGR_CONFIG_BLOCK,
                           "connect_retry_interval_max",
                           INT_PARAM_POSITIVE | INT_PARAM_NOT_NULL,
                           ( int * ) &conf->connect_retry_max, NULL, NULL, msg_out );
    if ( ( rc != 0 ) && ( rc != ENOENT ) )
        return rc;

    /* 3) ACCT configuration*/

    rc = GetBoolParam( lmgr_block, LMGR_CONFIG_BLOCK,
                       "user_acct", 0, &conf->user_acct, NULL, NULL, msg_out);
    if ( ( rc != 0 ) && ( rc != ENOENT ) )
        return rc;

    rc = GetBoolParam( lmgr_block, LMGR_CONFIG_BLOCK,
                       "group_acct", 0, &conf->group_acct, NULL, NULL, msg_out);
    if ( ( rc != 0 ) && ( rc != ENOENT ) )
        return rc;

    CheckUnknownParameters( lmgr_block, LMGR_CONFIG_BLOCK, lmgr_allowed );

    /* Database specific parameters */
#ifdef _MYSQL

    /* get MySQL block */

    db_block = rh_config_GetItemByName( lmgr_block, MYSQL_CONFIG_BLOCK );

    if ( db_block == NULL )
    {
        strcpy( msg_out,
                "Missing configuration block '" LMGR_CONFIG_BLOCK "::" MYSQL_CONFIG_BLOCK "'" );
        return ENOENT;
    }

    if ( rh_config_ItemType( db_block ) != CONFIG_ITEM_BLOCK )
    {
        sprintf( msg_out,
                 "A block is expected for '" LMGR_CONFIG_BLOCK "::" MYSQL_CONFIG_BLOCK
                 "' item, line %d", rh_config_GetItemLine( db_block ) );
        return EINVAL;
    }

    rc = GetStringParam( db_block, MYSQL_CONFIG_BLOCK, "server",
                         STR_PARAM_NO_WILDCARDS, conf->db_config.server, 256, NULL, NULL, msg_out );
    if ( ( rc != 0 ) && ( rc != ENOENT ) )
        return rc;

    rc = GetStringParam( db_block, MYSQL_CONFIG_BLOCK, "db",
                         PARAM_MANDATORY | STR_PARAM_NO_WILDCARDS,
                         conf->db_config.db, 256, NULL, NULL, msg_out );
    if ( rc )
        return rc;

    rc = GetStringParam( db_block, MYSQL_CONFIG_BLOCK, "user",
                         STR_PARAM_NO_WILDCARDS, conf->db_config.user, 256, NULL, NULL, msg_out );
    if ( ( rc != 0 ) && ( rc != ENOENT ) )
        return rc;

    rc = GetStringParam( db_block, MYSQL_CONFIG_BLOCK, "password",
                         0, conf->db_config.password, 256, NULL, NULL, msg_out );
    if ( ( rc != 0 ) && ( rc != ENOENT ) )
        return rc;
    else if ( rc == ENOENT )
    {
        FILE          *passfile;
        char           errstr[1024];

        rc = GetStringParam( db_block, MYSQL_CONFIG_BLOCK,
                             "password_file",
                             STR_PARAM_ABSOLUTE_PATH |
                             STR_PARAM_NO_WILDCARDS, tmpstr, 1024, NULL, NULL, msg_out );
        if ( ( rc != 0 ) && ( rc != ENOENT ) )
            return rc;
        else if ( rc == ENOENT )
        {
            strcpy( msg_out,
                    MYSQL_CONFIG_BLOCK "::password or "
                    MYSQL_CONFIG_BLOCK "::password_file must be provided" );
            return ENOENT;
        }

        /* read password file and @TODO check its rights */
        passfile = fopen( tmpstr, "r" );
        if ( !passfile )
        {
            rc = errno;
            sprintf( msg_out, "Error opening password file %s : %s", tmpstr, strerror(errno) );
            return rc;
        }
        fscanf( passfile, "%1024s", tmpstr );
        if ( ferror( passfile ) )
        {
            rc = errno;
            strerror_r( rc, errstr, 1024 );
            sprintf( msg_out, "Error reading password file %s : %s", tmpstr, errstr );
            return rc;
        }
        fclose( passfile );
        rh_strncpy(conf->db_config.password, tmpstr, 256);
    }

    rc = GetIntParam( db_block, MYSQL_CONFIG_BLOCK, "port",
                         INT_PARAM_POSITIVE | INT_PARAM_NOT_NULL,
                         (int*)&conf->db_config.port, NULL, NULL, msg_out );
    if ( ( rc != 0 ) && ( rc != ENOENT ) )
        return rc;

    rc = GetStringParam( db_block, MYSQL_CONFIG_BLOCK, "socket",
                         STR_PARAM_NO_WILDCARDS | STR_PARAM_ABSOLUTE_PATH,
                         conf->db_config.socket, RBH_PATH_MAX, NULL, NULL, msg_out );
    if ( ( rc != 0 ) && ( rc != ENOENT ) )
        return rc;

    rc = GetBoolParam( db_block, MYSQL_CONFIG_BLOCK, "innodb", 0,
                       &conf->db_config.innodb, NULL, NULL, msg_out );
    if ( ( rc != 0 ) && ( rc != ENOENT ) )
        return rc;

    CheckUnknownParameters( db_block, MYSQL_CONFIG_BLOCK, db_allowed );

#elif defined (_SQLITE)
    /* get SQLite block */

    db_block = rh_config_GetItemByName( lmgr_block, SQLITE_CONFIG_BLOCK );

    if ( db_block == NULL )
    {
        strcpy( msg_out,
                "Missing configuration block '" LMGR_CONFIG_BLOCK "::" SQLITE_CONFIG_BLOCK "'" );
        return ENOENT;
    }

    if ( rh_config_ItemType( db_block ) != CONFIG_ITEM_BLOCK )
    {
        sprintf( msg_out,
                 "A block is expected for '" LMGR_CONFIG_BLOCK "::" SQLITE_CONFIG_BLOCK
                 "' item, line %d", rh_config_GetItemLine( db_block ) );
        return EINVAL;
    }


    rc = GetStringParam( db_block, SQLITE_CONFIG_BLOCK, "db_file",
                         STR_PARAM_ABSOLUTE_PATH |
                         STR_PARAM_NO_WILDCARDS,
                         conf->db_config.filepath, RBH_PATH_MAX, NULL, NULL, msg_out );
    if ( ( rc != 0 ) && ( rc != ENOENT ) )
        return rc;

    rc = GetIntParam( db_block, SQLITE_CONFIG_BLOCK,
                      "retry_delay_microsec",
                      INT_PARAM_POSITIVE | INT_PARAM_NOT_NULL,
                      (int*)&conf->db_config.retry_delay_microsec, NULL, NULL, msg_out );
    if ( ( rc != 0 ) && ( rc != ENOENT ) )
        return rc;

    CheckUnknownParameters( db_block, SQLITE_CONFIG_BLOCK, db_allowed );
#endif


    return 0;
}
Example #17
0
static void display_line_log(log_stream_t *p_log, const char *tag,
                             const char *format, va_list arglist)
{
    char          line_log[MAX_LINE_LEN];
    int           written;
    time_t        now = time(NULL);
    unsigned int  th = GetThreadIndex();
    struct tm     date;
    int           would_print;

    if (log_initialized) {
        /* periodically check if log files have been renamed */
        if (now - last_time_test > TIME_TEST_FILE) {
            test_file_names();
            last_time_test = now;
        }
    }

    pthread_rwlock_rdlock(&p_log->f_lock);
    /* if logs are not initalized or the log is a NULL FILE*,
     * default logging to stderr */
    if ((!log_initialized) ||
        ((p_log->log_type != RBH_LOG_SYSLOG) && (p_log->f_log == NULL))) {
        localtime_r(&now, &date);
        written =
            snprintf(line_log, MAX_LINE_LEN,
                     "%.4d/%.2d/%.2d %.2d:%.2d:%.2d %s[%lu/%u] %s%s",
                     1900 + date.tm_year, date.tm_mon + 1, date.tm_mday,
                     date.tm_hour, date.tm_min, date.tm_sec,
                     log_config.log_process ? "robinhood" : "",
                     (unsigned long)getpid(), th, tag ? tag : "",
                     tag ? " | " : "");

        would_print =
            vsnprintf(line_log + written, MAX_LINE_LEN - written, format,
                      arglist);
        clean_str(line_log);

        if (would_print >= MAX_LINE_LEN - written)
            fprintf(stderr, "%s... <Line truncated. Original size=%u>\n",
                    line_log, would_print);
        else
            fprintf(stderr, "%s\n", line_log);
    } else if (p_log->log_type == RBH_LOG_SYSLOG) {
        /* add tag to syslog line */
        char new_format[MAX_LINE_LEN];
        if (tag)
            snprintf(new_format, MAX_LINE_LEN, "%s | %s", tag, format);
        else
            rh_strncpy(new_format, format, MAX_LINE_LEN);

        vsyslog(log_config.syslog_priority, new_format, arglist);
    } else {    /* log to a file */

        localtime_r(&now, &date);

        written =
            snprintf(line_log, MAX_LINE_LEN,
                     "%.4d/%.2d/%.2d %.2d:%.2d:%.2d %s%s%s[%lu/%u] %s%s",
                     1900 + date.tm_year, date.tm_mon + 1, date.tm_mday,
                     date.tm_hour, date.tm_min, date.tm_sec,
                     log_config.log_process ? prog_name : "",
                     log_config.log_host ? "@" : "",
                     log_config.log_host ? machine_name : "",
                     (unsigned long)getpid(), th,
                     tag ? tag : "", tag ? " | " : "");

        would_print =
            vsnprintf(line_log + written, MAX_LINE_LEN - written, format,
                      arglist);
        clean_str(line_log);

        if (p_log->f_log != NULL) {
            if (would_print >= MAX_LINE_LEN - written)
                fprintf(p_log->f_log,
                        "%s... <Line truncated. Original size=%u>\n", line_log,
                        would_print);
            else
                fprintf(p_log->f_log, "%s\n", line_log);
        }
    }
    pthread_rwlock_unlock(&p_log->f_lock);
}
Example #18
0
/**
 * Main daemon routine
 */
int main(int argc, char **argv)
{
    int c, option_index = 0;
    const char *bin;
    char config_file[MAX_OPT_LEN] = "";

    int rc;
    char err_msg[4096];
    bool chgd = false;
    char badcfg[RBH_PATH_MAX];
    char sm_name[SM_NAME_MAX + 1] = "";

    bin = rh_basename(argv[0]);

    /* parse command line options */
    while ((c = getopt_long(argc, argv, SHORT_OPT_STRING, option_tab,
                            &option_index)) != -1) {
        switch (c) {
        case 'f':
            rh_strncpy(config_file, optarg, MAX_OPT_LEN);
            break;
        case 'l':
        {
            int log_level = str2debuglevel(optarg);

            if (log_level == -1) {
                fprintf(stderr,
                        "Unsupported log level '%s'. CRIT, MAJOR, EVENT, VERB, DEBUG or FULL expected.\n",
                        optarg);
                exit(1);
            }
            force_debug_level(log_level);
            break;
        }

        case 's':
            if (!EMPTY_STRING(sm_name))
                fprintf(stderr,
                        "WARNING: only a single status manager is expected "
                        "on command line. '%s' ignored.\n", optarg);
            else
                rh_strncpy(sm_name, optarg, sizeof(sm_name));
            break;

        case 'h':
            display_help(bin);
            exit(EXIT_SUCCESS);
            break;
        case 'V':
            display_version(bin);
            exit(EXIT_SUCCESS);
            break;
        case ':':
        case '?':
        default:
            display_help(bin);
            exit(1);
            break;
        }
    }

    /* 2 expected argument: old backend path, new path is FS */
    if (optind > argc - 3) {
        fprintf(stderr, "Error: missing arguments on command line.\n");
        display_help(bin);
        exit(1);
    } else if (optind < argc - 4) {
        fprintf(stderr, "Error: too many arguments on command line.\n");
        display_help(bin);
        exit(1);
    }

    rc = rbh_init_internals();
    if (rc != 0)
        exit(EXIT_FAILURE);

    /* get default config file, if not specified */
    if (SearchConfig(config_file, 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", config_file);
    }

    /* only read common config (listmgr, ...) (mask=0) */
    if (rbh_cfg_load(0, config_file, err_msg)) {
        fprintf(stderr, "Error reading configuration file '%s': %s\n",
                config_file, err_msg);
        exit(1);
    }

    if (!log_config.force_debug_level)
        log_config.debug_level = LVL_MAJOR; /* no event message */

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

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

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

    /* Initialize status managers (XXX all or just the one used for undelete?)
     */
    rc = smi_init_all(0);
    if (rc)
        exit(EXIT_FAILURE);

    /* load the status manager */
    if (!EMPTY_STRING(sm_name)) {
        rc = load_smi(sm_name, &smi);
        if (rc)
            exit(EXIT_FAILURE);
    } else {
        /* if there is a single smi that allows undelete, use it */
        rc = load_single_smi(&smi);
        if (rc)
            exit(EXIT_FAILURE);
    }

    if (optind == argc - 3)
        rc = rebind_helper(argv[optind], argv[optind + 1], argv[optind + 2],
                          NULL);
    else if (optind == argc - 4)
        rc = rebind_helper(argv[optind], argv[optind + 1], argv[optind + 2],
                           argv[optind + 3]);

    exit(rc ? EXIT_FAILURE: EXIT_SUCCESS);
}
Example #19
0
int get_stripe_info(lmgr_t *p_mgr, PK_ARG_T pk, stripe_info_t *p_stripe_info,
                    stripe_items_t *p_items)
{
/* stripe_count, stripe_size, pool_name, validator => 4 */
#define STRIPE_INFO_COUNT 4
    char *res[STRIPE_INFO_COUNT];
    result_handle_t result;
    int i;
    int rc = DB_SUCCESS;
    GString *req;

    /* retrieve basic stripe info */
    req =
        g_string_new
        ("SELECT stripe_count, stripe_size, pool_name,validator FROM "
         STRIPE_INFO_TABLE " WHERE id=");
    g_string_append_printf(req, DPK, pk);

    rc = db_exec_sql(&p_mgr->conn, req->str, &result);
    if (rc)
        goto out;

    rc = db_next_record(&p_mgr->conn, &result, res, STRIPE_INFO_COUNT);

    if (rc == DB_END_OF_LIST)
        rc = DB_NOT_EXISTS;
    if (rc)
        goto res_free;

    for (i = 0; i < STRIPE_INFO_COUNT; i++) {
        DisplayLog(LVL_FULL, LISTMGR_TAG, "stripe_res[%u] = %s", i,
                   res[i] ? res[i] : "<null>");
        if (res[i] == NULL) {
            rc = DB_ATTR_MISSING;
            goto res_free;
        }
    }

    p_stripe_info->stripe_count = atoi(res[0]);
    p_stripe_info->stripe_size = atoi(res[1]);
    rh_strncpy(p_stripe_info->pool_name, res[2], MAX_POOL_LEN);
#ifdef HAVE_LLAPI_FSWAP_LAYOUTS
    p_stripe_info->validator = atoi(res[3]);
#endif

    db_result_free(&p_mgr->conn, &result);

    if (p_items) {
        /* retrieve stripe list */
        g_string_printf(req, "SELECT stripe_index,ostidx,details FROM "
                        STRIPE_ITEMS_TABLE " WHERE id=" DPK
                        " ORDER BY stripe_index ASC", pk);

        rc = db_exec_sql(&p_mgr->conn, req->str, &result);
        if (rc)
            goto out;

#ifndef _LUSTRE_HSM
        /* this is abnormal if LUSTRE/HSM feature is not present */
        if (p_stripe_info->stripe_count !=
            db_result_nb_records(&p_mgr->conn, &result)) {
            DisplayLog(LVL_MAJOR, LISTMGR_TAG,
                       "Warning: the number of stripe items (%d) doesn't match stripe count (%u)! (Pk="
                       DPK ")", db_result_nb_records(&p_mgr->conn, &result),
                       p_stripe_info->stripe_count, pk);
        }
#endif
        p_items->count = db_result_nb_records(&p_mgr->conn, &result);

        if (p_items->count > 0) {

            /* allocate stripe array */
            p_items->stripe = MemCalloc(p_items->count, sizeof(stripe_item_t));

            if (!p_items->stripe) {
                rc = DB_NO_MEMORY;
                goto res_free;
            }

            /* fill stripe units */
            for (i = 0; i < p_items->count; i++) {
                rc = db_next_record(&p_mgr->conn, &result, res,
                                    STRIPE_INFO_COUNT);
                if (rc)
                    goto stripe_free;

                if (res[0] == NULL) {
                    rc = DB_ATTR_MISSING;
                    goto stripe_free;
                }

                if (i != atoi(res[0])) {
                    DisplayLog(LVL_MAJOR, LISTMGR_TAG,
                               "Warning: inconsistent stripe order: stripe %s returned in position %u",
                               res[0], i);
                }
                p_items->stripe[i].ost_idx = atoi(res[1]);
                /* raw copy of binary buffer (last 3 fields of stripe_item_t
                 *                            = address of ost_gen field) */
                memcpy(&p_items->stripe[i].ost_gen, res[2], STRIPE_DETAIL_SZ);
            }
        } else
            p_items->stripe = NULL;

        /* last query result must be freed */
        rc = DB_SUCCESS;
        goto res_free;
    }

    rc = DB_SUCCESS;
    /* result is already freed */
    goto out;

 stripe_free:
    free_stripe_items(p_items);
 res_free:
    db_result_free(&p_mgr->conn, &result);
 out:
    g_string_free(req, TRUE);
    return rc;
}
Example #20
0
static int lmgr_cfg_read(config_file_t config, void *module_config,
                         char *msg_out)
{
    int rc;
    bool bval;
    lmgr_config_t *conf = (lmgr_config_t *) module_config;
    char **options = NULL;
    unsigned int nb_options = 0;
    char tmpstr[1024];
    config_item_t lmgr_block;
    config_item_t db_block;

    static const char *lmgr_allowed[] = {
        "commit_behavior", "connect_retry_interval_min",
        "connect_retry_interval_max", "accounting",
        MYSQL_CONFIG_BLOCK, SQLITE_CONFIG_BLOCK,
        "user_acct", "group_acct",  /* deprecated => accounting */
        NULL
    };

    const cfg_param_t cfg_params[] = {
        {"connect_retry_interval_min", PT_DURATION, PFLG_POSITIVE |
         PFLG_NOT_NULL, &conf->connect_retry_min, 0},
        {"connect_retry_interval_max", PT_DURATION, PFLG_POSITIVE |
         PFLG_NOT_NULL, &conf->connect_retry_max, 0},
        {"accounting", PT_BOOL, 0, &conf->acct, 0},
        END_OF_PARAMS
    };

#ifdef _MYSQL
    static const char *db_allowed[] = {
        "server", "db", "user", "password", "password_file", "port", "socket",
        "engine", "tokudb_compression", NULL
    };

    const cfg_param_t db_params[] = {
        {"server", PT_STRING, PFLG_NO_WILDCARDS,
         conf->db_config.server, sizeof(conf->db_config.server)}
        ,
        {"db", PT_STRING, PFLG_MANDATORY | PFLG_NO_WILDCARDS,
         conf->db_config.db, sizeof(conf->db_config.db)}
        ,
        {"user", PT_STRING, PFLG_NO_WILDCARDS, conf->db_config.user,
         sizeof(conf->db_config.user)}
        ,
        {"port", PT_INT, PFLG_POSITIVE | PFLG_NOT_NULL,
         (int *)&conf->db_config.port, 0},
        {"socket", PT_STRING, PFLG_NO_WILDCARDS | PFLG_ABSOLUTE_PATH,
         conf->db_config.socket, sizeof(conf->db_config.socket)}
        ,
        {"engine", PT_STRING, PFLG_NO_WILDCARDS | PFLG_NOT_EMPTY,
         conf->db_config.engine, sizeof(conf->db_config.engine)}
        ,
        {"tokudb_compression", PT_STRING, PFLG_NO_WILDCARDS,
         conf->db_config.tokudb_compression,
         sizeof(conf->db_config.tokudb_compression)}
        ,
        END_OF_PARAMS
    };
#elif defined(_SQLITE)
    static const char *db_allowed[] = {
        "db_file", "retry_delay_microsec",
        NULL
    };
    const cfg_param_t db_params[] = {
        {"db_file", PT_STRING, PFLG_ABSOLUTE_PATH | PFLG_NO_WILDCARDS,
         conf->db_config.filepath, sizeof(conf->db_config.filepath)}
        ,
        {"retry_delay_microsec", PT_INT, PFLG_POSITIVE | PFLG_NOT_NULL,
         (int *)&conf->db_config.retry_delay_microsec, 0},
        END_OF_PARAMS
    };
#endif

    /* get ListManager block */
    rc = get_cfg_block(config, LMGR_CONFIG_BLOCK, &lmgr_block, msg_out);
    if (rc)
        return rc;

    /* retrieve std parameters */
    rc = read_scalar_params(lmgr_block, LMGR_CONFIG_BLOCK, cfg_params, msg_out);
    if (rc)
        return rc;

    /* commit_behavior */
    rc = GetStringParam(lmgr_block, LMGR_CONFIG_BLOCK, "commit_behavior",
                        PFLG_NO_WILDCARDS, tmpstr, sizeof(tmpstr), &options,
                        &nb_options, msg_out);
    if ((rc != 0) && (rc != ENOENT))
        return rc;
    else if (rc != ENOENT) {
        if (!strcasecmp(tmpstr, "autocommit"))
            conf->commit_behavior = 0;
        else if (!strcasecmp(tmpstr, "transaction"))
            conf->commit_behavior = 1;
        else if (!strcasecmp(tmpstr, "periodic")) {
            if ((nb_options != 1) || !options || !options[0]) {
                strcpy(msg_out,
                       "A single argument is expected for periodic commit behavior. Eg: commit_behavior = periodic(1000)");
                return EINVAL;
            }

            conf->commit_behavior = atoi(options[0]);
            if (conf->commit_behavior == 0) {
                strcpy(msg_out,
                       "The argument for \"" LMGR_CONFIG_BLOCK
                       "::commit_behavior = periodic\" must be a positive integer. Eg: commit_behavior = periodic(1000)");
                return EINVAL;
            }
        } else {
            sprintf(msg_out,
                    "Invalid commit behavior '%s' (expected: autocommit, "
                    "transaction, periodic(<count>))", tmpstr);
            return EINVAL;
        }
    }

    /* manage deprecated parameters */
    rc = GetBoolParam(lmgr_block, LMGR_CONFIG_BLOCK, "user_acct", 0, &bval,
                      NULL, NULL, msg_out);
    if (rc == 0) {
        DisplayLog(LVL_CRIT, TAG,
                   "WARNING: parameter %s::%s' is deprecated. Specify 'accounting = yes/no' instead.",
                   LMGR_CONFIG_BLOCK, "user_acct");
        DisplayLog(LVL_MAJOR, TAG,
                   "Setting 'accounting = %s' for compatibility.",
                   bool2str(bval));
        conf->acct = bval;
    }

    rc = GetBoolParam(lmgr_block, LMGR_CONFIG_BLOCK, "group_acct", 0, &bval,
                      NULL, NULL, msg_out);
    if (rc == 0) {
        DisplayLog(LVL_CRIT, TAG,
                   "WARNING: parameter %s::%s' is deprecated. Specify 'accounting = yes/no' instead.",
                   LMGR_CONFIG_BLOCK, "group_acct");
        DisplayLog(LVL_MAJOR, TAG,
                   "Setting 'accounting = %s' for compatibility.",
                   bool2str(bval));
        conf->acct = bval;
    }

    CheckUnknownParameters(lmgr_block, LMGR_CONFIG_BLOCK, lmgr_allowed);

    /* Database parameters */
#ifdef _MYSQL
    /* get MySQL block */
    rc = get_cfg_block(config, LMGR_CONFIG_BLOCK "::" MYSQL_CONFIG_BLOCK,
                       &db_block, msg_out);
    if (rc)
        return rc;

    /* DB std params */
    rc = read_scalar_params(db_block, MYSQL_CONFIG_BLOCK, db_params, msg_out);
    if (rc)
        return rc;

    /* DB params with specific type */
    rc = GetStringParam(db_block, MYSQL_CONFIG_BLOCK, "password",
                        0, conf->db_config.password, 256, NULL, NULL, msg_out);
    if ((rc != 0) && (rc != ENOENT))
        return rc;
    else if (rc == ENOENT) {
        FILE *passfile;
        char errstr[1024];

        rc = GetStringParam(db_block, MYSQL_CONFIG_BLOCK,
                            "password_file",
                            PFLG_ABSOLUTE_PATH | PFLG_NO_WILDCARDS,
                            tmpstr, sizeof(tmpstr), NULL, NULL, msg_out);
        if ((rc != 0) && (rc != ENOENT))
            return rc;
        else if (rc == ENOENT) {
            strcpy(msg_out,
                   MYSQL_CONFIG_BLOCK "::password or "
                   MYSQL_CONFIG_BLOCK "::password_file must be provided");
            return ENOENT;
        }

        /* read password file and @TODO check its rights */
        passfile = fopen(tmpstr, "r");
        if (!passfile) {
            rc = errno;
            sprintf(msg_out, "Error opening password file %s : %s", tmpstr,
                    strerror(errno));
            return rc;
        }
        rc = fscanf(passfile, "%1023s", tmpstr);
        if (ferror(passfile) || rc < 1) {
            rc = errno;
            if (strerror_r(rc, errstr, sizeof(errstr))) {
                snprintf(errstr, sizeof(errstr), "%d", rc);
            }
            sprintf(msg_out, "Error reading password file %s : %s", tmpstr,
                    errstr);
            return rc;
        }
        fclose(passfile);
        rh_strncpy(conf->db_config.password, tmpstr, 256);
    }

    CheckUnknownParameters(db_block, MYSQL_CONFIG_BLOCK, db_allowed);

#elif defined(_SQLITE)
    /* get SQLite block */
    rc = get_cfg_block(config, LMGR_CONFIG_BLOCK "::" SQLITE_CONFIG_BLOCK,
                       &db_block, msg_out);
    if (rc)
        return rc;

    rc = read_scalar_params(db_block, SQLITE_CONFIG_BLOCK, db_params, msg_out);
    if (rc)
        return rc;

    CheckUnknownParameters(db_block, SQLITE_CONFIG_BLOCK, db_allowed);
#endif

    return 0;
}
Example #21
0
/**
 * build LOVEA buffer from stripe information
 * @return size of significant information in buffer.
 */
ssize_t BuildLovEA(const entry_id_t * p_id, const attr_set_t * p_attrs, void * buff, size_t buf_sz)
{
    int i;
    size_t len = 0;

    if (!ATTR_MASK_TEST(p_attrs, stripe_info)) /* no stripe info */
        return 0;

    /* check inconsistent values */
    if (!ATTR_MASK_TEST(p_attrs, stripe_items) ||
        (ATTR(p_attrs, stripe_items).count != ATTR(p_attrs, stripe_info).stripe_count))
    {
        DisplayLog(LVL_MAJOR, "BuildLovEA", "ERROR: inconsistent stripe info for "DFID, PFID(p_id));
        return -1;
    }

    /* is there a pool? */
    if (EMPTY_STRING(ATTR(p_attrs, stripe_info).pool_name))
    {
        /* no => build lov_user_md_v1 */
        struct lov_user_md_v1 * p_lum = (struct lov_user_md_v1 *) buff;
        len = sizeof(struct lov_user_md_v1) +
            ATTR(p_attrs, stripe_info).stripe_count * sizeof(struct lov_user_ost_data_v1);

        /* check buffer size */
        if (buf_sz < len)
            return -1;

        p_lum->lmm_magic = LOV_USER_MAGIC_V1;
        p_lum->lmm_pattern = LOV_PATTERN_RAID0; /* the only supported for now */
#ifdef _HAVE_FID
        p_lum->lmm_object_id = p_id->f_oid;
        p_lum->lmm_object_seq = p_id->f_seq;
#else /* lmm_object_gr for Lustre 1.x */
        p_lum->lmm_object_id = p_id->inode;
        p_lum->lmm_object_gr = 0;
#endif
        p_lum->lmm_stripe_size = ATTR(p_attrs, stripe_info).stripe_size;
        p_lum->lmm_stripe_count = ATTR(p_attrs, stripe_info).stripe_count;
        p_lum->lmm_stripe_offset = 0;

        /* set stripe items */
        for ( i = 0; i < ATTR(p_attrs, stripe_items).count; i++ )
        {
            p_lum->lmm_objects[i].l_ost_idx = ATTR(p_attrs, stripe_items).stripe[i].ost_idx;
            p_lum->lmm_objects[i].l_ost_gen = ATTR(p_attrs, stripe_items).stripe[i].ost_gen;
#ifdef HAVE_OBJ_ID
            p_lum->lmm_objects[i].l_object_id = ATTR(p_attrs, stripe_items).stripe[i].obj_id;
#ifdef HAVE_OBJ_SEQ
            p_lum->lmm_objects[i].l_object_seq = ATTR(p_attrs, stripe_items).stripe[i].obj_seq;
#else
            p_lum->lmm_objects[i].l_object_gr = ATTR(p_attrs, stripe_items).stripe[i].obj_seq;
#endif
#else /* new structure (union of fid and id/seq) */
            p_lum->lmm_objects[i].l_ost_oi.oi.oi_id = ATTR(p_attrs, stripe_items).obj_id;
            p_lum->lmm_objects[i].l_ost_oi.oi.oi_seq = ATTR(p_attrs, stripe_items).stripe[i].obj_seq;
#endif
        }
        return len;
    }
    else
    {
        /* yes => build lov_user_md_v3 */
        struct lov_user_md_v3 * p_lum = (struct lov_user_md_v3 *) buff;
        len = sizeof(struct lov_user_md_v3) +
            ATTR(p_attrs, stripe_info).stripe_count * sizeof(struct lov_user_ost_data_v1);

        /* check buffer size */
        if (buf_sz < len)
            return (size_t)-1;

        p_lum->lmm_magic = LOV_USER_MAGIC_V3;
        p_lum->lmm_pattern = LOV_PATTERN_RAID0; /* the only supported for now */
#ifdef _HAVE_FID
        p_lum->lmm_object_id = p_id->f_oid;
        p_lum->lmm_object_seq = p_id->f_seq;
#else /* lmm_object_gr for Lustre 1.x */
        p_lum->lmm_object_id = p_id->inode;
        p_lum->lmm_object_gr = 0;
#endif
        p_lum->lmm_stripe_size = ATTR(p_attrs, stripe_info).stripe_size;
        p_lum->lmm_stripe_count = ATTR(p_attrs, stripe_info).stripe_count;
        p_lum->lmm_stripe_offset = 0;
        /* pool name */
        rh_strncpy(p_lum->lmm_pool_name, ATTR(p_attrs, stripe_info).pool_name, LOV_MAXPOOLNAME);

        /* set stripe items */
        for ( i = 0; i < ATTR(p_attrs, stripe_items).count; i++ )
        {
            p_lum->lmm_objects[i].l_ost_idx = ATTR(p_attrs, stripe_items).stripe[i].ost_idx;
            p_lum->lmm_objects[i].l_ost_gen = ATTR(p_attrs, stripe_items).stripe[i].ost_gen;
#ifdef HAVE_OBJ_ID
            p_lum->lmm_objects[i].l_object_id = ATTR(p_attrs, stripe_items).stripe[i].obj_id;
#ifdef HAVE_OBJ_SEQ
            p_lum->lmm_objects[i].l_object_seq = ATTR(p_attrs, stripe_items).stripe[i].obj_seq;
#else
            p_lum->lmm_objects[i].l_object_gr = ATTR(p_attrs, stripe_items).stripe[i].obj_seq;
#endif
#else /* new structure (union of fid and id/seq) */
            p_lum->lmm_objects[i].l_ost_oi.oi.oi_id = ATTR(p_attrs, stripe_items).obj_id;
            p_lum->lmm_objects[i].l_ost_oi.oi.oi_seq = ATTR(p_attrs, stripe_items).stripe[i].obj_seq;
#endif
        }
        return len;
    }
}
Example #22
0
int lustre_mds_stat_by_fid( const entry_id_t * p_id, struct stat *inode )
{
    char filename[MAXNAMLEN];
    char           buffer[1024];
    struct lov_user_mds_data *lmd = ( struct lov_user_mds_data * ) buffer;
    int rc;

    /* ensure fid directory is opened */
    if ( fid_dir_fd == NULL )
    {
        P( dir_lock );
        if ( fid_dir_fd == NULL )
        {
            char path[RBH_PATH_MAX];
            char *curr = path;
            unsigned int mlen;

            /* filesystem root */
            strcpy( path, get_mount_point(&mlen) );
            curr += mlen;

            /* fid directory */
            strcpy( curr, "/" FIDDIR );

            /* open fir directory */
            fid_dir_fd = opendir( path );
        }
        V( dir_lock );
        if ( fid_dir_fd == NULL )
            return errno;
    }

    sprintf( filename, DFID, PFID(p_id) );
    memset( lmd, 0, sizeof( buffer ) );
    rh_strncpy(buffer, filename, strlen(filename) + 1);

    rc = ioctl( dirfd( fid_dir_fd ), IOC_MDC_GETFILEINFO, ( void * ) lmd );

    if ( rc )
    {
        if ( errno == ENOTTY )
        {
            return ENOTSUP;
        }
        else if ( ( errno == ENOENT ) || ( errno == ESTALE ) )
        {
            DisplayLog( LVL_MAJOR, TAG_MDSSTAT, "Warning: %s: %s does not exist",
                        __FUNCTION__, filename );
            return ENOENT;
        }
        else
        {
            DisplayLog( LVL_CRIT, TAG_MDSSTAT,
                        "Error: %s: IOC_MDC_GETFILEINFO failed for %s",
                        __FUNCTION__, filename );
            return errno;
        }
    }

    *inode = lmd->lmd_st;
    return 0;
}
Example #23
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 */
}
Example #24
0
/**
 * Force log file.
 * Won't be overridden by configuration.
 */
void force_log_file(const char *file)
{
    rh_strncpy(log_config.log_file, file, sizeof(log_config.log_file));
    log_config.force_log_file = true;
}
Example #25
0
/**
 * Main daemon routine
 */
int main( int argc, char **argv )
{
    int            c = 0;
    char          *bin = basename( argv[0] );
    int            rc;
    char           err_msg[4096];
    robinhood_config_t config;
    int chgd = 0;

    /* options */
    char           config_file[MAX_OPT_LEN] = "";
    char           badcfg[RBH_PATH_MAX];
    int            force_log_level = FALSE;
    int            log_level = 0;
    int            margin = 0;
    char           output_file[MAX_OPT_LEN] = "/tmp/lov_objid";

    lmgr_t         lmgr;
    FILE         * out;

    /* parse command line options */
    while ((c = getopt(argc, argv, OPT_STRING)) != -1)
    {
        switch (c)
        {
            case 'l':
                force_log_level = TRUE;
                log_level = str2debuglevel(optarg);
                if (log_level == -1)
                {
                    fprintf( stderr,
                             "Unsupported log level '%s'. CRIT, MAJOR, EVENT, VERB, DEBUG or FULL expected.\n",
                             optarg );
                    exit(1);
                }
                break;
            case 'f':
                rh_strncpy(config_file, optarg, MAX_OPT_LEN);
                break;
            case 'o':
                rh_strncpy(output_file, optarg, MAX_OPT_LEN);
                break;
            case 'm':
                margin = str2int(optarg);
                if (margin < 0)
                {
                    fprintf( stderr,
                             "Invalid parameter '%s' for '-m' option: positive integer expected\n",
                             optarg );
                    exit(1);
                }
                break;
            case ':':
            case '?':
            default:
                display_help(bin);
                exit( 1 );
                break;
        }
    }

    /* get default config file, if not specified */
    if (SearchConfig(config_file, 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", config_file );
    }

    /* only read ListMgr config */

    if ( ReadRobinhoodConfig( 0, config_file, err_msg, &config, FALSE ) )
    {
        fprintf( stderr, "Error reading configuration file '%s': %s\n", config_file, err_msg );
        exit( 1 );
    }
    process_config_file = config_file;

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

    if ( force_log_level )
        config.log_config.debug_level = log_level;
    else
        config.log_config.debug_level = LVL_MAJOR; /* no event message */

    /* set logging to stderr for this tool */
    strcpy( config.log_config.log_file, "stderr" );
    strcpy( config.log_config.report_file, "stderr" );
    strcpy( config.log_config.alert_file, "stderr" );

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

    /* Initialize list manager */
    rc = ListMgr_Init( &config.lmgr_config, TRUE );
    if ( rc )
    {
        DisplayLog( LVL_CRIT, TAG, "Error %d initializing list manager", rc );
        exit( rc );
    }
    else
        DisplayLog( LVL_DEBUG, TAG, "ListManager successfully initialized" );

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

    /* Create database access */
    rc = ListMgr_InitAccess( &lmgr );
    if ( rc )
    {
        DisplayLog( LVL_CRIT, TAG, "Error %d: cannot connect to database", rc );
        exit( rc );
    }

    out = fopen(output_file, "w");
    if (!out)
    {
        DisplayLog(LVL_CRIT, TAG, "Failed to open '%s' for writting: %s", output_file,
                   strerror(errno));
        return errno;
    }

    /* direct SQL request to retrieve the max object index from DB */
    result_handle_t res;
    /* FIXME max on the low weight 32bits of the 'objid' 64bits value */
    rc = db_exec_sql(&lmgr.conn, "SELECT ostidx, max(hex(cast(reverse(cast(details as binary(8))) as binary(4)))) "
                     "FROM "STRIPE_ITEMS_TABLE" GROUP BY ostidx ORDER BY ostidx", &res);
    if (rc)
        goto db_error;

    int index = -1;
    do
    {
        char *resstr[2];
        unsigned int ostidx;
        unsigned int objid;
        unsigned long long objid_long;
        resstr[0] = resstr[1] = NULL;

        rc = db_next_record( &lmgr.conn, &res, resstr, 2 );
        if (rc == DB_END_OF_LIST)
            break;
        else if (rc != DB_SUCCESS)
            goto db_error;

        index ++;

        if (resstr[0] == NULL || resstr[1] == NULL)
        {
            DisplayLog(LVL_MAJOR, TAG, "ERROR: got NULL record from DB at index %u", index);
            rc = EINVAL;
            goto out;
        }

        /* resstr[0] is ost_idx */
        if (sscanf(resstr[0], "%u", &ostidx) != 1)
        {
            DisplayLog(LVL_MAJOR, TAG, "ERROR: cannot parse OST index '%s' at index %u", resstr[0], index);
            rc = EINVAL;
            goto out;
        }
        else if (ostidx != index)
        {
            DisplayLog(LVL_MAJOR, TAG, "Warning: OST index %u not found in database, assuming current objid=1",
                       index);
            objid_long = 1 + margin;
            printf("ostidx=%u, max objid=%016LX\n", ostidx, objid_long);
            fwrite(&objid_long, sizeof(objid_long), 1, out);
            continue;
        }

        /* resstr[1] is objid (hexa) */
        if (sscanf(resstr[1], "%X", &objid) != 1)
        {
            DisplayLog(LVL_MAJOR, TAG, "ERROR: cannot parse objid '%s' at index %u", resstr[1], index);
            rc = EINVAL;
            goto out;
        }

        objid_long = objid + margin;
        printf("ostidx=%u, objid=%016LX\n", ostidx, objid_long);
        fwrite(&objid_long, sizeof(objid_long), 1, out);

    } while(rc == 0);

    fclose(out);
    ListMgr_CloseAccess( &lmgr );
    return 0;

db_error:
    DisplayLog( LVL_CRIT, TAG, "Database error %d\n", rc);
out:
    ListMgr_CloseAccess( &lmgr );
    return rc;
}
Example #26
0
/**
 * Main daemon routine
 */
int main( int argc, char **argv )
{
    int            c, option_index = 0;
    char          *bin = basename( argv[0] );

    char           config_file[MAX_OPT_LEN] = "";

    enum { ACTION_NONE, ACTION_LIST, ACTION_RESTORE } action = ACTION_NONE;
    int            force_log_level = FALSE;
    int            log_level = 0;

    int            rc;
    char           err_msg[4096];
    robinhood_config_t config;
    int chgd = 0;
    char    badcfg[RBH_PATH_MAX];

    /* parse command line options */
    while ( ( c = getopt_long( argc, argv, SHORT_OPT_STRING, option_tab,
                               &option_index ) ) != -1 )
    {
        switch ( c )
        {
        case 'L':
            if ( (action != ACTION_NONE) && (action != ACTION_LIST) )
                fprintf( stderr, "WARNING: only a single action (--list or --restore) is expected\n"
                                 "on command line. '--restore' will be ignored.\n" );
            action = ACTION_LIST;
            break;
        case 'R':
            if ( (action != ACTION_NONE) && (action != ACTION_RESTORE) )
                fprintf( stderr, "WARNING: only a single action (--list or --restore) is expected\n"
                                 "on command line. '--list' will be ignored.\n" );
            action = ACTION_RESTORE;
            break;
        case 'f':
            rh_strncpy(config_file, optarg, MAX_OPT_LEN);
            break;
        case 'l':
            force_log_level = TRUE;
            log_level = str2debuglevel( optarg );
            if ( 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:
            display_help( bin );
            exit( 1 );
            break;
        }
    }

    /* 1 expected argument: path */
    if ( optind != argc - 1 )
    {
        fprintf( stderr, "Error: missing mandatory argument on command line: <path|fid>\n" );
        exit( 1 );
    }
    rh_strncpy(path_filter, argv[optind], RBH_PATH_MAX);

    /* get default config file, if not specified */
    if (SearchConfig(config_file, 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", config_file );
    }

    /* only read ListMgr config */
    if ( ReadRobinhoodConfig( 0, config_file, err_msg, &config, FALSE ) )
    {
        fprintf( stderr, "Error reading configuration file '%s': %s\n", config_file, err_msg );
        exit( 1 );
    }
    process_config_file = config_file;

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

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

    if ( force_log_level )
        config.log_config.debug_level = log_level;

    /* XXX HOOK: Set logging to stderr */
    strcpy( config.log_config.log_file, "stderr" );
    strcpy( config.log_config.report_file, "stderr" );
    strcpy( config.log_config.alert_file, "stderr" );

    /* Initialize logging */
    rc = InitializeLogs( bin, &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);

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

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

    /* Create database access */
    rc = ListMgr_InitAccess( &lmgr );
    if ( rc )
    {
        DisplayLog( LVL_CRIT, LOGTAG, "Error %d: cannot connect to database", rc );
        exit( rc );
    }

#ifdef _HSM_LITE
    rc = Backend_Start( &config.backend_config, 0 );
    if ( rc )
    {
        DisplayLog( LVL_CRIT, LOGTAG, "Error initializing backend" );
        exit( 1 );
    }
#endif

    /* perform the action */
    switch( action )
    {
        case ACTION_LIST:
            rc= list_rm();
            break;
        case ACTION_RESTORE:
            rc = undo_rm();
            break;
        case ACTION_NONE:
            display_help( bin );
            rc = 1;
            break;
        default:
            fprintf(stderr, "Unexpected action (action code=%#x)\n", action );
            display_help( bin );
            rc = EINVAL;
            break;
    }

    ListMgr_CloseAccess( &lmgr );

    return rc;

}