return 0;
}
+
+void proc_buddyinfo_free(struct buddyinfo *bi) {
+ if (!bi)
+ return;
+
+ free(bi->zone);
+ free(bi);
+}
+
+int proc_get_buddyinfo(const char *zone, struct buddyinfo **bi) {
+ _cleanup_fclose_ FILE *f = NULL;
+ char buf[LINE_MAX];
+
+ assert(zone);
+ assert(bi);
+
+ f = fopen("/proc/buddyinfo", "re");
+ if (!f)
+ return -errno;
+
+ for (;;) {
+ _cleanup_buddyinfo_free_ struct buddyinfo *b = NULL;
+ int n;
+
+ if (!fgets(buf, sizeof(buf), f)) {
+ if (ferror(f))
+ return -errno;
+
+ break;
+ }
+
+ b = new0(struct buddyinfo, 1);
+ if (!b)
+ return -ENOMEM;
+
+ n = sscanf(buf, "Node %d, zone %m[^ ] %d %d %d %d %d %d %d %d %d %d %d",
+ &b->node,
+ &b->zone,
+ &b->page[PAGE_4K],
+ &b->page[PAGE_8K],
+ &b->page[PAGE_16K],
+ &b->page[PAGE_32K],
+ &b->page[PAGE_64K],
+ &b->page[PAGE_128K],
+ &b->page[PAGE_256K],
+ &b->page[PAGE_512K],
+ &b->page[PAGE_1M],
+ &b->page[PAGE_2M],
+ &b->page[PAGE_4M]);
+ if (n != 13)
+ break;
+
+ if (!streq(zone, b->zone))
+ continue;
+
+ *bi = b;
+ b = NULL;
+
+ return 0;
+ }
+
+ return -ENODATA;
+}
int proc_get_meminfo(struct meminfo *mi, enum meminfo_mask mask);
/**
+ * /proc/buddyinfo page index
+ */
+enum {
+ PAGE_4K = 0,
+ PAGE_8K,
+ PAGE_16K,
+ PAGE_32K,
+ PAGE_64K,
+ PAGE_128K,
+ PAGE_256K,
+ PAGE_512K,
+ PAGE_1M,
+ PAGE_2M,
+ PAGE_4M,
+ PAGE_MAX,
+};
+
+/**
+ * A zone buddy info
+ */
+struct buddyinfo {
+ /**
+ * Zone name
+ */
+ char *zone;
+ /**
+ * Node number
+ */
+ int node;
+ /**
+ * Each pages size
+ */
+ int page[PAGE_MAX];
+};
+
+/**
+ * @brief free struct buddyinfo
+ *
+ * @param bi a buddyinfo
+ */
+void proc_buddyinfo_free(struct buddyinfo *bi);
+
+static inline void buddyinfo_freep(struct buddyinfo **bi)
+{
+ proc_buddyinfo_free(*bi);
+}
+
+/**
+ * Declare struct buddyinfo with cleanup attribute. Allocated struct
+ * buddyinfo is destroyed on going out the scope.
+ */
+#define _cleanup_buddyinfo_free_ _cleanup_(buddyinfo_freep)
+
+/**
+ * @brief Parse a zone in /proc/buddyinfo
+ *
+ * @param zone A zone to parse such like "Normal"
+ *
+ * @param bi Allocated and parsed buddyinfo for given zone. This value
+ * has to be destroyed by caller. #_cleanup_buddyinfo_free_ is useful
+ * to make autofree this value.
+ *
+ * @return 0 on success, -errno on failure.
+ */
+int proc_get_buddyinfo(const char *zone, struct buddyinfo **bi);
+
+/**
* @}
*/