/** * Check that FS path is the same as the last time. */ int CheckLastFS( ) { int rc; lmgr_t lmgr; char value[1024]; rc = ListMgr_InitAccess( &lmgr ); if ( rc ) { DisplayLog( LVL_CRIT, "CheckFS", "Error %d connecting to database", rc ); return rc; } rc = ListMgr_GetVar( &lmgr, FS_PATH_VAR, value ); if ( rc == DB_SUCCESS ) { if ( strcmp( value, global_config.fs_path ) ) { DisplayLog( LVL_CRIT, "CheckFS", "Filesystem %s does not correspond to database content (%s)", global_config.fs_path, value ); DisplayLog( LVL_CRIT, "CheckFS", "Drop the database and restart the daemon." ); rc = -1; } else { DisplayLog( LVL_DEBUG, "CheckFS", "%s matches database content.", global_config.fs_path ); rc = 0; } } else if ( rc == DB_NOT_EXISTS ) { DisplayLog( LVL_FULL, "CheckFS", FS_PATH_VAR "='%s'.", global_config.fs_path ); rc = ListMgr_SetVar( &lmgr, FS_PATH_VAR, global_config.fs_path ); if ( rc ) DisplayLog( LVL_CRIT, "CheckFS", "Error %d setting variable 'FS_path'", rc ); } else { DisplayLog( LVL_CRIT, "CheckFS", "Error %d retrieving variable 'FS_path'", rc ); } ListMgr_CloseAccess( &lmgr ); return rc; }
/** * 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; }
/** * 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; }
/** * 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; }
/** * 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': 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 ); } strncpy( path_filter, argv[optind], RBH_PATH_MAX ); /* get default config file, if not specified */ if ( SearchConfig( config_file, config_file, &chgd, badcfg ) != 0 ) { fprintf(stderr, "No config file 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; }