/** * virDomainLxcEnterCGroup: * @domain: a domain object * @flags: currently unused, pass 0 * * This API is LXC specific, so it will only work with hypervisor * connections to the LXC driver. * * Attaches the process to the control cgroups associated * with the container @domain. * * Returns 0 on success, -1 on error */ int virDomainLxcEnterCGroup(virDomainPtr domain, unsigned int flags) { virConnectPtr conn; virCgroupPtr cgroup = NULL; VIR_DOMAIN_DEBUG(domain, "flags=%x", flags); virResetLastError(); virCheckDomainReturn(domain, -1); conn = domain->conn; virCheckReadOnlyGoto(conn->flags, error); virCheckFlagsGoto(0, error); if (virCgroupNewDetect(domain->id, -1, &cgroup) < 0) goto error; if (virCgroupAddTask(cgroup, getpid()) < 0) goto error; virCgroupFree(&cgroup); return 0; error: virDispatchError(NULL); virCgroupFree(&cgroup); return -1; }
/* Functions */ static int adminDispatchConnectOpen(virNetServerPtr server ATTRIBUTE_UNUSED, virNetServerClientPtr client, virNetMessagePtr msg ATTRIBUTE_UNUSED, virNetMessageErrorPtr rerr, struct admin_connect_open_args *args) { unsigned int flags; struct daemonAdmClientPrivate *priv = virNetServerClientGetPrivateData(client); int ret = -1; VIR_DEBUG("priv=%p dmn=%p", priv, priv->dmn); virMutexLock(&priv->lock); flags = args->flags; virCheckFlagsGoto(0, cleanup); ret = 0; cleanup: if (ret < 0) virNetMessageSaveError(rerr); virMutexUnlock(&priv->lock); return ret; }
/** * virAdmConnectOpen: * @name: uri of the daemon to connect to, NULL for default * @flags: extra flags; not used yet, so callers should always pass 0 * * Opens connection to admin interface of the daemon. * * Returns @virAdmConnectPtr object or NULL on error */ virAdmConnectPtr virAdmConnectOpen(const char *name, unsigned int flags) { char *sock_path = NULL; char *alias = NULL; virAdmConnectPtr conn = NULL; virConfPtr conf = NULL; if (virAdmInitialize() < 0) goto error; VIR_DEBUG("flags=%x", flags); virResetLastError(); virCheckFlagsGoto(VIR_CONNECT_NO_ALIASES, error); if (!(conn = virAdmConnectNew())) goto error; if (virConfLoadConfig(&conf, "libvirt-admin.conf") < 0) goto error; if (!name && !(name = virAdmGetDefaultURI(conf))) goto error; if ((!(flags & VIR_CONNECT_NO_ALIASES) && virURIResolveAlias(conf, name, &alias) < 0)) goto error; if (!(conn->uri = virURIParse(alias ? alias : name))) goto error; if (!(sock_path = getSocketPath(conn->uri))) goto error; if (!(conn->privateData = remoteAdminPrivNew(sock_path))) goto error; conn->privateDataFreeFunc = remoteAdminPrivFree; if (remoteAdminConnectOpen(conn, flags) < 0) goto error; cleanup: VIR_FREE(sock_path); VIR_FREE(alias); virConfFree(conf); return conn; error: virDispatchError(NULL); virObjectUnref(conn); conn = NULL; goto cleanup; }
/** * virDomainLxcEnterNamespace: * @domain: a domain object * @nfdlist: number of FDs in @fdlist * @fdlist: list of namespace file descriptors * @noldfdlist: filled with number of old FDs * @oldfdlist: pointer to hold list of old namespace file descriptors * @flags: currently unused, pass 0 * * This API is LXC specific, so it will only work with hypervisor * connections to the LXC driver. * * Attaches the process to the namespaces associated * with the FDs in @fdlist * * If @oldfdlist is non-NULL, it will be populated with file * descriptors representing the old namespace. This allows * the caller to switch back to its current namespace later * * Returns 0 on success, -1 on error */ int virDomainLxcEnterNamespace(virDomainPtr domain, unsigned int nfdlist, int *fdlist, unsigned int *noldfdlist, int **oldfdlist, unsigned int flags) { size_t i; VIR_DOMAIN_DEBUG(domain, "nfdlist=%d, fdlist=%p, " "noldfdlist=%p, oldfdlist=%p, flags=%x", nfdlist, fdlist, noldfdlist, oldfdlist, flags); virResetLastError(); virCheckFlagsGoto(0, error); if (noldfdlist && oldfdlist) { size_t nfds; if (virProcessGetNamespaces(getpid(), &nfds, oldfdlist) < 0) goto error; *noldfdlist = nfds; } if (virProcessSetNamespaces(nfdlist, fdlist) < 0) { if (oldfdlist && noldfdlist) { for (i = 0; i < *noldfdlist; i++) VIR_FORCE_CLOSE((*oldfdlist)[i]); VIR_FREE(*oldfdlist); *noldfdlist = 0; } goto error; } return 0; error: virDispatchError(domain->conn); return -1; }
/** * virAdmConnectLookupServer: * @conn: daemon connection reference * @name: name of the server too lookup * @flags: extra flags; not used yet, so callers should always pass 0 * * Try to lookup a server on the given daemon based on @name. * * virAdmServerFree() should be used to free the resources after the * server object is no longer needed. * * Returns the requested server or NULL in case of failure. If the * server cannot be found, then VIR_ERR_NO_SERVER error is raised. */ virAdmServerPtr virAdmConnectLookupServer(virAdmConnectPtr conn, const char *name, unsigned int flags) { virAdmServerPtr ret = NULL; VIR_DEBUG("conn=%p, name=%s, flags=%x", conn, NULLSTR(name), flags); virResetLastError(); virCheckAdmConnectGoto(conn, cleanup); virCheckNonNullArgGoto(name, cleanup); virCheckFlagsGoto(0, cleanup); ret = remoteAdminConnectLookupServer(conn, name, flags); cleanup: if (!ret) virDispatchError(NULL); return ret; }
/** * virDomainLxcEnterNamespace: * @domain: a domain object * @nfdlist: number of FDs in @fdlist * @fdlist: list of namespace file descriptors * @noldfdlist: filled with number of old FDs * @oldfdlist: pointer to hold list of old namespace file descriptors * @flags: currently unused, pass 0 * * This API is LXC specific, so it will only work with hypervisor * connections to the LXC driver. * * Attaches the process to the namespaces associated * with the FDs in @fdlist * * If @oldfdlist is non-NULL, it will be populated with file * descriptors representing the old namespace. This allows * the caller to switch back to its current namespace later * * Returns 0 on success, -1 on error */ int virDomainLxcEnterNamespace(virDomainPtr domain, unsigned int nfdlist, int *fdlist, unsigned int *noldfdlist, int **oldfdlist, unsigned int flags) { int i; virCheckFlagsGoto(0, error); if (noldfdlist && oldfdlist) { size_t nfds; if (virProcessGetNamespaces(getpid(), &nfds, oldfdlist) < 0) goto error; *noldfdlist = nfds; } if (virProcessSetNamespaces(nfdlist, fdlist) < 0) { if (oldfdlist && noldfdlist) { for (i = 0 ; i < *noldfdlist ; i++) { VIR_FORCE_CLOSE((*oldfdlist)[i]); } VIR_FREE(*oldfdlist); *noldfdlist = 0; } goto error; } return 0; error: virDispatchError(domain->conn); return -1; }
/** * virAdmConnectListServers: * @conn: daemon connection reference * @servers: Pointer to a list to store an array containing objects or NULL * if the list is not required (number of servers only) * @flags: extra flags; not used yet, so callers should always pass 0 * * Collect list of all servers provided by daemon the client is connected to. * * Returns the number of servers available on daemon side or -1 in case of a * failure, setting @servers to NULL. There is a guaranteed extra element set * to NULL in the @servers list returned to make the iteration easier, excluding * this extra element from the final count. * Caller is responsible to call virAdmServerFree() on each list element, * followed by freeing @servers. */ int virAdmConnectListServers(virAdmConnectPtr conn, virAdmServerPtr **servers, unsigned int flags) { int ret = -1; VIR_DEBUG("conn=%p, servers=%p, flags=%x", conn, servers, flags); virResetLastError(); virCheckFlagsGoto(0, error); if (servers) *servers = NULL; virCheckAdmConnectReturn(conn, -1); if ((ret = remoteAdminConnectListServers(conn, servers, flags)) < 0) goto error; return ret; error: virDispatchError(NULL); return -1; }
/** * virDomainLxcEnterSecurityLabel: * @model: the security model to set * @label: the security label to apply * @oldlabel: filled with old security label * @flags: currently unused, pass 0 * * This API is LXC specific, so it will only work with hypervisor * connections to the LXC driver. * * Attaches the process to the security label specified * by @label. @label is interpreted relative to @model * Depending on the security driver, this may * not take effect until the next call to exec(). * * If @oldlabel is not NULL, it will be filled with info * about the current security label. This may let the * process be moved back to the previous label if no * exec() has yet been performed. * * Returns 0 on success, -1 on error */ int virDomainLxcEnterSecurityLabel(virSecurityModelPtr model, virSecurityLabelPtr label, virSecurityLabelPtr oldlabel, unsigned int flags) { VIR_DEBUG("model=%p, label=%p, oldlabel=%p, flags=%x", model, label, oldlabel, flags); virResetLastError(); virCheckFlagsGoto(0, error); virCheckNonNullArgGoto(model, error); virCheckNonNullArgGoto(label, error); if (oldlabel) memset(oldlabel, 0, sizeof(*oldlabel)); if (STREQ(model->model, "selinux")) { #ifdef WITH_SELINUX if (oldlabel) { security_context_t ctx; if (getcon(&ctx) < 0) { virReportSystemError(errno, _("unable to get PID %d security context"), getpid()); goto error; } if (strlen((char *) ctx) >= VIR_SECURITY_LABEL_BUFLEN) { virReportError(VIR_ERR_INTERNAL_ERROR, _("security label exceeds " "maximum length: %d"), VIR_SECURITY_LABEL_BUFLEN - 1); freecon(ctx); goto error; } strcpy(oldlabel->label, (char *) ctx); freecon(ctx); if ((oldlabel->enforcing = security_getenforce()) < 0) { virReportSystemError(errno, "%s", _("error calling security_getenforce()")); goto error; } } if (setexeccon(label->label) < 0) { virReportSystemError(errno, _("Cannot set context %s"), label->label); goto error; } #else virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s", _("Support for SELinux is not enabled")); goto error; #endif } else if (STREQ(model->model, "apparmor")) { #ifdef WITH_APPARMOR if (aa_change_profile(label->label) < 0) { virReportSystemError(errno, _("error changing profile to %s"), label->label); goto error; } #else virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s", _("Support for AppArmor is not enabled")); goto error; #endif } else if (STREQ(model->model, "none")) { /* nothing todo */ } else { virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, _("Security model %s cannot be entered"), model->model); goto error; } return 0; error: virDispatchError(NULL); return -1; }