Files
s390-tools/ipl_tools/cmd_chshut.c
Michael Holzheu 221e74c27c Get rid of gcc 7 "fall through" warnings
With gcc 7 we get warnings like the following:

 fdasd.c: In function 'main':
 fdasd.c:3055:4: warning: this statement may fall through
                          [-Wimplicit-fallthrough=]
     fdasd_exit(&anchor, 0);
     ^~~~~~~~~~~~~~~~~~~~~~
 fdasd.c:3056:3: note: here
    default:
    ^~~~~~~

Fix this by marking functions with "__noreturn" to help gcc.

Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
2017-09-06 13:05:01 +02:00

162 lines
4.2 KiB
C

/*
* ipl_tools - Linux for System z reipl and shutdown tools
*
* Command: chshut
*
* Copyright IBM Corp. 2008, 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 "ipl_tools.h"
static const char *const usage_chshut =
"Usage: %s TRIGGER ACTION [COMMAND] [OPTIONS]\n"
"\n"
"Change the shutdown actions for Linux on System z.\n"
"\n"
"TRIGGER specifies when the action is performed:\n"
" halt System has been shut down (e.g. shutdown -h -H now)\n"
" poff System has been shut down for power off (e.g. shutdown -h -P now)\n"
" reboot System has been shut down for reboot (e.g. shutdown -r)\n"
" Note: Depending on the distribution, \"halt\" might be mapped to \"poff\".\n"
"\n"
"ACTION specifies the action to be performed:\n"
" ipl IPL with previous settings\n"
" reipl IPL with re-IPL settings (see chreipl)\n"
" stop Stop all CPUs\n"
" vmcmd Run z/VM CP command defined by COMMAND\n"
"\n"
"COMMAND defines the z/VM CP command to issue.\n"
"\n"
"OPTIONS:\n"
" -h, --help Print this help, then exit\n"
" -v, --version Print version information, then exit\n";
static void __noreturn print_usage_chshut_exit(void)
{
printf(usage_chshut, g.prog_name);
exit(0);
}
static void parse_chshut_options(int argc, char *argv[])
{
int opt, idx;
const struct option long_opts[] = {
{ "help", no_argument, NULL, 'h' },
{ "version", no_argument, NULL, 'v' },
{ NULL, 0, NULL, 0 }
};
while ((opt = getopt_long(argc, argv, "hv", long_opts, &idx)) != -1) {
switch (opt) {
case 'h':
print_usage_chshut_exit();
case 'v':
print_version_exit();
default:
print_help_hint_exit();
}
}
if (!is_root())
ERR_EXIT("You must be root to perform this operation");
}
static struct shutdown_trigger *shutdown_trigger_get(const char *trigger)
{
int i;
for (i = 0; shutdown_trigger_vec[i]; i++) {
if (strcmp(trigger, shutdown_trigger_vec[i]->name) != 0)
continue;
if (shutdown_trigger_vec[i]->available)
return shutdown_trigger_vec[i];
ERR_EXIT("Shutdown trigger \"%s\" is not available on "
"your system", trigger);
}
ERR_EXIT("Unknown shutdown trigger \"%s\" specified", trigger);
}
static struct shutdown_action *shutdown_action_get(const char *action)
{
int i;
for (i = 0; shutdown_action_vec[i]; i++) {
if (strcmp(action, shutdown_action_vec[i]->name) == 0)
return shutdown_action_vec[i];
}
ERR_EXIT("Unknown shutdown action \"%s\" specified", action);
}
/*
* Multiple CP commands can be specified via "vmcmd XY1 vmcmd XY2 ..."
*/
static void vmcmd_set(struct shutdown_trigger *st, int argc, char *argv[])
{
char vmcmd[1024], path[PATH_MAX];
int first = 1, i;
int vmcmd_length = 0;
if (is_lpar())
ERR_EXIT("vmcmd works only under z/VM");
memset(vmcmd, 0, sizeof(vmcmd));
for (i = 2; i < argc; i++) {
if (strcmp(argv[i], "vmcmd") != 0)
ERR_EXIT("Invalid vmcmd command specification");
if (i == argc - 1)
ERR_EXIT("vmcmd needs an additional argument");
if (!first) {
strcat(vmcmd, "\n");
vmcmd_length++;
} else {
first = 0;
}
vmcmd_length += strlen(argv[i + 1]);
if (vmcmd_length >= 127)
ERR_EXIT("The vmcmd command must not exceed 127 "
"characters");
strcat(vmcmd, argv[i + 1]);
i++;
}
sprintf(path, "vmcmd/%s", st->name_sysfs);
write_str(vmcmd, path);
}
void cmd_chshut(int argc, char *argv[])
{
struct shutdown_trigger *st;
struct shutdown_action *sa;
char path[PATH_MAX];
parse_chshut_options(argc, argv);
if (argc < 2) {
ERR("No trigger specified");
print_help_hint_exit();
}
shutdown_init();
st = shutdown_trigger_get(argv[1]);
if (st == &shutdown_trigger_panic ||
st == &shutdown_trigger_restart)
ERR_EXIT("Please use \"service dumpconf\" for "
"configuring the %s trigger",
st->name);
if (argc < 3) {
ERR("No action specified");
print_help_hint_exit();
}
sa = shutdown_action_get(argv[2]);
if (sa == &shutdown_action_vmcmd) {
vmcmd_set(st, argc, argv);
} else if (argc != 3) {
ERR("Too many parameters specified");
print_help_hint_exit();
}
sprintf(path, "shutdown_actions/%s", st->name_sysfs);
if (write_str_errno(argv[2], path))
ERR_EXIT_ERRNO("Could not set \"%s\"", path);
}