static inline void display_rm_entry(entry_id_t * id, const char *last_known_path, #ifdef _HSM_LITE const char *bkpath, #endif time_t soft_rm_time, time_t expiration_time) { char date_rm[128]; char date_exp[128]; struct tm t; strftime( date_rm, 128, "%Y/%m/%d %T", localtime_r( &soft_rm_time, &t ) ); strftime( date_exp, 128, "%Y/%m/%d %T", localtime_r( &expiration_time, &t ) ); printf( "Fid: "DFID"\n", PFID(id) ); if ( !EMPTY_STRING(last_known_path) ) printf( "Last known path: %s\n", last_known_path ); #ifdef _HSM_LITE if ( !EMPTY_STRING(bkpath) ) printf( "Backend path: %s\n", bkpath ); #endif printf( "Removal time: %s\n", date_rm ); if ( expiration_time <= time(NULL) ) printf( "Delayed until: %s (expired)\n", date_exp ); else printf( "Delayed until: %s\n", date_exp ); }
static inline void undo_rm_helper( entry_id_t * id, const char *last_known_path, #ifdef _HSM_LITE const char *bkpath #endif ) { entry_id_t new_id; recov_status_t st; attr_set_t attrs, new_attrs; int rc; /* XXX src path must be in the same filesystem as backend * because it we be renamed */ if ( EMPTY_STRING( last_known_path ) ) { fprintf(stderr, "Last filesystem path is not known for fid "DFID", backend_path=%s.\n", PFID(id), bkpath); fprintf(stderr, " ----> skipped\n"); return; } printf("Restoring '%s'...\n", last_known_path ); ATTR_MASK_INIT(&attrs); ATTR_MASK_SET(&attrs, fullpath); strcpy( ATTR(&attrs, fullpath), last_known_path ); if ( !EMPTY_STRING( bkpath ) ) { ATTR_MASK_SET(&attrs, backendpath); strcpy( ATTR(&attrs, backendpath), bkpath ); } /* copy file to Lustre */ ATTR_MASK_INIT(&new_attrs); st = rbhext_recover( id, &attrs, &new_id, &new_attrs, NULL ); if ((st == RS_FILE_OK) || (st == RS_FILE_DELTA)|| (st == RS_FILE_EMPTY) || (st == RS_NON_FILE)) { printf("Success\n"); /* discard entry from remove list */ if ( ListMgr_SoftRemove_Discard(&lmgr, id) != 0 ) fprintf(stderr, "Error: could not remove previous id "DFID" from database\n", PFID(id) ); /* clean read-only attrs */ new_attrs.attr_mask &= ~readonly_attr_set; /* insert or update it in the db */ rc = ListMgr_Insert( &lmgr, &new_id, &new_attrs, TRUE ); if ( rc == 0 ) printf("Entry successfully updated in the dabatase\n"); else fprintf(stderr, "ERROR %d inserting entry in the database\n", rc ); } else { printf("ERROR\n"); } }
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 */
static void test_file_names(void) { log_init_check(); test_log_descr(log_config.log_file, &log); test_log_descr(log_config.report_file, &report); if (!EMPTY_STRING(log_config.alert_file)) test_log_descr(log_config.alert_file, &alert); #ifdef HAVE_CHANGELOGS if (!EMPTY_STRING(log_config.changelogs_file)) test_log_descr(log_config.changelogs_file, &chglogs); #endif }
int File_CreateSetStripe( const char * path, const stripe_info_t * old_stripe ) { int rc; /* try to restripe using previous pool name */ if ( !EMPTY_STRING( old_stripe->pool_name ) ) { rc = llapi_file_create_pool( path, old_stripe->stripe_size, -1, old_stripe->stripe_count, 0, (char *)old_stripe->pool_name ); if ( rc == 0 || rc == -EEXIST ) return rc; else { DisplayLog( LVL_MAJOR, TAG_CR_STRIPE, "Error %d creating '%s' in pool '%s': %s", rc, path, old_stripe->pool_name, strerror(-rc) ); DisplayLog( LVL_MAJOR, TAG_CR_STRIPE, "Trying to create it without pool information..." ); } } rc = llapi_file_create( path, old_stripe->stripe_size, -1, old_stripe->stripe_count, 0 ); if ( rc != 0 || rc == -EEXIST ) DisplayLog( LVL_MAJOR, TAG_CR_STRIPE, "Error %d creating '%s' with stripe. Trying to create it without specific stripe...", rc, path ); return rc; }
int CreateStriped( const char * path, const stripe_info_t * old_stripe, int overwrite ) { int rc; /* try to restripe using previous pool name */ if ( !EMPTY_STRING( old_stripe->pool_name ) ) rc = llapi_file_create_pool( path, old_stripe->stripe_size, -1, old_stripe->stripe_count, 0, (char *)old_stripe->pool_name ); else rc = llapi_file_create( path, old_stripe->stripe_size, -1, old_stripe->stripe_count, 0 ); if ((rc == -EEXIST) && overwrite) { if (unlink(path)) { rc = -errno; DisplayLog( LVL_MAJOR, TAG_CR_STRIPE, "Can't remove previous entry %s: %s", path, strerror(-rc)); return rc; } return CreateStriped(path, old_stripe, false /*target not expected to exist*/); } else if ( rc != 0 && rc != -EEXIST ) { DisplayLog( LVL_MAJOR, TAG_CR_STRIPE, "Error %d creating '%s' with stripe.", rc, path ); } return rc; }
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; }
void RaiseAlert(const char *title, const char *format, ...) { va_list args; char mail[MAX_MAIL_LEN]; char title2[1024]; int written; time_t now = time(NULL); struct tm date; log_init_check(); /* send alert mail, if an address was specified in config file */ if (!EMPTY_STRING(log_config.alert_mail)) { localtime_r(&now, &date); written = snprintf(mail, MAX_MAIL_LEN, "===== %s =====\n" "Date: %.4d/%.2d/%.2d %.2d:%.2d:%.2d\n" "Program: %s (pid %lu)\n" "Host: %s\n" "Filesystem: %s\n", title, 1900 + date.tm_year, date.tm_mon + 1, date.tm_mday, date.tm_hour, date.tm_min, date.tm_sec, prog_name, (unsigned long)getpid(), machine_name, global_config.fs_path); va_start(args, format); vsnprintf(mail + written, MAX_MAIL_LEN - written, format, args); va_end(args); snprintf(title2, 1024, "%s (%s on %s)", title, global_config.fs_path, machine_name); SendMail(log_config.alert_mail, title2, mail); } if (!EMPTY_STRING(log_config.alert_file)) { display_line_log_(&alert, "ALERT", "%s", title); va_start(args, format); display_line_log(&alert, "ALERT", format, args); va_end(args); /* always flush alerts, because we don't want to lose events */ flush_log_descr(&alert); } } /* DisplayAlert */
void RaiseEntryAlert( const char *alert_name, /* alert name (if set) */ const char *alert_string, /* alert description */ const char *entry_path, /* entry path */ const char *entry_info) /* alert related attributes */ { char title[1024]; /* lockless check (not a big problem if some alerts are sent without * being batched). */ if ( alert_batching ) { if ( alert_name && !EMPTY_STRING(alert_name) ) strcpy(title, alert_name ); else { if ( snprintf(title, 1024, "unnamed alert %s", alert_string ) > 80 ) { /* truncate at 80 char: */ strcpy( title+77, "..." ); } } Alert_Add( title, entry_path, entry_info ); } else { if ( alert_name && !EMPTY_STRING(alert_name) ) snprintf(title, 1024, "Robinhood alert (%s on %s): %s", global_config.fs_path, machine_name, alert_name ); else snprintf(title, 1024, "Robinhood alert (%s on %s): entry matches alert rule", global_config.fs_path, machine_name ); if ( log_config.alert_show_attrs ) RaiseAlert( title, "Entry: %s\nAlert condition: %s\n" "Entry info:\n%s", entry_path, alert_string, entry_info ); else RaiseAlert( title, "Entry: %s\nAlert condition: %s\n", entry_path, alert_string ); } }
/* Display XML data from the result if any */ static void search_set_xml_metadata(const record_t *rc) { char *indented; indented = (rc && rc->xml) ? xml_indent(rc->xml) : NULL; set_text_buffer(gui_main_window_lookup("text_result_info_xml"), EMPTY_STRING(indented)); HFREE_NULL(indented); }
void search_gui_append_detail(const gchar *name, const gchar *value) { const gchar *titles[2]; g_return_if_fail(clist_search_details); titles[0] = name; titles[1] = EMPTY_STRING(value); gtk_clist_append(clist_search_details, (gchar **) titles); }
void DisplayChangelogs(const char *format, ...) { va_list args; /* Bail out if no file defined */ if (EMPTY_STRING(log_config.changelogs_file)) return; va_start(args, format); display_line_log(&chglogs, NULL, format, args); va_end(args); }
static int is_fid_filter(entry_id_t * id) { lustre_fid fid; if ( !EMPTY_STRING( path_filter ) ) { if (sscanf(path_filter, SFID, RFID(&fid)) != 3) return FALSE; else { if (id) *id = fid; return TRUE; } } return FALSE; }
/* * Append global filters on path * \param do_display [in] display filters? * \param initialized [in/out] indicate if the filter is initialized. */ static int mk_path_filter( lmgr_filter_t * filter, int do_display, int * initialized ) { filter_value_t fv; char path_regexp[RBH_PATH_MAX] = ""; size_t len; /* is a filter on path specified? */ if ( !EMPTY_STRING( path_filter ) ) { if ( (initialized != NULL) && !(*initialized) ) { lmgr_simple_filter_init( filter ); *initialized = TRUE; } if ( do_display ) printf("filter path: %s\n", path_filter ); len = strlen(path_filter); if ( path_filter[len-1] != '/' ) { /* ( fullpath LIKE 'path' OR fullpath LIKE 'path/%' ) */ fv.val_str = path_filter; lmgr_simple_filter_add( filter, ATTR_INDEX_fullpath, LIKE, fv, FILTER_FLAG_BEGIN ); snprintf( path_regexp, RBH_PATH_MAX, "%s/*", path_filter ); fv.val_str = path_regexp; lmgr_simple_filter_add( filter, ATTR_INDEX_fullpath, LIKE, fv, FILTER_FLAG_OR | FILTER_FLAG_END ); } else /* ends with slash */ { snprintf( path_regexp, RBH_PATH_MAX, "%s*", path_filter ); /* directory or directory/% */ fv.val_str = path_regexp; lmgr_simple_filter_add( filter, ATTR_INDEX_fullpath, LIKE, fv, FILTER_FLAG_BEGIN ); /* remove last slash */ path_filter[len-1] = '\0'; fv.val_str = path_filter; lmgr_simple_filter_add( filter, ATTR_INDEX_fullpath, LIKE, fv, FILTER_FLAG_OR | FILTER_FLAG_END ); } } return 0; }
int InitializeLogs( char *program_name, const log_config_t * config ) { struct utsname uts; char *tmp; int rc; /* store module configuration */ log_config = *config; /* get node name */ if ( uname( &uts ) == -1 ) strcpy( machine_name, "???" ); else 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 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; } last_time_test = time( NULL ); log_initialized = TRUE; return 0; } /* InitializeLogs */
static void test_file_names( ) { log_init_check( ); /* if the lock is taken, return immediately * (another thread is doing the check) */ if ( pthread_mutex_trylock( &mutex_reopen ) != 0 ) return; test_log_descr( log_config.log_file, &log ); test_log_descr( log_config.report_file, &report ); if ( !EMPTY_STRING( log_config.alert_file ) ) test_log_descr( log_config.alert_file, &alert ); pthread_mutex_unlock( &mutex_reopen ); }
/* * Append global filters on path * \param do_display [in] display filters? * \param initialized [in/out] indicate if the filter is initialized. */ static int mk_path_filter( lmgr_filter_t * filter, int do_display, int * initialized ) { filter_value_t fv; char path_regexp[RBH_PATH_MAX] = ""; size_t len; /* is a filter on path specified? */ if ( !EMPTY_STRING( path_filter ) ) { if ( (initialized != NULL) && !(*initialized) ) { lmgr_simple_filter_init( filter ); *initialized = TRUE; } if ( do_display ) printf("filter path: %s\n", path_filter ); len = strlen(path_filter); /* remove last slash */ if (path_filter[len-1] == '/') path_filter[len-1] = '\0'; /* as this is a RLIKE matching, shell regexp must be replaced by perl: * [abc] => OK * '*' => '.*' * '?' => '.' */ str_replace(path_filter, "*", ".*"); str_replace(path_filter, "?", "."); /* match 'path$' OR 'path/.*' */ snprintf(path_regexp, RBH_PATH_MAX, "%s($|/.*)", path_filter); fv.value.val_str = path_regexp; lmgr_simple_filter_add(filter, ATTR_INDEX_fullpath, RLIKE, fv, 0); } return 0; }
idmap_stat idmap_init_namemaps(idmap_nm_handle_t **adh, char *user, char *passwd, char *auth, char *windomain, int direction) { idmap_stat rc; idmap_nm_handle_t *p; p = (idmap_nm_handle_t *)calloc(1, sizeof (idmap_nm_handle_t)); if (p == NULL) return (IDMAP_ERR_MEMORY); rc = idmap_get_prop_str(PROP_DEFAULT_DOMAIN, &p->default_domain); if (rc != IDMAP_SUCCESS) { namemap_log( gettext("Error obtaining default domain from idmapd (%s)"), idmap_stat2string(rc)); goto cleanup; } rc = idmap_get_prop_str(PROP_AD_UNIXUSER_ATTR, &p->ad_unixuser_attr); if (rc != IDMAP_SUCCESS) { namemap_log( gettext("Error obtaining AD unixuser attribute (%s)"), idmap_stat2string(rc)); goto cleanup; } rc = idmap_get_prop_str(PROP_AD_UNIXGROUP_ATTR, &p->ad_unixgroup_attr); if (rc != IDMAP_SUCCESS) { namemap_log( gettext("Error obtaining AD unixgroup attribute (%s)"), idmap_stat2string(rc)); goto cleanup; } rc = idmap_get_prop_str(PROP_NLDAP_WINNAME_ATTR, &p->nldap_winname_attr); if (rc != IDMAP_SUCCESS) { namemap_log( gettext("Error obtaining AD unixgroup attribute (%s)"), idmap_stat2string(rc)); goto cleanup; } if (windomain != NULL) { p->windomain = strdup(windomain); if (p->windomain == NULL) { rc = IDMAP_ERR_MEMORY; goto cleanup; } } else if (!EMPTY_STRING(p->default_domain)) { p->windomain = strdup(p->default_domain); if (p->windomain == NULL) { rc = IDMAP_ERR_MEMORY; goto cleanup; } } else if (direction == IDMAP_DIRECTION_W2U) { namemap_log( gettext("Windows domain not given and idmapd daemon" " didn't provide a default one")); rc = IDMAP_ERR_ARG; goto cleanup; } p->direction = direction; if ((p->ad_unixuser_attr != NULL || p->ad_unixgroup_attr != NULL) && direction != IDMAP_DIRECTION_U2W) { rc = idmap_init_ad(p); if (rc != IDMAP_SUCCESS) { goto cleanup; } } if (p->nldap_winname_attr != NULL && direction != IDMAP_DIRECTION_W2U) { rc = idmap_init_nldap(p); if (rc != IDMAP_SUCCESS) { goto cleanup; } rc = strings2cred(&p->nsc, user, passwd, auth); if (rc != IDMAP_SUCCESS) { goto cleanup; } } cleanup: if (rc == IDMAP_SUCCESS) { *adh = p; return (IDMAP_SUCCESS); } /* There was an error: */ idmap_fini_namemaps(*adh); return (rc); }
/** * Extract information from SOAP fault tree. * * @param fault the XML <Fault> tree * @param code where UPnP error code is written, if non-NULL * @param error where address of UPnP error string is written, if non-NULL * * @attention * The error string is pointing in the XML tree and will become invalid as * soon as the tree is freed so it needs to be duplicated if it must persist. * * @return TRUE if OK, FALSE on error. */ static gboolean upnp_ctrl_extract_fault(xnode_t *fault, int *code, const char **error) { xnode_t *fcode, *fstring, *detail, *uerror; const char *parse_error = NULL; g_assert(fault != NULL); /* * The SOAP specification for the <faultcode> element are very bad. * Indeed, the content is a string bearing the *prefix* of the SOAP * namespace, which is completely arbitrary and not accessible at this * level since all nodes are normalized with their namespace, the prefix * string being irrelevant once parsing is done. And namespace have no * meaning in element *content*. * * Sure, we know we force the "s" prefix for SOAP, and most UPnP stacks * are going to use that prefix as well, but matching the <faultcode> * content to look for "s:Client" or "s:MustUnderstand" is just plain * wrong, and a blatant encapsulation violation. * * So instead we look backwards in the string to find the first ':' and * consider the tail part of the string, totally ignoring the prefix. * That's a lousy parsing, but in practice it's going to work and should * be safe since there's little choice anyway according to the SOAP * specifications (meaning they could have just as well ignored the * prefix in this string and just mandate "Client" or "MustUnderstand"). * * Also note that <faultcode>, <faultstring> and <detail> elements are * architected without any SOAP namespace. That's surprising. */ fcode = xnode_tree_find_depth(fault, 1, node_named_as, deconstify_gchar(SOAP_FAULT_CODE)); if (NULL == fcode) { parse_error = "cannot find <faultcode>"; goto error; } else { const char *value; const char *name; value = xnode_first_text(fcode); if (NULL == value) { parse_error = "<faultcode> does not contain text"; goto error; } /* * We're only handling "Client" errors. */ name = strrchr(value, ':'); if (NULL == name) { parse_error = "no ':' in fault code name"; goto error; } name++; if (0 != strcmp(name, SOAP_CLIENT_FAULT)) { parse_error = "not a Client fault"; goto error; } } /* * Here is a sample fault tree from the UPnP 1.0 architecture: * * <s:Fault> * <faultcode>s:Client</faultcode> * <faultstring>UPnPError</faultstring> * <detail> * <UPnpError xmlns="urn:schemas-upnp-org:control-1-0"> * <errorCode>error code</errorCode> * <errorDescription>error string</errorDescription> * </UPnPError> * </detail> * <s:Fault> * * Note that the UPnP tags are in the "urn:schemas-upnp-org:control-1-0" * namespace. */ fstring = xnode_tree_find_depth(fault, 1, node_named_as, deconstify_gchar(SOAP_FAULT_STRING)); if (NULL == fstring) { parse_error = "no <faultstring> found"; goto error; } else { const char *value; value = xnode_first_text(fstring); if (NULL == value) { parse_error = "<faultstring> does not contain text"; goto error; } if (0 != strcmp(value, SOAP_UPNP_ERROR)) { parse_error = "<faultstring> is not an UPnP error"; goto error; } } detail = xnode_tree_find_depth(fault, 1, node_named_as, deconstify_gchar(SOAP_FAULT_DETAIL)); if (NULL == detail) { parse_error = "no <detail> found"; goto error; } /* * First child must be a <UPnpError> tag. */ uerror = xnode_first_child(detail); if (xnode_is_element_named(uerror, UPNP_NS_ERROR, SOAP_UPNP_ERROR)) { xnode_t *xn; if (code != NULL) { const char *value; int err; xn = xnode_tree_find_depth(uerror, 1, node_named_as, deconstify_gchar(UPNP_ERROR_CODE)); if (NULL == xn) { parse_error = "no <errorCode> found"; goto error; } value = xnode_first_text(xn); if (NULL == value) { parse_error = "<errorCode> doest not contain text"; goto error; } *code = parse_uint32(value, NULL, 10, &err); if (err) { parse_error = "cannot parse <errorCode> value"; goto error; } } if (error != NULL) { xn = xnode_tree_find_depth(uerror, 1, node_named_as, deconstify_gchar(UPNP_ERROR_DESC)); *error = (NULL == xn) ? NULL : xnode_first_text(xn); } } else { parse_error = "no <UPnPError> found"; goto error; } return TRUE; error: if (GNET_PROPERTY(upnp_debug)) g_warning("UPNP fault parsing error: %s", EMPTY_STRING(parse_error)); return FALSE; }
/** * Initiates a new TLS session. * * @return 0 on success, -1 on error. */ int tls_init(struct gnutella_socket *s) { /** * ANON-DH is enabled because we don't use PKI. * DEFLATE is disabled because it seems to cause crashes. * ARCFOUR-40 is disabled because it is deprecated. */ static const char prio_want[] = "NORMAL:+ANON-DH:-ARCFOUR-40:-COMP-DEFLATE"; /* "-COMP-DEFLATE" is causing an error on MinGW with GnuTLS 2.10.2 */ static const char prio_must[] = "NORMAL:+ANON-DH:-ARCFOUR-40"; const bool server = SOCK_CONN_INCOMING == s->direction; struct tls_context *ctx; const char *fn; int e; #define TRY(function) (fn = (#function)), e = function socket_check(s); WALLOC0(ctx); ctx->s = s; s->tls.ctx = ctx; if ( TRY(gnutls_init)(&ctx->session, server ? GNUTLS_SERVER : GNUTLS_CLIENT) ) { ctx->session = NULL; goto failure; } if (TRY(gnutls_priority_set_direct)(ctx->session, prio_want, NULL)) { const char *error; if (TRY(gnutls_priority_set_direct)(ctx->session, prio_must, &error)) { g_warning("%s() failed at \"%s\"", fn, error); goto failure; } } if (TRY(gnutls_credentials_set)(ctx->session, GNUTLS_CRD_CERTIFICATE, cert_cred)) goto failure; gnutls_dh_set_prime_bits(ctx->session, TLS_DH_BITS); #ifdef USE_TLS_CUSTOM_IO gnutls_transport_set_ptr(ctx->session, s); gnutls_transport_set_push_function(ctx->session, tls_push); gnutls_transport_set_pull_function(ctx->session, tls_pull); #if !HAS_TLS(2, 12) /* * This routine has been removed starting TLS 3.0. It was used to disable * the lowat feature, and apparently this is now always the case in recent * TLS versions. --RAM, 2011-09-28 * * It's also flagged as deprecated in 2.12.x, so don't use it there. * --RAM, 2011-12-15 */ gnutls_transport_set_lowat(ctx->session, 0); #endif #else /* !USE_TLS_CUSTOM_IO */ g_assert(is_valid_fd(s->file_desc)); gnutls_transport_set_ptr(ctx->session, int_to_pointer(s->file_desc)); #endif /* USE_TLS_CUSTOM_IO */ if (server) { if (TRY(gnutls_anon_allocate_server_credentials)(&ctx->server_cred)) goto failure; gnutls_anon_set_server_dh_params(ctx->server_cred, get_dh_params()); if (TRY(gnutls_credentials_set)(ctx->session, GNUTLS_CRD_ANON, ctx->server_cred)) goto failure; } else { if (TRY(gnutls_anon_allocate_client_credentials)(&ctx->client_cred)) goto failure; if (TRY(gnutls_credentials_set)(ctx->session, GNUTLS_CRD_ANON, ctx->client_cred)) goto failure; } return 0; failure: g_warning("%s() failed: %s", EMPTY_STRING(fn), gnutls_strerror(e)); tls_free(s); return -1; #undef TRY }
/** * 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); }
// ----------------------------------------------------------------------------- // CLibxml2Tester::SerializeGZIPL // test GZIP Serialize // (other items were commented in a header). // ----------------------------------------------------------------------------- // TInt CLibxml2Tester::SerializeGZIPL(CStifItemParser& aItem) { TInt error(KErrGeneral); //get test controls, input&output paths TPtrC pControl; aItem.GetNextString( pControl ); TPtrC pBinary; aItem.GetNextString( pBinary ); TPtrC pXml; aItem.GetNextString( pXml ); TPtrC pSerialized; aItem.GetNextString( pSerialized ); TPtrC pGzipSerialized; aItem.GetNextString( pGzipSerialized ); TPtrC pOptions; aItem.GetNextString( pOptions ); // saves xml file with binary data added ( default serialize ) RXmlEngDocument iDocument; CleanupClosePushL( iDocument ); if( pControl.FindF( SINGLE ) != KErrNotFound ) { error = SaveXmlWithBinaryDataL( iDocument, pOptions, pBinary, pXml, EMPTY_STRING() ); } else if ( pControl.FindF( MULTI ) != KErrNotFound ) { error = SaveXmlWithBinaryDataL( iDocument, pOptions, pBinary, pXml, EMPTY_STRING(), TRUE ); } else { User::Leave(KErrArgument); } if ( pControl.FindF( ONE_PARA ) != KErrNotFound ) { User::LeaveIfError( TestSerialize1paraToFileL( iDocument, pGzipSerialized, pOptions, ESerializerGZip ) ); } if ( pControl.FindF( THREE_PARA ) != KErrNotFound ) { User::LeaveIfError ( TestSerialize3paraToFileL( iDocument, pGzipSerialized, pOptions, ESerializerGZip ) ); } if ( pControl.FindF( TO_RFS ) != KErrNotFound ) { User::LeaveIfError( TestSerializeRFsL( iDocument, pGzipSerialized, pOptions, ESerializerGZip ) ); } if ( pControl.FindF( BUFFER ) != KErrNotFound ) { User::LeaveIfError( TestSerializeToBufferL( iDocument, pGzipSerialized, pOptions, ESerializerGZip ) ); } CleanupStack::PopAndDestroy( 1 ); return error; }
static enum shell_reply shell_exec_download_show(struct gnutella_shell *sh, int argc, const char *argv[]) { fileinfo_t *fi; struct guid guid; const char *id, *property; gnet_fi_status_t status; gnet_fi_info_t *info; int i; shell_check(sh); g_assert(argv); g_assert(argc > 0); if (argc < 3) { shell_set_msg(sh, "parameter missing"); goto error; } id = argv[2]; if (!hex_to_guid(id, &guid)) { shell_set_msg(sh, "Unparsable ID"); goto error; } fi = file_info_by_guid(&guid); if (NULL == fi) { shell_set_msg(sh, "Invalid ID"); goto error; } info = guc_fi_get_info(fi->fi_handle); guc_fi_get_status(fi->fi_handle, &status); for (i = 3; i < argc; i++) { property = argv[i]; if (0 == strcmp(property, "id")) { show_property(sh, property, guid_to_string(info->guid)); } else if (0 == strcmp(property, "filename")) { show_property(sh, property, info->filename); } else if (0 == strcmp(property, "pathname")) { show_property(sh, property, fi->pathname); } else if (0 == strcmp(property, "size")) { show_property(sh, property, filesize_to_string(info->size)); } else if (0 == strcmp(property, "sha1")) { show_property(sh, property, info->sha1 ? sha1_to_urn_string(info->sha1) : ""); } else if (0 == strcmp(property, "tth")) { show_property(sh, property, info->tth ? tth_to_urn_string(info->tth) : ""); } else if (0 == strcmp(property, "bitprint")) { show_property(sh, property, (info->sha1 && info->tth) ? bitprint_to_urn_string(info->sha1, info->tth) : ""); } else if (0 == strcmp(property, "created")) { show_property(sh, property, info->created ? timestamp_to_string(info->created) : ""); } else if (0 == strcmp(property, "modified")) { show_property(sh, property, status.modified ? timestamp_to_string(status.modified) : ""); } else if (0 == strcmp(property, "downloaded")) { show_property(sh, property, filesize_to_string(status.done)); } else if (0 == strcmp(property, "uploaded")) { show_property(sh, property, uint64_to_string(status.uploaded)); } else if (0 == strcmp(property, "paused")) { show_property(sh, property, boolean_to_string(status.paused)); } else if (0 == strcmp(property, "seeding")) { show_property(sh, property, boolean_to_string(status.seeding)); } else if (0 == strcmp(property, "verifying")) { show_property(sh, property, boolean_to_string(status.verifying)); } else if (0 == strcmp(property, "finished")) { show_property(sh, property, boolean_to_string(status.finished)); } else if (0 == strcmp(property, "complete")) { show_property(sh, property, boolean_to_string(status.complete)); } else if (0 == strcmp(property, "magnet")) { char *magnet = file_info_build_magnet(fi->fi_handle); show_property(sh, property, EMPTY_STRING(magnet)); HFREE_NULL(magnet); } } guc_fi_free_info(info); return REPLY_READY; error: return REPLY_ERROR; }
/** * Misc. tools for config parsing */ int GetStringParam(config_item_t block, const char *block_name, const char *var_name, param_flags_t flags, char *target, unsigned int target_size, char ***extra_args_tab, unsigned int *nb_extra_args, char *err_msg) { config_item_t curr_item; int rc; int extra = 0; char *name; char *value; gsize sz; err_msg[0] = '\0'; if ( nb_extra_args ) *nb_extra_args = 0; if ( extra_args_tab ) *extra_args_tab = NULL; rc = get_cfg_param(block, block_name, var_name, flags, &name, &value, &extra, &curr_item, err_msg); if (rc) return rc; sz = g_strlcpy(target, value, target_size); if (sz >= target_size) { sprintf(err_msg, "Option too long for parameter '%s::%s', line %d", block_name, var_name, rh_config_GetItemLine(curr_item)); return EINVAL; } if ( extra ) { if ( !extra_args_tab || !nb_extra_args ) { sprintf( err_msg, "Unexpected options for parameter '%s::%s', line %d", block_name, var_name, rh_config_GetItemLine( curr_item ) ); return EINVAL; } else { *nb_extra_args = rh_config_GetExtraArgs( curr_item, extra_args_tab ); } } /* checks */ /* empty string? */ if ((flags & PFLG_NOT_EMPTY) && EMPTY_STRING(target)) { sprintf(err_msg, "Unexpected empty parameter '%s::%s', line %d", block_name, var_name, rh_config_GetItemLine(curr_item)); return EINVAL; } /* are stdio names allowed ? */ if ((flags & PFLG_STDIO_ALLOWED) && is_stdname(target)) return 0; if ((flags & PFLG_ABSOLUTE_PATH) && !IS_ABSOLUTE_PATH(target)) { sprintf( err_msg, "Absolute path expected for parameter '%s::%s', line %d", block_name, var_name, rh_config_GetItemLine( curr_item ) ); return EINVAL; } if ((flags & PFLG_NO_WILDCARDS) && WILDCARDS_IN(target)) { sprintf( err_msg, "Wildcards are not allowed in '%s::%s', line %d", block_name, var_name, rh_config_GetItemLine( curr_item ) ); return EINVAL; } if (flags & PFLG_MAIL) { char *arob = strchr( target, '@' ); /* check there is an arobase, and this arobase has text before and after */ if ( ( arob == NULL ) || ( arob == target ) || ( *( arob + 1 ) == '\0' ) ) { sprintf( err_msg, "Invalid mail address in '%s::%s', line %d", block_name, var_name, rh_config_GetItemLine( curr_item ) ); return EINVAL; } } if ((flags & PFLG_REMOVE_FINAL_SLASH) && FINAL_SLASH(target)) REMOVE_FINAL_SLASH(target); return 0; }
/** * Process the SOAP reply from the server. */ static void soap_process_reply(soap_rpc_t *sr) { const char *buf; vxml_parser_t *vp; vxml_error_t e; xnode_t *root = NULL; xnode_t *xn = NULL; const char *charset; soap_rpc_check(sr); if (sr->reply_len != 0 && (GNET_PROPERTY(soap_trace) & SOCK_TRACE_IN)) { g_debug("----Got SOAP HTTP reply data from %s:", sr->url); if (log_printable(LOG_STDERR)) { fwrite(sr->reply_data, sr->reply_len, 1, stderr); fputs("----End SOAP HTTP reply\n", stderr); } } if (GNET_PROPERTY(soap_debug) > 2) { g_debug("SOAP \"%s\" at \"%s\": processing reply (%lu byte%s) HTTP %d", sr->action, sr->url, (unsigned long) sr->reply_len, 1 == sr->reply_len ? "" : "s", sr->http_code); } /* * If we got a 2xx reply, we need to parse up to the <Body> element * and then pass up the remaining to the user for parsing specific * elemnts accordingly. * * Other reply codes indicate an error. On 4xx replies we may not * have any XML to parse. On 5xx replies, we should usually have * a <Fault> indication under the <Body>. * * The strategy used here is to parse the XML reply into a tree and then * analyse the tree, ignoring the HTTP status code which is redundant. */ buf = header_get(sr->header, "Content-Type"); if (NULL == buf) goto no_xml; /* * MIME type and subtypes are case-insensitive (see RFC 2616, section 3.7). */ if ( !http_field_starts_with(buf, SOAP_TEXT_REPLY, FALSE) && !http_field_starts_with(buf, SOAP_APPLICATION_REPLY, FALSE) ) { if (GNET_PROPERTY(soap_debug)) { g_debug("SOAP \"%s\" at \"%s\": got unexpected Content-Type: %s", sr->action, sr->url, buf); } goto no_xml; } /* * Extract charset if given. */ charset = http_parameter_get(buf, "charset"); /* * Parse the SOAP envelope. */ vp = vxml_parser_make(sr->action, VXML_O_STRIP_BLANKS); vxml_parser_add_data(vp, sr->reply_data, sr->reply_len); if (!vxml_parser_set_charset(vp, charset)) { g_warning("SOAP \"%s\" at \"%s\": ignoring unknown charset \"%s\"", sr->action, sr->url, charset); } e = vxml_parse_tree(vp, &root); vxml_parser_free(vp); if (e != VXML_E_OK) { if (GNET_PROPERTY(soap_debug)) { g_debug("SOAP \"%s\" at \"%s\": cannot parse XML reply: %s", sr->action, sr->url, vxml_strerror(e)); } goto bad_xml; } g_assert(root != NULL); /* * Make sure we got a SOAP reply. */ if (!xnode_is_element_named(root, SOAP_NAMESPACE, SOAP_X_ENVELOPE)) goto not_soap; /* * Look for the <SOAP:Body> element. */ for (xn = xnode_first_child(root); TRUE; xn = xnode_next_sibling(xn)) { if (NULL == xn || !xnode_within_namespace(xn, SOAP_NAMESPACE)) goto bad_soap; if (0 == strcmp(SOAP_X_BODY, xnode_element_name(xn))) break; } /* * Inspect the first child of the <SOAP:Body> element. * * If it's a <SOAP:Fault>, go process it and return an error. * If it's another SOAP tag, we have an unknown structure. * Otherwise it's the reply, for user code to handle. */ xn = xnode_first_child(xn); if (NULL == xn) goto bad_soap; if (xnode_is_element_named(xn, SOAP_NAMESPACE, SOAP_X_FAULT)) { xnode_detach(xn); soap_fault(sr, xn); } else if (xnode_within_namespace(xn, SOAP_NAMESPACE)) { goto bad_soap; } else { xnode_detach(xn); soap_reply(sr, xn); } xnode_tree_free(root); return; not_soap: if (GNET_PROPERTY(soap_debug)) { g_debug("SOAP \"%s\" at \"%s\": unexpected root XML " "element <%s:%s>", sr->action, sr->url, EMPTY_STRING(xnode_element_ns(root)), xnode_element_name(root)); } xnode_tree_free(root); /* FALL THROUGH */ no_xml: soap_error(sr, SOAP_E_PROTOCOL); return; bad_soap: if (GNET_PROPERTY(soap_debug)) { g_debug("SOAP \"%s\" at \"%s\": unexpected XML structure", sr->action, sr->url); } if (GNET_PROPERTY(soap_debug) > 1) { g_debug("SOAP current node is %s", xnode_to_string(xn)); } if (GNET_PROPERTY(soap_debug) > 2) xfmt_tree_dump(root, stderr); xnode_tree_free(root); /* FALL THROUGH */ bad_xml: soap_error(sr, SOAP_E_PROCESSING); return; }
/** * Search for Robinhood config file. * search a config file with the given name (+extension) * If cfg_in is empty: search any config in config paths * /!\ not thread safe */ int SearchConfig( const char * cfg_in, char * cfg_out, int * changed ) { static const char * default_cfg_paths[] = { "/etc/robinhood.d/"PURPOSE_EXT, "/etc/robinhood.d", "/etc/robinhood", ".", NULL }; const char * current_path; int i; DIR * dir; struct dirent * ent; struct stat stbuf; *changed = 1; /* most of the cases */ if (cfg_in == NULL || EMPTY_STRING(cfg_in)) { for ( i = 0, current_path = default_cfg_paths[0]; current_path != NULL; i++, current_path = default_cfg_paths[i] ) { /* look for files in current path */ dir = opendir( current_path ); if ( !dir ) continue; while ( (ent = readdir(dir)) != NULL ) { /* ignore .xxx files */ if (ent->d_name[0] == '.') continue; sprintf( cfg_out, "%s/%s", current_path, ent->d_name ); if ( (stat( cfg_out, &stbuf ) == 0) && S_ISREG(stbuf.st_mode) ) { /* file found: OK */ closedir(dir); return 0; } } closedir(dir); } } else if (access(cfg_in, F_OK) == 0) { /* the specified config file exists */ strcpy(cfg_out, cfg_in); *changed=0; return 0; } else if (strchr(cfg_in, '/')) { /* the argument is a path (not a single name * and this path was not found) */ *changed=0; return -ENOENT; } else /* look for a file in the given paths */ { char cfg_cp[RBH_PATH_MAX]; int has_ext = (strchr(cfg_in, '.') != NULL); strcpy(cfg_cp, cfg_in); for ( i = 0, current_path = default_cfg_paths[0]; current_path != NULL; i++, current_path = default_cfg_paths[i] ) { /* if the file already has an extension, try path/name */ if (has_ext) { sprintf(cfg_out, "%s/%s", current_path, cfg_cp); if (access(cfg_out, F_OK) == 0) return 0; } /* try path/name.cfg, path/name.conf */ sprintf(cfg_out, "%s/%s.conf", current_path, cfg_cp); if (access(cfg_out, F_OK) == 0) return 0; sprintf(cfg_out, "%s/%s.cfg", current_path, cfg_cp); if (access(cfg_out, F_OK) == 0) return 0; } } /* no file found, cleaning cfg_out */ cfg_out[0] = '\0'; return -ENOENT; }
/** * 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 */ }
/* Flush batched alerts. * Must be called under the protection of alert_mutex * release mutex ASAP if release_mutex_asap is true, * else: don't release it. */ static void FlushAlerts(bool release_mutex_asap) { alert_type_t *pcurr; unsigned int alert_types = 0; unsigned int mail_size = 0; char title[MAIL_TITLE_MAX]; GString *contents = NULL; time_t now; struct tm date; /* first list scan, to determine the number of alerts, etc... */ for (pcurr = alert_list; pcurr != NULL; pcurr = pcurr->next) { alert_types++; mail_size += pcurr->estim_size; } if (alert_count == 0) { if (release_mutex_asap) V(alert_mutex); return; } now = time(NULL); localtime_r(&now, &date); snprintf(title, MAIL_TITLE_MAX, "robinhood alert summary (%s on %s): %u alerts", global_config.fs_path, machine_name, alert_count); contents = g_string_new(""); g_string_printf(contents, "Date: %.4d/%.2d/%.2d %.2d:%.2d:%.2d\n" "Program: %s (pid %lu)\n" "Host: %s\n" "Filesystem: %s\n", 1900 + date.tm_year, date.tm_mon + 1, date.tm_mday, date.tm_hour, date.tm_min, date.tm_sec, prog_name, (unsigned long)getpid(), machine_name, global_config.fs_path); g_string_append(contents, "\n===== alert summary ====\n\n"); g_string_append_printf(contents, "%u alerts:\n", alert_count); for (pcurr = alert_list; pcurr != NULL; pcurr = pcurr->next) { g_string_append_printf(contents, "\t* %u %s\n", pcurr->count, pcurr->title); } for (pcurr = alert_list; pcurr != NULL;) { unsigned int i; g_string_append_printf(contents, "\n==== alert '%s' ====\n\n", pcurr->title); for (i = 0; i < pcurr->count; i++) { /* print and free */ if (pcurr->entries[i]) { g_string_append_printf(contents, "%s\n", pcurr->entries[i]); if (log_config.alert_show_attrs) g_string_append_printf(contents, "Entry info:\n%s\n", pcurr->info[i]); free(pcurr->entries[i]); free(pcurr->info[i]); } } /* free the list of entries */ free(pcurr->entries); free(pcurr->info); /* set the list to the next item */ alert_list = pcurr->next; /* free the item */ free(pcurr); /* next item */ pcurr = alert_list; } /* reset alert count */ alert_count = 0; /* all alerts has been released, we can put the lock */ if (release_mutex_asap) V(alert_mutex); /* send the mail and/or write the alert in alert file */ if (!EMPTY_STRING(log_config.alert_mail)) SendMail(log_config.alert_mail, title, contents->str); if (!EMPTY_STRING(log_config.alert_file)) { if (alert.log_type == RBH_LOG_SYSLOG) { /* we need to split the content after each '\n' */ char *curr = contents->str; char *next = NULL; display_line_log_(&alert, "ALERT", "=== ALERT REPORT ==="); do { next = strchr(curr, '\n'); if (next != NULL) { next[0] = '\0'; next++; } display_line_log_(&alert, "ALERT", curr); curr = next; } while (curr != NULL); display_line_log_(&alert, "ALERT", "=== END OF ALERT REPORT ==="); } else { display_line_log_(&alert, "ALERT", "=== ALERT REPORT ===\n%s", contents->str); display_line_log_(&alert, "ALERT", "=== END OF ALERT REPORT ==="); } /* always flush alerts, because we don't want to lose events */ flush_log_descr(&alert); } g_string_free(contents, TRUE); /* mutex already released, can go out now */ } /* Flush alerts */
static inline int rebind_helper(const char *old_bk_id, const char *new_bk_id, const char *new_path, const char *new_fid_str) { int rc; attr_set_t old_attrs = ATTR_SET_INIT; attr_set_t new_attrs = ATTR_SET_INIT; entry_id_t new_fid; entry_id_t old_fid; bool old_fid_set = false; char *tmp; /* full path required */ tmp = realpath(new_path, NULL); if (tmp == NULL) { rc = -errno; DisplayLog(LVL_CRIT, LOGTAG, "Error in realpath(%s): %s", new_path, strerror(-rc)); return rc; } if (strlen(tmp) >= RBH_PATH_MAX) { DisplayLog(LVL_CRIT, LOGTAG, "Path length is too long!"); return -ENAMETOOLONG; } /* safe because of previous check */ strcpy(ATTR(&new_attrs, fullpath), tmp); ATTR_MASK_SET(&new_attrs, fullpath); strcpy(ATTR(&old_attrs, fullpath), tmp); ATTR_MASK_SET(&old_attrs, fullpath); /* now we can free tmp path */ free(tmp); if ((new_fid_str != NULL) && !EMPTY_STRING(new_fid_str)) rc = read_fid(new_fid_str, &new_fid); else /* get fid for the given file */ rc = Path2Id(new_path, &new_fid); if (rc) return rc; printf("Rebinding '%s' (" DFID ") from '%s' to '%s'...\n", new_path, PFID(&new_fid), old_bk_id, new_bk_id); /* parse old/new bk ids and set attr accordingly */ if (parse_bk_id(&old_attrs, old_bk_id, &old_fid, &old_fid_set)) return -EINVAL; if (parse_bk_id(&new_attrs, new_bk_id, &new_fid, NULL)) return -EINVAL; /* rebind is like undelete with 'already recovered = true' */ rc = smi->sm->undelete_func(smi, old_fid_set ? &old_fid : NULL, &old_attrs, &new_fid, &new_attrs, true); fprintf(stderr, "Rebind status for '%s': %s\n", ATTR(&new_attrs, fullpath), recov_status2str(rc)); if (rc == RS_NOBACKUP || rc == RS_ERROR) return -1; return 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; } }