mirror of
https://github.com/libvirt/libvirt.git
synced 2026-10-02 12:20:06 -05:00
bhyve: implement the domainGetMemoryParameters API
Implement the domainGetMemoryParameters() API for the bhyve driver. To parse live limits execute rctl(8) to list the active rules and parse them. Introduce the bhyve_rctl.c for working with rctl(8). Signed-off-by: Roman Bogorodskiy <bogorodskiy@gmail.com> Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
This commit is contained in:
1 parent
dd34991f6e
commit
3c013d1627
4 files changed
+185
No files matched your search
@@ -70,6 +70,7 @@
|
||||
#include "bhyve_domain.h"
|
||||
#include "bhyve_process.h"
|
||||
#include "bhyve_capabilities.h"
|
||||
#include "bhyve_rctl.h"
|
||||
|
||||
#define VIR_FROM_THIS VIR_FROM_BHYVE
|
||||
|
||||
@@ -2167,6 +2168,63 @@ bhyveDomainGetHostname(virDomainPtr domain,
|
||||
return hostname;
|
||||
}
|
||||
|
||||
|
||||
#define BHYVE_NB_MEM_PARAM 1
|
||||
#define BHYVE_ASSIGN_MEM_PARAM(index, name, value) \
|
||||
if (index < *nparams && \
|
||||
virTypedParameterAssign(¶ms[index], name, VIR_TYPED_PARAM_ULLONG, \
|
||||
value) < 0) \
|
||||
goto cleanup
|
||||
|
||||
static int
|
||||
bhyveDomainGetMemoryParameters(virDomainPtr domain,
|
||||
virTypedParameterPtr params,
|
||||
int *nparams,
|
||||
unsigned int flags)
|
||||
{
|
||||
virDomainObj *vm = NULL;
|
||||
virDomainDef *persistentDef = NULL;
|
||||
int ret = -1;
|
||||
unsigned long long mem_hard_limit;
|
||||
|
||||
virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
|
||||
VIR_DOMAIN_AFFECT_CONFIG |
|
||||
VIR_TYPED_PARAM_STRING_OKAY, -1);
|
||||
|
||||
if (!(vm = bhyveDomObjFromDomain(domain)))
|
||||
return -1;
|
||||
|
||||
if (virDomainGetMemoryParametersEnsureACL(domain->conn, vm->def) < 0)
|
||||
goto cleanup;
|
||||
|
||||
if (virDomainObjGetDefs(vm, flags, NULL, &persistentDef) < 0)
|
||||
goto cleanup;
|
||||
|
||||
if ((*nparams) == 0) {
|
||||
*nparams = BHYVE_NB_MEM_PARAM;
|
||||
ret = 0;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (persistentDef) {
|
||||
mem_hard_limit = persistentDef->mem.hard_limit;
|
||||
} else {
|
||||
if (bhyveRctlGetMemoryHardLimit(vm->pid, &mem_hard_limit) < 0)
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
BHYVE_ASSIGN_MEM_PARAM(0, VIR_DOMAIN_MEMORY_HARD_LIMIT, mem_hard_limit);
|
||||
|
||||
if (BHYVE_NB_MEM_PARAM < *nparams)
|
||||
*nparams = BHYVE_NB_MEM_PARAM;
|
||||
ret = 0;
|
||||
|
||||
cleanup:
|
||||
virDomainObjEndAPI(&vm);
|
||||
return ret;
|
||||
}
|
||||
#undef BHYVE_ASSIGN_MEM_PARAM
|
||||
|
||||
static virHypervisorDriver bhyveHypervisorDriver = {
|
||||
.name = "bhyve",
|
||||
.connectURIProbe = bhyveConnectURIProbe,
|
||||
@@ -2236,6 +2294,7 @@ static virHypervisorDriver bhyveHypervisorDriver = {
|
||||
.domainInterfaceAddresses = bhyveDomainInterfaceAddresses, /* 12.3.0 */
|
||||
.domainGetHostname = bhyveDomainGetHostname, /* 12.3.0 */
|
||||
.domainQemuAgentCommand = bhyveDomainQemuAgentCommand, /* 12.4.0 */
|
||||
.domainGetMemoryParameters = bhyveDomainGetMemoryParameters, /* 12.4.0 */
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* bhyve_rctl.c: Resource limits management with rctl(8)
|
||||
*
|
||||
* Copyright (C) 2026 The FreeBSD Foundation
|
||||
*
|
||||
* 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 <sys/types.h>
|
||||
#include <sys/event.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#include "bhyve_rctl.h"
|
||||
#include "vircommand.h"
|
||||
#include "viralloc.h"
|
||||
#include "virerror.h"
|
||||
#include "virfile.h"
|
||||
#include "virlog.h"
|
||||
#include "virobject.h"
|
||||
#include "virstring.h"
|
||||
|
||||
#define VIR_FROM_THIS VIR_FROM_BHYVE
|
||||
|
||||
VIR_LOG_INIT("bhyve.bhyve_rctl");
|
||||
|
||||
|
||||
static int
|
||||
bhyveRctlGetAmountFromRule(const char *rule, unsigned long long *amount)
|
||||
{
|
||||
/* From rctl(8):
|
||||
*
|
||||
* Syntax for a rule is subject:subject-id:resource:action=amount/per.
|
||||
* A valid rule has all those fields specified, except for per, which
|
||||
* defaults to the value of subject.
|
||||
*/
|
||||
g_auto(GStrv) tokens = NULL;
|
||||
unsigned long long bytes;
|
||||
|
||||
if (!(tokens = g_strsplit_set(rule, "=/", 0)))
|
||||
return -1;
|
||||
|
||||
if (g_strv_length(tokens) < 2)
|
||||
return -1;
|
||||
|
||||
if (virStrToLong_ull(tokens[1], NULL, 10, &bytes) < 0)
|
||||
return -1;
|
||||
|
||||
*amount = bytes / 1024;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
bhyveRctlGetMemoryHardLimit(pid_t pid, unsigned long long *kb)
|
||||
{
|
||||
g_auto(GStrv) lines = NULL;
|
||||
g_autofree char *outbuf = NULL;
|
||||
g_autoptr(virCommand) cmd = NULL;
|
||||
size_t i;
|
||||
|
||||
cmd = virCommandNew("rctl");
|
||||
virCommandAddArgFormat(cmd, "process:%d:memoryuse", pid);
|
||||
virCommandSetOutputBuffer(cmd, &outbuf);
|
||||
if (virCommandRun(cmd, NULL) < 0) {
|
||||
*kb = VIR_DOMAIN_MEMORY_PARAM_UNLIMITED;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Empty output means no matching rules, thus no limits */
|
||||
if (strlen(outbuf) == 0) {
|
||||
*kb = VIR_DOMAIN_MEMORY_PARAM_UNLIMITED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(lines = g_strsplit(outbuf, "\n", 0)))
|
||||
return -1;
|
||||
|
||||
/* There could be multiple actions for a resource, such as
|
||||
* 'log' for example, so we need to look for the 'deny' action
|
||||
* specifically */
|
||||
for (i = 0; lines[i]; i++)
|
||||
if (strstr(lines[i], ":deny="))
|
||||
return bhyveRctlGetAmountFromRule(lines[i], kb);
|
||||
|
||||
return -1;
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* bhyve_rctl.h: Resource limits management with rctl(8)
|
||||
*
|
||||
* Copyright (C) 2026 The FreeBSD Foundation
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
int
|
||||
bhyveRctlGetMemoryHardLimit(pid_t pid, unsigned long long *kb);
|
||||
@@ -9,6 +9,7 @@ bhyve_sources = files(
|
||||
'bhyve_driver.c',
|
||||
'bhyve_monitor.c',
|
||||
'bhyve_process.c',
|
||||
'bhyve_rctl.c',
|
||||
)
|
||||
|
||||
driver_source_files += bhyve_sources
|
||||
|
||||
Reference in new issue
Block a user