[libvirt] [PATCH 3/4] util: introduce new helpers to manage shmem device

Luyao Huang lhuang at redhat.com
Thu Jul 23 10:13:48 UTC 2015


Signed-off-by: Luyao Huang <lhuang at redhat.com>
---
 configure.ac             |  10 +
 po/POTFILES.in           |   3 +-
 src/Makefile.am          |   5 +-
 src/libvirt_private.syms |  16 ++
 src/util/virshm.c        | 623 +++++++++++++++++++++++++++++++++++++++++++++++
 src/util/virshm.h        | 104 ++++++++
 6 files changed, 759 insertions(+), 2 deletions(-)
 create mode 100644 src/util/virshm.c
 create mode 100644 src/util/virshm.h

diff --git a/configure.ac b/configure.ac
index a7f38e8..940eb66 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1176,6 +1176,16 @@ if test "$with_linux" = "yes"; then
       ]])
 fi
 
+dnl
+dnl check for POSIX share memory functions
+dnl
+LIBRT_LIBS=""
+AC_CHECK_LIB([rt],[shm_open],[LIBRT_LIBS="-lrt"])
+old_libs="$LIBS"
+LIBS="$old_libs $LIBRT_LIBS"
+AC_CHECK_FUNCS([shm_open])
+LIBS="$old_libs"
+AC_SUBST([LIBRT_LIBS])
 
 dnl Need to test if pkg-config exists
 PKG_PROG_PKG_CONFIG
diff --git a/po/POTFILES.in b/po/POTFILES.in
index a75f5ae..7687a82 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -215,8 +215,9 @@ src/util/virpolkit.c
 src/util/virportallocator.c
 src/util/virprocess.c
 src/util/virrandom.c
-src/util/virsexpr.c
 src/util/virscsi.c
+src/util/virsexpr.c
+src/util/virshm.c
 src/util/virsocketaddr.c
 src/util/virstats.c
 src/util/virstorageencryption.c
diff --git a/src/Makefile.am b/src/Makefile.am
index 7338ab9..048a096 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -152,6 +152,7 @@ UTIL_SOURCES =							\
 		util/virscsi.c util/virscsi.h			\
 		util/virseclabel.c util/virseclabel.h		\
 		util/virsexpr.c util/virsexpr.h			\
+		util/virshm.c util/virshm.h			\
 		util/virsocketaddr.h util/virsocketaddr.c	\
 		util/virstats.c util/virstats.h	\
 		util/virstorageencryption.c util/virstorageencryption.h \
@@ -1048,7 +1049,7 @@ libvirt_util_la_LIBADD = $(CAPNG_LIBS) $(YAJL_LIBS) $(LIBNL_LIBS) \
 		$(THREAD_LIBS) $(AUDIT_LIBS) $(DEVMAPPER_LIBS) \
 		$(LIB_CLOCK_GETTIME) $(DBUS_LIBS) $(MSCOM_LIBS) $(LIBXML_LIBS) \
 		$(SECDRIVER_LIBS) $(NUMACTL_LIBS) $(SYSTEMD_DAEMON_LIBS) \
-		$(POLKIT_LIBS)
+		$(POLKIT_LIBS) $(LIBRT_LIBS)
 
 
 noinst_LTLIBRARIES += libvirt_conf.la
@@ -1284,6 +1285,7 @@ libvirt_driver_qemu_impl_la_LIBADD = $(CAPNG_LIBS) \
                                 $(GNUTLS_LIBS) \
 				$(LIBNL_LIBS) \
 				$(LIBXML_LIBS) \
+                                $(LIBRT_LIBS) \
 				$(NULL)
 libvirt_driver_qemu_impl_la_SOURCES = $(QEMU_DRIVER_SOURCES)
 
@@ -2264,6 +2266,7 @@ libvirt_setuid_rpc_client_la_LDFLAGS =		\
 		$(AM_LDFLAGS)			\
 		$(LIBXML_LIBS)			\
 		$(SECDRIVER_LIBS)		\
+                $(LIBRT_LIBS)                   \
 		$(NULL)
 libvirt_setuid_rpc_client_la_CFLAGS =		\
 		-DLIBVIRT_SETUID_RPC_CLIENT	\
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index af73177..977fd34 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2078,6 +2078,22 @@ sexpr_u64;
 string2sexpr;
 
 
+# util/virshm.h
+virShmBuildPath;
+virShmCreate;
+virShmObjectFree;
+virShmObjectNew;
+virShmObjectListAdd;
+virShmObjectListDel;
+virShmObjectFindByName;
+virShmObjectListGetDefault;
+virShmObjectRemoveStateFile;
+virShmObjectSaveState;
+virShmOpen;
+virShmRemoveUsedDomain;
+virShmSetUsedDomain;
+virShmUnlink;
+
 # util/virsocketaddr.h
 virSocketAddrBroadcast;
 virSocketAddrBroadcastByPrefix;
diff --git a/src/util/virshm.c b/src/util/virshm.c
new file mode 100644
index 0000000..7ab39be
--- /dev/null
+++ b/src/util/virshm.c
@@ -0,0 +1,623 @@
+/*
+ * virshm.c: helper API for POSIX share memory
+ *
+ * Copyright (C) 2015 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <config.h>
+
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#ifdef HAVE_SHM_OPEN
+# include <sys/mman.h>
+#endif
+
+#include "virshm.h"
+#include "virxml.h"
+#include "virbuffer.h"
+#include "virerror.h"
+#include "virstring.h"
+#include "virlog.h"
+#include "virutil.h"
+#include "viralloc.h"
+#include "virfile.h"
+#include "configmake.h"
+
+#define VIR_FROM_THIS VIR_FROM_NONE
+
+VIR_LOG_INIT("util.shm");
+
+#define SHMEM_STATE_DIR LOCALSTATEDIR "/run/libvirt/shmem"
+
+VIR_ENUM_IMPL(virShmObject, VIR_SHM_TYPE_LAST,
+              "shm",
+              "server");
+
+static virClassPtr virShmObjectListClass;
+
+static virShmObjectListPtr mainlist; /* global shm object list */
+
+static void virShmObjectListDispose(void *obj);
+
+static int
+virShmObjectListLoadState(virShmObjectPtr *shmobj,
+                          const char *stateDir,
+                          const char *name)
+{
+    char *stateFile = NULL;
+    xmlXPathContextPtr ctxt = NULL;
+    xmlDocPtr xml = NULL;
+    virShmObjectPtr tmpshm;
+    xmlNodePtr *usagenode = NULL;
+    xmlNodePtr save = NULL;
+    int ret = -1;
+    char *drivername = NULL;
+    char *shmtype = NULL;
+    int nusages;
+
+    if (VIR_ALLOC(tmpshm) < 0)
+        return -1;
+
+    if (!(stateFile = virFileBuildPath(stateDir, name, ".xml")))
+        goto error;
+
+    if (!(xml = virXMLParseFileCtxt(stateFile, &ctxt)))
+        goto error;
+
+    tmpshm->name = virXPathString("string(./name)", ctxt);
+    if (!tmpshm->name) {
+        virReportError(VIR_ERR_XML_ERROR, "%s",
+                       _("shmem missing name attribute"));
+        goto error;
+    }
+
+    shmtype = virXPathString("string(./type)", ctxt);
+    if (!shmtype) {
+        virReportError(VIR_ERR_XML_ERROR, "%s",
+                       _("shmem missing type attribute"));
+        goto error;
+    }
+    if ((tmpshm->type = virShmObjectTypeFromString(shmtype)) < 0) {
+        virReportError(VIR_ERR_XML_ERROR,
+                       _("invalid shmem object type %s"), shmtype);
+        goto error;
+    }
+
+    if (virXPathULongLong("string(./size)", ctxt, &tmpshm->size) < 0) {
+        virReportError(VIR_ERR_XML_ERROR, "%s",
+                       _("shmem missing or have invalid size attribute"));
+        goto error;
+    }
+
+    tmpshm->path = virXPathString("string(./path)", ctxt);
+    if (virXPathBoolean("boolean(./othercreate)", ctxt))
+        tmpshm->othercreate = true;
+
+    if (!(drivername = virXPathString("string(./@driver)", ctxt))) {
+        virReportError(VIR_ERR_XML_ERROR, "%s",
+                       _("shmem usage element missing driver attribute"));
+        goto error;
+    }
+    nusages = virXPathNodeSet("./domain", ctxt, &usagenode);
+    if (nusages < 0)
+        goto error;
+
+    if (nusages > 0) {
+        size_t i;
+
+        for (i = 0; i < nusages; i++) {
+            char *domainname;
+
+            save = ctxt->node;
+            ctxt->node = usagenode[i];
+
+            if (!(domainname = virXPathString("string(./@name)", ctxt))) {
+                virReportError(VIR_ERR_XML_ERROR, "%s",
+                               _("shmem domain element missing name attribute"));
+                goto error;
+            }
+
+            if (virShmSetUsedDomain(tmpshm, drivername, domainname) < 0) {
+                VIR_FREE(domainname);
+                goto error;
+            }
+            VIR_FREE(domainname);
+            ctxt->node = save;
+        }
+    }
+    *shmobj = tmpshm;
+    ret = 0;
+ cleanup:
+    VIR_FREE(stateFile);
+    VIR_FREE(drivername);
+    VIR_FREE(shmtype);
+    xmlFreeDoc(xml);
+    xmlXPathFreeContext(ctxt);
+    return ret;
+
+ error:
+    virShmObjectFree(tmpshm);
+    goto cleanup;
+}
+
+static int
+virShmObjectListLoadAllState(virShmObjectListPtr list)
+{
+    DIR *dir;
+    struct dirent *entry;
+
+    if (!(dir = opendir(list->stateDir))) {
+        if (errno == ENOENT)
+            return 0;
+        virReportSystemError(errno, _("Failed to open dir '%s'"), list->stateDir);
+        return -1;
+    }
+
+    while (virDirRead(dir, &entry, list->stateDir) > 0) {
+        virShmObjectPtr shmobj;
+
+        if (entry->d_name[0] == '.' ||
+            !virFileStripSuffix(entry->d_name, ".xml"))
+            continue;
+        if (virShmObjectListLoadState(&shmobj, list->stateDir, entry->d_name) < 0)
+            continue;
+        if (virShmObjectListAdd(list, shmobj) < 0)
+            continue;
+    }
+    closedir(dir);
+    return 0;
+}
+
+static virShmObjectListPtr
+virShmObjectListNew(void)
+{
+    virShmObjectListPtr list;
+    bool privileged = geteuid() == 0;
+
+    if (!(list = virObjectLockableNew(virShmObjectListClass)))
+        return NULL;
+
+    virObjectLock(list);
+    if (privileged) {
+        if (VIR_STRDUP(list->stateDir, SHMEM_STATE_DIR) < 0)
+            goto error;
+    } else {
+        char *rundir = NULL;
+
+        if (!(rundir = virGetUserRuntimeDirectory()))
+            goto error;
+
+        if (virAsprintf(&list->stateDir, "%s/shmem", rundir) < 0) {
+            VIR_FREE(rundir);
+            goto error;
+        }
+        VIR_FREE(rundir);
+    }
+    if (virFileMakePath(list->stateDir) < 0) {
+        virReportError(VIR_ERR_OPERATION_FAILED,
+                       _("Failed to create state dir '%s'"),
+                       list->stateDir);
+        goto error;
+    }
+    if (virShmObjectListLoadAllState(list) < 0)
+        goto error;
+
+    virObjectUnlock(list);
+    return list;
+
+ error:
+    virObjectUnlock(list);
+    virObjectUnref(list);
+    return NULL;
+}
+
+static int
+virShmOnceInit(void)
+{
+    if (!(virShmObjectListClass = virClassNew(virClassForObjectLockable(),
+                                              "virShmObjectList",
+                                              sizeof(virShmObjectList),
+                                              virShmObjectListDispose)))
+        return -1;
+
+    if (!(mainlist = virShmObjectListNew()))
+        return -1;
+
+    return 0;
+}
+
+VIR_ONCE_GLOBAL_INIT(virShm)
+
+virShmObjectListPtr
+virShmObjectListGetDefault(void)
+{
+    if (virShmInitialize() < 0)
+        return NULL;
+
+    return virObjectRef(mainlist);
+}
+
+int
+virShmSetUsedDomain(virShmObjectPtr shmobj,
+                    const char *drvname,
+                    const char *domname)
+{
+    char *tmpdomain = NULL;
+
+    if (shmobj->drvname) {
+        if (STRNEQ(drvname, shmobj->drvname)) {
+            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                           _("cannot use one shmem for different driver"));
+            goto error;
+        }
+    } else {
+        if (VIR_STRDUP(shmobj->drvname, drvname) < 0)
+            goto error;
+    }
+
+    if (VIR_STRDUP(tmpdomain, domname) < 0)
+        goto error;
+
+    if (VIR_APPEND_ELEMENT(shmobj->domains, shmobj->ndomains, tmpdomain) < 0)
+        goto error;
+
+    return 0;
+
+ error:
+    VIR_FREE(tmpdomain);
+    return -1;
+}
+
+void
+virShmObjectFree(virShmObjectPtr shmobj)
+{
+    size_t i;
+
+    if (!shmobj)
+        return;
+
+    VIR_FREE(shmobj->name);
+    VIR_FREE(shmobj->path);
+    VIR_FREE(shmobj->drvname);
+    for (i = 0; i < shmobj->ndomains; i++)
+        VIR_FREE(shmobj->domains[i]);
+    VIR_FREE(shmobj->domains);
+    VIR_FREE(shmobj);
+}
+
+virShmObjectPtr
+virShmObjectNew(const char *name,
+                unsigned long long size,
+                const char *path,
+                int type,
+                bool othercreate,
+                const char *drvname,
+                const char *domname)
+{
+    virShmObjectPtr shmobj;
+
+    if (VIR_ALLOC(shmobj) < 0)
+        return NULL;
+
+    shmobj->size = size;
+    shmobj->type = type;
+
+    if (VIR_STRDUP(shmobj->name, name) < 0)
+        goto error;
+
+    if (path) {
+        if (VIR_STRDUP(shmobj->path, path) < 0)
+            goto error;
+    } else {
+        VIR_FREE(shmobj->path);
+    }
+    shmobj->othercreate = othercreate;
+
+    if (virShmSetUsedDomain(shmobj, drvname, domname) < 0)
+        goto error;
+
+    return shmobj;
+
+ error:
+    virShmObjectFree(shmobj);
+    return NULL;
+}
+
+static void
+virShmObjectListDispose(void *obj)
+{
+    virShmObjectListPtr list = obj;
+    size_t i;
+
+    for (i = 0; i < list->nshmobjs; i++)
+        virShmObjectFree(list->shmobjs[i]);
+
+    VIR_FREE(list->shmobjs);
+}
+
+int
+virShmObjectSaveState(virShmObjectPtr shmobj,
+                      const char *stateDir)
+{
+    virBuffer buf = VIR_BUFFER_INITIALIZER;
+    int ret = -1;
+    size_t i;
+    char *xml = NULL;
+    char *stateFile = NULL;
+
+    virBufferAddLit(&buf, "<shmem>\n");
+    virBufferAdjustIndent(&buf, 2);
+
+    virBufferAsprintf(&buf, "<name>%s</name>\n", shmobj->name);
+
+    virBufferAsprintf(&buf, "<type>%s</type>\n", virShmObjectTypeToString(shmobj->type));
+
+    virBufferAsprintf(&buf, "<size>%llu</size>\n", shmobj->size);
+    if (shmobj->path)
+        virBufferAsprintf(&buf, "<path>%s</path>\n", shmobj->path);
+    if (shmobj->othercreate)
+        virBufferAddLit(&buf, "<othercreate/>\n");
+    virBufferAsprintf(&buf, "<driver>%s</driver>\n", shmobj->drvname);
+    for (i = 0; i < shmobj->ndomains; i++)
+        virBufferAsprintf(&buf, "<domain name='%s'/>\n", shmobj->domains[i]);
+
+    virBufferAdjustIndent(&buf, -2);
+    virBufferAddLit(&buf, "</shmem>\n");
+
+    if (virBufferCheckError(&buf) < 0)
+        goto cleanup;
+
+    if (!(xml = virBufferContentAndReset(&buf)))
+        goto cleanup;
+
+    if (!(stateFile = virFileBuildPath(stateDir, shmobj->name, ".xml")))
+        goto cleanup;
+
+    if (virXMLSaveFile(stateFile, NULL, NULL, xml) < 0)
+        goto cleanup;
+
+    ret = 0;
+
+ cleanup:
+    VIR_FREE(stateFile);
+    VIR_FREE(xml);
+    return ret;
+}
+
+int
+virShmRemoveUsedDomain(virShmObjectPtr shmobj,
+                       const char *drvname,
+                       const char *domname)
+{
+    size_t i;
+
+    if (shmobj->drvname) {
+        if (STRNEQ(drvname, shmobj->drvname)) {
+            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                           _("cannot use one shmem for different driver"));
+            return -1;
+        }
+    } else {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("cannot get shmem object driver name"));
+        return -1;
+    }
+
+    for (i = 0; i < shmobj->ndomains; i++) {
+        if (STREQ(shmobj->domains[i], domname)) {
+            VIR_FREE(shmobj->domains[i]);
+            VIR_DELETE_ELEMENT(shmobj->domains, i, shmobj->ndomains);
+            return 0;
+        }
+    }
+
+    virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                   _("cannot find domname in shmem object domain list"));
+    return -1;
+}
+
+int
+virShmObjectRemoveStateFile(virShmObjectListPtr list,
+                                const char *name)
+{
+    char *stateFile = NULL;
+
+    if (!(stateFile = virFileBuildPath(list->stateDir, name, ".xml")))
+         return -1;
+    unlink(stateFile);
+    VIR_FREE(stateFile);
+    return 0;
+}
+
+int
+virShmObjectListDel(virShmObjectListPtr list,
+                    virShmObjectPtr shmobj)
+{
+    size_t i;
+
+    for (i = 0; i < list->nshmobjs; i++) {
+        virShmObjectPtr tmp = list->shmobjs[i];
+
+        if (STREQ(tmp->name, shmobj->name)) {
+            VIR_DELETE_ELEMENT(list->shmobjs, i, list->nshmobjs);
+            return 0;
+        }
+    }
+    return -1;
+}
+
+virShmObjectPtr
+virShmObjectFindByName(virShmObjectListPtr list,
+                       const char *name)
+{
+    size_t i;
+
+    for (i = 0; i < list->nshmobjs; i++) {
+        if (STREQ_NULLABLE(list->shmobjs[i]->name, name))
+            return list->shmobjs[i];
+    }
+
+    return NULL;
+}
+
+int
+virShmObjectListAdd(virShmObjectListPtr list,
+                    virShmObjectPtr shmobj)
+{
+    if (virShmObjectFindByName(list, shmobj->name)) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("A share memory object named '%s' already exists"),
+                       shmobj->name);
+        return -1;
+    }
+
+    return VIR_APPEND_ELEMENT(list->shmobjs, list->nshmobjs, shmobj);
+}
+
+#ifdef HAVE_SHM_OPEN
+int
+virShmOpen(const char *name,
+           unsigned long long size,
+           mode_t mode)
+{
+    int fd = -1;
+    struct stat sb;
+
+    if ((fd = shm_open(name, O_RDWR, mode)) < 0) {
+        virReportSystemError(errno,
+                             _("Unable to open shared memory"
+                               " objects '%s'"),
+                             name);
+        return -1;
+    }
+
+    if (fstat(fd, &sb) < 0) {
+        virReportSystemError(errno,
+                             _("cannot stat file '%s'"), name);
+        goto error;
+    }
+
+    if (sb.st_size < size) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("already exist shared memory object"
+                         " size %ju is smaller than required size %llu"),
+                       (uintmax_t)sb.st_size, size);
+        goto error;
+    }
+
+    return fd;
+
+ error:
+    VIR_FORCE_CLOSE(fd);
+    return -1;
+}
+
+int
+virShmCreate(const char *name,
+             unsigned long long size,
+             bool outerr,
+             bool *othercreate,
+             mode_t mode)
+{
+    int fd = -1;
+
+    fd = shm_open(name, O_RDWR|O_CREAT|O_EXCL, mode);
+
+    if (fd > 0) {
+        if (ftruncate(fd, size) != 0) {
+            virReportSystemError(errno,
+                                 _("Unable to truncate"
+                                   " file descriptor to %llu"),
+                                 size);
+            ignore_value(shm_unlink(name));
+            VIR_FORCE_CLOSE(fd);
+            return -1;
+        }
+    } else if (errno == EEXIST) {
+        if (outerr) {
+            virReportSystemError(errno,
+                                 _("shared memory objects"
+                                   " '%s' is already exist"),
+                                 name);
+            return -1;
+        }
+
+        VIR_WARN("shared memory objects '%s' is already exist", name);
+        *othercreate = true;
+
+        return virShmOpen(name, size, mode);
+    } else {
+        virReportSystemError(errno,
+                             _("Unable to create shared memory"
+                               " objects '%s'"),
+                             name);
+        return -1;
+    }
+
+    return fd;
+}
+
+int
+virShmUnlink(const char *name)
+{
+    int ret;
+
+    if ((ret = shm_unlink(name)) < 0) {
+        virReportSystemError(errno,
+                             _("Unable to delete shared memory"
+                               " objects '%s'"),
+                             name);
+    }
+    return ret;
+}
+
+# if defined(__linux__)
+# define SHM_DEFAULT_PATH "/dev/shm"
+
+int
+virShmBuildPath(const char *name, char **path)
+{
+
+    if (virAsprintf(path, "%s/%s", SHM_DEFAULT_PATH, name) < 0)
+        return -1;
+
+    if (!virFileExists(*path)) {
+        virReportSystemError(errno,
+                             _("could not access %s"),
+                             *path);
+        VIR_FREE(*path);
+        return -1;
+    }
+    return 0;
+}
+
+# else
+
+int
+virShmBuildPath(const char *name ATTRIBUTE_UNUSED,
+                char **path ATTRIBUTE_UNUSED)
+{
+    virReportSystemError(ENOSYS, "%s",
+                         _("Cannot get share memory object path on this platform"));
+    return -2;
+}
+
+# endif
+#endif /* HAVE_SHM_OPEN */
diff --git a/src/util/virshm.h b/src/util/virshm.h
new file mode 100644
index 0000000..945a541
--- /dev/null
+++ b/src/util/virshm.h
@@ -0,0 +1,104 @@
+/*
+ * virshm.h: helper API for POSIX share memory
+ *
+ * Copyright (C) 2015 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef __VIR_SHM_H__
+# define __VIR_SHM_H__
+
+# include "internal.h"
+# include "virutil.h"
+# include "virobject.h"
+
+typedef enum {
+    VIR_SHM_TYPE_SHM = 0,
+    VIR_SHM_TYPE_SERVER,
+
+    VIR_SHM_TYPE_LAST
+} virShmObjectType;
+
+typedef struct _virShmObject virShmObject;
+typedef  virShmObject *virShmObjectPtr;
+struct _virShmObject {
+    char *name;                   /* shmem object name */
+    int type;                     /* shmem object type */
+    unsigned long long size;      /* size of shmem object */
+    char *path;                   /* shmem path */
+    bool othercreate;             /* a bool parameter record if the shm is created by libvirt */
+
+    char *drvname;                /* which driver */
+    char **domains;               /* domain(s) using this shm */
+    size_t ndomains;              /* number of useds */
+};
+
+VIR_ENUM_DECL(virShmObject);
+
+typedef struct _virShmObjectList virShmObjectList;
+typedef virShmObjectList *virShmObjectListPtr;
+struct _virShmObjectList {
+    virObjectLockable parent;
+    char *stateDir;
+    size_t nshmobjs;
+    virShmObjectPtr *shmobjs;
+};
+
+virShmObjectListPtr virShmObjectListGetDefault(void);
+
+int virShmSetUsedDomain(virShmObjectPtr shmobj, const char *drvname, const char *domname)
+                    ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3);
+int virShmRemoveUsedDomain(virShmObjectPtr shmobj, const char *drvname, const char *domname)
+                    ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3);
+void virShmObjectFree(virShmObjectPtr shmobj);
+virShmObjectPtr virShmObjectNew(const char *name, unsigned long long size,
+                                const char *path, int type, bool othercreate,
+                                const char *drvname, const char *domname)
+                                ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(6)
+                                ATTRIBUTE_NONNULL(7);
+int virShmObjectSaveState(virShmObjectPtr shmobj, const char *stateDir)
+                                ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
+int virShmObjectRemoveStateFile(virShmObjectListPtr list, const char *name)
+                                ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
+int virShmObjectListAdd(virShmObjectListPtr list, virShmObjectPtr shmobj)
+                                ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
+int virShmObjectListDel(virShmObjectListPtr list, virShmObjectPtr shmobj)
+                                ATTRIBUTE_NONNULL(1);
+virShmObjectPtr virShmObjectFindByName(virShmObjectListPtr list,
+                                       const char *name)
+                                ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
+
+# ifdef HAVE_SHM_OPEN
+int virShmCreate(const char *name, unsigned long long size,
+                 bool outerr, bool *othercreate, mode_t mode)
+                 ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(4);
+int virShmOpen(const char *name,
+               unsigned long long size,
+               mode_t mode)
+                 ATTRIBUTE_NONNULL(1);
+int virShmUnlink(const char *name)
+                 ATTRIBUTE_NONNULL(1);
+int virShmBuildPath(const char *name, char **path)
+                 ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
+# else /* HAVE_SHM_OPEN  */
+# define virShmCreate(name, size, outerr, othercreate, mode) -2
+# define virShmOpen(name, size, mode) -2
+# define virShmUnlink(name) -2
+# define virShmBuildPath(name, path) -2
+
+# endif /* HAVE_SHM_OPEN */
+#endif /* __VIR_SHM_H__ */
-- 
1.8.3.1




More information about the libvir-list mailing list