diff utils.c @ 0:6ce4443e7545

Add the draft of an API to collect statistics on LXC
author Louis Opter <kalessin@kalessin.fr>
date Wed, 29 Dec 2010 23:28:14 +0100
parents
children 50215911acb3
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/utils.c	Wed Dec 29 23:28:14 2010 +0100
@@ -0,0 +1,100 @@
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+
+#include <assert.h>
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "_lxcstats.h"
+
+char *
+_lxcst_join_path(char *dest, size_t size, const char *left, const char *right)
+{
+    if (*right != '/') {
+        _lxcst_strlcpy(dest, left, size);
+        _lxcst_strlcat(dest, "/", size);
+        _lxcst_strlcat(dest, right, size);
+    } else {
+        _lxcst_strlcpy(dest, right, size);
+    }
+
+    return (dest);
+}
+
+int
+_lxcst_isdir(const struct _lxcst_controller *hdl, const struct dirent *d)
+{
+    struct stat sb;
+    char        buf[PATH_MAX];
+
+    _lxcst_join_path(buf, sizeof(buf), hdl->cgroup_dir, d->d_name);
+
+    if (stat(buf, &sb) == -1) {
+        warn("can't stat file: %s", buf);
+        return (0);
+    }
+
+    return (sb.st_mode & S_IFDIR);
+}
+
+/*
+ * Files under cgroups are virtual and always have a size of zero so we have to
+ * do some reallocs.
+ */
+ssize_t
+_lxcst_read_file(const char *path, char **content)
+{
+    char        buf[1024];
+    int         fd;
+    ssize_t     ret;
+    ssize_t     size;
+    char        *p;
+    int         sverrno;
+
+    assert(path);
+    assert(content);
+
+    *content = NULL;
+    size = 0;
+
+    fd = open(path, O_RDONLY);
+    if (fd != -1) {
+
+        while (1) {
+            ret = read(fd, buf, sizeof(buf));
+            if (ret == -1) {
+                if (errno == EINTR)
+                    continue ;
+                break ;
+            }
+            if (ret == 0)
+                break ;
+
+            p = realloc(*content, size + ret);
+            if (!p)
+                break ;
+
+            *content = p;
+            memcpy(&content[0][size], buf, ret);
+            size += ret;
+        }
+
+        if (*content) {
+            close(fd);
+            return (size);
+        }
+
+        sverrno = errno;
+        close(fd);
+        errno = sverrno;
+    }
+
+    free(*content);
+    return (ret);
+}