]> xenbits.xensource.com Git - libvirt.git/commitdiff
lxcProcReadMeminfo: Fix case when @offset != 0
authorMichal Privoznik <mprivozn@redhat.com>
Mon, 28 Feb 2022 15:30:08 +0000 (16:30 +0100)
committerMichal Privoznik <mprivozn@redhat.com>
Mon, 7 Mar 2022 13:01:48 +0000 (14:01 +0100)
The idea behind lxcProcReadMeminfo() is that we read the host's
/proc/meminfo and copy it line by line producing the content for
container, changing only those lines we need. Thus, when a
process inside container opens the file and lseek()-s to a
different position (or reads the content in small chunks), we
mirror the seek in host's /proc/meminfo. But this doesn't work
really. We are not guaranteed to end up aligned on the beginning
of new line. It's better if we construct the new content and then
mimic seeking in it.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
src/lxc/lxc_fuse.c

index 537e16c380ee306c281f3eb8f22f6d77ba3b0658..b068d21cf4f090713cf0379d2a853c73b4a7b4a9 100644 (file)
@@ -152,6 +152,7 @@ lxcProcReadMeminfo(char *hostpath,
     size_t n;
     struct virLXCMeminfo meminfo;
     g_auto(virBuffer) buffer = VIR_BUFFER_INITIALIZER;
+    const char *new_meminfo = NULL;
 
     if (virLXCCgroupGetMeminfo(&meminfo) < 0) {
         virErrorSetErrnoFromLastError();
@@ -164,11 +165,6 @@ lxcProcReadMeminfo(char *hostpath,
         return -errno;
     }
 
-    if (fseek(fp, offset, SEEK_SET) < 0) {
-        virReportSystemError(errno, "%s", _("fseek failed"));
-        return -errno;
-    }
-
     res = -1;
     while (getline(&line, &n, fp) > 0) {
         char *ptr = strchr(line, ':');
@@ -241,10 +237,18 @@ lxcProcReadMeminfo(char *hostpath,
         }
 
     }
-    res = strlen(virBufferCurrentContent(&buffer));
+
+    new_meminfo = virBufferCurrentContent(&buffer);
+    res = virBufferUse(&buffer);
+
+    if (offset > res)
+        return 0;
+
+    res -= offset;
+
     if (res > size)
         res = size;
-    memcpy(buf, virBufferCurrentContent(&buffer), res);
+    memcpy(buf, new_meminfo + offset, res);
 
     return res;
 }