diff --git a/include/qapi/qmp/dispatch.h b/include/qapi/qmp/dispatch.h index 1486cac3ef..135dfdef71 100644 --- a/include/qapi/qmp/dispatch.h +++ b/include/qapi/qmp/dispatch.h @@ -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); diff --git a/qapi/qmp-dispatch.c b/qapi/qmp-dispatch.c index 0a2b20a4e4..5e597c76f7 100644 --- a/qapi/qmp-dispatch.c +++ b/qapi/qmp-dispatch.c @@ -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)) { diff --git a/qapi/qmp-registry.c b/qapi/qmp-registry.c index 58c65b5052..f78c064aae 100644 --- a/qapi/qmp-registry.c +++ b/qapi/qmp-registry.c @@ -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) diff --git a/qga/channel-win32.c b/qga/channel-win32.c index 4f04868a76..779007e39b 100644 --- a/qga/channel-win32.c +++ b/qga/channel-win32.c @@ -292,9 +292,9 @@ static gboolean ga_channel_open(GAChannel *c, GAChannelMethod method, return false; } - if (method == GA_CHANNEL_ISA_SERIAL){ + if (method == GA_CHANNEL_ISA_SERIAL) { snprintf(newpath, sizeof(newpath), "\\\\.\\%s", path); - }else { + } else { g_strlcpy(newpath, path, sizeof(newpath)); } @@ -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); diff --git a/qga/commands-posix.c b/qga/commands-posix.c index 3f18df1bb6..4299ebd96f 100644 --- a/qga/commands-posix.c +++ b/qga/commands-posix.c @@ -110,7 +110,7 @@ void qmp_guest_shutdown(bool has_mode, const char *mode, Error **errp) reopen_fd_to_null(2); execle("/sbin/shutdown", "shutdown", "-h", shutdown_flag, "+0", - "hypervisor initiated shutdown", (char*)NULL, environ); + "hypervisor initiated shutdown", (char *)NULL, environ); _exit(EXIT_FAILURE); } else if (pid < 0) { error_setg_errno(errp, errno, "failed to create child process"); @@ -479,7 +479,7 @@ GuestFileRead *guest_file_read_unsafe(GuestFileHandle *gfh, gfh->state = RW_STATE_NEW; } - buf = g_malloc0(count+1); + buf = g_malloc0(count + 1); read_count = fread(buf, 1, count, fh); if (ferror(fh)) { error_setg_errno(errp, errno, "failed to read 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) { diff --git a/qga/commands-win32.c b/qga/commands-win32.c index a00e6cb165..27baf17d6c 100644 --- a/qga/commands-win32.c +++ b/qga/commands-win32.c @@ -110,15 +110,15 @@ static OpenFlags guest_file_open_modes[] = { {"w", GENERIC_WRITE, CREATE_ALWAYS}, {"wb", GENERIC_WRITE, CREATE_ALWAYS}, {"a", FILE_GENERIC_APPEND, OPEN_ALWAYS }, - {"r+", GENERIC_WRITE|GENERIC_READ, OPEN_EXISTING}, - {"rb+", GENERIC_WRITE|GENERIC_READ, OPEN_EXISTING}, - {"r+b", GENERIC_WRITE|GENERIC_READ, OPEN_EXISTING}, - {"w+", GENERIC_WRITE|GENERIC_READ, CREATE_ALWAYS}, - {"wb+", GENERIC_WRITE|GENERIC_READ, CREATE_ALWAYS}, - {"w+b", GENERIC_WRITE|GENERIC_READ, CREATE_ALWAYS}, - {"a+", FILE_GENERIC_APPEND|GENERIC_READ, OPEN_ALWAYS }, - {"ab+", FILE_GENERIC_APPEND|GENERIC_READ, OPEN_ALWAYS }, - {"a+b", FILE_GENERIC_APPEND|GENERIC_READ, OPEN_ALWAYS } + {"r+", GENERIC_WRITE | GENERIC_READ, OPEN_EXISTING}, + {"rb+", GENERIC_WRITE | GENERIC_READ, OPEN_EXISTING}, + {"r+b", GENERIC_WRITE | GENERIC_READ, OPEN_EXISTING}, + {"w+", GENERIC_WRITE | GENERIC_READ, CREATE_ALWAYS}, + {"wb+", GENERIC_WRITE | GENERIC_READ, CREATE_ALWAYS}, + {"w+b", GENERIC_WRITE | GENERIC_READ, CREATE_ALWAYS}, + {"a+", FILE_GENERIC_APPEND | GENERIC_READ, OPEN_ALWAYS }, + {"ab+", FILE_GENERIC_APPEND | GENERIC_READ, OPEN_ALWAYS }, + {"a+b", FILE_GENERIC_APPEND | GENERIC_READ, OPEN_ALWAYS } }; #define debug_error(msg) do { \ @@ -280,7 +280,7 @@ static void acquire_privilege(const char *name, Error **errp) Error *local_err = NULL; if (OpenProcessToken(GetCurrentProcess(), - TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY, &token)) + TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token)) { if (!LookupPrivilegeValue(NULL, name, &priv.Privileges[0].Luid)) { error_setg(&local_err, QERR_QGA_COMMAND_FAILED, @@ -1116,7 +1116,7 @@ static GuestFilesystemInfo *build_guest_fsinfo(char *guid, Error **errp) len = strlen(mnt_point); mnt_point[len] = '\\'; - mnt_point[len+1] = 0; + mnt_point[len + 1] = 0; if (!GetVolumeInformationByHandleW(hLocalDiskHandle, vol_info, sizeof(vol_info), NULL, NULL, NULL, @@ -1323,7 +1323,7 @@ qmp_guest_fstrim(bool has_minimum, int64_t minimum, Error **errp) DWORD char_count = 0; char *path, *out; GError *gerr = NULL; - gchar * argv[4]; + gchar *argv[4]; GetVolumePathNamesForVolumeNameW(guid, NULL, 0, &char_count); @@ -2174,7 +2174,7 @@ static ga_win_10_0_server_t const WIN_10_0_SERVER_VERSION_MATRIX[3] = { static void ga_get_win_version(RTL_OSVERSIONINFOEXW *info, Error **errp) { - typedef NTSTATUS(WINAPI * rtl_get_version_t)( + typedef NTSTATUS(WINAPI *rtl_get_version_t)( RTL_OSVERSIONINFOEXW *os_version_info_ex); info->dwOSVersionInfoSize = sizeof(RTL_OSVERSIONINFOEXW); diff --git a/qga/commands.c b/qga/commands.c index e866fc7081..a6491d2cf8 100644 --- a/qga/commands.c +++ b/qga/commands.c @@ -22,9 +22,9 @@ #include "commands-common.h" /* Maximum captured guest-exec out_data/err_data - 16MB */ -#define GUEST_EXEC_MAX_OUTPUT (16*1024*1024) +#define GUEST_EXEC_MAX_OUTPUT (16 * 1024 * 1024) /* Allocation and I/O buffer for reading guest-exec out_data/err_data - 4KB */ -#define GUEST_EXEC_IO_SIZE (4*1024) +#define GUEST_EXEC_IO_SIZE (4 * 1024) /* * Maximum file size to read - 48MB * diff --git a/qga/main.c b/qga/main.c index e7f8f3b161..15fd3a4149 100644 --- a/qga/main.c +++ b/qga/main.c @@ -279,20 +279,20 @@ QEMU_HELP_BOTTOM "\n" static const char *ga_log_level_str(GLogLevelFlags level) { switch (level & G_LOG_LEVEL_MASK) { - case G_LOG_LEVEL_ERROR: - return "error"; - case G_LOG_LEVEL_CRITICAL: - return "critical"; - case G_LOG_LEVEL_WARNING: - return "warning"; - case G_LOG_LEVEL_MESSAGE: - return "message"; - case G_LOG_LEVEL_INFO: - return "info"; - case G_LOG_LEVEL_DEBUG: - return "debug"; - default: - return "user"; + case G_LOG_LEVEL_ERROR: + return "error"; + case G_LOG_LEVEL_CRITICAL: + return "critical"; + case G_LOG_LEVEL_WARNING: + return "warning"; + case G_LOG_LEVEL_MESSAGE: + return "message"; + case G_LOG_LEVEL_INFO: + return "info"; + case G_LOG_LEVEL_DEBUG: + return "debug"; + default: + return "user"; } } @@ -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"); } } @@ -586,7 +586,7 @@ end: static gboolean channel_event_cb(GIOCondition condition, gpointer data) { GAState *s = data; - gchar buf[QGA_READ_COUNT_DEFAULT+1]; + gchar buf[QGA_READ_COUNT_DEFAULT + 1]; gsize count; GIOStatus status = ga_channel_read(s->channel, buf, QGA_READ_COUNT_DEFAULT, &count); switch (status) { @@ -610,7 +610,7 @@ static gboolean channel_event_cb(GIOCondition condition, gpointer data) * host-side chardev. sleep a bit to mitigate this */ if (s->virtio) { - usleep(100*1000); + usleep(100 * 1000); } return true; default: @@ -686,21 +686,20 @@ DWORD WINAPI service_ctrl_handler(DWORD ctrl, DWORD type, LPVOID data, DWORD ret = NO_ERROR; GAService *service = &ga_state->service; - switch (ctrl) - { - case SERVICE_CONTROL_STOP: - case SERVICE_CONTROL_SHUTDOWN: - quit_handler(SIGTERM); - SetEvent(ga_state->wakeup_event); - service->status.dwCurrentState = SERVICE_STOP_PENDING; - SetServiceStatus(service->status_handle, &service->status); - break; - case SERVICE_CONTROL_DEVICEEVENT: - handle_serial_device_events(type, data); - break; + switch (ctrl) { + case SERVICE_CONTROL_STOP: + case SERVICE_CONTROL_SHUTDOWN: + quit_handler(SIGTERM); + SetEvent(ga_state->wakeup_event); + service->status.dwCurrentState = SERVICE_STOP_PENDING; + SetServiceStatus(service->status_handle, &service->status); + break; + case SERVICE_CONTROL_DEVICEEVENT: + handle_serial_device_events(type, data); + break; - default: - ret = ERROR_CALL_NOT_IMPLEMENTED; + default: + ret = ERROR_CALL_NOT_IMPLEMENTED; } return ret; } @@ -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); }