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

Use Malloc for path's buffers instead of stack #5888

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
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
2 changes: 2 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -2,6 +2,8 @@

This release:
- Significantly reduces the libpmem's stack usage.
- Decrease stack usage by allocating paths' buffers on heap


Tue Aug 8 2023 Oksana Sałyk <oksana.salyk@intel.com>

2 changes: 1 addition & 1 deletion src/core/out.c
Original file line number Diff line number Diff line change
@@ -161,7 +161,7 @@ out_init(const char *log_prefix, const char *log_level_var,
log_file[0] != '\0') {

/* reserve more than enough space for a PID + '\0' */
char log_file_pid[PATH_MAX];
static char log_file_pid[PATH_MAX];
size_t len = strlen(log_file);
if (len > 0 && log_file[len - 1] == '-') {
if (util_snprintf(log_file_pid, PATH_MAX, "%s%d",
14 changes: 12 additions & 2 deletions src/libpmem2/auto_flush_linux.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: BSD-3-Clause
/* Copyright 2018-2020, Intel Corporation */
/* Copyright 2018-2023, Intel Corporation */

/*
* auto_flush_linux.c -- Linux auto flush detection
@@ -16,6 +16,7 @@
#include "os.h"
#include "fs.h"
#include "auto_flush.h"
#include "alloc.h"

#define BUS_DEVICE_PATH "/sys/bus/nd/devices"
#define PERSISTENCE_DOMAIN "persistence_domain"
@@ -87,9 +88,16 @@ check_domain_in_region(const char *region_path)

struct fs *reg = NULL;
struct fs_entry *reg_entry;
char domain_path[PATH_MAX];
char *domain_path = NULL;
int cpu_cache = 0;

domain_path = Malloc(PATH_MAX * sizeof(char));
if (domain_path == NULL) {
ERR("!Malloc");
cpu_cache = -1;
goto end;
}

reg = fs_new(region_path);
if (reg == NULL) {
ERR("!fs_new: \"%s\"", region_path);
@@ -122,6 +130,8 @@ check_domain_in_region(const char *region_path)
end:
if (reg)
fs_delete(reg);
if (domain_path)
Free(domain_path);
return cpu_cache;
}

30 changes: 22 additions & 8 deletions src/libpmem2/deep_flush_linux.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: BSD-3-Clause
/* Copyright 2020, Intel Corporation */
/* Copyright 2020-2023, Intel Corporation */

/*
* deep_flush_linux.c -- deep_flush functionality
@@ -18,6 +18,7 @@
#include "persist.h"
#include "pmem2_utils.h"
#include "region_namespace.h"
#include "alloc.h"

/*
* pmem2_deep_flush_write -- perform write to deep_flush file
@@ -28,19 +29,28 @@ pmem2_deep_flush_write(unsigned region_id)
{
LOG(3, "region_id %d", region_id);

char deep_flush_path[PATH_MAX];
int deep_flush_fd;
int ret = 0;
char *deep_flush_path = NULL;
int deep_flush_fd = -1;
char rbuf[2];

deep_flush_path = Malloc(PATH_MAX * sizeof(char));
if (deep_flush_path == NULL) {
ERR("!Malloc");
ret = PMEM2_E_ERRNO;
goto end;
}

if (util_snprintf(deep_flush_path, PATH_MAX,
"/sys/bus/nd/devices/region%u/deep_flush", region_id) < 0) {
ERR("!snprintf");
return PMEM2_E_ERRNO;
ret = PMEM2_E_ERRNO;
goto end;
}

if ((deep_flush_fd = os_open(deep_flush_path, O_RDONLY)) < 0) {
LOG(1, "!os_open(\"%s\", O_RDONLY)", deep_flush_path);
return 0;
goto end;
}

if (read(deep_flush_fd, rbuf, sizeof(rbuf)) != 2) {
@@ -54,11 +64,12 @@ pmem2_deep_flush_write(unsigned region_id)
}

os_close(deep_flush_fd);
deep_flush_fd = -1;

if ((deep_flush_fd = os_open(deep_flush_path, O_WRONLY)) < 0) {
LOG(1, "Cannot open deep_flush file %s to write",
deep_flush_path);
return 0;
goto end;
}

if (write(deep_flush_fd, "1", 1) != 1) {
@@ -67,8 +78,11 @@ pmem2_deep_flush_write(unsigned region_id)
}

end:
os_close(deep_flush_fd);
return 0;
if (deep_flush_fd > -1)
os_close(deep_flush_fd);
if (deep_flush_path)
Free(deep_flush_path);
return ret;
}

/*
41 changes: 33 additions & 8 deletions src/libpmem2/pmem2_utils_linux.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: BSD-3-Clause
/* Copyright 2014-2020, Intel Corporation */
/* Copyright 2014-2023, Intel Corporation */

#include <errno.h>
#include <fcntl.h>
@@ -14,6 +14,7 @@
#include "pmem2_utils.h"
#include "region_namespace.h"
#include "source.h"
#include "alloc.h"

/*
* pmem2_get_type_from_stat -- determine type of file based on output of stat
@@ -37,34 +38,58 @@ pmem2_get_type_from_stat(const os_stat_t *st, enum pmem2_file_type *type)
return PMEM2_E_INVALID_FILE_TYPE;
}

char spath[PATH_MAX];
int ret = util_snprintf(spath, PATH_MAX,
int ret = 0;
char *spath = NULL;
char *npath = NULL;

spath = Malloc(PATH_MAX * sizeof(char));
if (spath == NULL) {
ERR("!Malloc");
return PMEM2_E_ERRNO;
}

ret = util_snprintf(spath, PATH_MAX,
"/sys/dev/char/%u:%u/subsystem",
os_major(st->st_rdev), os_minor(st->st_rdev));

if (ret < 0) {
/* impossible */
ERR("!snprintf");
ASSERTinfo(0, "snprintf failed");
return PMEM2_E_ERRNO;
ret = PMEM2_E_ERRNO;
goto end;
}

LOG(4, "device subsystem path \"%s\"", spath);

char npath[PATH_MAX];
npath = Malloc(PATH_MAX * sizeof(char));
if (npath == NULL) {
ERR("!Malloc");
ret = PMEM2_E_ERRNO;
goto end;
}

char *rpath = realpath(spath, npath);
if (rpath == NULL) {
ERR("!realpath \"%s\"", spath);
return PMEM2_E_ERRNO;
ret = PMEM2_E_ERRNO;
goto end;
}

char *basename = strrchr(rpath, '/');
if (!basename || strcmp("dax", basename + 1) != 0) {
LOG(3, "%s path does not match device dax prefix path", rpath);
return PMEM2_E_INVALID_FILE_TYPE;
ret = PMEM2_E_INVALID_FILE_TYPE;
goto end;
}

*type = PMEM2_FTYPE_DEVDAX;

return 0;
end:
if (npath)
Free(npath);
if (spath)
Free(spath);

return ret;
}
65 changes: 48 additions & 17 deletions src/libpmem2/region_namespace_ndctl.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: BSD-3-Clause
/* Copyright 2020-2022, Intel Corporation */
/* Copyright 2020-2023, Intel Corporation */

/*
* region_namespace_ndctl.c -- common ndctl functions
@@ -16,6 +16,7 @@
#include "region_namespace_ndctl.h"
#include "region_namespace.h"
#include "out.h"
#include "alloc.h"

/*
* ndctl_match_devdax -- (internal) returns 0 if the devdax matches
@@ -27,30 +28,43 @@ ndctl_match_devdax(dev_t st_rdev, const char *devname)
{
LOG(3, "st_rdev %lu devname %s", st_rdev, devname);

int ret = 0;
char *path;
os_stat_t stat;

if (*devname == '\0')
return 1;

char path[PATH_MAX];
os_stat_t stat;
path = Malloc(PATH_MAX * sizeof(char));
if (path == NULL) {
ERR("!Malloc");
return PMEM2_E_ERRNO;
}

if (util_snprintf(path, PATH_MAX, "/dev/%s", devname) < 0) {
ERR("!snprintf");
return PMEM2_E_ERRNO;
ret = PMEM2_E_ERRNO;
goto end;
}

if (os_stat(path, &stat)) {
ERR("!stat %s", path);
return PMEM2_E_ERRNO;
ret = PMEM2_E_ERRNO;
goto end;
}

if (st_rdev != stat.st_rdev) {
LOG(10, "skipping not matching device: %s", path);
return 1;
ret = 1;
goto end;
}

LOG(4, "found matching device: %s", path);

return 0;
end:
Free(path);

return ret;
}

#define BUFF_LENGTH 64
@@ -65,27 +79,37 @@ ndctl_match_fsdax(dev_t st_dev, const char *devname)
{
LOG(3, "st_dev %lu devname %s", st_dev, devname);

int ret = 0;
char *path;
char dev_id[BUFF_LENGTH];

if (*devname == '\0')
return 1;

char path[PATH_MAX];
char dev_id[BUFF_LENGTH];
path = Malloc(PATH_MAX * sizeof(char));
if (path == NULL) {
ERR("!Malloc");
return PMEM2_E_ERRNO;
}

if (util_snprintf(path, PATH_MAX, "/sys/block/%s/dev", devname) < 0) {
ERR("!snprintf");
return PMEM2_E_ERRNO;
ret = PMEM2_E_ERRNO;
goto end;
}

if (util_snprintf(dev_id, BUFF_LENGTH, "%d:%d",
major(st_dev), minor(st_dev)) < 0) {
ERR("!snprintf");
return PMEM2_E_ERRNO;
ret = PMEM2_E_ERRNO;
goto end;
}

int fd = os_open(path, O_RDONLY);
if (fd < 0) {
ERR("!open \"%s\"", path);
return PMEM2_E_ERRNO;
ret = PMEM2_E_ERRNO;
goto end;
}

char buff[BUFF_LENGTH];
@@ -95,31 +119,38 @@ ndctl_match_fsdax(dev_t st_dev, const char *devname)
int oerrno = errno; /* save the errno */
os_close(fd);
errno = oerrno;
return PMEM2_E_ERRNO;
ret = PMEM2_E_ERRNO;
goto end;
}

os_close(fd);

if (nread == 0) {
ERR("%s is empty", path);
return PMEM2_E_INVALID_DEV_FORMAT;
ret = PMEM2_E_INVALID_DEV_FORMAT;
goto end;
}

if (buff[nread - 1] != '\n') {
ERR("%s doesn't end with new line", path);
return PMEM2_E_INVALID_DEV_FORMAT;
ret = PMEM2_E_INVALID_DEV_FORMAT;
goto end;
}

buff[nread - 1] = '\0';

if (strcmp(buff, dev_id) != 0) {
LOG(10, "skipping not matching device: %s", path);
return 1;
ret = 1;
goto end;
}

LOG(4, "found matching device: %s", path);

return 0;
end:
Free(path);

return ret;
}

/*
Loading