aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/libredundancyfileop.h57
-rw-r--r--lib/Makefile.am30
-rw-r--r--lib/file-util.c73
-rw-r--r--lib/file-util.h26
-rw-r--r--lib/fileop.c377
-rw-r--r--lib/fileop.h53
-rw-r--r--lib/libredundancyfileop.c223
-rw-r--r--lib/libredundancyfileop.sym5
-rw-r--r--lib/static-configurator.c21
-rw-r--r--lib/static-configurator.h16
10 files changed, 881 insertions, 0 deletions
diff --git a/include/libredundancyfileop.h b/include/libredundancyfileop.h
new file mode 100644
index 0000000..22d48d0
--- /dev/null
+++ b/include/libredundancyfileop.h
@@ -0,0 +1,57 @@
+/**
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * @file libredundancyfileop.h
+ * @brief Interface header for the redundancy file operation library
+ */
+#ifndef LIBREDUNDANCY_FILEOP_H
+#define LIBREDUNDANCY_FILEOP_H
+//-----------------------------------------------------------------------------
+#include <stdbool.h>
+#include <stdint.h>
+
+//-----------------------------------------------------------------------------
+#ifdef __cplusplus
+extern "C" {
+#endif
+//-----------------------------------------------------------------------------
+/**
+ * Error code and type definition
+ * @enum refop_error_t
+ */
+typedef enum refop_error {
+ //! This operation was succeeded.
+ REFOP_SUCCESS = 0,
+
+ //! This operation was succeeded within recovery.
+ REFOP_RECOVER = 1,
+
+ //! The target file/directroy was nothing.
+ REFOP_NOENT = -1,
+
+ //! This operation was failed. Because all recovery method was failed.
+ REFOP_BROAKEN = -2,
+
+ //! Argument error.
+ REFOP_ARGERROR = -3,
+
+ //! Internal operation was failed such as no memory, no disk space and etc.
+ REFOP_SYSERROR = -100,
+
+} refop_error_t;
+//-----------------------------------------------------------------------------
+typedef struct refop_halndle *refop_handle_t;
+
+//-----------------------------------------------------------------------------
+refop_error_t refop_create_redundancy_handle(refop_handle_t *handle, const char *directry, const char *filename);
+refop_error_t refop_release_redundancy_handle(refop_handle_t handle);
+refop_error_t refop_set_redundancy_data(refop_handle_t handle, uint8_t *data, int64_t datasize);
+refop_error_t refop_get_redundancy_data(refop_handle_t handle, uint8_t *data, int64_t datasize, int64_t *getsize);
+refop_error_t refop_remove_redundancy_data(refop_handle_t handle);
+
+//-----------------------------------------------------------------------------
+#ifdef __cplusplus
+}
+#endif
+//-----------------------------------------------------------------------------
+#endif //#ifndef LIBREDUNDANCY_FILEOP_H
diff --git a/lib/Makefile.am b/lib/Makefile.am
new file mode 100644
index 0000000..f2f317c
--- /dev/null
+++ b/lib/Makefile.am
@@ -0,0 +1,30 @@
+AUTOMAKE_OPTIONS = foreign
+ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS}
+
+lib_LTLIBRARIES = libredundancyfileop.la
+
+libredundancyfileop_la_SOURCES = \
+ fileop.c file-util.c \
+ static-configurator.c \
+ libredundancyfileop.c
+
+libredundancyfileop_la_LBSADD =
+
+libredundancyfileop_la_CFLAGS = \
+ -g \
+ -I$(top_srcdir)/include \
+ -D_GNU_SOURCE
+
+libredundancyfileop_la_LDFLAGS = \
+ -export-symbols libredundancyfileop.sym -version-info 0:0:0
+
+# configure option
+if ENABLE_ADDRESS_SANITIZER
+CFLAGS += -fsanitize=address
+endif
+
+if ENABLE_GCOV
+CFLAGS += -coverage
+endif
+
+CLEANFILES = *.gcda *.gcno
diff --git a/lib/file-util.c b/lib/file-util.c
new file mode 100644
index 0000000..a45c946
--- /dev/null
+++ b/lib/file-util.c
@@ -0,0 +1,73 @@
+/**
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * @file file-util.c
+ * @brief EINTR safe file functions
+ */
+#include "file-util.h"
+
+#include <stdint.h>
+#include <unistd.h>
+#include <errno.h>
+
+/**
+ * INTR safe read
+ * Interface spec is similar to read.
+ */
+ssize_t safe_read(int fd, void *buf, size_t count)
+{
+ ssize_t size = 0,ressize = 0;
+ size_t reqsize = 0;
+ uint8_t *pbuf = NULL;
+
+ pbuf = (uint8_t*)buf;
+ reqsize = count;
+
+ do {
+ size = read(fd, pbuf, (reqsize - ressize));
+ if (size < 0) {
+ if (errno == EINTR) {
+ continue;
+ } else {
+ ressize = size;
+ break;
+ }
+ }
+
+ pbuf += size;
+ ressize += size;
+ } while((ressize < reqsize) && (size != 0));
+
+ return ressize;
+}
+
+/**
+ * INTR safe write
+ * Interface spec is similar to read.
+ */
+ssize_t safe_write(int fd, void *buf, size_t count)
+{
+ ssize_t size = 0,ressize = 0;
+ size_t reqsize = 0;
+ uint8_t *pbuf = NULL;
+
+ pbuf = (uint8_t*)buf;
+ reqsize = count;
+
+ do {
+ size = write(fd, pbuf, (reqsize - ressize));
+ if (size < 0) {
+ if (errno == EINTR) {
+ continue;
+ } else {
+ ressize = size;
+ break;
+ }
+ }
+
+ pbuf += size;
+ ressize += size;
+ } while((ressize < reqsize) && (size != 0));
+
+ return ressize;
+}
diff --git a/lib/file-util.h b/lib/file-util.h
new file mode 100644
index 0000000..d5f7e9c
--- /dev/null
+++ b/lib/file-util.h
@@ -0,0 +1,26 @@
+/**
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * @file file-util.h
+ * @brief file utility functions
+ */
+#ifndef REFOP_FILE_UTIL_H
+#define REFOP_FILE_UTIL_H
+//-----------------------------------------------------------------------------
+#include <unistd.h>
+
+//-----------------------------------------------------------------------------
+#ifdef __cplusplus
+extern "C" {
+#endif
+//-----------------------------------------------------------------------------
+
+ssize_t safe_read(int fd, void *buf, size_t count);
+ssize_t safe_write(int fd, void *buf, size_t count);
+
+//-----------------------------------------------------------------------------
+#ifdef __cplusplus
+}
+#endif
+//-----------------------------------------------------------------------------
+#endif //#ifndef REFOP_FILE_UTIL_H
diff --git a/lib/fileop.c b/lib/fileop.c
new file mode 100644
index 0000000..c246bd7
--- /dev/null
+++ b/lib/fileop.c
@@ -0,0 +1,377 @@
+/**
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * @file fileop.c
+ * @brief file operation functions
+ */
+#include "libredundancyfileop.h"
+#include "fileop.h"
+#include "file-util.h"
+#include "static-configurator.h"
+#include "crc16.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+
+
+int refop_file_get_with_validation(const char *file, uint8_t *data, int64_t bufsize, int64_t *readsize);
+void refop_header_create(s_refop_file_header *head, uint16_t crc16value, uint64_t sizevalue);
+int refop_header_validation(const s_refop_file_header *head);
+int refop_file_test(const char *filename);
+
+/**
+ * Redundancy data write.
+ *
+ * @param [in] event sd event loop handle
+ *
+ * @return refop_error_t
+ * @retval 0 Succeeded.
+ * @retval -1 Abnormal fail. Shall not continue.
+ * @retval -2 Lager than size limit.
+ */
+int refop_new_file_write(refop_handle_t handle, uint8_t *data, int64_t bufsize)
+{
+ struct refop_halndle *hndl = (struct refop_halndle *)handle;
+ int ret = -1, fd = -1;
+ ssize_t wsize = 0;
+ uint8_t *pbuf = NULL, *pdata = NULL;
+ uint16_t crc16value = 0;
+ int new_state = 0;
+
+ if (bufsize > refop_get_config_data_size_limit() || bufsize <= 0)
+ return -2;
+
+ // Fource remove new file - success and noent is ok.
+ ret = unlink(hndl->newfile);
+ if (ret < 0) {
+ if (errno != ENOENT)
+ return -1;
+ }
+
+ // Create write buffer. To reduce sync write operation
+ pbuf = (uint8_t*)malloc(bufsize + sizeof(s_refop_file_header));
+ if (pbuf == NULL)
+ return -1;
+
+ // Create write data
+ pdata = pbuf + sizeof(s_refop_file_header);
+ memcpy(pdata, data, bufsize);
+ crc16value = crc16(0xffff, pdata, bufsize);
+
+ refop_header_create((s_refop_file_header*)pbuf, crc16value, bufsize);
+
+ fd = open(hndl->newfile, (O_CLOEXEC | O_WRONLY | O_CREAT | O_EXCL | O_NOFOLLOW), (S_IRUSR | S_IWUSR));
+ if (fd < 0) {
+ // All open error couldnt recover.
+ free(pbuf);
+ return -1;
+ }
+
+ wsize = safe_write(fd, pbuf, bufsize + sizeof(s_refop_file_header));
+ if (wsize < 0) {
+ // All open error couldnt recover.
+ (void)close(fd);
+ free(pbuf);
+ return -1;
+ }
+
+ // sync and close
+ (void)fsync(fd);
+ (void)close(fd);
+ free(pbuf);
+
+ return 0;
+}
+
+
+/**
+ * Redundancy data write.
+ *
+ * @param [in] event sd event loop handle
+ *
+ * @return refop_error_t
+ * @retval 0 Succeeded.
+ * @retval -1 Abnormal fail. Shall not continue.
+ */
+int refop_file_rotation(refop_handle_t handle)
+{
+ struct refop_halndle *hndl = (struct refop_halndle *)handle;
+ int latest_state = -1, backup_state = -1;
+ int fd = -1;
+
+ //Get all file state
+ latest_state = refop_file_test(hndl->latestfile);
+ backup_state = refop_file_test(hndl->backupfile1);
+
+ if (latest_state == -2 || backup_state == -2)
+ return -1;
+
+ // Operation algorithm
+ // Current Next
+ // | latest | backup | | latest | backup |
+ // a1 | 1 | 2 | | new | 1 |
+ // a2 | 1 | x | | new | 1 |
+ // a3 | x | 2 | | new | 2 |
+ // a4 | x | x | | new | x |
+
+ // All error case of file was checked before this point such as stat check and new file create.
+ if (latest_state == 0) {
+ // a1 or a2
+ if (backup_state == 0) {
+ //a1
+ (void)unlink(hndl->backupfile1);
+ (void)rename(hndl->latestfile, hndl->backupfile1);
+ (void)rename(hndl->newfile, hndl->latestfile);
+ } else {
+ //a2
+ // nop (void)unlink(hndl->backupfile1);
+ (void)rename(hndl->latestfile, hndl->backupfile1);
+ (void)rename(hndl->newfile, hndl->latestfile);
+ }
+ } else {
+ //a3 or a4
+ if (backup_state == 0) {
+ //a3
+ // nop (void)unlink(hndl->backupfile1);
+ // nop (void)rename(hndl->latestfile, hndl->backupfile1);
+ (void)rename(hndl->newfile, hndl->latestfile);
+ } else {
+ //a4
+ // nop (void)unlink(hndl->backupfile1);
+ // nop (void)rename(hndl->latestfile, hndl->backupfile1);
+ (void)rename(hndl->newfile, hndl->latestfile);
+ }
+ }
+
+ // directry sync
+ fd = open(hndl->basedir, (O_CLOEXEC | O_DIRECTORY | O_NOFOLLOW));
+ if (fd >= 0) {
+ (void)fsync(fd);
+ (void)close(fd);
+ }
+
+ return 0;
+}
+
+/**
+ * Redundancy data write.
+ *
+ * @param [in] event sd event loop handle
+ *
+ * @return refop_error_t
+ * @retval 0 Succeeded.
+ * @retval 1 Succeeded with recover.
+ * @retval -1 Abnormal fail. Shall not continue.
+ * @retval -2 No data.
+ * @retval -3 Broaken data.
+ */
+int refop_file_pickup(refop_handle_t handle, uint8_t *data, int64_t bufsize, int64_t *readsize)
+{
+ struct refop_halndle *hndl = (struct refop_halndle *)handle;
+ int ret1 = -1, ret2 = -1;
+ int64_t ressize = 0;
+
+
+ ret1 = refop_file_get_with_validation(hndl->latestfile, data, bufsize, &ressize);
+ if (ret1 == 0) {
+ // got valid data
+ (*readsize) = ressize;
+ return 0;
+ } else if (ret1 < -1) {
+ // latest file was broaken, file remove
+ (void)unlink(hndl->latestfile);
+ }
+
+ ret2 = refop_file_get_with_validation(hndl->backupfile1, data, bufsize, &ressize);
+ if (ret2 == 0) {
+ // got valid data
+ (*readsize) = ressize;
+ return 1;
+ } else if (ret2 < -1) {
+ // latest file was broaken, file remove
+ (void)unlink(hndl->latestfile);
+ }
+
+ if (ret1 == -1 && ret2 == -1)
+ return -2;
+
+ return -3;
+}
+
+/**
+ * Target file status check
+ *
+ * @param [in] filename Target file path
+ *
+ * @return int
+ * @retval 0 Target file is available.
+ * @retval -1 No target file.
+ * @retval -2 Abnormal fail.
+ */
+int refop_file_test(const char *filename)
+{
+ struct stat sb;
+ int ret = -1;
+
+ //Check a directry
+ ret = stat(filename, &sb);
+ if (ret < 0) {
+ if (errno == ENOENT)
+ return -1;
+ else
+ return -2;
+ }
+
+ return 0;
+}
+
+/**
+ * Redundancy data write.
+ *
+ * @param [in] event sd event loop handle
+ *
+ * @return int
+ * @retval 0 succeeded.
+ * @retval -1 No file entry.
+ * @retval -2 Invalid file size.
+ * @retval -3 Invalid header.
+ * @retval -4 Abnomal request size (smaller than real size)
+ * @retval -5 Invalid data.
+ * @retval -6 Abnomal file responce.
+ */
+int refop_file_get_with_validation(const char *file, uint8_t *data, int64_t bufsize, int64_t *readsize)
+{
+ s_refop_file_header head = {0};
+ uint8_t *pbuf = NULL, *pmalloc = NULL;
+ uint16_t crc16value = 0;
+ ssize_t size = 0;
+ int result = -1,ret = -1;
+ int fd = -1;
+
+ fd = open(file, (O_CLOEXEC | O_RDONLY | O_NOFOLLOW));
+ if (fd < 0) {
+ if (errno == ENOENT)
+ return -1;
+ else
+ return -6;
+ }
+
+ size = safe_read(fd, &head, sizeof(head));
+ if (size != sizeof(head)) {
+ ret = -2;
+ goto invalid;
+ }
+
+ result = refop_header_validation(&head);
+ if (result != 0) {
+ ret = -3;
+ goto invalid;
+ }
+
+ if (head.size > bufsize) {
+ if (head.size <= refop_get_config_data_size_limit()) {
+ pmalloc = (uint8_t*)malloc(head.size);
+ pbuf = pmalloc;
+ } else {
+ ret = -4;
+ goto invalid;
+ }
+ } else {
+ pbuf = data;
+ }
+
+ size = safe_read(fd, pbuf, (size_t)head.size);
+ if (size != head.size) {
+ ret = -2;
+ goto invalid;
+ }
+
+ crc16value = crc16(0xffff, pbuf, head.size);
+ if (head.crc16 != crc16value) {
+ ret = -5;
+ goto invalid;
+ }
+
+ if (pmalloc != NULL) {
+ memcpy(data, pmalloc, bufsize);
+ free(pmalloc);
+ pmalloc = NULL;
+ (*readsize) = bufsize;
+ } else
+ (*readsize) = head.size;
+
+ (void)close(fd);
+
+ return 0;
+
+invalid:
+ free(pmalloc); //free is NULL safe
+
+ if (fd != -1)
+ (void)close(fd);
+
+ return ret;
+}
+
+/**
+ * The refop header create
+ *
+ * @param [in] head The memory of file header.
+ * @param [in] crc16value The crc value of data block.
+ * @param [in] sizevalue The size of data block.
+ */
+void refop_header_create(s_refop_file_header *head, uint16_t crc16value, uint64_t sizevalue)
+{
+ head->magic = REFOP_FILE_HEADER_MAGIC;
+
+ head->version = REFOP_FILE_HEADER_VERSION_V1;
+ head->version_inv = ~head->version;
+
+ head->crc16 = crc16value;
+ head->crc16_inv = ~head->crc16;
+
+ head->size = sizevalue;
+ head->size_inv = ~head->size;
+}
+
+/**
+ * The refop header validation
+ *
+ * @param [in] head The memory of file header.
+ *
+ * @return int
+ * @retval 0 succeeded.
+ * @retval -1 Invalid header.
+ */
+int refop_header_validation(const s_refop_file_header *head)
+{
+ int ret = -1;
+
+ //magic check
+ if (head->magic != (uint32_t)REFOP_FILE_HEADER_MAGIC)
+ goto invalid;
+
+ if (head->version == (uint32_t)(~head->version_inv)) {
+ if (head->version != REFOP_FILE_HEADER_VERSION_V1)
+ goto invalid;
+ } else
+ goto invalid;
+
+ if (head->crc16 != (uint16_t)(~head->crc16_inv))
+ goto invalid;
+
+ if (head->size != (uint64_t)(~head->size_inv))
+ goto invalid;
+
+ ret = 0;
+
+invalid:
+ return ret;
+}
diff --git a/lib/fileop.h b/lib/fileop.h
new file mode 100644
index 0000000..d005fd5
--- /dev/null
+++ b/lib/fileop.h
@@ -0,0 +1,53 @@
+/**
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * @file fileop.h
+ * @brief The file operation functions
+ */
+#ifndef REFOP_FILEOP_H
+#define REFOP_FILEOP_H
+//-----------------------------------------------------------------------------
+#include <stdbool.h>
+#include <stdint.h>
+#include <stddef.h>
+#include <linux/limits.h>
+
+//-----------------------------------------------------------------------------
+#ifdef __cplusplus
+extern "C" {
+#endif
+//-----------------------------------------------------------------------------
+struct __attribute__((packed)) s_refop_file_header_v1 {
+ uint32_t magic; /* 4 *//**< Magic code */
+ uint32_t version; /* 8 *//**< Data format version */
+ uint32_t version_inv; /* 12 *//**< Data format version (inversion value) */
+ uint16_t crc16; /* 14 *//**< Data block crc */
+ uint16_t crc16_inv; /* 16 *//**< Data block crc (inversion value) */
+ uint64_t size; /* 24 *//**< Data block size */
+ uint64_t size_inv; /* 32 *//**< Data block size (inversion value) */
+};
+
+#define REFOP_FILE_HEADER_MAGIC ((uint32_t)0x96962323)
+#define REFOP_FILE_HEADER_VERSION_V1 ((uint32_t)0x00000001)
+
+typedef struct s_refop_file_header_v1 s_refop_file_header;
+
+struct refop_halndle {
+ char latestfile[PATH_MAX];
+ char backupfile1[PATH_MAX];
+ char newfile[PATH_MAX];
+ char basedir[PATH_MAX];
+};
+
+//-----------------------------------------------------------------------------
+int refop_new_file_write(refop_handle_t handle, uint8_t *data, int64_t bufsize);
+int refop_file_rotation(refop_handle_t handle);
+
+int refop_file_pickup(refop_handle_t handle, uint8_t *data, int64_t bufsize, int64_t *readsize);
+
+//-----------------------------------------------------------------------------
+#ifdef __cplusplus
+}
+#endif
+//-----------------------------------------------------------------------------
+#endif //#ifndef REFOP_FILEOP_H
diff --git a/lib/libredundancyfileop.c b/lib/libredundancyfileop.c
new file mode 100644
index 0000000..b49f4bd
--- /dev/null
+++ b/lib/libredundancyfileop.c
@@ -0,0 +1,223 @@
+/**
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * @file libredundancyfileop.c
+ * @brief The redundancy file operation library
+ */
+#include "libredundancyfileop.h"
+#include "fileop.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include <stdlib.h>
+#include <string.h>
+
+const char c_bk1_suffix[] = ".bk1";
+const char c_new_suffix[] = ".tmp";
+
+/**
+ * Handle create function of refop.
+ *
+ * @param [out] handle Created refophandle
+ * @param [in] directry Terget directry
+ * @param [in] filename Target file name.
+ *
+ * @return refop_error_t
+ * @retval REFOP_SUCCESS This operation was succeeded.
+ * @retval REFOP_NOENT The target file/directroy was nothing.
+ * @retval REFOP_ARGERROR Argument error.
+ * @retval REFOP_SYSERROR Internal operation was failed such as no memory, no disk space and etc.
+ */
+refop_error_t refop_create_redundancy_handle(refop_handle_t *handle, const char *directry, const char *filename)
+{
+ struct stat sb;
+ struct refop_halndle *hndl = NULL;
+ int ret = -1;
+ size_t dirlen = 0, filelen = 0;
+ refop_error_t refop_error = REFOP_SYSERROR;
+
+ if ((handle == NULL) || (directry == NULL) || (filename == NULL))
+ return REFOP_ARGERROR;
+
+ //Check a directry
+ ret = stat(directry, &sb);
+ if (ret < 0) {
+ if ((errno == EACCES) || (errno == ELOOP) || (errno == ENOENT) || (errno == ENOTDIR))
+ return REFOP_NOENT;
+ else if (errno == ENAMETOOLONG)
+ return REFOP_ARGERROR;
+ else
+ return REFOP_SYSERROR;
+ }
+
+ //Handle memory allocate
+ hndl = (struct refop_halndle*)malloc(sizeof(struct refop_halndle));
+ if (hndl == NULL)
+ return REFOP_SYSERROR;
+ memset(hndl, 0, sizeof(struct refop_halndle));
+
+ //Create file path
+ dirlen = strnlen(directry,PATH_MAX);
+ filelen = strnlen(filename,PATH_MAX);
+ if ((dirlen + filelen + 10 + 1) > PATH_MAX || (dirlen == 0) || (filelen == 0)) { //file suffix = max 10 byte, / = max 1 byte
+ // Path error
+ free(hndl);
+ return REFOP_ARGERROR;
+ }
+
+ // string length was checked, safe.
+ (void)strncpy(hndl->latestfile, directry, PATH_MAX);
+ if (hndl->latestfile[dirlen-1] != '/')
+ (void)strcat(hndl->latestfile, "/");
+
+ (void)strncpy(hndl->basedir, hndl->latestfile, PATH_MAX);
+
+ (void)strcat(hndl->latestfile, filename);
+
+ (void)strncpy(hndl->backupfile1, hndl->latestfile, PATH_MAX);
+ (void)strcat(hndl->backupfile1, c_bk1_suffix);
+
+ (void)strncpy(hndl->newfile, hndl->latestfile, PATH_MAX);
+ (void)strcat(hndl->newfile, c_new_suffix);
+
+ (*handle) = hndl;
+
+ return REFOP_SUCCESS;
+}
+/**
+ * Handle release function of refop.
+ *
+ * @param [in] handle Refop handle
+ *
+ * @return refop_error_t
+ * @retval REFOP_SUCCESS This operation was succeeded.
+ * @retval REFOP_ARGERROR Argument error.
+ */
+refop_error_t refop_release_redundancy_handle(refop_handle_t handle)
+{
+ if (handle == NULL)
+ return REFOP_ARGERROR;
+
+ free(handle);
+
+ return REFOP_SUCCESS;
+}
+
+/**
+ * The data set function of refop.
+ *
+ * @param [in] handle Refop handle
+ * @param [in] data Write data for set data.
+ * @param [in] datasize Write data size (byte).
+ *
+ * @return refop_error_t
+ * @retval REFOP_SUCCESS This operation was succeeded.
+ * @retval REFOP_ARGERROR Argument error.
+ * @retval REFOP_SYSERROR Internal operation was failed such as no memory, no disk space and etc.
+ */
+refop_error_t refop_set_redundancy_data(refop_handle_t handle, uint8_t *data, int64_t datasize)
+{
+ struct refop_halndle *hndl = (struct refop_halndle *)handle;
+ int ret = -1;
+
+ if (handle == NULL || data == NULL || datasize < 0)
+ return REFOP_ARGERROR;
+
+ ret = refop_new_file_write(handle, data, datasize);
+ if (ret < 0) {
+ if (ret == -1)
+ return REFOP_SYSERROR;
+ else
+ return REFOP_ARGERROR;
+ }
+
+ ret = refop_file_rotation(handle);
+ if (ret < 0) {
+ (void)unlink(hndl->newfile);
+ return REFOP_SYSERROR;
+ }
+
+ return REFOP_SUCCESS;
+}
+/**
+ * The data get function of refop.
+ *
+ * @param [in] handle Refop handle
+ * @param [in] data Read buffer for get data.
+ * @param [in] datasize Read buffer size (byte).
+ * @param [out] getsize Readed size (byte).
+ *
+ * @return refop_error_t
+ * @retval REFOP_SUCCESS This operation was succeeded.
+ * @retval REFOP_RECOVER This operation was succeeded within recovery.
+ * @retval REFOP_NOENT The target file/directroy was nothing.
+ * @retval REFOP_BROAKEN This operation was failed. Because all recovery method was failed.
+ * @retval REFOP_ARGERROR Argument error.
+ * @retval REFOP_SYSERROR Internal operation was failed such as no memory, no disk space and etc.
+ */
+
+refop_error_t refop_get_redundancy_data(refop_handle_t handle, uint8_t *data, int64_t datasize, int64_t *getsize)
+{
+ refop_error_t result = REFOP_SYSERROR;
+ int ret = -1;
+
+ if (handle == NULL || data == NULL || datasize < 0 || getsize == NULL)
+ return REFOP_ARGERROR;
+
+ ret = refop_file_pickup(handle, data, datasize, getsize);
+ if (ret == 0)
+ result = REFOP_SUCCESS;
+ else if (ret == 1)
+ result = REFOP_RECOVER;
+ else if (ret == -2)
+ result = REFOP_NOENT;
+ else if (ret == -3)
+ result = REFOP_BROAKEN;
+ else
+ result = REFOP_SYSERROR;
+
+ return result;
+}
+
+/**
+ * The function of refop all file clean.
+ *
+ * @param [in] handle refop handle
+ *
+ * @return refop_error_t
+ * @retval REFOP_SUCCESS This operation was succeeded.
+ * @retval REFOP_ARGERROR Argument error.
+ * @retval REFOP_SYSERROR Internal operation was failed such as no memory, no disk space and etc.
+ */
+refop_error_t refop_remove_redundancy_data(refop_handle_t handle)
+{
+ struct refop_halndle *hndl = (struct refop_halndle *)handle;
+ refop_error_t errorret = REFOP_SUCCESS;
+ int ret = -1;
+
+ if (handle == NULL)
+ return REFOP_ARGERROR;
+
+ ret = unlink(hndl->newfile);
+ if (ret < 0) {
+ if (errno != ENOENT)
+ errorret = REFOP_SYSERROR;
+ }
+
+ ret = unlink(hndl->latestfile);
+ if (ret < 0) {
+ if (errno != ENOENT)
+ errorret = REFOP_SYSERROR;
+ }
+
+ ret = unlink(hndl->backupfile1);
+ if (ret < 0) {
+ if (errno != ENOENT)
+ errorret = REFOP_SYSERROR;
+ }
+
+ return errorret;
+}
diff --git a/lib/libredundancyfileop.sym b/lib/libredundancyfileop.sym
new file mode 100644
index 0000000..81105b1
--- /dev/null
+++ b/lib/libredundancyfileop.sym
@@ -0,0 +1,5 @@
+refop_create_redundancy_handle
+refop_release_redundancy_handle
+refop_set_redundancy_data
+refop_get_redundancy_data
+refop_remove_redundancy_data \ No newline at end of file
diff --git a/lib/static-configurator.c b/lib/static-configurator.c
new file mode 100644
index 0000000..7d60a16
--- /dev/null
+++ b/lib/static-configurator.c
@@ -0,0 +1,21 @@
+/**
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * @file static-configurator.c
+ * @brief static configurator
+ */
+
+#include "static-configurator.h"
+
+
+/** refop static configurator.*/
+
+/**
+ * Getter for the data size limit.
+ *
+ * @return uint64_t Maximum data size.
+ */
+uint64_t refop_get_config_data_size_limit(void)
+{
+ return (1 * 1024 * 1024); // 1 MByte;
+}
diff --git a/lib/static-configurator.h b/lib/static-configurator.h
new file mode 100644
index 0000000..45bf271
--- /dev/null
+++ b/lib/static-configurator.h
@@ -0,0 +1,16 @@
+/**
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * @file static-configurator.h
+ * @brief static configurator header
+ */
+#ifndef STATIC_CONFIGURATOR_H
+#define STATIC_CONFIGURATOR_H
+//-----------------------------------------------------------------------------
+#include <stdint.h>
+
+
+uint64_t refop_get_config_data_size_limit(void);
+
+//-----------------------------------------------------------------------------
+#endif //#ifndef STATIC_CONFIGURATOR_H