mirror of
https://github.com/clearlinux/kvmtool.git
synced 2026-06-15 18:05:49 +00:00
0cf9e1f442
Currently list always returns 0, even if there was an error. Instead have it accumulate any errors and return that. Signed-off-by: Michael Ellerman <michael@ellerman.id.au> Signed-off-by: Pekka Enberg <penberg@kernel.org>
156 lines
2.7 KiB
C
156 lines
2.7 KiB
C
#include <kvm/util.h>
|
|
#include <kvm/kvm-cmd.h>
|
|
#include <kvm/builtin-list.h>
|
|
#include <kvm/kvm.h>
|
|
#include <kvm/parse-options.h>
|
|
#include <kvm/kvm-ipc.h>
|
|
|
|
#include <dirent.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <signal.h>
|
|
#include <fcntl.h>
|
|
|
|
static bool run;
|
|
static bool rootfs;
|
|
|
|
static const char * const list_usage[] = {
|
|
"lkvm list",
|
|
NULL
|
|
};
|
|
|
|
static const struct option list_options[] = {
|
|
OPT_GROUP("General options:"),
|
|
OPT_BOOLEAN('i', "run", &run, "List running instances"),
|
|
OPT_BOOLEAN('r', "rootfs", &rootfs, "List rootfs instances"),
|
|
OPT_END()
|
|
};
|
|
|
|
#define KVM_INSTANCE_RUNNING "running"
|
|
#define KVM_INSTANCE_PAUSED "paused"
|
|
#define KVM_INSTANCE_SHUTOFF "shut off"
|
|
|
|
void kvm_list_help(void)
|
|
{
|
|
usage_with_options(list_usage, list_options);
|
|
}
|
|
|
|
static pid_t get_pid(int sock)
|
|
{
|
|
pid_t pid;
|
|
int r;
|
|
|
|
r = kvm_ipc__send(sock, KVM_IPC_PID);
|
|
if (r < 0)
|
|
return r;
|
|
|
|
r = read(sock, &pid, sizeof(pid));
|
|
if (r < 0)
|
|
return r;
|
|
|
|
return pid;
|
|
}
|
|
|
|
int get_vmstate(int sock)
|
|
{
|
|
int vmstate;
|
|
int r;
|
|
|
|
r = kvm_ipc__send(sock, KVM_IPC_VMSTATE);
|
|
if (r < 0)
|
|
return r;
|
|
|
|
r = read(sock, &vmstate, sizeof(vmstate));
|
|
if (r < 0)
|
|
return r;
|
|
|
|
return vmstate;
|
|
|
|
}
|
|
|
|
static int print_guest(const char *name, int sock)
|
|
{
|
|
pid_t pid;
|
|
int vmstate;
|
|
|
|
pid = get_pid(sock);
|
|
vmstate = get_vmstate(sock);
|
|
|
|
if ((int)pid < 0 || vmstate < 0)
|
|
return -1;
|
|
|
|
if (vmstate == KVM_VMSTATE_PAUSED)
|
|
printf("%5d %-20s %s\n", pid, name, KVM_INSTANCE_PAUSED);
|
|
else
|
|
printf("%5d %-20s %s\n", pid, name, KVM_INSTANCE_RUNNING);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int kvm_list_running_instances(void)
|
|
{
|
|
return kvm__enumerate_instances(print_guest);
|
|
}
|
|
|
|
static int kvm_list_rootfs(void)
|
|
{
|
|
DIR *dir;
|
|
struct dirent *dirent;
|
|
|
|
dir = opendir(kvm__get_dir());
|
|
if (dir == NULL)
|
|
return -1;
|
|
|
|
while ((dirent = readdir(dir))) {
|
|
if (dirent->d_type == DT_DIR &&
|
|
strcmp(dirent->d_name, ".") &&
|
|
strcmp(dirent->d_name, ".."))
|
|
printf("%5s %-20s %s\n", "", dirent->d_name, KVM_INSTANCE_SHUTOFF);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static void parse_setup_options(int argc, const char **argv)
|
|
{
|
|
while (argc != 0) {
|
|
argc = parse_options(argc, argv, list_options, list_usage,
|
|
PARSE_OPT_STOP_AT_NON_OPTION);
|
|
if (argc != 0)
|
|
kvm_list_help();
|
|
}
|
|
}
|
|
|
|
int kvm_cmd_list(int argc, const char **argv, const char *prefix)
|
|
{
|
|
int status, r;
|
|
|
|
parse_setup_options(argc, argv);
|
|
|
|
if (!run && !rootfs)
|
|
run = rootfs = true;
|
|
|
|
printf("%6s %-20s %s\n", "PID", "NAME", "STATE");
|
|
printf("------------------------------------\n");
|
|
|
|
status = 0;
|
|
|
|
if (run) {
|
|
r = kvm_list_running_instances();
|
|
if (r < 0)
|
|
perror("Error listing instances");
|
|
|
|
status |= r;
|
|
}
|
|
|
|
if (rootfs) {
|
|
r = kvm_list_rootfs();
|
|
if (r < 0)
|
|
perror("Error listing rootfs");
|
|
|
|
status |= r;
|
|
}
|
|
|
|
return status;
|
|
}
|