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
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
Expand Up @@ -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>

Expand Down
2 changes: 1 addition & 1 deletion src/core/out.c
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
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
Expand All @@ -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"
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
}

Expand Down
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
Expand All @@ -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
Expand All @@ -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) {
Expand All @@ -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) {
Expand All @@ -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;
}

/*
Expand Down
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>
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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];
Expand All @@ -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;
}

/*
Expand Down