cgi-io: use splice() to stream backup archive

This improves the I/O performance when outputting large backups.

Signed-off-by: Jo-Philipp Wich <jo@mein.io>
This commit is contained in:
Jo-Philipp Wich 2019-09-13 09:17:58 +02:00 committed by John Crispin
parent 8c22db6531
commit a8b4a28372
2 changed files with 8 additions and 10 deletions

View file

@ -8,7 +8,7 @@
include $(TOPDIR)/rules.mk include $(TOPDIR)/rules.mk
PKG_NAME:=cgi-io PKG_NAME:=cgi-io
PKG_RELEASE:=11 PKG_RELEASE:=12
PKG_LICENSE:=GPL-2.0-or-later PKG_LICENSE:=GPL-2.0-or-later

View file

@ -16,6 +16,8 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#define _GNU_SOURCE /* splice(), SPLICE_F_MORE */
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdbool.h> #include <stdbool.h>
@ -736,7 +738,6 @@ main_backup(int argc, char **argv)
int len; int len;
int status; int status;
int fds[2]; int fds[2];
char buf[4096];
char datestr[16] = { 0 }; char datestr[16] = { 0 };
char hostname[64] = { 0 }; char hostname[64] = { 0 };
char *fields[] = { "sessionid", NULL }; char *fields[] = { "sessionid", NULL };
@ -768,7 +769,6 @@ main_backup(int argc, char **argv)
return -1; return -1;
default: default:
fcntl(fds[0], F_SETFL, fcntl(fds[0], F_GETFL) | O_NONBLOCK);
now = time(NULL); now = time(NULL);
strftime(datestr, sizeof(datestr) - 1, "%Y-%m-%d", localtime(&now)); strftime(datestr, sizeof(datestr) - 1, "%Y-%m-%d", localtime(&now));
@ -780,15 +780,13 @@ main_backup(int argc, char **argv)
printf("Content-Disposition: attachment; " printf("Content-Disposition: attachment; "
"filename=\"backup-%s-%s.tar.gz\"\r\n\r\n", hostname, datestr); "filename=\"backup-%s-%s.tar.gz\"\r\n\r\n", hostname, datestr);
fflush(stdout);
do { do {
waitpid(pid, &status, 0); len = splice(fds[0], NULL, 1, NULL, 4096, SPLICE_F_MORE);
} while (len > 0);
while ((len = read(fds[0], buf, sizeof(buf))) > 0) { waitpid(pid, &status, 0);
fwrite(buf, len, 1, stdout);
fflush(stdout);
}
} while (!WIFEXITED(status));
close(fds[0]); close(fds[0]);
close(fds[1]); close(fds[1]);