72 lines
2.3 KiB
Diff
72 lines
2.3 KiB
Diff
From 01b8e557ce129b2f4677061ba04bbb5ff2a703eb Mon Sep 17 00:00:00 2001
|
|
From: "Richard W.M. Jones" <rjones@redhat.com>
|
|
Date: Mon, 27 Oct 2025 09:15:47 +0000
|
|
Subject: [PATCH] linuxdisk: Fix parsing of last line of 'du' command output
|
|
|
|
A recent change to glibc breaks this code. Previously we could read
|
|
the lines of output from the 'du' command until getline(3) returned
|
|
EOF, and the 'line' buffer would contain the last line read. However
|
|
after this change, glibc now sets line[0] = '\0' in the EOF case,
|
|
breaking the last line of output that we wanted to parse.
|
|
|
|
https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=33eff78c8b28adc4963987880e10d96761f2a167
|
|
|
|
We also previously didn't handle the unlikely case where 'du' produces
|
|
no output at all. Fix both problems here.
|
|
---
|
|
plugins/linuxdisk/filesystem.c | 23 ++++++++++++++++++-----
|
|
1 file changed, 18 insertions(+), 5 deletions(-)
|
|
|
|
diff --git a/plugins/linuxdisk/filesystem.c b/plugins/linuxdisk/filesystem.c
|
|
index 3e4e2f3a..283af61a 100644
|
|
--- a/plugins/linuxdisk/filesystem.c
|
|
+++ b/plugins/linuxdisk/filesystem.c
|
|
@@ -148,7 +148,7 @@ create_filesystem (struct virtual_disk *disk)
|
|
static int64_t
|
|
estimate_size (void)
|
|
{
|
|
- CLEANUP_FREE char *command = NULL, *line = NULL;
|
|
+ CLEANUP_FREE char *command = NULL, *line = NULL, *lastline = NULL;
|
|
size_t len = 0;
|
|
FILE *fp;
|
|
int64_t ret;
|
|
@@ -177,8 +177,16 @@ estimate_size (void)
|
|
|
|
/* Ignore everything up to the last line. */
|
|
len = 0;
|
|
- while (getline (&line, &len, fp) != -1)
|
|
- /* empty */;
|
|
+ while (getline (&line, &len, fp) != -1) {
|
|
+ nbdkit_debug ("du: %s", line);
|
|
+ free (lastline);
|
|
+ lastline = strndup (line, len);
|
|
+ if (lastline == NULL) {
|
|
+ nbdkit_error ("strndup: %m");
|
|
+ pclose (fp);
|
|
+ return -1;
|
|
+ }
|
|
+ }
|
|
if (ferror (fp)) {
|
|
nbdkit_error ("getline failed: %m");
|
|
pclose (fp);
|
|
@@ -193,9 +201,14 @@ estimate_size (void)
|
|
if (exit_status_to_nbd_error (r, "pclose: du") == -1)
|
|
return -1;
|
|
|
|
+ if (lastline == NULL) {
|
|
+ nbdkit_error ("no output from du command");
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
/* Parse the last line. */
|
|
- if (sscanf (line, "%" SCNi64, &ret) != 1 || ret < 0) {
|
|
- nbdkit_error ("could not parse last line of output: %s", line);
|
|
+ if (sscanf (lastline, "%" SCNi64, &ret) != 1 || ret < 0) {
|
|
+ nbdkit_error ("could not parse last line from du command: %s", lastline);
|
|
return -1;
|
|
}
|
|
|
|
--
|
|
2.47.3
|
|
|