diff --git a/system/coredump/Kconfig b/system/coredump/Kconfig index 1ddeaf0cdb..c6e74964be 100644 --- a/system/coredump/Kconfig +++ b/system/coredump/Kconfig @@ -22,10 +22,23 @@ config SYSTEM_COREDUMP_PRIORITY ---help--- This is the task priority that will be used when starting the coredump. -config SYSTEM_COREDUMP_SWAPBUFFER_NUMS - int "coredump read/write swap buffer nums" - default 64 +config SYSTEM_COREDUMP_SWAPBUFFER_SIZE + int "coredump read/write swap buffer size" + default 16384 ---help--- - The coredump read/write swap buffer nums. swap buffer size = sectorsize * nums + The coredump read/write swap buffer size in bytes. + +config SYSTEM_COREDUMP_RESTORE + bool "coredump restore from block/mtd device to filesystem" + default BOARD_COREDUMP_BLKDEV || BOARD_COREDUMP_MTDDEV + ---help--- + Userspace restore from block/mtd device to specific filesystem path. + +config SYSTEM_COREDUMP_DEVPATH + string "coredump block device path to restore" + depends on SYSTEM_COREDUMP_RESTORE + default BOARD_COREDUMP_DEVPATH if BOARD_COREDUMP_BLKDEV || BOARD_COREDUMP_MTDDEV + ---help--- + This is the block device path to restore. endif # SYSTEM_COREDUMP diff --git a/system/coredump/coredump.c b/system/coredump/coredump.c index 0d4b0fd895..1846dc9ee8 100644 --- a/system/coredump/coredump.c +++ b/system/coredump/coredump.c @@ -39,6 +39,18 @@ #include #include +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifdef CONFIG_BOARD_COREDUMP_COMPRESSION +# define COREDUMP_FILE_SUFFIX ".lzf" +#else +# define COREDUMP_FILE_SUFFIX ".core" +#endif + +#define COREDUMP_FILE_SUFFIX_LEN (sizeof(COREDUMP_FILE_SUFFIX) - 1) + /**************************************************************************** * Private Types ****************************************************************************/ @@ -65,7 +77,23 @@ static struct memory_region_s g_memory_region[] = * dumpfile_iterate ****************************************************************************/ -#ifdef CONFIG_BOARD_COREDUMP_BLKDEV +#ifdef CONFIG_SYSTEM_COREDUMP_RESTORE + +static bool dumpfile_is_valid(FAR const char *name) +{ + FAR const char *suffix; + size_t name_len; + + name_len = strlen(name); + if (name_len < COREDUMP_FILE_SUFFIX_LEN) + { + return false; + } + + suffix = name + name_len - COREDUMP_FILE_SUFFIX_LEN; + return !!memcmp(suffix, COREDUMP_FILE_SUFFIX, COREDUMP_FILE_SUFFIX_LEN); +} + static int dumpfile_iterate(FAR char *path, dumpfile_cb_t cb, FAR void *arg) { FAR struct dirent *entry; @@ -84,7 +112,7 @@ static int dumpfile_iterate(FAR char *path, dumpfile_cb_t cb, FAR void *arg) while ((entry = readdir(dir)) != NULL) { - if (entry->d_type == DT_REG && !strncmp(entry->d_name, "core-", 5)) + if (entry->d_type == DT_REG && dumpfile_is_valid(entry->d_name)) { cb(path, entry->d_name, arg); } @@ -131,17 +159,11 @@ static void dumpfile_delete(FAR char *path, FAR const char *filename, static void coredump_restore(FAR char *savepath, size_t maxfile) { - FAR struct coredump_info_s *info; - char dumppath[PATH_MAX] = - { - 0 - }; - + struct coredump_info_s info; + char dumppath[PATH_MAX]; unsigned char *swap; - struct geometry geo; ssize_t writesize; ssize_t readsize; - struct tm *dtime; size_t offset = 0; size_t max = 0; int dumpfd; @@ -149,48 +171,36 @@ static void coredump_restore(FAR char *savepath, size_t maxfile) off_t off; int ret; - blkfd = open(CONFIG_BOARD_COREDUMP_BLKDEV_PATH, O_RDWR); + blkfd = open(CONFIG_SYSTEM_COREDUMP_DEVPATH, O_RDWR); if (blkfd < 0) { return; } - ret = ioctl(blkfd, BIOC_GEOMETRY, (unsigned long)((uintptr_t)&geo)); - if (ret < 0) + off = lseek(blkfd, -(off_t)sizeof(info), SEEK_END); + if (off < 0) { + printf("Seek %s fail\n", CONFIG_SYSTEM_COREDUMP_DEVPATH); goto blkfd_err; } - info = malloc(geo.geo_sectorsize); - if (info == NULL) + readsize = read(blkfd, &info, sizeof(info)); + if (readsize != sizeof(info)) { + printf("Read %s fail\n", CONFIG_SYSTEM_COREDUMP_DEVPATH); goto blkfd_err; } - off = lseek(blkfd, (geo.geo_nsectors - 1) * geo.geo_sectorsize, SEEK_SET); - if (off < 0) - { - printf("Seek %s fail\n", CONFIG_BOARD_COREDUMP_BLKDEV_PATH); - goto info_err; - } - - readsize = read(blkfd, info, geo.geo_sectorsize); - if (readsize != geo.geo_sectorsize) + if (info.magic != COREDUMP_MAGIC) { - printf("Read %s fail\n", CONFIG_BOARD_COREDUMP_BLKDEV_PATH); - goto info_err; - } - - if (info->magic != COREDUMP_MAGIC) - { - printf("%s coredump not found!\n", CONFIG_BOARD_COREDUMP_BLKDEV_PATH); - goto info_err; + printf("%s coredump not found!\n", CONFIG_SYSTEM_COREDUMP_DEVPATH); + goto blkfd_err; } ret = dumpfile_iterate(savepath, dumpfile_count, &max); if (ret < 0) { - goto info_err; + goto blkfd_err; } if (max >= maxfile) @@ -198,27 +208,16 @@ static void coredump_restore(FAR char *savepath, size_t maxfile) ret = dumpfile_iterate(savepath, dumpfile_delete, dumppath); if (ret < 0) { - goto info_err; + goto blkfd_err; } } - ret = snprintf(dumppath, sizeof(dumppath), - "%s/core-%s", savepath, - info->name.version); - dtime = localtime(&info->time.tv_sec); - if (dtime) - { - ret += snprintf(dumppath + ret, sizeof(dumppath) - ret, - "-%d-%d-%d-%d-%d", dtime->tm_mon + 1, - dtime->tm_mday, dtime->tm_hour, - dtime->tm_min, dtime->tm_sec); - } + /* 'date -d @$(printf "%d" 0x6720C67E)' restore utc to date */ -#ifdef CONFIG_BOARD_COREDUMP_COMPRESSION - ret += snprintf(dumppath + ret, sizeof(dumppath) - ret, ".lzf"); -#else - ret += snprintf(dumppath + ret, sizeof(dumppath) - ret, ".core"); -#endif + ret = snprintf(dumppath, sizeof(dumppath), + "%s/%.16s-%llx"COREDUMP_FILE_SUFFIX, + savepath, info.name.version, + (unsigned long long)info.time.tv_sec); while (ret--) { @@ -232,11 +231,10 @@ static void coredump_restore(FAR char *savepath, size_t maxfile) if (dumpfd < 0) { printf("Open %s fail\n", dumppath); - goto info_err; + goto blkfd_err; } - swap = malloc(geo.geo_sectorsize * - CONFIG_SYSTEM_COREDUMP_SWAPBUFFER_NUMS); + swap = malloc(CONFIG_SYSTEM_COREDUMP_SWAPBUFFER_SIZE); if (swap == NULL) { printf("Malloc fail\n"); @@ -244,13 +242,12 @@ static void coredump_restore(FAR char *savepath, size_t maxfile) } lseek(blkfd, 0, SEEK_SET); - while (offset < info->size) + while (offset < info.size) { - readsize = read(blkfd, swap, geo.geo_sectorsize * - CONFIG_SYSTEM_COREDUMP_SWAPBUFFER_NUMS); + readsize = read(blkfd, swap, CONFIG_SYSTEM_COREDUMP_SWAPBUFFER_SIZE); if (readsize < 0) { - printf("Read %s fail\n", CONFIG_BOARD_COREDUMP_BLKDEV_PATH); + printf("Read %s fail\n", CONFIG_SYSTEM_COREDUMP_DEVPATH); break; } else if (readsize == 0) @@ -268,36 +265,34 @@ static void coredump_restore(FAR char *savepath, size_t maxfile) offset += writesize; } - if (offset < info->size) + if (offset < info.size) { printf("Coredump error [%s] need [%zu], but just get %zu\n", - dumppath, info->size, offset); + dumppath, info.size, offset); } else { - printf("Coredump finish [%s][%zu]\n", dumppath, info->size); + printf("Coredump finish [%s][%zu]\n", dumppath, info.size); } - info->magic = 0; - off = lseek(blkfd, (geo.geo_nsectors - 1) * geo.geo_sectorsize, SEEK_SET); + info.magic = 0; + off = lseek(blkfd, -(off_t)sizeof(info), SEEK_END); if (off < 0) { - printf("Seek %s fail\n", CONFIG_BOARD_COREDUMP_BLKDEV_PATH); + printf("Seek %s fail\n", CONFIG_SYSTEM_COREDUMP_DEVPATH); goto swap_err; } - writesize = write(blkfd, info, geo.geo_sectorsize); - if (writesize != geo.geo_sectorsize) + writesize = write(blkfd, &info, sizeof(info)); + if (writesize != sizeof(info)) { - printf("Write %s fail\n", CONFIG_BOARD_COREDUMP_BLKDEV_PATH); + printf("Write %s fail\n", CONFIG_SYSTEM_COREDUMP_DEVPATH); } swap_err: free(swap); fd_err: close(dumpfd); -info_err: - free(info); blkfd_err: close(blkfd); } @@ -416,10 +411,10 @@ static void usage(FAR const char *progname, int exitcode) fprintf(stderr, "\t -p, --pid , Default, all thread\n"); fprintf(stderr, "\t -f, --filename , Default stdout\n"); -#ifdef CONFIG_BOARD_COREDUMP_BLKDEV +#ifdef CONFIG_SYSTEM_COREDUMP_RESTORE fprintf(stderr, "Second usage, will restore coredump" "from %s to savepath\n", - CONFIG_BOARD_COREDUMP_BLKDEV_PATH); + CONFIG_SYSTEM_COREDUMP_DEVPATH); fprintf(stderr, "\t -s, --savepath \n"); fprintf(stderr, "\t -m, --maxfile ," "Maximum number of coredump files, Default 1\n"); @@ -437,7 +432,7 @@ static void usage(FAR const char *progname, int exitcode) int main(int argc, FAR char *argv[]) { -#ifdef CONFIG_BOARD_COREDUMP_BLKDEV +#ifdef CONFIG_SYSTEM_COREDUMP_RESTORE FAR char *savepath = NULL; size_t maxfile = 1; #endif @@ -449,7 +444,7 @@ int main(int argc, FAR char *argv[]) { {"pid", 1, NULL, 'p'}, {"filename", 1, NULL, 'f'}, -#ifdef CONFIG_BOARD_COREDUMP_BLKDEV +#ifdef CONFIG_SYSTEM_COREDUMP_RESTORE {"savepath", 1, NULL, 's'}, {"maxfile", 1, NULL, 'm'}, #endif @@ -467,7 +462,7 @@ int main(int argc, FAR char *argv[]) case 'f': name = optarg; break; -#ifdef CONFIG_BOARD_COREDUMP_BLKDEV +#ifdef CONFIG_SYSTEM_COREDUMP_RESTORE case 's': savepath = optarg; break; @@ -482,7 +477,7 @@ int main(int argc, FAR char *argv[]) } } -#ifdef CONFIG_BOARD_COREDUMP_BLKDEV +#ifdef CONFIG_SYSTEM_COREDUMP_RESTORE if (savepath != NULL) { coredump_restore(savepath, maxfile);