/* * ipl_tools - Linux for System z reipl and shutdown tools * * Command: lsreipl * * 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 "lib/util_path.h" #include "lib/util_file.h" #include "lib/util_libc.h" #include "ipl_tools.h" static struct { int ipl_set; /* --ipl has been specified */ } l; static const char *const usage_lsreipl = "Usage: %s [OPTIONS]\n" "\n" "Show re-IPL or IPL settings.\n" "\n" "OPTIONS:\n" " -i, --ipl Print the IPL setting\n" " -h, --help Print this help, then exit\n" " -v, --version Print version information, then exit\n"; static void __noreturn print_usage_lsreipl_exit(void) { printf(usage_lsreipl, g.prog_name); exit(0); } static const char *get_ipl_banner(int show_ipl) { if (show_ipl) return "IPL type:"; else return "Re-IPL type:"; } void print_nss(int show_ipl) { char *dir = show_ipl ? "ipl" : "reipl/nss"; char *path_bootparms = util_path_sysfs("firmware/%s/parm", dir); printf("%-12s nss\n", get_ipl_banner(show_ipl)); print_fw_str("Name: %s\n", dir, "name"); if (access(path_bootparms, R_OK) == 0) print_fw_str("Bootparms: \"%s\"\n", dir, "parm"); free(path_bootparms); } void print_fcp(int show_ipl, int dump) { char *dir = show_ipl ? "ipl" : "reipl/fcp"; char *path_bootparms = util_path_sysfs("firmware/%s/scp_data", dir); char *path_loadparm = util_path_sysfs("firmware/%s/loadparm", dir); char *path_reipl_clear = util_path_sysfs("firmware/reipl/fcp/clear"); char *path_secure_boot = util_path_sysfs("firmware/ipl/secure"); char *loadparm; if (dump) printf("%-12s fcp_dump\n", get_ipl_banner(show_ipl)); else printf("%-12s fcp\n", get_ipl_banner(show_ipl)); print_fw_str("WWPN: %s\n", dir, "wwpn"); print_fw_str("LUN: %s\n", dir, "lun"); print_fw_str("Device: %s\n", dir, "device"); print_fw_str("bootprog: %s\n", dir, "bootprog"); print_fw_str("br_lba: %s\n", dir, "br_lba"); if (access(path_loadparm, R_OK) == 0) { loadparm = util_file_read_text_file(path_loadparm, 1); util_strstrip(loadparm); printf("Loadparm: \"%s\"\n", loadparm); free(loadparm); } if (access(path_bootparms, R_OK) == 0) print_fw_str("Bootparms: \"%s\"\n", dir, "scp_data"); if (!show_ipl && access(path_reipl_clear, R_OK) == 0) print_fw_str("clear: %s\n", dir, "clear"); if (access(path_secure_boot, R_OK) == 0) print_fw_str("Secure boot: %s\n", "ipl", "secure"); free(path_bootparms); free(path_loadparm); free(path_reipl_clear); free(path_secure_boot); } void print_nvme(int show_ipl, int dump) { char *dir = show_ipl ? "ipl" : "reipl/nvme"; char *path_bootparms = util_path_sysfs("firmware/%s/scp_data", dir); char *path_loadparm = util_path_sysfs("firmware/%s/loadparm", dir); char *path_reipl_clear = util_path_sysfs("firmware/reipl/nvme/clear"); char *path_secure_boot = util_path_sysfs("firmware/ipl/secure"); char *loadparm; if (dump) printf("%-12s nvme_dump\n", get_ipl_banner(show_ipl)); else printf("%-12s nvme\n", get_ipl_banner(show_ipl)); print_fw_str("FID: %s\n", dir, "fid"); print_fw_str("NSID: %s\n", dir, "nsid"); print_fw_str("bootprog: %s\n", dir, "bootprog"); print_fw_str("br_lba: %s\n", dir, "br_lba"); if (access(path_loadparm, R_OK) == 0) { loadparm = util_file_read_text_file(path_loadparm, 1); util_strstrip(loadparm); printf("Loadparm: \"%s\"\n", loadparm); free(loadparm); } if (access(path_bootparms, R_OK) == 0) print_fw_str("Bootparms: \"%s\"\n", dir, "scp_data"); if (!show_ipl && access(path_reipl_clear, R_OK) == 0) print_fw_str("clear: %s\n", dir, "clear"); if (access(path_secure_boot, R_OK) == 0) print_fw_str("Secure boot: %s\n", "ipl", "secure"); free(path_bootparms); free(path_loadparm); free(path_reipl_clear); free(path_secure_boot); } void print_ccw(int show_ipl) { char *dir = show_ipl ? "ipl" : "reipl/ccw"; char *path_loadparm = util_path_sysfs("firmware/%s/loadparm", dir); char *path_bootparms = util_path_sysfs("firmware/%s/parm", dir); char *path_reipl_clear = util_path_sysfs("firmware/reipl/ccw/clear"); char *loadparm; printf("%-12s ccw\n", get_ipl_banner(show_ipl)); print_fw_str("Device: %s\n", dir, "device"); if (access(path_loadparm, R_OK) == 0) { loadparm = util_file_read_text_file(path_loadparm, 1); util_strstrip(loadparm); printf("Loadparm: \"%s\"\n", loadparm); free(loadparm); } if (access(path_bootparms, R_OK) == 0) print_fw_str("Bootparms: \"%s\"\n", dir, "parm"); if (!show_ipl && access(path_reipl_clear, R_OK) == 0) print_fw_str("clear: %s\n", dir, "clear"); free(path_loadparm); free(path_bootparms); free(path_reipl_clear); } void print_eckd(int show_ipl, const char *name) { char *dir = show_ipl ? "ipl" : "reipl/eckd"; char *path_loadparm = util_path_sysfs("firmware/%s/loadparm", dir); char *path_reipl_clear = util_path_sysfs("firmware/reipl/eckd/clear"); char *path_secure_boot = util_path_sysfs("firmware/ipl/secure"); char *loadparm; printf("%-12s %s\n", get_ipl_banner(show_ipl), name); print_fw_str("Device: %s\n", dir, "device"); print_fw_str("bootprog: %s\n", dir, "bootprog"); print_fw_str("br_chr: %s\n", dir, "br_chr"); print_fw_str("Bootparm: \"%s\"\n", dir, "scp_data"); if (access(path_loadparm, R_OK) == 0) { loadparm = util_file_read_text_file(path_loadparm, 1); util_strstrip(loadparm); printf("Loadparm: \"%s\"\n", loadparm); free(loadparm); } if (!show_ipl && access(path_reipl_clear, R_OK) == 0) print_fw_str("clear: %s\n", dir, "clear"); if (access(path_secure_boot, R_OK) == 0) print_fw_str("Secure boot: %s\n", "ipl", "secure"); free(path_loadparm); free(path_secure_boot); } static void parse_lsreipl_options(int argc, char *argv[]) { int opt, idx; const struct option long_opts[] = { { "help", no_argument, NULL, 'h' }, { "ipl", no_argument, NULL, 'i' }, { "version", no_argument, NULL, 'v' }, { NULL, 0, NULL, 0 } }; while ((opt = getopt_long(argc, argv, "hvi", long_opts, &idx)) != -1) { switch (opt) { case 'i': l.ipl_set = 1; break; case 'h': print_usage_lsreipl_exit(); case 'v': print_version_exit(); default: print_help_hint_exit(); } } /* don't run with too many arguments */ if (optind != argc) ERR_EXIT("Invalid positional parameter \"%s\" specified", argv[optind]); } void cmd_lsreipl(int argc, char *argv[]) { char *reipl_type_str; parse_lsreipl_options(argc, argv); if (l.ipl_set) reipl_type_str = read_fw_str("ipl/ipl_type"); else reipl_type_str = read_fw_str("reipl/reipl_type"); if (strcmp(reipl_type_str, "fcp") == 0) print_fcp(l.ipl_set, 0); else if (strcmp(reipl_type_str, "fcp_dump") == 0) print_fcp(l.ipl_set, 1); else if (strcmp(reipl_type_str, "nvme") == 0) print_nvme(l.ipl_set, 0); else if (strcmp(reipl_type_str, "nvme_dump") == 0) print_nvme(l.ipl_set, 1); else if (strcmp(reipl_type_str, "ccw") == 0) print_ccw(l.ipl_set); else if (strcmp(reipl_type_str, "eckd") == 0 || strcmp(reipl_type_str, "eckd_dump") == 0) print_eckd(l.ipl_set, reipl_type_str); else if (strcmp(reipl_type_str, "nss") == 0) print_nss(l.ipl_set); else printf("%s: %s (unknown)\n", get_ipl_banner(l.ipl_set), reipl_type_str); free(reipl_type_str); exit(0); }