mirror of
https://github.com/ibm-s390-linux/s390-tools.git
synced 2026-08-05 02:14:52 +00:00
Add generation of shell autocompletion scripts. Acked-by: Steffen Eiden <seiden@linux.ibm.com> Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com> Signed-off-by: Szabina Korbai <szkorbai@linux.ibm.com> Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
186 lines
4.5 KiB
C
186 lines
4.5 KiB
C
/*
|
|
* lsscm - Show information about Storage Class Memory Increments
|
|
*
|
|
* Copyright IBM Corp. 2016, 2017
|
|
*
|
|
* s390-tools is free software; you can redistribute it and/or modify
|
|
* it under the terms of the MIT license. See LICENSE for details.
|
|
*/
|
|
|
|
#include <err.h>
|
|
|
|
#include "lib/util_base.h"
|
|
#include "lib/util_file.h"
|
|
#include "lib/util_opt.h"
|
|
#include "lib/util_panic.h"
|
|
#include "lib/util_path.h"
|
|
#include "lib/util_prg.h"
|
|
#include "lib/util_rec.h"
|
|
#include "lib/util_scandir.h"
|
|
#include "lib/zt_common.h"
|
|
|
|
#include "lsscm_cli.h"
|
|
|
|
/*
|
|
* Program configuration
|
|
*/
|
|
const struct util_prg prg = {
|
|
.desc = "List information about available Storage Class Memory Increments.",
|
|
.copyright_vec = {
|
|
{
|
|
.owner = "IBM Corp.",
|
|
.pub_first = 2016,
|
|
.pub_last = 2017,
|
|
},
|
|
UTIL_PRG_COPYRIGHT_END
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Print all attributes of one device
|
|
*
|
|
* @param[in] name Block device name, or NULL if scm_block.ko is not loaed
|
|
* @param[in] data Address of scm device
|
|
* @param[in] rec Container for tabular output
|
|
*/
|
|
static void print_scm_attrs(const char *name, const char *addr,
|
|
struct util_rec *rec)
|
|
{
|
|
long value;
|
|
char *path;
|
|
|
|
path = util_path_sysfs("bus/scm/devices/%s", addr);
|
|
|
|
util_rec_set(rec, "addr", addr);
|
|
if (name) {
|
|
util_rec_set(rec, "name", name);
|
|
if (util_file_read_l(&value, 10, "%s/block/%s/size", path, name))
|
|
goto out_free_path;
|
|
util_rec_set(rec, "size", "%ldMB", value * 512 / (1024 * 1024));
|
|
} else {
|
|
util_rec_set(rec, "name", "N/A");
|
|
util_rec_set(rec, "size", "%ldMB", 0);
|
|
}
|
|
|
|
if (util_file_read_l(&value, 10, "%s/rank", path))
|
|
goto out_free_path;
|
|
util_rec_set(rec, "rank", "%ld", value);
|
|
|
|
if (util_file_read_l(&value, 10, "%s/data_state", path))
|
|
goto out_free_path;
|
|
util_rec_set(rec, "dstate", "%ld", value);
|
|
|
|
if (util_file_read_l(&value, 10, "%s/oper_state", path))
|
|
goto out_free_path;
|
|
util_rec_set(rec, "ostate", "%ld", value);
|
|
|
|
if (util_file_read_l(&value, 10, "%s/persistence", path))
|
|
goto out_free_path;
|
|
util_rec_set(rec, "pers", "%ld", value);
|
|
|
|
if (util_file_read_l(&value, 10, "%s/res_id", path))
|
|
goto out_free_path;
|
|
util_rec_set(rec, "resid", "%ld", value);
|
|
|
|
util_rec_print(rec);
|
|
out_free_path:
|
|
free(path);
|
|
}
|
|
|
|
/**
|
|
* Print one scm block device
|
|
*
|
|
* @param[in] addr Address
|
|
* @param[in] rec Container for tabular output
|
|
*/
|
|
void print_scm(const char *addr, struct util_rec *rec)
|
|
{
|
|
struct dirent **de_vec;
|
|
char *path;
|
|
int count;
|
|
|
|
path = util_path_sysfs("bus/scm/devices/%s/block", addr);
|
|
/* Match scma..scmzz */
|
|
count = util_scandir(&de_vec, NULL, path, "^scm[[:lower:]]{1,2}$");
|
|
if (count < 0) {
|
|
/* If scm_block not loaded */
|
|
print_scm_attrs(NULL, addr, rec);
|
|
} else {
|
|
util_assert(count == 1, "We expect only one block device\n");
|
|
print_scm_attrs(de_vec[0]->d_name, addr, rec);
|
|
util_scandir_free(de_vec, count);
|
|
}
|
|
free(path);
|
|
}
|
|
|
|
/*
|
|
* Look for used scm increments
|
|
*/
|
|
static void cmd_lsscm(void)
|
|
{
|
|
struct dirent **de_vec;
|
|
struct util_rec *rec;
|
|
int i, count;
|
|
char *path;
|
|
|
|
rec = util_rec_new_wide("-");
|
|
util_rec_def(rec, "addr", UTIL_REC_ALIGN_LEFT, 16, "SCM Increment");
|
|
util_rec_def(rec, "size", UTIL_REC_ALIGN_LEFT, 7, "Size");
|
|
util_rec_def(rec, "name", UTIL_REC_ALIGN_LEFT, 5, "Name");
|
|
util_rec_def(rec, "rank", UTIL_REC_ALIGN_RIGHT, 4, "Rank");
|
|
util_rec_def(rec, "dstate", UTIL_REC_ALIGN_RIGHT, 7, "D_state");
|
|
util_rec_def(rec, "ostate", UTIL_REC_ALIGN_RIGHT, 7, "O_state");
|
|
util_rec_def(rec, "pers", UTIL_REC_ALIGN_RIGHT, 4, "Pers");
|
|
util_rec_def(rec, "resid", UTIL_REC_ALIGN_RIGHT, 5, "ResID");
|
|
|
|
util_rec_print_hdr(rec);
|
|
/* Call print_scm() for each "/sys/bus/scm/devices/[%16x]" softlink */
|
|
path = util_path_sysfs("bus/scm/devices");
|
|
count = util_scandir(&de_vec, util_scandir_hexsort,
|
|
path, "^[[:xdigit:]]{16}$");
|
|
if (count < 0)
|
|
errx(EXIT_FAILURE, "Could not read directory: %s", path);
|
|
for (i = 0; i < count; i++) {
|
|
if (de_vec[i]->d_type != DT_LNK)
|
|
continue;
|
|
print_scm(de_vec[i]->d_name, rec);
|
|
}
|
|
util_ptr_vec_free((void **) de_vec, count);
|
|
util_rec_free(rec);
|
|
free(path);
|
|
}
|
|
|
|
/*
|
|
* Entry point
|
|
*/
|
|
int main(int argc, char **argv)
|
|
{
|
|
int c;
|
|
|
|
util_prg_init(&prg);
|
|
util_opt_init(opt_vec, NULL);
|
|
while (1) {
|
|
c = util_opt_getopt_long(argc, argv);
|
|
if (c == -1)
|
|
break;
|
|
switch (c) {
|
|
case 'h':
|
|
util_prg_print_help();
|
|
util_opt_print_help();
|
|
return EXIT_SUCCESS;
|
|
case 'v':
|
|
util_prg_print_version();
|
|
return EXIT_SUCCESS;
|
|
default:
|
|
util_opt_print_parse_error(c, argv);
|
|
return EXIT_FAILURE;
|
|
}
|
|
}
|
|
if (argc > optind) {
|
|
util_prg_print_arg_error(argv[optind]);
|
|
return EXIT_FAILURE;
|
|
}
|
|
cmd_lsscm();
|
|
return EXIT_SUCCESS;
|
|
}
|