1
0
mirror of https://github.com/systemd/systemd.git synced 2024-12-26 03:22:00 +03:00

Merge pull request #13727 from keszybz/pstore-greedy-realloc

Use greedy realloc in pstore
This commit is contained in:
Yu Watanabe 2019-10-09 15:01:45 +09:00 committed by GitHub
commit 6e5d630265
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -179,9 +179,11 @@ static int write_dmesg(const char *dmesg, size_t size, const char *id) {
ssize_t wr;
int r;
if (isempty(dmesg) || size == 0)
if (size == 0)
return 0;
assert(dmesg);
ofd_path = path_join(arg_archivedir, id, "dmesg.txt");
if (!ofd_path)
return log_oom();
@ -205,7 +207,8 @@ static int write_dmesg(const char *dmesg, size_t size, const char *id) {
static void process_dmesg_files(PStoreList *list) {
/* Move files, reconstruct dmesg.txt */
_cleanup_free_ char *dmesg = NULL, *dmesg_id = NULL;
size_t dmesg_size = 0;
size_t dmesg_size = 0, dmesg_allocated = 0;
bool dmesg_bad = false;
PStoreEntry *pe;
/* Handle each dmesg file: files processed in reverse
@ -282,33 +285,39 @@ static void process_dmesg_files(PStoreList *list) {
/* Now move file from pstore to archive storage */
move_file(pe, pe_id);
if (dmesg_bad)
continue;
/* If the current record id is NOT the same as the
* previous record id, then start a new dmesg.txt file */
if (!pe_id || !dmesg_id || !streq(pe_id, dmesg_id)) {
if (!streq_ptr(pe_id, dmesg_id)) {
/* Encountered a new dmesg group, close out old one, open new one */
if (dmesg) {
(void) write_dmesg(dmesg, dmesg_size, dmesg_id);
dmesg = mfree(dmesg);
dmesg_size = 0;
}
(void) write_dmesg(dmesg, dmesg_size, dmesg_id);
dmesg_size = 0;
/* now point dmesg_id to storage of pe_id */
free_and_replace(dmesg_id, pe_id);
}
/* Reconstruction of dmesg is done as a useful courtesy, do not log errors */
dmesg = realloc(dmesg, dmesg_size + strlen(pe->dirent.d_name) + strlen(":\n") + pe->content_size + 1);
if (dmesg) {
dmesg_size += sprintf(&dmesg[dmesg_size], "%s:\n", pe->dirent.d_name);
if (pe->content) {
memcpy(&dmesg[dmesg_size], pe->content, pe->content_size);
dmesg_size += pe->content_size;
}
/* Reconstruction of dmesg is done as a useful courtesy: do not fail, but don't write garbled
* output either. */
size_t needed = strlen(pe->dirent.d_name) + strlen(":\n") + pe->content_size + 1;
if (!GREEDY_REALLOC(dmesg, dmesg_allocated, dmesg_size + needed)) {
log_warning_errno(ENOMEM, "Failed to write dmesg file: %m");
dmesg_bad = true;
continue;
}
dmesg_size += sprintf(dmesg + dmesg_size, "%s:\n", pe->dirent.d_name);
if (pe->content) {
memcpy(dmesg + dmesg_size, pe->content, pe->content_size);
dmesg_size += pe->content_size;
}
pe_id = mfree(pe_id);
}
if (dmesg)
if (!dmesg_bad)
(void) write_dmesg(dmesg, dmesg_size, dmesg_id);
}
@ -359,15 +368,18 @@ static int run(int argc, char *argv[]) {
log_setup_service();
if (argc > 1)
if (argc == 3) {
arg_sourcedir = argv[1];
arg_archivedir = argv[2];
} else if (argc > 1)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"This program takes no arguments.");
"This program takes zero or two arguments.");
/* Ignore all parse errors */
(void) parse_config();
log_debug("Selected storage '%s'.", pstore_storage_to_string(arg_storage));
log_debug("Selected Unlink '%d'.", arg_unlink);
log_debug("Selected storage: %s.", pstore_storage_to_string(arg_storage));
log_debug("Selected unlink: %s.", yes_no(arg_unlink));
if (arg_storage == PSTORE_STORAGE_NONE)
/* Do nothing, intentionally, leaving pstore untouched */