package/uci: prevent writing empty configuration files when disk is full
Signed-off-by: Liangbin Lian <jjm2473@gmail.com> (cherry picked from commit 2408c5fdeead2d77529a6306a5d1b5a6c2fcf663)
This commit is contained in:
parent
cc5541096d
commit
a228b256f7
@ -9,7 +9,7 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=uci
|
||||
PKG_RELEASE:=1
|
||||
PKG_RELEASE:=2
|
||||
|
||||
PKG_SOURCE_URL=$(PROJECT_GIT)/project/uci.git
|
||||
PKG_SOURCE_PROTO:=git
|
||||
|
||||
@ -0,0 +1,97 @@
|
||||
From 237d5542986ddb00733e172e638339544058d2d8 Mon Sep 17 00:00:00 2001
|
||||
From: Liangbin Lian <jjm2473@gmail.com>
|
||||
Date: Thu, 6 Jun 2024 15:42:11 +0800
|
||||
Subject: [PATCH] file: don't save broken uci config
|
||||
|
||||
Signed-off-by: Liangbin Lian <jjm2473@gmail.com>
|
||||
---
|
||||
file.c | 32 +++++++++++++++++++++++---------
|
||||
1 file changed, 23 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/file.c b/file.c
|
||||
index 93abfae..5c942b8 100644
|
||||
--- a/file.c
|
||||
+++ b/file.c
|
||||
@@ -607,7 +607,7 @@ static const char *uci_escape(struct uci_context *ctx, const char *str)
|
||||
/*
|
||||
* export a single config package to a file stream
|
||||
*/
|
||||
-static void uci_export_package(struct uci_package *p, FILE *stream, bool header)
|
||||
+static int uci_export_package(struct uci_package *p, FILE *stream, bool header)
|
||||
{
|
||||
struct uci_context *ctx = p->ctx;
|
||||
struct uci_element *s, *o, *i;
|
||||
@@ -639,7 +639,8 @@ static void uci_export_package(struct uci_package *p, FILE *stream, bool header)
|
||||
}
|
||||
}
|
||||
}
|
||||
- fprintf(stream, "\n");
|
||||
+ /* return last fprintf to check 'No space left on device' error */
|
||||
+ return fprintf(stream, "\n");
|
||||
}
|
||||
|
||||
int uci_export(struct uci_context *ctx, FILE *stream, struct uci_package *package, bool header)
|
||||
@@ -649,11 +650,15 @@ int uci_export(struct uci_context *ctx, FILE *stream, struct uci_package *packag
|
||||
UCI_HANDLE_ERR(ctx);
|
||||
UCI_ASSERT(ctx, stream != NULL);
|
||||
|
||||
- if (package)
|
||||
- uci_export_package(package, stream, header);
|
||||
- else {
|
||||
+ if (package) {
|
||||
+ if (uci_export_package(package, stream, header) < 0) {
|
||||
+ return UCI_ERR_IO;
|
||||
+ }
|
||||
+ } else {
|
||||
uci_foreach_element(&ctx->root, e) {
|
||||
- uci_export_package(uci_to_package(e), stream, header);
|
||||
+ if (uci_export_package(uci_to_package(e), stream, header) < 0) {
|
||||
+ return UCI_ERR_IO;
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -739,6 +744,7 @@ static void uci_file_commit(struct uci_context *ctx, struct uci_package **packag
|
||||
char *filename = NULL;
|
||||
struct stat statbuf;
|
||||
volatile bool do_rename = false;
|
||||
+ volatile bool clean_temp = false;
|
||||
int fd, sz;
|
||||
|
||||
if (!p->path) {
|
||||
@@ -800,14 +806,19 @@ static void uci_file_commit(struct uci_context *ctx, struct uci_package **packag
|
||||
if (!f2)
|
||||
UCI_THROW(ctx, UCI_ERR_IO);
|
||||
|
||||
- uci_export(ctx, f2, p, false);
|
||||
+ clean_temp = true;
|
||||
+ if (uci_export(ctx, f2, p, false))
|
||||
+ goto no_space;
|
||||
|
||||
- fflush(f2);
|
||||
+ if (fflush(f2))
|
||||
+ goto no_space;
|
||||
fsync(fileno(f2));
|
||||
- uci_close_stream(f2);
|
||||
|
||||
do_rename = true;
|
||||
|
||||
+no_space:
|
||||
+ uci_close_stream(f2);
|
||||
+
|
||||
UCI_TRAP_RESTORE(ctx);
|
||||
|
||||
done:
|
||||
@@ -821,6 +832,9 @@ done:
|
||||
UCI_THROW(ctx, UCI_ERR_IO);
|
||||
}
|
||||
free(path);
|
||||
+ } else if (clean_temp) {
|
||||
+ unlink(filename);
|
||||
+ UCI_THROW(ctx, UCI_ERR_IO);
|
||||
}
|
||||
if (ctx->err)
|
||||
UCI_THROW(ctx, ctx->err);
|
||||
--
|
||||
2.41.0
|
||||
|
||||
@ -0,0 +1,46 @@
|
||||
From 17586039934498210dc0a10bbe5a21cc042cdcd2 Mon Sep 17 00:00:00 2001
|
||||
From: Liangbin Lian <jjm2473@gmail.com>
|
||||
Date: Thu, 6 Jun 2024 15:42:46 +0800
|
||||
Subject: [PATCH] file: flush delta only after successful save
|
||||
|
||||
Signed-off-by: Liangbin Lian <jjm2473@gmail.com>
|
||||
---
|
||||
file.c | 15 +++++++++++++--
|
||||
1 file changed, 13 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/file.c b/file.c
|
||||
index 5c942b8..a6f30fe 100644
|
||||
--- a/file.c
|
||||
+++ b/file.c
|
||||
@@ -787,8 +787,8 @@ static void uci_file_commit(struct uci_context *ctx, struct uci_package **packag
|
||||
path = NULL;
|
||||
}
|
||||
|
||||
- /* flush delta */
|
||||
- if (!uci_load_delta(ctx, p, true))
|
||||
+ /* flush delta after successful save */
|
||||
+ if (!uci_load_delta(ctx, p, false))
|
||||
goto done;
|
||||
}
|
||||
|
||||
@@ -830,6 +830,17 @@ done:
|
||||
if (!path || stat(path, &statbuf) || chmod(filename, statbuf.st_mode) || rename(filename, path)) {
|
||||
unlink(filename);
|
||||
UCI_THROW(ctx, UCI_ERR_IO);
|
||||
+ } else if (p->has_delta) {
|
||||
+ /* flush delta */
|
||||
+ filename = NULL;
|
||||
+ if ((asprintf(&filename, "%s/%s", ctx->savedir, p->e.name) < 0) || !filename)
|
||||
+ UCI_THROW(ctx, UCI_ERR_MEM);
|
||||
+ f1 = uci_open_stream(ctx, filename, NULL, SEEK_SET, true, false);
|
||||
+ if (f1) {
|
||||
+ ftruncate(fileno(f1), 0);
|
||||
+ uci_close_stream(f1);
|
||||
+ }
|
||||
+ free(filename);
|
||||
}
|
||||
free(path);
|
||||
} else if (clean_temp) {
|
||||
--
|
||||
2.41.0
|
||||
|
||||
Loading…
Reference in New Issue
Block a user