SRCS-$(CONFIG_RTE_APP_TEST) += test_alarm.c
SRCS-$(CONFIG_RTE_APP_TEST) += test_interrupts.c
SRCS-$(CONFIG_RTE_APP_TEST) += test_version.c
+SRCS-$(CONFIG_RTE_APP_TEST) += test_eal_fs.c
CFLAGS += -O3
CFLAGS += $(WERROR_FLAGS)
if (all || !strcmp(res->autotest, "version_autotest"))
ret |= test_version();
+ if (all || !strcmp(res->autotest, "eal_fs_autotest"))
+ ret |= test_eal_fs();
if (all || !strcmp(res->autotest, "debug_autotest"))
ret |= test_debug();
if (all || !strcmp(res->autotest, "pci_autotest"))
"string_autotest#multiprocess_autotest#"
"cpuflags_autotest#eal_flags_autotest#"
"alarm_autotest#interrupt_autotest#"
- "version_autotest#"
+ "version_autotest#eal_fs_autotest#"
"all_autotests");
cmdline_parse_inst_t cmd_autotest = {
int test_alarm(void);
int test_interrupt(void);
int test_version(void);
+int test_eal_fs(void);
+
int test_pci_run;
#endif
--- /dev/null
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <cmdline_parse.h>
+
+#include "test.h"
+#ifndef RTE_EXEC_ENV_BAREMETAL
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* eal_filesystem.h is not a public header file, so use relative path */
+#include "../../lib/librte_eal/linuxapp/eal/include/eal_filesystem.h"
+
+static int
+test_parse_sysfs_value(void)
+{
+ char filename[PATH_MAX] = "";
+ char proc_path[PATH_MAX];
+ char file_template[] = "/tmp/eal_test_XXXXXX";
+ int tmp_file_handle = -1;
+ FILE *fd = NULL;
+ unsigned valid_number;
+ unsigned long retval = 0;
+
+ printf("Testing function eal_parse_sysfs_value()\n");
+
+ /* get a temporary filename to use for all tests - create temp file handle and then
+ * use /proc to get the actual file that we can open */
+ tmp_file_handle = mkstemp(file_template);
+ if (tmp_file_handle == -1) {
+ perror("mkstemp() failure");
+ goto error;
+ }
+ rte_snprintf(proc_path, sizeof(proc_path), "/proc/self/fd/%d", tmp_file_handle);
+ if (readlink(proc_path, filename, sizeof(filename)) < 0) {
+ perror("readlink() failure");
+ goto error;
+ }
+ printf("Temporary file is: %s\n", filename);
+
+ /* test we get an error value if we use file before it's created */
+ printf("Test reading a missing file ...\n");
+ if (eal_parse_sysfs_value("/dev/not-quite-null", &retval) == 0) {
+ printf("Error with eal_parse_sysfs_value() - returned success on reading empty file\n");
+ goto error;
+ }
+ printf("Confirmed return error when reading empty file\n");
+
+ /* test reading a valid number value with "\n" on the end */
+ printf("Test reading valid values ...\n");
+ valid_number = 15;
+ fd = fopen(filename,"w");
+ if (fd == NULL) {
+ printf("line %d, Error opening %s: %s\n", __LINE__, filename, strerror(errno));
+ goto error;
+ }
+ fprintf(fd,"%u\n", valid_number);
+ fclose(fd);
+ fd = NULL;
+ if (eal_parse_sysfs_value(filename, &retval) < 0) {
+ printf("eal_parse_sysfs_value() returned error - test failed\n");
+ goto error;
+ }
+ if (retval != valid_number) {
+ printf("Invalid value read by eal_parse_sysfs_value() - test failed\n");
+ goto error;
+ }
+ printf("Read '%u\\n' ok\n", valid_number);
+
+ /* test reading a valid hex number value with "\n" on the end */
+ valid_number = 25;
+ fd = fopen(filename,"w");
+ if (fd == NULL) {
+ printf("line %d, Error opening %s: %s\n", __LINE__, filename, strerror(errno));
+ goto error;
+ }
+ fprintf(fd,"0x%x\n", valid_number);
+ fclose(fd);
+ fd = NULL;
+ if (eal_parse_sysfs_value(filename, &retval) < 0) {
+ printf("eal_parse_sysfs_value() returned error - test failed\n");
+ goto error;
+ }
+ if (retval != valid_number) {
+ printf("Invalid value read by eal_parse_sysfs_value() - test failed\n");
+ goto error;
+ }
+ printf("Read '0x%x\\n' ok\n", valid_number);
+
+ printf("Test reading invalid values ...\n");
+
+ /* test reading an empty file - expect failure!*/
+ fd = fopen(filename,"w");
+ if (fd == NULL) {
+ printf("line %d, Error opening %s: %s\n", __LINE__, filename, strerror(errno));
+ goto error;
+ }
+ fclose(fd);
+ fd = NULL;
+ if (eal_parse_sysfs_value(filename, &retval) == 0) {
+ printf("eal_parse_sysfs_value() read invalid value - test failed\n");
+ goto error;
+ }
+
+ /* test reading a valid number value *without* "\n" on the end - expect failure!*/
+ valid_number = 3;
+ fd = fopen(filename,"w");
+ if (fd == NULL) {
+ printf("line %d, Error opening %s: %s\n", __LINE__, filename, strerror(errno));
+ goto error;
+ }
+ fprintf(fd,"%u", valid_number);
+ fclose(fd);
+ fd = NULL;
+ if (eal_parse_sysfs_value(filename, &retval) == 0) {
+ printf("eal_parse_sysfs_value() read invalid value - test failed\n");
+ goto error;
+ }
+
+ /* test reading a valid number value followed by string - expect failure!*/
+ valid_number = 3;
+ fd = fopen(filename,"w");
+ if (fd == NULL) {
+ printf("line %d, Error opening %s: %s\n", __LINE__, filename, strerror(errno));
+ goto error;
+ }
+ fprintf(fd,"%uJ\n", valid_number);
+ fclose(fd);
+ fd = NULL;
+ if (eal_parse_sysfs_value(filename, &retval) == 0) {
+ printf("eal_parse_sysfs_value() read invalid value - test failed\n");
+ goto error;
+ }
+
+ /* test reading a non-numeric value - expect failure!*/
+ fd = fopen(filename,"w");
+ if (fd == NULL) {
+ printf("line %d, Error opening %s: %s\n", __LINE__, filename, strerror(errno));
+ goto error;
+ }
+ fprintf(fd,"error\n");
+ fclose(fd);
+ fd = NULL;
+ if (eal_parse_sysfs_value(filename, &retval) == 0) {
+ printf("eal_parse_sysfs_value() read invalid value - test failed\n");
+ goto error;
+ }
+
+ close(tmp_file_handle);
+ unlink(filename);
+ printf("eal_parse_sysfs_value() - OK\n");
+ return 0;
+
+error:
+ if (fd)
+ fclose(fd);
+ if (tmp_file_handle > 0)
+ close(tmp_file_handle);
+ if (filename[0] != '\0')
+ unlink(filename);
+ return -1;
+}
+
+int
+test_eal_fs(void)
+{
+ if (test_parse_sysfs_value() < 0)
+ return -1;
+ return 0;
+}
+#else
+/* baremetal does not have a filesystem */
+int
+test_eal_fs(void)
+{
+ return 0;
+}
+#endif
#include "eal_private.h"
#include "eal_thread.h"
#include "eal_internal_cfg.h"
-#include "eal_fs_paths.h"
+#include "eal_filesystem.h"
#include "eal_hugepages.h"
#define OPT_HUGE_DIR "huge-dir"
return &rte_config;
}
+/* parse a sysfs (or other) file containing one integer value */
+int
+eal_parse_sysfs_value(const char *filename, unsigned long *val)
+{
+ FILE *f;
+ char buf[BUFSIZ];
+ char *end = NULL;
+
+ if ((f = fopen(filename, "r")) == NULL) {
+ RTE_LOG(ERR, EAL, "%s(): cannot open sysfs value %s\n",
+ __func__, filename);
+ return -1;
+ }
+
+ if (fgets(buf, sizeof(buf), f) == NULL) {
+ RTE_LOG(ERR, EAL, "%s(): cannot read sysfs value %s\n",
+ __func__, filename);
+ fclose(f);
+ return -1;
+ }
+ *val = strtoul(buf, &end, 0);
+ if ((buf[0] == '\0') || (end == NULL) || (*end != '\n')) {
+ RTE_LOG(ERR, EAL, "%s(): cannot parse sysfs value %s\n",
+ __func__, filename);
+ fclose(f);
+ return -1;
+ }
+ fclose(f);
+ return 0;
+}
+
+
/* create memory configuration in shared/mmap memory. Take out
* a write lock on the memsegs, so we can auto-detect primary/secondary.
* This means we never close the file while running (auto-close on exit).
#include "rte_string_fns.h"
#include "eal_internal_cfg.h"
#include "eal_hugepages.h"
+#include "eal_filesystem.h"
static const char sys_dir_path[] = "/sys/kernel/mm/hugepages";
rte_snprintf(path, sizeof(path), "%s/%s/%s",
sys_dir_path, subdir, nr_hp_file);
- FILE *fd = fopen(path, "r");
- if (fd == NULL || fscanf(fd, "%u", &num_pages) != 1)
- rte_panic("Error reading file '%s'\n", path);
- fclose(fd);
+
+ if (eal_parse_sysfs_value(path, &num_pages) < 0)
+ return 0;
return num_pages;
}
#include "eal_private.h"
#include "eal_internal_cfg.h"
-#include "eal_fs_paths.h"
+#include "eal_filesystem.h"
#include "eal_hugepages.h"
/**
#include <rte_debug.h>
#include "eal_internal_cfg.h"
+#include "eal_filesystem.h"
#include "eal_private.h"
/**
TAILQ_HEAD(uio_res_list, uio_resource);
static struct uio_res_list *uio_res_list = NULL;
-static int pci_parse_sysfs_value(const char *filename, unsigned long *val);
/*
* Check that a kernel module is loaded. Returns 0 on success, or if the
/* get mapping offset */
rte_snprintf(filename, sizeof(filename),
"%s/maps/map0/offset", dirname2);
- if (pci_parse_sysfs_value(filename, &offset) < 0) {
+ if (eal_parse_sysfs_value(filename, &offset) < 0) {
RTE_LOG(ERR, EAL, "%s(): cannot parse offset\n",
__func__);
return -1;
/* get mapping size */
rte_snprintf(filename, sizeof(filename),
"%s/maps/map0/size", dirname2);
- if (pci_parse_sysfs_value(filename, &size) < 0) {
+ if (eal_parse_sysfs_value(filename, &size) < 0) {
RTE_LOG(ERR, EAL, "%s(): cannot parse size\n",
__func__);
return -1;
return -1;
}
-/* parse a sysfs file containing one integer value */
-static int
-pci_parse_sysfs_value(const char *filename, unsigned long *val)
-{
- FILE *f;
- char buf[BUFSIZ];
- char *end = NULL;
-
- f = fopen(filename, "r");
- if (f == NULL) {
- RTE_LOG(ERR, EAL, "%s(): cannot open sysfs value %s\n",
- __func__, filename);
- return -1;
- }
-
- if (fgets(buf, sizeof(buf), f) == NULL) {
- RTE_LOG(ERR, EAL, "%s(): cannot read sysfs value %s\n",
- __func__, filename);
- fclose(f);
- return -1;
- }
- *val = strtoul(buf, &end, 0);
- if ((buf[0] == '\0') || (end == NULL) || (*end != '\n')) {
- RTE_LOG(ERR, EAL, "%s(): cannot parse sysfs value %s\n",
- __func__, filename);
- fclose(f);
- return -1;
- }
- fclose(f);
- return 0;
-}
/* Scan one pci sysfs entry, and fill the devices list from it. */
static int
/* get vendor id */
rte_snprintf(filename, sizeof(filename), "%s/vendor", dirname);
- if (pci_parse_sysfs_value(filename, &tmp) < 0) {
+ if (eal_parse_sysfs_value(filename, &tmp) < 0) {
free(dev);
return -1;
}
/* get device id */
rte_snprintf(filename, sizeof(filename), "%s/device", dirname);
- if (pci_parse_sysfs_value(filename, &tmp) < 0) {
+ if (eal_parse_sysfs_value(filename, &tmp) < 0) {
free(dev);
return -1;
}
/* get subsystem_vendor id */
rte_snprintf(filename, sizeof(filename), "%s/subsystem_vendor",
dirname);
- if (pci_parse_sysfs_value(filename, &tmp) < 0) {
+ if (eal_parse_sysfs_value(filename, &tmp) < 0) {
free(dev);
return -1;
}
/* get subsystem_device id */
rte_snprintf(filename, sizeof(filename), "%s/subsystem_device",
dirname);
- if (pci_parse_sysfs_value(filename, &tmp) < 0) {
+ if (eal_parse_sysfs_value(filename, &tmp) < 0) {
free(dev);
return -1;
}
--- /dev/null
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/**
+ * @file
+ * Stores functions and path defines for files and directories
+ * on the filesystem for Linux, that are used by the Linux EAL.
+ */
+
+#ifndef _EAL_LINUXAPP_FILESYSTEM_H
+#define _EAL_LINUXAPP_FILESYSTEM_H
+
+/** Path of rte config file. */
+#define RUNTIME_CONFIG_FMT "%s/.%s_config"
+
+#include <stdint.h>
+#include <limits.h>
+#include <unistd.h>
+#include <rte_string_fns.h>
+#include "eal_internal_cfg.h"
+
+static const char *default_config_dir = "/var/run";
+
+static inline const char *
+eal_runtime_config_path(void)
+{
+ static char buffer[PATH_MAX]; /* static so auto-zeroed */
+ const char *directory = default_config_dir;
+ const char *home_dir = getenv("HOME");
+
+ if (getuid() != 0 && home_dir != NULL)
+ directory = home_dir;
+ rte_snprintf(buffer, sizeof(buffer) - 1, RUNTIME_CONFIG_FMT, directory,
+ internal_config.hugefile_prefix);
+ return buffer;
+}
+
+/** Path of hugepage info file. */
+#define HUGEPAGE_INFO_FMT "%s/.%s_hugepage_info"
+
+static inline const char *
+eal_hugepage_info_path(void)
+{
+ static char buffer[PATH_MAX]; /* static so auto-zeroed */
+ const char *directory = default_config_dir;
+ const char *home_dir = getenv("HOME");
+
+ if (getuid() != 0 && home_dir != NULL)
+ directory = home_dir;
+ rte_snprintf(buffer, sizeof(buffer) - 1, HUGEPAGE_INFO_FMT, directory,
+ internal_config.hugefile_prefix);
+ return buffer;
+}
+
+/** String format for hugepage map files. */
+#define HUGEFILE_FMT "%s/%smap_%d"
+
+static inline const char *
+eal_get_hugefile_path(char *buffer, size_t buflen, const char *hugedir, int f_id)
+{
+ rte_snprintf(buffer, buflen, HUGEFILE_FMT, hugedir,
+ internal_config.hugefile_prefix, f_id);
+ buffer[buflen - 1] = '\0';
+ return buffer;
+}
+
+/** define the default filename prefix for the %s values above */
+#define HUGEFILE_PREFIX_DEFAULT "rte"
+
+/** Function to read a single numeric value from a file on the filesystem.
+ * Used to read information from files on /sys */
+int eal_parse_sysfs_value(const char *filename, unsigned long *val);
+
+#endif /* _EAL_LINUXAPP_FILESYSTEM_H */
+++ /dev/null
-/*-
- * BSD LICENSE
- *
- * Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Intel Corporation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-/**
- * @file
- * Paths used for storing hugepage and config info for multi-process support.
- */
-
-#ifndef _EAL_LINUXAPP_FS_PATHS_H
-#define _EAL_LINUXAPP_FS_PATHS_H
-
-/** Path of rte config file. */
-#define RUNTIME_CONFIG_FMT "%s/.%s_config"
-
-static const char *default_config_dir = "/var/run";
-
-static inline const char *
-eal_runtime_config_path(void)
-{
- static char buffer[PATH_MAX]; /* static so auto-zeroed */
- const char *directory = default_config_dir;
- const char *home_dir = getenv("HOME");
-
- if (getuid() != 0 && home_dir != NULL)
- directory = home_dir;
- rte_snprintf(buffer, sizeof(buffer) - 1, RUNTIME_CONFIG_FMT, directory,
- internal_config.hugefile_prefix);
- return buffer;
-}
-
-/** Path of hugepage info file. */
-#define HUGEPAGE_INFO_FMT "%s/.%s_hugepage_info"
-
-static inline const char *
-eal_hugepage_info_path(void)
-{
- static char buffer[PATH_MAX]; /* static so auto-zeroed */
- const char *directory = default_config_dir;
- const char *home_dir = getenv("HOME");
-
- if (getuid() != 0 && home_dir != NULL)
- directory = home_dir;
- rte_snprintf(buffer, sizeof(buffer) - 1, HUGEPAGE_INFO_FMT, directory,
- internal_config.hugefile_prefix);
- return buffer;
-}
-
-/** String format for hugepage map files. */
-#define HUGEFILE_FMT "%s/%smap_%d"
-
-static inline const char *
-eal_get_hugefile_path(char *buffer, size_t buflen, const char *hugedir, int f_id)
-{
- rte_snprintf(buffer, buflen, HUGEFILE_FMT, hugedir,
- internal_config.hugefile_prefix, f_id);
- buffer[buflen - 1] = '\0';
- return buffer;
-}
-
-/** define the default filename prefix for the %s values above */
-#define HUGEFILE_PREFIX_DEFAULT "rte"
-
-
-#endif /* _EAL_LINUXAPP_FS_PATHS_H */