Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Coredump restore application isolate with board_crashdump #2871

Merged
merged 4 commits into from
Nov 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 17 additions & 4 deletions system/coredump/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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
143 changes: 69 additions & 74 deletions system/coredump/coredump.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,18 @@
#include <nuttx/sched.h>
#include <nuttx/coredump.h>

/****************************************************************************
* 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
****************************************************************************/
Expand All @@ -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;
Expand All @@ -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);
}
Expand Down Expand Up @@ -131,94 +159,65 @@ 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;
int blkfd;
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)
{
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--)
{
Expand All @@ -232,25 +231,23 @@ 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");
goto fd_err;
}

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)
Expand All @@ -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);
}
Expand Down Expand Up @@ -416,10 +411,10 @@ static void usage(FAR const char *progname, int exitcode)
fprintf(stderr, "\t -p, --pid <pid>, Default, all thread\n");
fprintf(stderr, "\t -f, --filename <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 <savepath>\n");
fprintf(stderr, "\t -m, --maxfile <maxfile>,"
"Maximum number of coredump files, Default 1\n");
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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;
Expand All @@ -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);
Expand Down
Loading