/* * admin_remote.c * * 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 * . * * Author: Erik Skultety */ #include #include #include "admin_protocol.h" typedef struct _remoteAdminPriv remoteAdminPriv; typedef remoteAdminPriv *remoteAdminPrivPtr; struct _remoteAdminPriv { virObjectLockable parent; int counter; virNetClientPtr client; virNetClientProgramPtr program; }; static virClassPtr remoteAdminPrivClass; static void remoteAdminPrivDispose(void *opaque) { remoteAdminPrivPtr priv = opaque; virObjectUnref(priv->program); virObjectUnref(priv->client); } static int callFull(virAdmConnectPtr conn ATTRIBUTE_UNUSED, remoteAdminPrivPtr priv, int *fdin, size_t fdinlen, int **fdout, size_t *fdoutlen, int proc_nr, xdrproc_t args_filter, char *args, xdrproc_t ret_filter, char *ret) { int rv; virNetClientProgramPtr prog = priv->program; int counter = priv->counter++; virNetClientPtr client = priv->client; /* Unlock, so that if we get any async events/stream data * while processing the RPC, we don't deadlock when our * callbacks for those are invoked */ virObjectRef(priv); virObjectUnlock(priv); rv = virNetClientProgramCall(prog, client, counter, proc_nr, fdinlen, fdin, fdoutlen, fdout, args_filter, args, ret_filter, ret); virObjectLock(priv); virObjectUnref(priv); return rv; } static int call(virAdmConnectPtr conn, unsigned int flags, int proc_nr, xdrproc_t args_filter, char *args, xdrproc_t ret_filter, char *ret) { virCheckFlags(0, -1); return callFull(conn, conn->privateData, NULL, 0, NULL, NULL, proc_nr, args_filter, args, ret_filter, ret); } #include "admin_client.h" static void remoteAdminPrivFree(void *opaque) { virAdmConnectPtr conn = opaque; remoteAdminConnectClose(conn); virObjectUnref(conn->privateData); } static remoteAdminPrivPtr remoteAdminPrivNew(const char *sock_path) { remoteAdminPrivPtr priv = NULL; if (!(priv = virObjectLockableNew(remoteAdminPrivClass))) goto error; if (!(priv->client = virNetClientNewUNIX(sock_path, false, NULL))) goto error; if (!(priv->program = virNetClientProgramNew(ADMIN_PROGRAM, ADMIN_PROTOCOL_VERSION, NULL, 0, NULL))) goto error; if (virNetClientAddProgram(priv->client, priv->program) < 0) goto error; return priv; error: virObjectUnref(priv); return NULL; }