📄 holding.c
字号:
}GSList *holding_get_files( char *hdir, int fullpaths){ holding_get_datap_t data; data.result = NULL; data.fullpaths = fullpaths; if (hdir) { holding_walk_dir(hdir, (gpointer)&data, STOP_AT_FILE, holding_get_walk_fn, NULL); } else { holding_walk((gpointer)&data, STOP_AT_FILE, NULL, NULL, holding_get_walk_fn, NULL); } return data.result;}GSList *holding_get_file_chunks(char *hfile){ holding_get_datap_t data; data.result = NULL; holding_walk_file(hfile, (gpointer)&data, holding_get_walk_fn); return data.result;}GSList *holding_get_files_for_flush( GSList *dateargs){ GSList *file_list, *file_elt; GSList *date; int date_matches; disk_t *dp; dumpfile_t file; GSList *result_list = NULL; /* loop over *all* files, checking each one's datestamp against the expressions * in dateargs */ file_list = holding_get_files(NULL, 1); for (file_elt = file_list; file_elt != NULL; file_elt = file_elt->next) { /* get info on that file */ if (!holding_file_get_dumpfile((char *)file_elt->data, &file)) continue; if (file.type != F_DUMPFILE) continue; if (dateargs) { date_matches = 0; /* loop over date args, until we find a match */ for (date = dateargs; date !=NULL; date = date->next) { if (strcmp((char *)date->data, file.datestamp) == 0) { date_matches = 1; break; } } } else { /* if no date list was provided, then all dates match */ date_matches = 1; } if (!date_matches) continue; /* check that the hostname and disk are in the disklist */ dp = lookup_disk(file.name, file.disk); if (dp == NULL) { dbprintf(_("%s: disk %s:%s not in database, skipping it."), (char *)file_elt->data, file.name, file.disk); continue; } /* passed all tests -- we'll flush this file */ result_list = g_slist_insert_sorted(result_list, stralloc(file_elt->data), g_compare_strings); } if (file_list) g_slist_free_full(file_list); return result_list;}GSList *holding_get_all_datestamps(void){ GSList *all_files, *file; GSList *datestamps = NULL; /* enumerate all files */ all_files = holding_get_files(NULL, 1); for (file = all_files; file != NULL; file = file->next) { dumpfile_t dfile; if (!holding_file_get_dumpfile((char *)file->data, &dfile)) continue; if (!g_slist_find_custom(datestamps, dfile.datestamp, g_compare_strings)) { datestamps = g_slist_insert_sorted(datestamps, stralloc(dfile.datestamp), g_compare_strings); } } g_slist_free_full(all_files); return datestamps;}off_tholding_file_size( char *hfile, int strip_headers){ dumpfile_t file; char *filename; off_t size = (off_t)0; struct stat finfo; /* (note: we don't use holding_get_file_chunks here because that would * entail opening each file twice) */ /* Loop through all cont_filenames (subsequent chunks) */ filename = stralloc(hfile); while (filename != NULL && filename[0] != '\0') { /* stat the file for its size */ if (stat(filename, &finfo) == -1) { dbprintf(_("stat %s: %s\n"), filename, strerror(errno)); return (off_t)-1; } size += (finfo.st_size+(off_t)1023)/(off_t)1024; if (strip_headers) size -= (off_t)(DISK_BLOCK_BYTES / 1024); /* get the header to look for cont_filename */ if (!holding_file_get_dumpfile(filename, &file)) { dbprintf(_("holding_file_size: open of %s failed.\n"), filename); amfree(filename); return (off_t)-1; } /* on to the next chunk */ filename = newstralloc(filename, file.cont_filename); } amfree(filename); return size;}intholding_file_unlink( char *hfile){ GSList *chunklist; GSList *chunk; chunklist = holding_get_file_chunks(hfile); if (!chunklist) return 0; for (chunk = chunklist; chunk != NULL; chunk = chunk->next) { if (unlink((char *)chunk->data)<0) { dbprintf(_("holding_file_unlink: could not unlink %s: %s\n"), (char *)chunk->data, strerror(errno)); return 0; } } return 1;}intholding_file_get_dumpfile( char * fname, dumpfile_t *file){ char buffer[DISK_BLOCK_BYTES]; int fd; memset(buffer, 0, sizeof(buffer)); fh_init(file); file->type = F_UNKNOWN; if((fd = robust_open(fname, O_RDONLY, 0)) == -1) return 0; if(fullread(fd, buffer, SIZEOF(buffer)) != (ssize_t)sizeof(buffer)) { aclose(fd); return 0; } aclose(fd); parse_file_header(buffer, file, SIZEOF(buffer)); return 1;}/* * Cleanup */typedef struct { corrupt_dle_fn corrupt_dle; FILE *verbose_output;} holding_cleanup_datap_t;static intholding_cleanup_disk( gpointer datap, G_GNUC_UNUSED char *base, G_GNUC_UNUSED char *element, char *fqpath, int is_cruft){ holding_cleanup_datap_t *data = (holding_cleanup_datap_t *)datap; if (data->verbose_output) { if (is_cruft) g_fprintf(data->verbose_output, _("Invalid holding disk '%s'\n"), fqpath); else g_fprintf(data->verbose_output, _("Cleaning up holding disk '%s'\n"), fqpath); } return 1;}static intholding_cleanup_dir( gpointer datap, G_GNUC_UNUSED char *base, char *element, char *fqpath, int is_cruft){ holding_cleanup_datap_t *data = (holding_cleanup_datap_t *)datap; if (is_cruft) { if (data->verbose_output) g_fprintf(data->verbose_output, _("Invalid holding directory '%s'\n"), fqpath); return 0; } /* try removing it */ if (rmdir(fqpath) == 0) { /* success, so don't try to walk into it */ if (data->verbose_output) g_fprintf(data->verbose_output, _(" ..removed empty directory '%s'\n"), element); return 0; } if (data->verbose_output) g_fprintf(data->verbose_output, _(" ..cleaning up holding directory '%s'\n"), element); return 1;}static intholding_cleanup_file( gpointer datap, G_GNUC_UNUSED char *base, char *element, char *fqpath, int is_cruft){ holding_cleanup_datap_t *data = (holding_cleanup_datap_t *)datap; int stat; int l; dumpfile_t file; disk_t *dp; if (is_cruft) { if (data->verbose_output) g_fprintf(data->verbose_output, _("Invalid holding file '%s'\n"), element); return 0; } stat = holding_file_get_dumpfile(fqpath, &file); if (!stat) { if (data->verbose_output) g_fprintf(data->verbose_output, _("Could not read read header from '%s'\n"), element); return 0; } if (file.type != F_DUMPFILE && file.type != F_CONT_DUMPFILE) { if (data->verbose_output) g_fprintf(data->verbose_output, _("File '%s' is not a dump file\n"), element); return 0; } if(file.dumplevel < 0 || file.dumplevel > 9) { if (data->verbose_output) g_fprintf(data->verbose_output, _("File '%s' has invalid level %d\n"), element, file.dumplevel); return 0; } dp = lookup_disk(file.name, file.disk); if (dp == NULL) { if (data->verbose_output) g_fprintf(data->verbose_output, _("File '%s' is for '%s:%s', which is not in the disklist\n"), element, file.name, file.disk); return 0; } if ((l = strlen(element)) >= 7 && strncmp(&fqpath[l-4],".tmp",4) == 0) { char *destname; /* generate a name without '.tmp' */ destname = stralloc(fqpath); destname[strlen(destname) - 4] = '\0'; /* OK, it passes muster -- rename it to salvage some data, * and mark the DLE as corrupted */ if (data->verbose_output) g_fprintf(data->verbose_output, _("Processing partial holding file '%s'\n"), element); if(rename_tmp_holding(destname, 0)) { if (data->corrupt_dle) data->corrupt_dle(dp->host->hostname, dp->name); } else { dbprintf(_("rename_tmp_holding(%s) failed\n"), destname); if (data->verbose_output) g_fprintf(data->verbose_output, _("Rename of '%s' to '%s' failed.\n"), element, destname); } amfree(destname); } return 1;}voidholding_cleanup( corrupt_dle_fn corrupt_dle, FILE *verbose_output){ holding_cleanup_datap_t data; data.corrupt_dle = corrupt_dle; data.verbose_output = verbose_output; holding_walk((gpointer)&data, STOP_AT_FILE, holding_cleanup_disk, holding_cleanup_dir, holding_cleanup_file, NULL);}/* * Application support */intrename_tmp_holding( char * holding_file, int complete){ int fd; ssize_t buflen; char buffer[DISK_BLOCK_BYTES]; dumpfile_t file; char *filename; char *filename_tmp = NULL; memset(buffer, 0, sizeof(buffer)); filename = stralloc(holding_file); while(filename != NULL && filename[0] != '\0') { filename_tmp = newvstralloc(filename_tmp, filename, ".tmp", NULL); if((fd = robust_open(filename_tmp,O_RDONLY, 0)) == -1) { dbprintf(_("rename_tmp_holding: open of %s failed: %s\n"),filename_tmp,strerror(errno)); amfree(filename); amfree(filename_tmp); return 0; } buflen = fullread(fd, buffer, SIZEOF(buffer)); close(fd); if(rename(filename_tmp, filename) != 0) { dbprintf(_("rename_tmp_holding: could not rename \"%s\" to \"%s\": %s"), filename_tmp, filename, strerror(errno)); } if (buflen <= 0) { dbprintf(_("rename_tmp_holding: %s: empty file?\n"), filename); amfree(filename); amfree(filename_tmp); return 0; } parse_file_header(buffer, &file, (size_t)buflen); if(complete == 0 ) { char * header; if((fd = robust_open(filename, O_RDWR, 0)) == -1) { dbprintf(_("rename_tmp_holdingX: open of %s failed: %s\n"), filename, strerror(errno)); amfree(filename); amfree(filename_tmp); return 0; } file.is_partial = 1; header = build_header(&file, DISK_BLOCK_BYTES); fullwrite(fd, header, DISK_BLOCK_BYTES); close(fd); } filename = newstralloc(filename, file.cont_filename); } amfree(filename); amfree(filename_tmp); return 1;}intmkholdingdir( char * diskdir){ struct stat stat_hdp; int success = 1; if (mkpdir(diskdir, 0770, (uid_t)-1, (gid_t)-1) != 0 && errno != EEXIST) { log_add(L_WARNING, _("WARNING: could not create parents of %s: %s"), diskdir, strerror(errno)); success = 0; } else if (mkdir(diskdir, 0770) != 0 && errno != EEXIST) { log_add(L_WARNING, _("WARNING: could not create %s: %s"), diskdir, strerror(errno)); success = 0; } else if (stat(diskdir, &stat_hdp) == -1) { log_add(L_WARNING, _("WARNING: could not stat %s: %s"), diskdir, strerror(errno)); success = 0; } else { if (!S_ISDIR((stat_hdp.st_mode))) { log_add(L_WARNING, _("WARNING: %s is not a directory"), diskdir); success = 0; } else if (access(diskdir,W_OK) != 0) { log_add(L_WARNING, _("WARNING: directory %s is not writable"), diskdir); success = 0; } } return success;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -