qemu-ga patch queue for soft-freeze

* fix guest-get-vcpus reporting after vcpu unplug
 * coding style fix-ups
 * report a reason for disabled commands
 -----BEGIN PGP SIGNATURE-----
 
 iQEzBAABCgAdFiEEzqzJ4VU066u4LT+gM1PJzvEItYQFAmBRc6kACgkQM1PJzvEI
 tYRTyAf/RAL9jEf6zFtztqpTKOUoptnBjtF2bb4A9WQ72/9sFzoufYoCSKeSEbuv
 9vEK1DW5JkgR5DETsk3qWCr4TK2wNf7rZde87iy5pOxPQqaUNwx5HFZqZnBMv3wl
 SIWRoa5fPucUOZQkYgjellRNlGVm0QJ1+hqmj+0Dwbw04KBti0Hbyl7YS23BskD0
 wafPensotjEswtbxG20yCW4WerI5XVnrPYURD8+lBMYYOxLgsIc+fSUZ+Ak+4gO+
 i3rgK7RamzoWJ/L9am8v7uImH1k74tO3g6iws79exT8wWK2o4/vqQYF2TMtTrUvq
 9ZBA1ehd6L0bDDRXFNsBOc27jADRIw==
 =d1L/
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/mdroth/tags/qga-pull-2021-03-16-tag' into staging

qemu-ga patch queue for soft-freeze

* fix guest-get-vcpus reporting after vcpu unplug
* coding style fix-ups
* report a reason for disabled commands

# gpg: Signature made Wed 17 Mar 2021 03:12:41 GMT
# gpg:                using RSA key CEACC9E15534EBABB82D3FA03353C9CEF108B584
# gpg: Good signature from "Michael Roth <flukshun@gmail.com>" [full]
# gpg:                 aka "Michael Roth <mdroth@utexas.edu>" [full]
# gpg:                 aka "Michael Roth <mdroth@linux.vnet.ibm.com>" [full]
# Primary key fingerprint: CEAC C9E1 5534 EBAB B82D  3FA0 3353 C9CE F108 B584

* remotes/mdroth/tags/qga-pull-2021-03-16-tag:
  qga: return a more explicit error on why a command is disabled
  qga: Switch and case should be at the same indent
  qga: Open brace '{' following struct go on the same
  qga: Delete redundant spaces
  qga: Add spaces around operator
  qga: Correct loop count in qmp_guest_get_vcpus()

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2021-03-18 11:27:11 +00:00
commit 7286d62d4e
8 changed files with 79 additions and 88 deletions

View file

@ -36,6 +36,7 @@ typedef struct QmpCommand
QmpCommandOptions options;
QTAILQ_ENTRY(QmpCommand) node;
bool enabled;
const char *disable_reason;
} QmpCommand;
typedef QTAILQ_HEAD(QmpCommandList, QmpCommand) QmpCommandList;
@ -44,7 +45,8 @@ void qmp_register_command(QmpCommandList *cmds, const char *name,
QmpCommandFunc *fn, QmpCommandOptions options);
const QmpCommand *qmp_find_command(const QmpCommandList *cmds,
const char *name);
void qmp_disable_command(QmpCommandList *cmds, const char *name);
void qmp_disable_command(QmpCommandList *cmds, const char *name,
const char *err_msg);
void qmp_enable_command(QmpCommandList *cmds, const char *name);
bool qmp_command_is_enabled(const QmpCommand *cmd);

View file

@ -157,8 +157,10 @@ QDict *qmp_dispatch(const QmpCommandList *cmds, QObject *request,
}
if (!cmd->enabled) {
error_set(&err, ERROR_CLASS_COMMAND_NOT_FOUND,
"The command %s has been disabled for this instance",
command);
"Command %s has been disabled%s%s",
command,
cmd->disable_reason ? ": " : "",
cmd->disable_reason ?: "");
goto out;
}
if (oob && !(cmd->options & QCO_ALLOW_OOB)) {

View file

@ -43,26 +43,28 @@ const QmpCommand *qmp_find_command(const QmpCommandList *cmds, const char *name)
}
static void qmp_toggle_command(QmpCommandList *cmds, const char *name,
bool enabled)
bool enabled, const char *disable_reason)
{
QmpCommand *cmd;
QTAILQ_FOREACH(cmd, cmds, node) {
if (strcmp(cmd->name, name) == 0) {
cmd->enabled = enabled;
cmd->disable_reason = disable_reason;
return;
}
}
}
void qmp_disable_command(QmpCommandList *cmds, const char *name)
void qmp_disable_command(QmpCommandList *cmds, const char *name,
const char *disable_reason)
{
qmp_toggle_command(cmds, name, false);
qmp_toggle_command(cmds, name, false, disable_reason);
}
void qmp_enable_command(QmpCommandList *cmds, const char *name)
{
qmp_toggle_command(cmds, name, true);
qmp_toggle_command(cmds, name, true, NULL);
}
bool qmp_command_is_enabled(const QmpCommand *cmd)

View file

@ -307,7 +307,8 @@ static gboolean ga_channel_open(GAChannel *c, GAChannelMethod method,
return false;
}
if (method == GA_CHANNEL_ISA_SERIAL && !SetCommTimeouts(c->handle,&comTimeOut)) {
if (method == GA_CHANNEL_ISA_SERIAL
&& !SetCommTimeouts(c->handle, &comTimeOut)) {
g_autofree gchar *emsg = g_win32_error_message(GetLastError());
g_critical("error setting timeout for com port: %s", emsg);
CloseHandle(c->handle);

View file

@ -2370,24 +2370,6 @@ error:
return NULL;
}
#define SYSCONF_EXACT(name, errp) sysconf_exact((name), #name, (errp))
static long sysconf_exact(int name, const char *name_str, Error **errp)
{
long ret;
errno = 0;
ret = sysconf(name);
if (ret == -1) {
if (errno == 0) {
error_setg(errp, "sysconf(%s): value indefinite", name_str);
} else {
error_setg_errno(errp, errno, "sysconf(%s)", name_str);
}
}
return ret;
}
/* Transfer online/offline status between @vcpu and the guest system.
*
* On input either @errp or *@errp must be NULL.
@ -2458,30 +2440,33 @@ static void transfer_vcpu(GuestLogicalProcessor *vcpu, bool sys2vcpu,
GuestLogicalProcessorList *qmp_guest_get_vcpus(Error **errp)
{
int64_t current;
GuestLogicalProcessorList *head, **tail;
long sc_max;
const char *cpu_dir = "/sys/devices/system/cpu";
const gchar *line;
g_autoptr(GDir) cpu_gdir = NULL;
Error *local_err = NULL;
current = 0;
head = NULL;
tail = &head;
sc_max = SYSCONF_EXACT(_SC_NPROCESSORS_CONF, &local_err);
cpu_gdir = g_dir_open(cpu_dir, 0, NULL);
while (local_err == NULL && current < sc_max) {
if (cpu_gdir == NULL) {
error_setg_errno(errp, errno, "failed to list entries: %s", cpu_dir);
return NULL;
}
while (local_err == NULL && (line = g_dir_read_name(cpu_gdir)) != NULL) {
GuestLogicalProcessor *vcpu;
int64_t id = current++;
char *path = g_strdup_printf("/sys/devices/system/cpu/cpu%" PRId64 "/",
id);
if (g_file_test(path, G_FILE_TEST_EXISTS)) {
int64_t id;
if (sscanf(line, "cpu%" PRId64, &id)) {
g_autofree char *path = g_strdup_printf("/sys/devices/system/cpu/"
"cpu%" PRId64 "/", id);
vcpu = g_malloc0(sizeof *vcpu);
vcpu->logical_id = id;
vcpu->has_can_offline = true; /* lolspeak ftw */
transfer_vcpu(vcpu, true, path, &local_err);
QAPI_LIST_APPEND(tail, vcpu);
}
g_free(path);
}
if (local_err == NULL) {

View file

@ -375,7 +375,7 @@ static void ga_disable_non_whitelisted(const QmpCommand *cmd, void *opaque)
}
if (!whitelisted) {
g_debug("disabling command: %s", name);
qmp_disable_command(&ga_commands, name);
qmp_disable_command(&ga_commands, name, "the agent is in frozen state");
}
}
@ -686,8 +686,7 @@ DWORD WINAPI service_ctrl_handler(DWORD ctrl, DWORD type, LPVOID data,
DWORD ret = NO_ERROR;
GAService *service = &ga_state->service;
switch (ctrl)
{
switch (ctrl) {
case SERVICE_CONTROL_STOP:
case SERVICE_CONTROL_SHUTDOWN:
quit_handler(SIGTERM);
@ -1329,7 +1328,7 @@ static GAState *initialize_agent(GAConfig *config, int socket_activation)
s->blacklist = config->blacklist;
do {
g_debug("disabling command: %s", (char *)l->data);
qmp_disable_command(&ga_commands, l->data);
qmp_disable_command(&ga_commands, l->data, NULL);
l = g_list_next(l);
} while (l);
}