Use a native implementation of the jailhouse-cell-list interface. Though this implementation requires more lines of code, it is nice to be able to run jailhouse cell list without a dependency on python.
Keep the output format of the former python script. Also Add add simple interface to read sysfs entries. Signed-off-by: Ralf Ramsauer <[email protected]> --- tools/jailhouse-cell-list | 71 --------------------- tools/jailhouse.c | 153 +++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 152 insertions(+), 72 deletions(-) delete mode 100755 tools/jailhouse-cell-list diff --git a/tools/jailhouse-cell-list b/tools/jailhouse-cell-list deleted file mode 100755 index 3b5bc20..0000000 --- a/tools/jailhouse-cell-list +++ /dev/null @@ -1,71 +0,0 @@ -#!/usr/bin/env python - -# Jailhouse, a Linux-based partitioning hypervisor -# -# Copyright (c) Siemens AG, 2014 -# -# Authors: -# Jan Kiszka <[email protected]> -# -# This work is licensed under the terms of the GNU GPL, version 2. See -# the COPYING file in the top-level directory. - -import glob -import os -import sys - - -def read_cpus(path): - return int(open(path).readline().strip().replace(",", ""), 16) - - -def finish_cpu_list(last_cpu, cpu): - if last_cpu is not None: - if cpu-last_cpu > 1: - return "%s%d," % ("-" if cpu-last_cpu > 2 else ",", cpu-1) - else: - return "," - else: - return "" - - -def print_cpus(mask): - last_cpu = None - cpu = 0 - output = "" - while mask > 0: - if mask & 1: - if last_cpu is None: - last_cpu = cpu - output += str(cpu) - else: - output += finish_cpu_list(last_cpu, cpu) - last_cpu = None - mask >>= 1 - cpu += 1 - output += finish_cpu_list(last_cpu, cpu) - return output.strip(",") - - -if len(sys.argv) > 1: - print("usage: %s" % os.path.basename(sys.argv[0]).replace("-", " ")) - exit(0 if sys.argv[1] in ("--help", "-h") else 1) - -cells = [] -for cell_path in glob.glob('/sys/devices/jailhouse/cells/*'): - cells.append({ - 'name': os.path.basename(cell_path), - 'id': open(cell_path + "/id").readline().strip(), - 'state': open(cell_path + "/state").readline().strip(), - 'cpus_assigned': read_cpus(cell_path + "/cpus_assigned"), - 'cpus_failed': read_cpus(cell_path + "/cpus_failed") - }) - -line_format = "%-8s%-24s%-16s%-24s%-24s" -if not cells == []: - print(line_format % ("ID", "Name", "State", - "Assigned CPUs", "Failed CPUs")) -for cell in sorted(cells, key=lambda cell: cell['id']): - print(line_format % (cell['id'], cell['name'], cell['state'], - print_cpus(cell['cpus_assigned']), - print_cpus(cell['cpus_failed']))) diff --git a/tools/jailhouse.c b/tools/jailhouse.c index 8a2a2b2..ea3c315 100644 --- a/tools/jailhouse.c +++ b/tools/jailhouse.c @@ -14,6 +14,7 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <dirent.h> #include <unistd.h> #include <fcntl.h> #include <errno.h> @@ -27,6 +28,7 @@ #define JAILHOUSE_EXEC_DIR LIBEXECDIR "/jailhouse" #define JAILHOUSE_DEVICE "/dev/jailhouse" +#define JAILHOUSE_CELLS "/sys/devices/jailhouse/cells/" enum shutdown_load_mode {LOAD, SHUTDOWN}; static int jailhouse_fd = -1; @@ -35,11 +37,17 @@ struct extension { char *cmd, *subcmd, *help; }; +struct jailhouse_cell_info { + struct jailhouse_cell_id id; + char *state; + char *cpus_assigned; + char *cpus_failed; +}; + static const struct extension extensions[] = { { "cell", "linux", "CELLCONFIG KERNEL [-i | --initrd FILE]\n" " [-c | --cmdline \"STRING\"] " "[-w | --write-params FILE]" }, - { "cell", "list", "" }, { "cell", "stats", "{ ID | [--name] NAME }" }, { "config", "create", "[-h] [-g] [-r ROOT] " "[--mem-inmates MEM_INMATES]\n" @@ -58,6 +66,7 @@ static void __attribute__((noreturn)) help(char *prog, int exit_status) " enable SYSCONFIG\n" " disable\n" " cell create CELLCONFIG\n" + " cell list\n" " cell load { ID | [--name] NAME } " "{ IMAGE | { -s | --string } \"STRING\" }\n" " [-a | --address ADDRESS] ...\n" @@ -185,6 +194,20 @@ static void *read_file(const char *name, size_t *size, bool respect_size) return buffer; } +static char *read_sysfs_entry(const char *name) +{ + char *ret; + size_t size; + + ret = read_file(name, &size, false); + + /* enforce the string to be null-terminated */ + if (size && ret[size-1] != '\0') + ret[size-1] = '\0'; + + return ret; +} + static int enable(int argc, char *argv[]) { void *config; @@ -267,6 +290,132 @@ static bool match_opt(const char *argv, const char *short_opt, strcmp(argv, long_opt) == 0; } +static struct jailhouse_cell_info *get_cell_info(const char *name) +{ + char buf[sizeof(JAILHOUSE_CELLS) + JAILHOUSE_CELL_ID_NAMELEN + + sizeof("/cpus_assigned") + 1]; + struct jailhouse_cell_info *cinfo; + char *tmp; + + cinfo = calloc(1, sizeof(struct jailhouse_cell_info)); + + /* copy cell name */ + strncpy(cinfo->id.name, name, JAILHOUSE_CELL_ID_NAMELEN); + + /* get cell id */ + snprintf(buf, sizeof(buf), JAILHOUSE_CELLS "/%s/id", cinfo->id.name); + tmp = read_sysfs_entry(buf); + cinfo->id.id = (__s32)strtol(tmp, NULL, 10); + free(tmp); + + /* get cell state */ + snprintf(buf, sizeof(buf), JAILHOUSE_CELLS "/%s/state", cinfo->id.name); + cinfo->state = read_sysfs_entry(buf); + + /* getassigned cpus */ + snprintf(buf, sizeof(buf), JAILHOUSE_CELLS "/%s/cpus_assigned", cinfo->id.name); + cinfo->cpus_assigned = read_sysfs_entry(buf); + + /* get failed cpus */ + snprintf(buf, sizeof(buf), JAILHOUSE_CELLS "/%s/cpus_failed", cinfo->id.name); + cinfo->cpus_failed = read_sysfs_entry(buf); + + return cinfo; +} + +static void cell_info_free(struct jailhouse_cell_info *cinfo) +{ + free(cinfo->state); + free(cinfo->cpus_assigned); + free(cinfo->cpus_failed); + free(cinfo); +} + +static char **get_cell_names(void) +{ + DIR *dir; + struct dirent *dent; + char **ret; + int num_cells = 0; + + ret = calloc(1, sizeof(char*)); + if (ret == NULL) { + perror("calloc"); + exit(1); + } + + dir = opendir(JAILHOUSE_CELLS); + if (dir == NULL) { + perror("opendir " JAILHOUSE_CELLS); + exit(1); + } + + while ((dent = readdir(dir)) != NULL) { + /* Skip hidden files, '.' and '..' */ + if (dent->d_name[0] == '.') + continue; + + ret = realloc(ret, (++num_cells+1) * sizeof(char*)); + if (ret == NULL) { + perror("realloc"); + exit(1); + } + + ret[num_cells-1] = strdup(dent->d_name); + if (ret[num_cells-1] == NULL) { + perror("strdup"); + exit(1); + } + + /* propagate null termination */ + ret[num_cells] = NULL; + } + + if (closedir(dir)) { + perror("closedir " JAILHOUSE_CELLS); + exit(1); + } + + return ret; +} + +static void cell_names_free(char **cell_names) +{ + char **cell_name; + for (cell_name = cell_names; *cell_name; cell_name++) + free(*cell_name); + free(cell_names); +} + +static int cell_list(int argc, char *argv[]) +{ + char **cell_names, **cell_name; + struct jailhouse_cell_info *cinfo; + (void)argv; + + if (argc != 3) + help(argv[0], 1); + + cell_names = get_cell_names(); + if (cell_names[0] == NULL) { + printf("No active jailhouse cells\n"); + goto out; + } + + printf("%-8s%-24s%-16s%-24s%-24s\n", + "ID", "Name", "State", "Assigned CPUs", "Failed CPUs"); + for (cell_name = cell_names; *cell_name; cell_name++) { + cinfo = get_cell_info(*cell_name); + printf("%-8d%-24s%-16s%-24s%-24s\n", cinfo->id.id, cinfo->id.name, cinfo->state, + cinfo->cpus_assigned, cinfo->cpus_failed); + cell_info_free(cinfo); + } + +out: + cell_names_free(cell_names); + return 0; +} + static int cell_shutdown_load(int argc, char *argv[], enum shutdown_load_mode mode) { @@ -378,6 +527,8 @@ static int cell_management(int argc, char *argv[]) if (strcmp(argv[2], "create") == 0) { err = cell_create(argc, argv); + } else if (strcmp(argv[2], "list") == 0) { + err = cell_list(argc, argv); } else if (strcmp(argv[2], "load") == 0) { err = cell_shutdown_load(argc, argv, LOAD); } else if (strcmp(argv[2], "start") == 0) { -- 2.9.2 -- You received this message because you are subscribed to the Google Groups "Jailhouse" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/d/optout.
