diff --git a/0001-s390-tools-1.5.3-zipl-zfcpdump-2.patch b/0001-s390-tools-1.5.3-zipl-zfcpdump-2.patch new file mode 100644 index 0000000..c9d8a75 --- /dev/null +++ b/0001-s390-tools-1.5.3-zipl-zfcpdump-2.patch @@ -0,0 +1,27 @@ +From 2b8336a93376953ba0ed84223264be55243ac7f8 Mon Sep 17 00:00:00 2001 +From: Dan Horak +Date: Sun, 20 Jul 2008 09:24:05 +0200 +Subject: [PATCH 1/9] s390-tools-1.5.3-zipl-zfcpdump-2 + +--- + common.mak | 4 ++-- + 1 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/common.mak b/common.mak +index 8b248f1..0a7916e 100644 +--- a/common.mak ++++ b/common.mak +@@ -63,8 +63,8 @@ GROUP = $(shell id -gn) + export INSTROOT BINDIR LIBDIR MANDIR OWNER GROUP + + # Special defines for zfcpdump +-ZFCPDUMP_DIR = /usr/local/share/zfcpdump +-ZFCPDUMP_IMAGE = zfcpdump.image ++ZFCPDUMP_DIR = /boot ++ZFCPDUMP_IMAGE = zfcpdump + ZFCPDUMP_RD = zfcpdump.rd + export ZFCPDUMP_DIR ZFCPDUMP_IMAGE ZFCPDUMP_RD + +-- +1.6.3.3 + diff --git a/0002-s390-tools-1.8.1-zipl-automenu.patch b/0002-s390-tools-1.8.1-zipl-automenu.patch new file mode 100644 index 0000000..28ff804 --- /dev/null +++ b/0002-s390-tools-1.8.1-zipl-automenu.patch @@ -0,0 +1,423 @@ +From 2513c0f8096c681f962d77420dac731f7bb33e44 Mon Sep 17 00:00:00 2001 +From: =?utf-8?q?Dan=20Hor=C3=A1k?= +Date: Thu, 23 Apr 2009 11:45:36 +0200 +Subject: [PATCH 2/9] s390-tools-1.8.1-zipl-automenu + +--- + zipl/man/zipl.8 | 7 ++ + zipl/src/job.c | 194 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- + zipl/src/scan.c | 4 +- + zipl/src/zipl.c | 1 + + 4 files changed, 197 insertions(+), 9 deletions(-) + +diff --git a/zipl/man/zipl.8 b/zipl/man/zipl.8 +index 8a83c01..6ebf240 100644 +--- a/zipl/man/zipl.8 ++++ b/zipl/man/zipl.8 +@@ -249,6 +249,13 @@ whether they contain a dump signature or not. + This option can only be used together with + .BR \-\-mvdump . + ++.TP ++.BR "\-x" " or " "\-\-no-automenu" ++Disables the automatic creation of a multiboot menu. Specifying a menu with the ++"-m " option or a section disables this feature, too. This option was ++added for compatibility with previous versions of the multiboot version of ++zipl. ++ + .SH EXAMPLE + 1. Scenario: prepare disk for booting a Linux kernel image using the + following parameters: +diff --git a/zipl/src/job.c b/zipl/src/job.c +index c5c85d8..6a526e4 100644 +--- a/zipl/src/job.c ++++ b/zipl/src/job.c +@@ -43,6 +43,7 @@ static struct option options[] = { + { "version", no_argument, NULL, 'v'}, + { "verbose", no_argument, NULL, 'V'}, + { "add-files", no_argument, NULL, 'a'}, ++ { "no-automenu", no_argument, NULL, 'x'}, + { "tape", required_argument, NULL, 'T'}, + { "dry-run", no_argument, NULL, '0'}, + { "force", no_argument, NULL, 'f'}, +@@ -50,7 +51,7 @@ static struct option options[] = { + }; + + /* Command line option abbreviations */ +-static const char option_string[] = "-c:t:i:r:p:P:d:D:M:s:m:hHnVvaT:f"; ++static const char option_string[] = "-c:t:i:r:p:P:d:D:M:s:m:hHnVvaxT:f"; + + struct command_line { + char* data[SCAN_KEYWORD_NUM]; +@@ -62,11 +63,14 @@ struct command_line { + int version; + int verbose; + int add_files; ++ int automenu; + int dry_run; + int force; + enum scan_section_type type; + }; + ++/* Global variable for default boot target. Ugly but necessary... */ ++static char *default_target; + + static int + store_option(struct command_line* cmdline, enum scan_keyword_id keyword, +@@ -92,6 +96,7 @@ get_command_line(int argc, char* argv[], struct command_line* line) + int i; + + memset((void *) &cmdline, 0, sizeof(struct command_line)); ++ cmdline.automenu = 1; + cmdline.type = section_invalid; + is_keyword = 0; + /* Process options */ +@@ -101,16 +106,22 @@ get_command_line(int argc, char* argv[], struct command_line* line) + switch (opt) { + case 'd': + is_keyword = 1; ++ cmdline.automenu = 0; ++ scan_key_table[1][8] = req; + rc = store_option(&cmdline, scan_keyword_dumpto, + optarg); + break; + case 'D': + is_keyword = 1; ++ cmdline.automenu = 0; ++ scan_key_table[1][8] = req; + rc = store_option(&cmdline, scan_keyword_dumptofs, + optarg); + break; + case 'M': + is_keyword = 1; ++ cmdline.automenu = 0; ++ scan_key_table[1][8] = req; + rc = store_option(&cmdline, scan_keyword_mvdump, + optarg); + #ifndef __s390x__ +@@ -121,35 +132,49 @@ get_command_line(int argc, char* argv[], struct command_line* line) + break; + case 'i': + is_keyword = 1; ++ cmdline.automenu = 0; ++ scan_key_table[1][8] = req; + rc = store_option(&cmdline, scan_keyword_image, + optarg); + break; + case 'P': ++ cmdline.automenu = 0; ++ scan_key_table[1][8] = req; + rc = store_option(&cmdline, scan_keyword_parameters, + optarg); + break; + case 'p': + is_keyword = 1; ++ cmdline.automenu = 0; ++ scan_key_table[1][8] = req; + rc = store_option(&cmdline, scan_keyword_parmfile, + optarg); + break; + case 'r': + is_keyword = 1; ++ cmdline.automenu = 0; ++ scan_key_table[1][8] = req; + rc = store_option(&cmdline, scan_keyword_ramdisk, + optarg); + break; + case 's': + is_keyword = 1; ++ cmdline.automenu = 0; ++ scan_key_table[1][8] = req; + rc = store_option(&cmdline, scan_keyword_segment, + optarg); + break; + case 't': + is_keyword = 1; ++ cmdline.automenu = 0; ++ scan_key_table[1][8] = req; + rc = store_option(&cmdline, scan_keyword_target, + optarg); + break; + case 'T': + is_keyword = 1; ++ cmdline.automenu = 0; ++ scan_key_table[1][8] = req; + rc = store_option(&cmdline, scan_keyword_tape, + optarg); + break; +@@ -190,6 +215,10 @@ get_command_line(int argc, char* argv[], struct command_line* line) + case 'f': + cmdline.force = 1; + break; ++ case 'x': ++ cmdline.automenu = 0; ++ scan_key_table[1][8] = req; ++ break; + case 1: + /* Non-option is interpreted as section name */ + if (cmdline.section != NULL) { +@@ -214,6 +243,9 @@ get_command_line(int argc, char* argv[], struct command_line* line) + if (cmdline.help || cmdline.version) { + /* Always accept --help and --version */ + } else if ((cmdline.menu != NULL) || (cmdline.section != NULL)) { ++ /* If either menu or section has been selected disable ++ automenu generation */ ++ cmdline.automenu = 0; + /* Config file mode */ + if ((cmdline.menu != NULL) && (cmdline.section != NULL)) { + error_reason("Option 'menu' cannot be used when " +@@ -832,7 +864,14 @@ get_job_from_section_data(char* data[], struct job_data* job, char* section) + /* IPL job */ + job->id = job_ipl; + /* Fill in name of bootmap directory */ +- job->bootmap_dir = misc_strdup(data[(int) scan_keyword_target]); ++ if (data[(int) scan_keyword_target] == NULL) { ++ if (default_target == NULL) { ++ error_text("Unable to find default section in your config file."); ++ break; ++ } ++ job->bootmap_dir = misc_strdup(default_target); ++ } else ++ job->bootmap_dir = misc_strdup(data[(int) scan_keyword_target]); + if (job->bootmap_dir == NULL) + return -1; + /* Fill in name and address of image file */ +@@ -1102,6 +1141,8 @@ get_menu_job(struct scan_token* scan, char* menu, struct job_data* job) + if (temp_job == NULL) + return -1; + memset((void *) temp_job, 0, sizeof(struct job_data)); ++ if (data[(int) scan_keyword_target] == NULL) ++ data[(int) scan_keyword_target] = misc_strdup(job->bootmap_dir); + rc = get_job_from_section_data(data, temp_job, + job->data.menu.entry[current].name); + if (rc) { +@@ -1150,6 +1191,7 @@ get_default_section(struct scan_token* scan, char** section, int* is_menu) + i = scan_find_section(scan, DEFAULTBOOT_SECTION, + scan_id_section_heading, 0); + if (i<0) { ++ *section = NULL; + error_reason("No '" DEFAULTBOOT_SECTION "' section found and " + "no section specified on command line"); + return -1; +@@ -1169,6 +1211,7 @@ get_default_section(struct scan_token* scan, char** section, int* is_menu) + } + } + /* Should not happen */ ++ *section = NULL; + error_reason("No default section specified"); + return -1; + } +@@ -1184,19 +1227,35 @@ get_section_job(struct scan_token* scan, char* section, struct job_data* job, + { + char* data[SCAN_KEYWORD_NUM]; + char* buffer; ++ char* default_section; + int rc; + int i; + ++ rc = get_default_section(scan, &default_section, &i); ++ if (rc) ++ return rc; + if (section == NULL) { +- rc = get_default_section(scan, §ion, &i); +- if (rc) +- return rc; ++ section = default_section; + if (i) { + /* 'defaultmenu' was specified */ + rc = get_menu_job(scan, section, job); + return rc; + } + } ++ else ++ { ++ char* name = NULL; ++ ++ for (i = 0; (int) scan[i].id != 0; i++) { ++ if (scan[i].id == scan_id_section_heading) { ++ name = scan[i].content.section.name; ++ } ++ if (scan[i].id == scan_id_keyword_assignment && ++ scan[i].content.keyword.keyword == scan_keyword_target && ++ !strcmp(DEFAULTBOOT_SECTION, name)) ++ default_target = misc_strdup(scan[i].content.keyword.value); ++ } ++ } + if (strcmp(section, DEFAULTBOOT_SECTION) == 0) { + error_reason("Special section '" DEFAULTBOOT_SECTION "' cannot " + "be used as target section"); +@@ -1268,10 +1327,118 @@ get_section_job(struct scan_token* scan, char* section, struct job_data* job, + } + + ++/* Create a fake menu to simulate the old s390utils-1.1.7 multiboot ++ * behaviour. */ ++static struct scan_token * ++create_fake_menu(struct scan_token *scan) ++{ ++ int i, j, pos, numsec, size, defaultpos; ++ char *name; ++ char *target; ++ char *timeout; ++ char *seclist[1024]; ++ char *defaultsection; ++ char buf[1024]; ++ struct scan_token *tmp; ++ ++ /* Count # of sections */ ++ numsec = 0; ++ name = NULL; ++ target = NULL; ++ timeout = NULL; ++ for (i = 0; (int) scan[i].id != 0; i++) { ++ if (scan[i].id == scan_id_section_heading) { ++ name = scan[i].content.section.name; ++ if (strcmp(DEFAULTBOOT_SECTION, name)) ++ seclist[numsec++] = name; ++ } ++ if (scan[i].id == scan_id_keyword_assignment && ++ (scan[i].content.keyword.keyword == scan_keyword_dumpto || ++ scan[i].content.keyword.keyword == scan_keyword_dumptofs)) { ++ numsec--; ++ continue; ++ } ++ if (scan[i].id == scan_id_keyword_assignment && ++ scan[i].content.keyword.keyword == scan_keyword_target && ++ !strcmp(DEFAULTBOOT_SECTION, name)) ++ target = scan[i].content.keyword.value; ++ ++ if (scan[i].id == scan_id_keyword_assignment && ++ scan[i].content.keyword.keyword == scan_keyword_timeout) ++ timeout = scan[i].content.keyword.value; ++ } ++ get_default_section(scan, &defaultsection, &j); ++ ++ if (defaultsection == NULL) { ++ error_text("Unable to find default section in your config file."); ++ return NULL; ++ } ++ ++ if (target == NULL) { ++ error_text("Keyword target is missing in default section."); ++ return NULL; ++ } ++ ++ default_target = misc_strdup(target); ++ ++ size = i+6+numsec; ++ tmp = (struct scan_token *) misc_malloc(size * sizeof(struct scan_token)); ++ if (tmp == NULL) { ++ error_text("Couldn't allocate memory for menu entries"); ++ return NULL; ++ } ++ ++ memset(tmp, 0, size * sizeof(struct scan_token)); ++ memcpy(tmp, scan, i * sizeof(struct scan_token)); ++ free(scan); ++ scan = tmp; ++ ++ defaultpos = 0; ++ for (j = 0; j < numsec; j++) { ++ if (!strcmp(defaultsection, seclist[j])) ++ defaultpos = j+1; ++ } ++ ++ snprintf(buf, 1024, "%d", defaultpos); ++ ++ scan[i].id = scan_id_menu_heading; ++ scan[i].line = i; ++ scan[i++].content.menu.name = misc_strdup("rh-automatic-menu"); ++ scan[i].id = scan_id_keyword_assignment; ++ scan[i].line = i; ++ scan[i].content.keyword.keyword = scan_keyword_target; ++ scan[i++].content.keyword.value = misc_strdup(target); ++ scan[i].id = scan_id_keyword_assignment; ++ scan[i].line = i; ++ scan[i].content.keyword.keyword = scan_keyword_default; ++ scan[i++].content.keyword.value = misc_strdup(buf); ++ scan[i].id = scan_id_keyword_assignment; ++ scan[i].line = i; ++ scan[i].content.keyword.keyword = scan_keyword_prompt; ++ scan[i++].content.keyword.value = misc_strdup("1"); ++ scan[i].id = scan_id_keyword_assignment; ++ scan[i].line = i; ++ scan[i].content.keyword.keyword = scan_keyword_timeout; ++ if (timeout) ++ scan[i++].content.keyword.value = misc_strdup(timeout); ++ else ++ scan[i++].content.keyword.value = misc_strdup("15"); ++ ++ pos = i; ++ for (i = 0; iautomenu) { ++ nscan = create_fake_menu(scan); ++ if (nscan == NULL) { ++ scan_free(scan); ++ return -1; ++ } ++ scan = nscan; ++ } ++ + /* Get job from config file data */ +- if (cmdline->menu != NULL) ++ if (cmdline->menu != NULL || cmdline->automenu) { ++ if (cmdline->automenu) ++ cmdline->menu = misc_strdup("rh-automatic-menu"); + rc = get_menu_job(scan, cmdline->menu, job); ++ } + else { + rc = get_section_job(scan, cmdline->section, job, + cmdline->data[(int) scan_keyword_parameters]); +diff --git a/zipl/src/scan.c b/zipl/src/scan.c +index 9948092..caca3cf 100644 +--- a/zipl/src/scan.c ++++ b/zipl/src/scan.c +@@ -33,9 +33,9 @@ enum scan_key_state scan_key_table[SCAN_SECTION_NUM][SCAN_KEYWORD_NUM] = { + * rs enu + */ + /* defaultboot */ +- {opt, inv, inv, inv, inv, inv, inv, inv, inv, inv, inv, opt, inv, inv}, ++ {opt, inv, inv, inv, inv, inv, inv, inv, req, inv, opt, opt, inv, inv}, + /* ipl */ +- {inv, inv, inv, req, opt, opt, opt, inv, req, inv, inv, inv, inv, inv}, ++ {inv, inv, inv, req, opt, opt, opt, inv, opt, inv, inv, inv, inv, inv}, + /* segment load */ + {inv, inv, inv, inv, inv, inv, inv, req, req, inv, inv, inv, inv, inv}, + /* part dump */ +diff --git a/zipl/src/zipl.c b/zipl/src/zipl.c +index 9cb764c..4d9fd36 100644 +--- a/zipl/src/zipl.c ++++ b/zipl/src/zipl.c +@@ -73,6 +73,7 @@ static const char* usage_text[] = { + "-n, --noninteractive Answer all confirmation questions with 'yes'", + "-V, --verbose Provide more verbose output", + "-a, --add-files Add all referenced files to bootmap file", ++"-x, --no-automenu Don't autogenerate multiboot menu", + " --dry-run Simulate run but don't modify IPL records" + }; + +-- +1.6.3.3 + diff --git a/0003-s390-tools-1.8.1-fdasd-su.patch b/0003-s390-tools-1.8.1-fdasd-su.patch new file mode 100644 index 0000000..ac49f37 --- /dev/null +++ b/0003-s390-tools-1.8.1-fdasd-su.patch @@ -0,0 +1,33 @@ +From f8acd63e169cdec39c47ac0d8c1b98e115cf24a1 Mon Sep 17 00:00:00 2001 +From: =?utf-8?q?Dan=20Hor=C3=A1k?= +Date: Thu, 23 Apr 2009 11:46:01 +0200 +Subject: [PATCH 3/9] s390-tools-1.8.1-fdasd-su + +--- + fdasd/fdasd.c | 10 ++++++---- + 1 files changed, 6 insertions(+), 4 deletions(-) + +diff --git a/fdasd/fdasd.c b/fdasd/fdasd.c +index aa16659..3a54968 100644 +--- a/fdasd/fdasd.c ++++ b/fdasd/fdasd.c +@@ -2009,10 +2009,12 @@ fdasd_get_geometry (fdasd_anchor_t *anc) + if (anc->verbose) printf("disk type check : ok\n"); + + if (dasd_info.FBA_layout != 0) { +- snprintf(err_str, ERROR_STRING_SIZE, +- "%s is not formatted with z/OS compatible " +- "disk layout!", options.device); +- fdasd_error(anc, wrong_disk_format, err_str); ++ if(!anc->silent) { ++ snprintf(err_str, ERROR_STRING_SIZE, ++ "%s is not formatted with z/OS compatible " ++ "disk layout!", options.device); ++ fdasd_error(anc, wrong_disk_format, err_str); ++ } + } + + if (anc->verbose) printf("disk layout check : ok\n"); +-- +1.6.3.3 + diff --git a/0004-s390-tools-1.8.1-fdasd-raid-lvm.patch b/0004-s390-tools-1.8.1-fdasd-raid-lvm.patch new file mode 100644 index 0000000..da27e0a --- /dev/null +++ b/0004-s390-tools-1.8.1-fdasd-raid-lvm.patch @@ -0,0 +1,153 @@ +From 35298f5f9512835071b8c08e843731bbfbb15b7e Mon Sep 17 00:00:00 2001 +From: =?utf-8?q?Dan=20Hor=C3=A1k?= +Date: Thu, 23 Apr 2009 11:46:16 +0200 +Subject: [PATCH 4/9] s390-tools-1.8.1-fdasd-raid-lvm + +--- + fdasd/fdasd.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++---------- + 1 files changed, 53 insertions(+), 12 deletions(-) + +diff --git a/fdasd/fdasd.c b/fdasd/fdasd.c +index 3a54968..a526d7f 100644 +--- a/fdasd/fdasd.c ++++ b/fdasd/fdasd.c +@@ -258,10 +258,10 @@ fdasd_error(fdasd_anchor_t *anc, enum fdasd_failure why, char *str) + static int + read_line(void) + { +- bzero(line_buffer, LINE_LENGTH); + line_ptr = line_buffer; + if (!fgets(line_buffer, LINE_LENGTH, stdin)) + return 0; ++ line_buffer[LINE_LENGTH-1] = 0; + while (*line_ptr && !isgraph(*line_ptr)) + line_ptr++; + return *line_ptr; +@@ -312,6 +312,10 @@ fdasd_partition_type (char *str) + strcpy(str, "Linux native"); + else if (strncmp("SWAP ", str, 6) == 0) + strcpy(str, "Linux swap"); ++ else if (strncmp("RAID ", str, 6) == 0) ++ strcpy(str, "Linux Raid"); ++ else if (strncmp("LVM ", str, 6) == 0) ++ strcpy(str, "Linux LVM"); + else + strcpy(str, "unknown"); + +@@ -1122,14 +1126,24 @@ fdasd_write_vtoc_labels (fdasd_anchor_t *anc) + strncpy(c1, s2, 31); + } + else { ++ char str[20]; + char *tmp = strstr(ch, "SWAP"); ++ char *tmp1 = strstr(ch, "RAID"); + + /* create a new data set name */ + while (getpos(anc, k) > -1) + k++; + + setpos(anc, k, i-1); +- ++ ++ strncpy(s2, ch, 44); ++ s2[44]=0; ++ vtoc_ebcdic_dec(s2, s2, 44); ++ c2 = strstr(s2, "PART"); ++ if (c2 != NULL) strncpy(str, c2+=9, 6); ++ str[6] = '\0'; ++ fdasd_partition_type(str); ++ + strncpy(ch, "LINUX.V " + " ", 44); + +@@ -1145,10 +1159,21 @@ fdasd_write_vtoc_labels (fdasd_anchor_t *anc) + strncpy(c1, dsno, 4); + + c1 += 4; +- if (tmp) +- strncpy(c1, ".SWAP", 5); +- else +- strncpy(c1, ".NATIVE", 7); ++ if (tmp || tmp1) { ++ if (tmp) ++ strncpy(c1, ".SWAP", 5); ++ if (tmp1) ++ strncpy(c1, ".RAID", 5); ++ } else { ++ if (strcmp("unknown", str) == 0) { ++ strncpy(c1, ".NATIVE", 7); ++ } ++ else { ++ strncpy(c1, ".", 1); ++ strncpy(c1+1, c2, 6); ++ } ++ } ++ + } + vtoc_ebcdic_enc(ch, ch, 44); + if (anc->verbose) printf("%2x ", part_info->f1->DS1FMTID); +@@ -1433,9 +1458,10 @@ fdasd_change_part_type (fdasd_anchor_t *anc) + + printf("current partition type is: %s\n\n", fdasd_partition_type(str)); + printf(" 1 Linux native\n" \ +- " 2 Linux swap\n\n"); ++ " 2 Linux swap\n" \ ++ " 3 Linux raid\n\n"); + part_type = 0; +- while ((part_type < 1) || (part_type > 2)) { ++ while ((part_type < 1) || (part_type > 3)) { + while (!isdigit(part_type = + read_char("new partition type: "))); + part_type -= 48; +@@ -1448,6 +1474,9 @@ fdasd_change_part_type (fdasd_anchor_t *anc) + case 2: + strncpy(str, "SWAP ", 6); + break; ++ case 3: ++ strncpy(str, "RAID ", 6); ++ break; + default: + printf("'%d' is not supported!\n", part_type); + } +@@ -1625,7 +1654,7 @@ fdasd_process_invalid_vtoc(fdasd_anchor_t *anc) + static void + fdasd_process_valid_vtoc(fdasd_anchor_t *anc, unsigned long blk) + { +- int f1_counter = 0, f7_counter = 0, f5_counter = 0; ++ int f1_counter = 0, f7_counter = 0, f5_counter = 0, oldfmt = 0; + int i, part_no, f1_size = sizeof(format1_label_t); + partition_info_t *part_info = anc->first; + format1_label_t f1_label; +@@ -1677,14 +1706,26 @@ fdasd_process_valid_vtoc(fdasd_anchor_t *anc, unsigned long blk) + vtoc_ebcdic_enc(part_info->f1->DS1DSNAM, + part_info->f1->DS1DSNAM, 44); + +- if ((part_no < 0) || (part_no >= USABLE_PARTITIONS)) ++ /* this dasd has data set names 0000-0002 ++ but we use now 0001-0003 */ ++ if (part_no == -1) ++ oldfmt++; ++ ++ if (((oldfmt == 0) && (part_no < 0)) ++ || (part_no >= USABLE_PARTITIONS)) + printf("WARNING: partition number (%i) found " + "in data set name of an existing " + "partition\ndoes not match range of " + "possible partition numbers (1-%d)\n\n", + part_no + 1, USABLE_PARTITIONS); +- else +- setpos(anc, part_no, f1_counter); ++ else { ++ if (oldfmt) /* correct +1 */ { ++ setpos(anc, part_no+1, f1_counter); ++ printf("Correcting f1 header number!\n"); ++ } ++ else ++ setpos(anc, part_no, f1_counter); ++ } + + part_info = part_info->next; + f1_counter++; +-- +1.6.3.3 + diff --git a/0005-don-t-create-automenu-when-default-menu-exists.patch b/0005-don-t-create-automenu-when-default-menu-exists.patch new file mode 100644 index 0000000..1cad83c --- /dev/null +++ b/0005-don-t-create-automenu-when-default-menu-exists.patch @@ -0,0 +1,59 @@ +From 1efcfe8d7ad20f7a3f584628375da60682b4579c Mon Sep 17 00:00:00 2001 +From: =?utf-8?q?Dan=20Hor=C3=A1k?= +Date: Thu, 23 Apr 2009 15:28:06 +0200 +Subject: [PATCH 5/9] don't create automenu when default menu exists + +--- + zipl/src/job.c | 25 +++++++++++++++---------- + 1 files changed, 15 insertions(+), 10 deletions(-) + +diff --git a/zipl/src/job.c b/zipl/src/job.c +index 6a526e4..89c8c23 100644 +--- a/zipl/src/job.c ++++ b/zipl/src/job.c +@@ -1441,6 +1441,8 @@ get_job_from_config_file(struct command_line* cmdline, struct job_data* job) + struct scan_token* scan, *nscan; + char* filename; + char* source; ++ char* default_section; ++ int is_menu; + int rc; + + /* Read configuration file */ +@@ -1470,20 +1472,23 @@ get_job_from_config_file(struct command_line* cmdline, struct job_data* job) + scan_free(scan); + return rc; + } +- +- if (cmdline->automenu) { +- nscan = create_fake_menu(scan); +- if (nscan == NULL) { +- scan_free(scan); +- return -1; +- } +- scan = nscan; +- } ++ ++ /* disable automenu iff default menu exists */ ++ rc = get_default_section(scan, &default_section, &is_menu); ++ if (!rc && is_menu) ++ cmdline->automenu = 0; + + /* Get job from config file data */ + if (cmdline->menu != NULL || cmdline->automenu) { +- if (cmdline->automenu) ++ if (cmdline->automenu) { ++ nscan = create_fake_menu(scan); ++ if (nscan == NULL) { ++ scan_free(scan); ++ return -1; ++ } ++ scan = nscan; + cmdline->menu = misc_strdup("rh-automatic-menu"); ++ } + rc = get_menu_job(scan, cmdline->menu, job); + } + else { +-- +1.6.3.3 + diff --git a/0006-s390-tools-1.8.1-zipl-kdump-man.patch b/0006-s390-tools-1.8.1-zipl-kdump-man.patch new file mode 100644 index 0000000..cdbcf37 --- /dev/null +++ b/0006-s390-tools-1.8.1-zipl-kdump-man.patch @@ -0,0 +1,31 @@ +From 894de5382653e4389dc8490f2ee4a2a9c59eb86d Mon Sep 17 00:00:00 2001 +From: =?utf-8?q?Dan=20Hor=C3=A1k?= +Date: Fri, 19 Jun 2009 10:01:30 +0200 +Subject: [PATCH 6/9] s390-tools-1.8.1-zipl-kdump-man + +Description: Add kdump kernel installation instruction to zipl man page. +Symptom: User wants to prepare SCSI disk for dump, but has not installed + the kdump kernel rpm. +Problem: The installation of the kdump kernel rpm is prereq for preparing + a SCSI dump disk for dump. +Solution: Document that in the zipl man page. +--- + zipl/man/zipl.8 | 2 ++ + 1 files changed, 2 insertions(+), 0 deletions(-) + +diff --git a/zipl/man/zipl.8 b/zipl/man/zipl.8 +index 6ebf240..6df6026 100644 +--- a/zipl/man/zipl.8 ++++ b/zipl/man/zipl.8 +@@ -176,6 +176,8 @@ will be incomplete. + It is not possible to specify both this parameter and the name of a menu + or configuration section on the command line at the same time. + ++.B Note that before using this option the "kernel-kdump" rpm has to be ++.B installed. + .TP + .BR "\-M " " or " "--mvdump=" + Install a multi-volume dump record on each device associated with one of the +-- +1.6.3.3 + diff --git a/0007-s390-tools-1.8.1-lszfcp-perf.patch b/0007-s390-tools-1.8.1-lszfcp-perf.patch new file mode 100644 index 0000000..47bd955 --- /dev/null +++ b/0007-s390-tools-1.8.1-lszfcp-perf.patch @@ -0,0 +1,25 @@ +From 80e1e88e108b774c7aa7c201326f1a92cf1b7e35 Mon Sep 17 00:00:00 2001 +From: =?utf-8?q?Dan=20Hor=C3=A1k?= +Date: Wed, 26 Aug 2009 14:21:14 +0200 +Subject: [PATCH 7/9] s390-tools-1.8.1-lszfcp-perf + +--- + zconf/lszfcp | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +diff --git a/zconf/lszfcp b/zconf/lszfcp +index d0bf84f..a872d05 100755 +--- a/zconf/lszfcp ++++ b/zconf/lszfcp +@@ -233,7 +233,7 @@ show_devices() + # Differentiate old and new sysfs layout + if $FC_CLASS; then + SCSI_DEVICE_LIST=`ls -d \ +- $SYSFS/devices/css0/*/*/host*/rport*/target*/*/ \ ++ $SYSFS/bus/ccw/drivers/zfcp/*/host*/rport*/target*/*/ \ + 2>/dev/null |grep -P '\d+:\d+:\d+:\d+'` + else + SCSI_DEVICE_LIST=`ls -d $SYSFS/devices/css0/*/*/host*/*/` +-- +1.6.3.3 + diff --git a/0008-fix-string-overflow-in-vtoc_volume_label_init.patch b/0008-fix-string-overflow-in-vtoc_volume_label_init.patch new file mode 100644 index 0000000..790ebad --- /dev/null +++ b/0008-fix-string-overflow-in-vtoc_volume_label_init.patch @@ -0,0 +1,28 @@ +From d0c06736586d8f85f2e7c64291f3f289c12a0caa Mon Sep 17 00:00:00 2001 +From: =?utf-8?q?Dan=20Hor=C3=A1k?= +Date: Thu, 24 Sep 2009 09:12:39 +0200 +Subject: [PATCH 8/9] fix string overflow in vtoc_volume_label_init + +Originaly it tries to copy a 84B string into 4B field and reset also +the other fields thru the overflow. This doesn't work with recent GCC +and the security-related compile flags that are used in Fedora. +--- + libvtoc/vtoc.c | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +diff --git a/libvtoc/vtoc.c b/libvtoc/vtoc.c +index 62a02a0..cebd5a4 100644 +--- a/libvtoc/vtoc.c ++++ b/libvtoc/vtoc.c +@@ -326,7 +326,7 @@ void vtoc_volume_label_init (volume_label_t *vlabel) + { + sprintf(buffer, "%84s", " "); + vtoc_ebcdic_enc(buffer, buffer, 84); +- strncpy(vlabel->volkey, buffer, 84); ++ memcpy(vlabel, buffer, 84); + } + + +-- +1.6.3.3 + diff --git a/0009-change-default-load-address-for-ramdisk.patch b/0009-change-default-load-address-for-ramdisk.patch new file mode 100644 index 0000000..f0b8d73 --- /dev/null +++ b/0009-change-default-load-address-for-ramdisk.patch @@ -0,0 +1,27 @@ +From 1697d4f40be133c78cd09fb0af14af22e8c6219e Mon Sep 17 00:00:00 2001 +From: =?utf-8?q?Dan=20Hor=C3=A1k?= +Date: Sun, 4 Oct 2009 17:46:16 +0200 +Subject: [PATCH 9/9] change default load address for ramdisk + +The default load address for the initial ramdisk is changed from +0x800000 to 0x2000000 to allow larger kernels to be loaded. +--- + zipl/include/zipl.h | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +diff --git a/zipl/include/zipl.h b/zipl/include/zipl.h +index 1f70e48..d2d26dd 100644 +--- a/zipl/include/zipl.h ++++ b/zipl/include/zipl.h +@@ -22,7 +22,7 @@ + #define DEFAULT_PARMFILE_ADDRESS 0x1000LL + #define DEFAULT_STAGE3_ADDRESS 0xa000LL + #define DEFAULT_IMAGE_ADDRESS 0x10000LL +-#define DEFAULT_RAMDISK_ADDRESS 0x800000LL ++#define DEFAULT_RAMDISK_ADDRESS 0x2000000LL + + #define PSW_ADDRESS_MASK 0x000000007fffffffLL + #define PSW_LOAD 0x0008000080000000LL +-- +1.6.3.3 + diff --git a/0010-improve-mon_statd-init-script.patch b/0010-improve-mon_statd-init-script.patch new file mode 100644 index 0000000..0d91681 --- /dev/null +++ b/0010-improve-mon_statd-init-script.patch @@ -0,0 +1,189 @@ +From 7cd1f2254e27cae8e061d1b42fa6c78bc10a5f39 Mon Sep 17 00:00:00 2001 +From: =?utf-8?q?Dan=20Hor=C3=A1k?= +Date: Thu, 8 Oct 2009 10:29:23 +0200 +Subject: [PATCH] improve mon_statd init script + +- stop: do not print error messages if a daemon is not configured +- start: do not load module if no daemon is configured +- remove useless newlines +--- + etc/init.d/mon_statd | 113 ++++++++++++++++++++++++++++---------------------- + 1 files changed, 64 insertions(+), 49 deletions(-) + +diff --git a/etc/init.d/mon_statd b/etc/init.d/mon_statd +index 4d84b5b..60bcf00 100755 +--- a/etc/init.d/mon_statd ++++ b/etc/init.d/mon_statd +@@ -22,7 +22,6 @@ PROCD_PATH=/usr/sbin/$PROCD + CONFIG_FILE=/etc/sysconfig/$DAEMON + FSSTATD_PID_FILE=/var/run/$FSSTATD.pid + PROCD_PID_FILE=/var/run/$PROCD.pid +-RETVAL=0 + + # source function library + . /lib/lsb/init-functions +@@ -32,68 +31,81 @@ if [ -f $CONFIG_FILE ]; then + . $CONFIG_FILE + fi + +-start() ++load_kernel_module() + { + if [ ! -e /dev/monwriter ]; then + echo "Loading monwriter module..." + modprobe monwriter 2>&1 +- if [ "$?" -ne 0 ]; then ++ if [ $? -ne 0 ]; then ++ exit 1 ++ fi ++ udevsettle ++ if [ $? -ne 0 ]; then + exit 1 + fi +- while [ ! -e /dev/monwriter ]; do +- sleep 0 +- done + fi ++} + +- if [ ! -f $FSSTATD_PID_FILE -a "$FSSTAT" = "yes" ]; then +- echo -n $"Starting $FSSTATD:" +- $FSSTATD_PATH -i $FSSTAT_INTERVAL +- if [ $? == 0 ]; then ++start_daemon() ++{ ++ local daemon_name=$1 ++ local daemon_interval=$2 ++ local daemon_pid_file=$3 ++ local daemon_path=$4 ++ ++ if [ ! -f $daemon_pid_file ]; then ++ load_kernel_module ++ echo -n "Starting $daemon_name:" ++ $daemon_path -i $daemon_interval ++ if [ $? -eq 0 ]; then + touch /var/lock/subsys/mon_statd + log_success_msg + else + log_failure_msg + fi +- elif [ "$FSSTAT" = "yes" ]; then +- echo "$FSSTATD (pid $(cat $FSSTATD_PID_FILE)) is already running..." ++ else ++ echo "$daemon_name (pid $(cat $daemon_pid_file)) is already running..." ++ fi ++} ++ ++start() ++{ ++ if [ "$FSSTAT" = "yes" ]; then ++ start_daemon $FSSTATD $FSSTAT_INTERVAL $FSSTATD_PID_FILE \ ++ $FSSTATD_PATH + fi + +- if [ ! -f $PROCD_PID_FILE -a "$PROC" = "yes" ]; then +- echo -n $"Starting $PROCD:" +- $PROCD_PATH -i $PROC_INTERVAL +- if [ $? == 0 ]; then +- touch /var/lock/subsys/mon_statd +- log_success_msg +- else +- log_failure_msg +- fi +- elif [ "$PROC" = "yes" ]; then +- echo "$PROCD (pid $(cat $PROCD_PID_FILE)) is already running..." ++ if [ "$PROC" = "yes" ]; then ++ start_daemon $PROCD $PROC_INTERVAL $PROCD_PID_FILE \ ++ $PROCD_PATH + fi +- echo + } + +-stop() ++stop_daemon() + { +- echo -n $"Stopping $FSSTATD:" +- if [ -f $FSSTATD_PID_FILE ]; then +- killproc $FSSTATD_PATH -TERM ++ local daemon_name=$1 ++ local daemon_pid_file=$2 ++ local daemon_path=$3 ++ ++ echo -n "Stopping $daemon_name:" ++ if [ -f $daemon_pid_file ]; then ++ killproc $daemon_path -TERM + log_success_msg +- rm -f $FSSTATD_PID_FILE ++ rm -f $daemon_pid_file + else + log_failure_msg + fi ++} + +- echo -n $"Stopping $PROCD:" +- if [ -f $PROCD_PID_FILE ]; then +- killproc $PROCD_PATH -TERM +- log_success_msg +- rm -f $PROCD_PID_FILE +- else +- log_failure_msg ++stop() ++{ ++ if [ "$FSSTAT" = "yes" ]; then ++ stop_daemon $FSSTATD $FSSTATD_PID_FILE $FSSTATD_PATH ++ fi ++ if [ "$PROC" = "yes" ]; then ++ stop_daemon $PROCD $PROCD_PID_FILE $PROCD_PATH + fi + rm -f /var/lock/subsys/mon_statd +- echo + } + + restart() { +@@ -101,20 +113,23 @@ restart() { + start + } + +-status() ++status_daemon() + { +- if [ ! -f $FSSTATD_PID_FILE ]; then +- echo "$FSSTATD is not running." +- else +- echo "$FSSTATD (pid $(cat $FSSTATD_PID_FILE), interval: $FSSTAT_INTERVAL) is running." +- fi ++ local daemon_name=$1 ++ local daemon_pid_file=$2 ++ local daemon_interval=$3 + +- if [ ! -f $PROCD_PID_FILE ]; then +- echo "$PROCD is not running." ++ if [ ! -f $daemon_pid_file ]; then ++ echo "$daemon_name is not running." + else +- echo "$PROCD (pid $(cat $PROCD_PID_FILE), interval: $PROC_INTERVAL) is running." ++ echo "$daemon_name (pid $(cat $daemon_pid_file), interval: $daemon_interval) is running." + fi +- echo ++} ++ ++status() ++{ ++ status_daemon $FSSTATD $FSSTATD_PID_FILE $FSSTAT_INTERVAL ++ status_daemon $PROCD $PROCD_PID_FILE $PROC_INTERVAL + } + + # How are we called? +@@ -133,7 +148,7 @@ case "$1" in + ;; + *) + echo "Usage: $DAEMON {start|stop|status|restart|reload}" +- RETVAL=1 ++ exit 1 + esac + +-exit $RETVAL ++exit 0 +-- +1.6.3.3 + diff --git a/0011-update-readahead-value-for-better-performance.patch b/0011-update-readahead-value-for-better-performance.patch new file mode 100644 index 0000000..99ac905 --- /dev/null +++ b/0011-update-readahead-value-for-better-performance.patch @@ -0,0 +1,38 @@ +From 5707bfdf0aac985e8e82c9a5004eb458d1d79801 Mon Sep 17 00:00:00 2001 +From: =?utf-8?q?Dan=20Hor=C3=A1k?= +Date: Fri, 30 Oct 2009 11:23:08 +0100 +Subject: [PATCH] update readahead value for better performance + +Description: dasd,zfcp: Add udev rule to set increased "default max readahead" +Symptom: Sequential read performance on disks is not as good as it could be. +Problem: The current "default max readahead" defined by the kernel is too + small for s390 (128 kb). +Solution: Add udev rule to set a better default value (512 kb). This will + increase sequential read performance up to 40%. +--- + etc/udev/rules.d/60-readahead.rules | 13 +++++++++++++ + 1 files changed, 13 insertions(+), 0 deletions(-) + create mode 100644 etc/udev/rules.d/60-readahead.rules + +diff --git a/etc/udev/rules.d/60-readahead.rules b/etc/udev/rules.d/60-readahead.rules +new file mode 100644 +index 0000000..3133c66 +--- /dev/null ++++ b/etc/udev/rules.d/60-readahead.rules +@@ -0,0 +1,13 @@ ++# ++# Rules to set an increased default max readahead size for s390 disk devices ++# This file should be installed in /etc/udev/rules.d ++# ++ ++SUBSYSTEM!="block", GOTO="ra_end" ++ ++ACTION!="add", GOTO="ra_end" ++# on device add set initial readahead to 512 (instead of in kernel 128) ++KERNEL=="sd*[!0-9]", ATTR{queue/read_ahead_kb}="512" ++KERNEL=="dasd*[!0-9]", ATTR{queue/read_ahead_kb}="512" ++ ++LABEL="ra_end" +-- +1.6.3.3 + diff --git a/0012-fix-multipath-device-detection-in-ziomon.patch b/0012-fix-multipath-device-detection-in-ziomon.patch new file mode 100644 index 0000000..c66b762 --- /dev/null +++ b/0012-fix-multipath-device-detection-in-ziomon.patch @@ -0,0 +1,33 @@ +From e9c5f5e15122b143f5f202e9782773321f8cf6b9 Mon Sep 17 00:00:00 2001 +From: =?utf-8?q?Dan=20Hor=C3=A1k?= +Date: Fri, 13 Nov 2009 10:46:57 +0100 +Subject: [PATCH 12/14] fix multipath device detection in ziomon + +Description: ziomon: Fix multipath device detection +Symptom: Running ziomon with a valid multipath device like + /dev/mapper/36005076303ffc56200000000000010cc + fails with "ziomon: The following devices do not seem + to exist:". +Problem: The output from multipath -l is not appended correctly to + the mp_arr array. +Solution: Properly initializing mp_arr to an empty array fixes this. +--- + ziomon/ziomon | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +diff --git a/ziomon/ziomon b/ziomon/ziomon +index 7449843..924c1dd 100755 +--- a/ziomon/ziomon ++++ b/ziomon/ziomon +@@ -471,7 +471,7 @@ function clean_devices() { + function check_for_multipath_devices() { + local i; + local j; +- local mp_arr; ++ local mp_arr=(); + local line; + local devices_basenames; + local tmp; +-- +1.6.3.3 + diff --git a/0013-zipl-handle-status-during-ipl.patch b/0013-zipl-handle-status-during-ipl.patch new file mode 100644 index 0000000..60c0265 --- /dev/null +++ b/0013-zipl-handle-status-during-ipl.patch @@ -0,0 +1,119 @@ +From 4770ba2827a5c582c6376139f1ec2d10519779e2 Mon Sep 17 00:00:00 2001 +From: =?utf-8?q?Dan=20Hor=C3=A1k?= +Date: Fri, 13 Nov 2009 10:48:17 +0100 +Subject: [PATCH 13/14] zipl - handle status during ipl + +Description: zipl: handle status during ipl +Symptom: You encounter an error during IPL with "disabled wait" message. +Problem: During the IPL sequence the subchannel of the IPL device has + to be enabled. If there is a status pending or busy condition + on the subchannel the IPL code abborts the IPL and goes into + disabled wait. +Solution: To resolve the problem the IPL code accepts the status pending + or busy condition on the subchannel and does up to 256 retries. +--- + zipl/boot/common.S | 65 ++++++++++++++++++++++++++++++++++----------------- + 1 files changed, 43 insertions(+), 22 deletions(-) + +diff --git a/zipl/boot/common.S b/zipl/boot/common.S +index 620fed9..fa45e5a 100644 +--- a/zipl/boot/common.S ++++ b/zipl/boot/common.S +@@ -6,6 +6,7 @@ + # + + # some definitions from kernel land ++__LC_IRB = 0x0300 + __LC_IPLDEV = 0xC6C + __LC_PANIC_MAGIC= 0xE00 + +@@ -186,23 +187,33 @@ _load_blocklist: + _enable_device: + stm %r6,%r15,24(%r15) + basr %r13,0 # base register +-0: s %r15,1f-0b(%r13) ++0: s %r15,4f-0b(%r13) + lr %r1,%r2 +- l %r2,4f-0b(%r13) # set panik code early +- stsch 2f-0b(%r13) +- oi 2f-0b+5(%r13),0x84 # enable ssch and multipath mode +- msch 2f-0b(%r13) +- bnz _panik-0b(%r13) # subchannel busy or in error ? +- lctl %c6,%c6,3f-0b(%r13) # enable all interrupt classes ++ l %r2,7f-0b(%r13) # set panik code early ++ stsch 5f-0b(%r13) ++ brc 1,3f # panic if not operational ++ oi 5f-0b+5(%r13),0x80 # enable subchannel ++ lhi %r6,256 # r6 retry counter ++1: # modify subchannel ++ msch 5f-0b(%r13) ++ brc 6,2f # status pending or busy ++ brc 1,3f # panic if not operational ++ lctl %c6,%c6,6f-0b(%r13) # enable all interrupt classes + sr %r2,%r2 +- ic %r2,10+2f-0b(%r13) # return lpum in r2 ++ ic %r2,10+5f-0b(%r13) # return lpum in r2 + lm %r6,%r15,120(%r15) + br %r14 +-1: .long 96 ++2: # clear status and retry ++ tsch __LC_IRB ++ brc 1,3f # panic if not operational ++ brct %r6,1b # retry ++3: # panic ++ b _panik-0b(%r13) # panic ++4: .long 96 + .align 8 +-2: .fill 64,1,0 +-3: .long 0xff000000 # CR6 initial value +-4: .long EENABLE_DEV ++5: .fill 64,1,0 ++6: .long 0xff000000 # CR6 initial value ++7: .long EENABLE_DEV + + # + # Disable I/O on the ipl device. +@@ -211,20 +222,30 @@ _enable_device: + _disable_device: + stm %r6,%r15,24(%r15) + basr %r13,0 # base register +-0: s %r15,1f-0b(%r13) ++0: s %r15,4f-0b(%r13) + lr %r1,%r2 +- l %r2,3f-0b(%r13) # set panik code early +- lctl %c6,%c6,2f-0b(%r13) # disable all interrupt classes +- stsch 2f-0b(%r13) +- ni 2f-0b+5(%r13),0x7B # disable ssch and multipath mode +- msch 2f-0b(%r13) +- bnz _panik-0b(%r13) # subchannel busy or in error ? ++ l %r2,6f-0b(%r13) # set panik code early ++ lctl %c6,%c6,5f-0b(%r13) # disable all interrupt classes ++ stsch 5f-0b(%r13) ++ brc 1,3f # panic if not operational ++ ni 5f-0b+5(%r13),0x7F # disable subchannel ++ lhi %r6,256 # r6 retry counter ++1: # modify subchannel ++ msch 5f-0b(%r13) ++ brc 6,2f # status pending or busy ++ brc 1,3f # panic if not operational + lm %r6,%r15,120(%r15) + br %r14 +-1: .long 96 ++2: # clear status and retry ++ tsch __LC_IRB ++ brc 1,3f # panic if not operational ++ brct %r6,1b ++3: # panic ++ b _panik-0b(%r13) # panic ++4: .long 96 + .align 8 +-2: .long 0x00000000 # CR6 (all interrupts classes disabled) +-3: .long EDISABLE_DEV ++5: .long 0x00000000 # CR6 (all interrupts classes disabled) ++6: .long EDISABLE_DEV + .endm + + .macro io_subroutines +-- +1.6.3.3 + diff --git a/0014-dasdview-fdasd-fix-floating-point-error-for-unformat.patch b/0014-dasdview-fdasd-fix-floating-point-error-for-unformat.patch new file mode 100644 index 0000000..9c7b486 --- /dev/null +++ b/0014-dasdview-fdasd-fix-floating-point-error-for-unformat.patch @@ -0,0 +1,285 @@ +From 72168f2269dac94d25112e0ad548bd3fcdf907d9 Mon Sep 17 00:00:00 2001 +From: =?utf-8?q?Dan=20Hor=C3=A1k?= +Date: Fri, 13 Nov 2009 10:49:37 +0100 +Subject: [PATCH 14/14] dasdview, fdasd: fix floating point error for unformatted devices + +When executed on an unformatted device the tools dasdview and fdasd +will end with an floating point exception error. +The reason for the error lies in the fact that we cannot rely on the +HDIO_GETGEO ioctl to report a correct number of cylinders and so we +compute the number of cylinders from the device size. However, +for unformatted devices the device size is zero and thus our +computation ends with a floating point exception. +To solve this issue read the correct number of cylinders from +the DASD device characteristics, which can be found in the data +returned by the BIODASDINFO ioctl. +--- + dasdview/dasdview.c | 22 +++++++------- + dasdview/dasdview.h | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++ + fdasd/fdasd.c | 18 ++++++------ + fdasd/fdasd.h | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++ + 4 files changed, 168 insertions(+), 20 deletions(-) + +diff --git a/dasdview/dasdview.c b/dasdview/dasdview.c +index a74ae33..2909b16 100644 +--- a/dasdview/dasdview.c ++++ b/dasdview/dasdview.c +@@ -169,7 +169,7 @@ static void + dasdview_get_info(dasdview_info_t *info) + { + int fd; +- u_int64_t device_size; ++ struct dasd_eckd_characteristics *characteristics; + + fd = open(info->device, O_RDONLY); + if (fd == -1) +@@ -201,16 +201,6 @@ dasdview_get_info(dasdview_info_t *info) + exit(-1); + } + +- if (ioctl(fd, BLKGETSIZE64, &device_size) != 0) { +- close(fd); +- zt_error_print("dasdview: ioctl error\n" \ +- "Could not retrieve device size information.\n"); +- exit(-1); +- } +- +- info->hw_cylinders = ((device_size / info->blksize) +- / info->geo.sectors) / info->geo.heads; +- + /* get disk information */ + if (ioctl(fd, BIODASDINFO2, &info->dasd_info) == 0) { + info->dasd_info_version = 2; +@@ -223,6 +213,16 @@ dasdview_get_info(dasdview_info_t *info) + exit(-1); + } + } ++ ++ characteristics = (struct dasd_eckd_characteristics *) ++ &info->dasd_info.characteristics; ++ if (characteristics->no_cyl == LV_COMPAT_CYL && ++ characteristics->long_no_cyl) ++ info->hw_cylinders = characteristics->long_no_cyl; ++ else ++ info->hw_cylinders = characteristics->no_cyl; ++ ++ + close(fd); + } + +diff --git a/dasdview/dasdview.h b/dasdview/dasdview.h +index 39e1228..5388592 100644 +--- a/dasdview/dasdview.h ++++ b/dasdview/dasdview.h +@@ -72,6 +72,80 @@ typedef struct dasd_information2_t { + unsigned int reserved7; /* reserved for further use ,... */ + } dasd_information2_t; + ++struct dasd_eckd_characteristics { ++ unsigned short cu_type; ++ struct { ++ unsigned char support:2; ++ unsigned char async:1; ++ unsigned char reserved:1; ++ unsigned char cache_info:1; ++ unsigned char model:3; ++ } __attribute__ ((packed)) cu_model; ++ unsigned short dev_type; ++ unsigned char dev_model; ++ struct { ++ unsigned char mult_burst:1; ++ unsigned char RT_in_LR:1; ++ unsigned char reserved1:1; ++ unsigned char RD_IN_LR:1; ++ unsigned char reserved2:4; ++ unsigned char reserved3:8; ++ unsigned char defect_wr:1; ++ unsigned char XRC_supported:1; ++ unsigned char reserved4:1; ++ unsigned char striping:1; ++ unsigned char reserved5:4; ++ unsigned char cfw:1; ++ unsigned char reserved6:2; ++ unsigned char cache:1; ++ unsigned char dual_copy:1; ++ unsigned char dfw:1; ++ unsigned char reset_alleg:1; ++ unsigned char sense_down:1; ++ } __attribute__ ((packed)) facilities; ++ unsigned char dev_class; ++ unsigned char unit_type; ++ unsigned short no_cyl; ++ unsigned short trk_per_cyl; ++ unsigned char sec_per_trk; ++ unsigned char byte_per_track[3]; ++ unsigned short home_bytes; ++ unsigned char formula; ++ union { ++ struct { ++ unsigned char f1; ++ unsigned short f2; ++ unsigned short f3; ++ } __attribute__ ((packed)) f_0x01; ++ struct { ++ unsigned char f1; ++ unsigned char f2; ++ unsigned char f3; ++ unsigned char f4; ++ unsigned char f5; ++ } __attribute__ ((packed)) f_0x02; ++ } __attribute__ ((packed)) factors; ++ unsigned short first_alt_trk; ++ unsigned short no_alt_trk; ++ unsigned short first_dia_trk; ++ unsigned short no_dia_trk; ++ unsigned short first_sup_trk; ++ unsigned short no_sup_trk; ++ unsigned char MDR_ID; ++ unsigned char OBR_ID; ++ unsigned char director; ++ unsigned char rd_trk_set; ++ unsigned short max_rec_zero; ++ unsigned char reserved1; ++ unsigned char RWANY_in_LR; ++ unsigned char factor6; ++ unsigned char factor7; ++ unsigned char factor8; ++ unsigned char reserved2[3]; ++ unsigned char reserved3[6]; ++ unsigned int long_no_cyl; ++} __attribute__ ((packed)); ++ + /* + * values to be used for dasd_information2_t.format + * 0x00: NOT formatted +diff --git a/fdasd/fdasd.c b/fdasd/fdasd.c +index a526d7f..8f7f5aa 100644 +--- a/fdasd/fdasd.c ++++ b/fdasd/fdasd.c +@@ -2002,7 +2002,7 @@ fdasd_get_geometry (fdasd_anchor_t *anc) + int fd, blksize = 0; + dasd_information_t dasd_info; + char err_str[ERROR_STRING_SIZE]; +- u_int64_t device_size; ++ struct dasd_eckd_characteristics *characteristics; + + if ((fd = open(options.device,O_RDONLY)) < 0) { + snprintf(err_str, ERROR_STRING_SIZE, +@@ -2023,14 +2023,6 @@ fdasd_get_geometry (fdasd_anchor_t *anc) + "Could not retrieve blocksize information."); + } + +- if (ioctl(fd, BLKGETSIZE64, &device_size) != 0) { +- close(fd); +- fdasd_error(anc, unable_to_ioctl, +- "Could not retrieve device size information."); +- } +- +- anc->hw_cylinders = ((device_size / blksize) / geo.sectors) / geo.heads; +- + /* get disk type */ + if (ioctl(fd, BIODASDINFO, &dasd_info) != 0) { + close(fd); +@@ -2038,6 +2030,14 @@ fdasd_get_geometry (fdasd_anchor_t *anc) + "Could not retrieve disk information."); + } + ++ characteristics = ++ (struct dasd_eckd_characteristics *) &dasd_info.characteristics; ++ if (characteristics->no_cyl == LV_COMPAT_CYL && ++ characteristics->long_no_cyl) ++ anc->hw_cylinders = characteristics->long_no_cyl; ++ else ++ anc->hw_cylinders = characteristics->no_cyl; ++ + close(fd); + + if (strncmp(dasd_info.type, "ECKD", 4) != 0) { +diff --git a/fdasd/fdasd.h b/fdasd/fdasd.h +index 107e486..8a1bfd0 100644 +--- a/fdasd/fdasd.h ++++ b/fdasd/fdasd.h +@@ -43,6 +43,80 @@ typedef struct dasd_information_t { + char configuration_data[256]; /* from read_configuration_data */ + } dasd_information_t; + ++struct dasd_eckd_characteristics { ++ unsigned short cu_type; ++ struct { ++ unsigned char support:2; ++ unsigned char async:1; ++ unsigned char reserved:1; ++ unsigned char cache_info:1; ++ unsigned char model:3; ++ } __attribute__ ((packed)) cu_model; ++ unsigned short dev_type; ++ unsigned char dev_model; ++ struct { ++ unsigned char mult_burst:1; ++ unsigned char RT_in_LR:1; ++ unsigned char reserved1:1; ++ unsigned char RD_IN_LR:1; ++ unsigned char reserved2:4; ++ unsigned char reserved3:8; ++ unsigned char defect_wr:1; ++ unsigned char XRC_supported:1; ++ unsigned char reserved4:1; ++ unsigned char striping:1; ++ unsigned char reserved5:4; ++ unsigned char cfw:1; ++ unsigned char reserved6:2; ++ unsigned char cache:1; ++ unsigned char dual_copy:1; ++ unsigned char dfw:1; ++ unsigned char reset_alleg:1; ++ unsigned char sense_down:1; ++ } __attribute__ ((packed)) facilities; ++ unsigned char dev_class; ++ unsigned char unit_type; ++ unsigned short no_cyl; ++ unsigned short trk_per_cyl; ++ unsigned char sec_per_trk; ++ unsigned char byte_per_track[3]; ++ unsigned short home_bytes; ++ unsigned char formula; ++ union { ++ struct { ++ unsigned char f1; ++ unsigned short f2; ++ unsigned short f3; ++ } __attribute__ ((packed)) f_0x01; ++ struct { ++ unsigned char f1; ++ unsigned char f2; ++ unsigned char f3; ++ unsigned char f4; ++ unsigned char f5; ++ } __attribute__ ((packed)) f_0x02; ++ } __attribute__ ((packed)) factors; ++ unsigned short first_alt_trk; ++ unsigned short no_alt_trk; ++ unsigned short first_dia_trk; ++ unsigned short no_dia_trk; ++ unsigned short first_sup_trk; ++ unsigned short no_sup_trk; ++ unsigned char MDR_ID; ++ unsigned char OBR_ID; ++ unsigned char director; ++ unsigned char rd_trk_set; ++ unsigned short max_rec_zero; ++ unsigned char reserved1; ++ unsigned char RWANY_in_LR; ++ unsigned char factor6; ++ unsigned char factor7; ++ unsigned char factor8; ++ unsigned char reserved2[3]; ++ unsigned char reserved3[6]; ++ unsigned int long_no_cyl; ++} __attribute__ ((packed)); ++ + /* Get information on a dasd device (enhanced) */ + #define BIODASDINFO _IOR(DASD_IOCTL_LETTER,1,dasd_information_t) + +-- +1.6.3.3 + diff --git a/0015-s390tools-1.8.2-zipl-dm.patch b/0015-s390tools-1.8.2-zipl-dm.patch new file mode 100644 index 0000000..306006d --- /dev/null +++ b/0015-s390tools-1.8.2-zipl-dm.patch @@ -0,0 +1,2716 @@ +From e089f907d7ba7f18479eaff61852171842a219e2 Mon Sep 17 00:00:00 2001 +From: =?utf-8?q?Dan=20Hor=C3=A1k?= +Date: Thu, 10 Dec 2009 18:27:58 +0100 +Subject: [PATCH 15/16] s390tools-1.8.2-zipl-dm + +device mapper support for zipl +--- + zipl/include/disk.h | 25 ++- + zipl/include/install.h | 9 +- + zipl/include/job.h | 17 +- + zipl/include/scan.h | 19 +- + zipl/man/zipl.8 | 88 +++++- + zipl/man/zipl.conf.5 | 71 ++++- + zipl/src/Makefile | 1 + + zipl/src/bootmap.c | 70 ++--- + zipl/src/disk.c | 242 ++++++++++--- + zipl/src/install.c | 11 +- + zipl/src/job.c | 362 +++++++++++++++++- + zipl/src/scan.c | 262 ++++++++++++- + zipl/src/zipl.c | 13 +- + zipl/src/zipl_helper.device-mapper | 716 ++++++++++++++++++++++++++++++++++++ + 14 files changed, 1759 insertions(+), 147 deletions(-) + create mode 100644 zipl/src/zipl_helper.device-mapper + +diff --git a/zipl/include/disk.h b/zipl/include/disk.h +index c5179b7..4b39698 100644 +--- a/zipl/include/disk.h ++++ b/zipl/include/disk.h +@@ -2,7 +2,7 @@ + * s390-tools/zipl/include/disk.h + * Functions to handle disk layout specific operations. + * +- * Copyright IBM Corp. 2001, 2006. ++ * Copyright IBM Corp. 2001, 2009. + * + * Author(s): Carsten Otte + * Peter Oberparleiter +@@ -59,6 +59,19 @@ struct hd_geometry { + unsigned long start; + }; + ++/* Disk information source */ ++typedef enum { ++ source_auto, ++ source_user, ++ source_script ++} source_t; ++ ++/* targetbase definition */ ++typedef enum { ++ defined_as_device, ++ defined_as_name ++} definition_t; ++ + /* Disk information type */ + struct disk_info { + disk_type_t type; +@@ -72,11 +85,17 @@ struct disk_info { + struct hd_geometry geo; + char* name; + char* drv_name; ++ source_t source; ++ definition_t targetbase; + }; + ++struct job_target_data; + +-int disk_get_info(const char* device, struct disk_info** info); +-int disk_get_info_from_file(const char* filename, struct disk_info** info); ++int disk_get_info(const char* device, struct job_target_data* target, ++ struct disk_info** info); ++int disk_get_info_from_file(const char* filename, ++ struct job_target_data* target, ++ struct disk_info** info); + void disk_free_info(struct disk_info* info); + char* disk_get_type_name(disk_type_t type); + int disk_is_large_volume(struct disk_info* info); +diff --git a/zipl/include/install.h b/zipl/include/install.h +index ba31bff..5504deb 100644 +--- a/zipl/include/install.h ++++ b/zipl/include/install.h +@@ -2,7 +2,7 @@ + * s390-tools/zipl/include/install.h + * Functions handling the installation of the boot loader code onto disk. + * +- * Copyright IBM Corp. 2001, 2006. ++ * Copyright IBM Corp. 2001, 2009. + * + * Author(s): Carsten Otte + * Peter Oberparleiter +@@ -24,8 +24,9 @@ int install_tapeloader(const char* device, const char* image, + const char* parmline, const char* ramdisk, + address_t image_addr, address_t parm_addr, + address_t initrd_addr); +-int install_dump(const char* device, uint64_t mem); +-int install_mvdump(char* const device[], int device_count, uint64_t mem, +- uint8_t force); ++int install_dump(const char* device, struct job_target_data* target, ++ uint64_t mem); ++int install_mvdump(char* const device[], struct job_target_data* target, ++ int device_count, uint64_t mem, uint8_t force); + + #endif /* INSTALL_H */ +diff --git a/zipl/include/job.h b/zipl/include/job.h +index 824ffc4..cf881db 100644 +--- a/zipl/include/job.h ++++ b/zipl/include/job.h +@@ -3,7 +3,7 @@ + * Functions and data structures representing the actual 'job' that the + * user wants us to execute. + * +- * Copyright IBM Corp. 2001, 2006. ++ * Copyright IBM Corp. 2001, 2009. + * + * Author(s): Carsten Otte + * Peter Oberparleiter +@@ -13,6 +13,7 @@ + #define JOB_H + + #include "zipl.h" ++#include "disk.h" + + + enum job_id { +@@ -27,6 +28,17 @@ enum job_id { + job_mvdump = 9, + }; + ++struct job_target_data { ++ char* bootmap_dir; ++ char* targetbase; ++ disk_type_t targettype; ++ int targetcylinders; ++ int targetheads; ++ int targetsectors; ++ int targetblocksize; ++ blocknum_t targetoffset; ++}; ++ + struct job_ipl_data { + char* image; + char* parmline; +@@ -94,7 +106,7 @@ struct job_menu_data { + + struct job_data { + enum job_id id; +- char* bootmap_dir; ++ struct job_target_data target; + char* name; + union { + struct job_ipl_data ipl; +@@ -115,5 +127,6 @@ struct job_data { + + int job_get(int argc, char* argv[], struct job_data** data); + void job_free(struct job_data* job); ++int type_from_target(char *target, disk_type_t *type); + + #endif /* not JOB_H */ +diff --git a/zipl/include/scan.h b/zipl/include/scan.h +index b1c0e3a..ed5714e 100644 +--- a/zipl/include/scan.h ++++ b/zipl/include/scan.h +@@ -2,7 +2,7 @@ + * s390-tools/zipl/include/scan.h + * Scanner for zipl.conf configuration files + * +- * Copyright IBM Corp. 2001, 2006. ++ * Copyright IBM Corp. 2001, 2009. + * + * Author(s): Carsten Otte + * Peter Oberparleiter +@@ -15,7 +15,7 @@ + + + #define SCAN_SECTION_NUM 7 +-#define SCAN_KEYWORD_NUM 14 ++#define SCAN_KEYWORD_NUM 19 + + enum scan_id { + scan_id_empty = 0, +@@ -40,6 +40,11 @@ enum scan_keyword_id { + scan_keyword_defaultmenu = 11, + scan_keyword_tape = 12, + scan_keyword_mvdump = 13, ++ scan_keyword_targetbase = 14, ++ scan_keyword_targettype = 15, ++ scan_keyword_targetgeometry = 16, ++ scan_keyword_targetblocksize = 17, ++ scan_keyword_targetoffset = 18, + }; + + enum scan_section_type { +@@ -53,6 +58,14 @@ enum scan_section_type { + section_mvdump = 6, + }; + ++enum scan_target_type { ++ target_type_invalid = -1, ++ target_type_scsi = 0, ++ target_type_fba = 1, ++ target_type_ldl = 2, ++ target_type_cdl = 3, ++}; ++ + enum scan_key_state { + req, /* Keyword is required */ + opt, /* Keyword is optional */ +@@ -100,6 +113,8 @@ int scan_find_section(struct scan_token* scan, char* name, enum scan_id type, + int offset); + int scan_check_section_data(char* keyword[], int* line, char* name, + int section_line, enum scan_section_type* type); ++int scan_check_target_data(char* keyword[], int* line); + enum scan_section_type scan_get_section_type(char* keyword[]); ++enum scan_target_type scan_get_target_type(char *type); + + #endif /* not SCAN_H */ +diff --git a/zipl/man/zipl.8 b/zipl/man/zipl.8 +index 6df6026..e291445 100644 +--- a/zipl/man/zipl.8 ++++ b/zipl/man/zipl.8 +@@ -1,4 +1,4 @@ +-.TH ZIPL 8 "Apr 2006" "s390-tools" ++.TH ZIPL 8 "Nov 2009" "s390-tools" + .SH NAME + zipl \- boot loader for IBM S/390 and zSeries architectures + +@@ -58,6 +58,45 @@ See the + .BR zipl.conf (5) + man page for details on how to use the boot menu. + ++.B Logical devices ++ ++zipl can be used to prepare logical devices (e.g. a linear device mapper target) ++for booting when the following requirements are met by the logical device setup: ++.IP " -" ++all boot relevant files (i.e. kernel, ramdisk and parameter files) must be ++located on a logical device which is mapped to a single physical disk of a type ++supported by zipl (i.e. DASD or SCSI disk) ++.IP " -" ++adjacent data blocks on the logical device must correspond to adjacent blocks on ++the physical device ++.IP " -" ++access to the first blocks (starting at block 0) of the physical device must be ++given ++.PP ++Examples for logical device setups that are supported are linear and mirror ++mapping. ++ ++When working with logical devices, zipl requires that the user provides more ++information about the target device: ++.IP " -" ++device characteristics of the underlying physical device: disk type and format ++(e.g. ECKD CDL or FCP SCSI), disk geometry in case of ECKD DASDs and block size ++.IP " -" ++target device offset, i.e. the number of blocks between the physical device ++start and the start of the logical device containing the filesystem with all ++boot relevant files ++.IP " -" ++a device node which provides access to the first blocks of the device ++.PP ++If the user does not provide this information explicitly by parameters ++zipl automatically runs a driver specific helper script to obtain these data, ++e.g. zipl_helper.device-mapper. ++ ++Note that zipl uses /proc/devices to determine the driver name for a given ++device. If the driver name cannot be determined the preparation of a logical ++device for boot might fail. ++This can be the case in a chroot environment when /proc is not mounted ++explicitly. + + .SH OPTIONS + .TP +@@ -85,6 +124,53 @@ It is not possible to specify both this parameter and the name of a menu + or configuration section on the command line at the same time. + + .TP ++.BR "\-\-targetbase=" ++Install the actual boot loader on the device node specified by BASE DEVICE. ++ ++This option is required when working with logical devices (see section ++"Logical devices" above). ++ ++.TP ++.BR "\-\-targettype=" ++Assume that the physical device is of the specified type. Valid values are: ++.IP " -" 12 ++CDL: DASD disk with ECKD/compatible disk layout ++.IP " -" 12 ++LDL: DASD disk with ECDK/linux disk layout ++.IP " -" 12 ++FBA: FBA disk DASD ++.IP " -" 12 ++SCSI: SCSI disk ++.PP ++.IP " " 8 ++This option is required when working with logical devices (see section ++"Logical devices" above). ++ ++.TP ++.BR "\-\-targetgeometry=" ++Assume that the physical device has the specified number of cylinders, heads and ++sectors. ++ ++This option is required when working with logical devices which are located on ++DASD ECKD disks (see section "Logical devices" above). ++ ++.TP ++.BR "\-\-targetblocksize=" ++Assume that blocks on the physical device are SIZE bytes long. ++ ++This option is required when working with logical devices (see section ++"Logical devices" above). ++ ++.TP ++.BR "\-\-targetoffset=" ++Assume that the logical device containing the directory specified by the ++--target option is located on the physical device starting at the block ++specified by OFFSET. ++ ++This option is required when working with logical devices (see section ++"Logical devices" above). ++ ++.TP + .BR "\-T " " or " "\-\-tape=" + Install bootloader on the specified . Use this option instead + of the 'target' option to prepare a tape device for IPL. +diff --git a/zipl/man/zipl.conf.5 b/zipl/man/zipl.conf.5 +index 6be623e..9d0f60d 100644 +--- a/zipl/man/zipl.conf.5 ++++ b/zipl/man/zipl.conf.5 +@@ -1,4 +1,4 @@ +-.TH ZIPL.CONF 5 "Apr 2006" "s390-tools" ++.TH ZIPL.CONF 5 "Nov 2009" "s390-tools" + + .SH NAME + zipl.conf \- zipl configuration file +@@ -490,6 +490,75 @@ The device on which the target directory is located will be used as 'target + device', i.e. it will be prepared for booting (initial program load). + .PP + ++.B targetbase ++= ++.I base\-device ++(configuration and menu) ++.IP ++.B Configuration and menu section: ++.br ++Specify the device which will be prepared for booting. ++ ++This parameter is required when working with logical devices (see zipl(8)). ++.PP ++ ++.B targettype ++= ++.I type ++(configuration and menu) ++.IP ++.B Configuration and menu section: ++.br ++Specify the device type for the physical device. ++.IP " - " 12 ++CDL: DASD disk with ECKD/compatible disk layout ++.IP " - " 12 ++LDL: DASD disk with ECDK/linux disk layout ++.IP " - " 12 ++FBA: FBA disk DASD ++.IP " - " 12 ++SCSI disk ++.PP ++.IP " " 8 ++This parameter is required when working with logical devices (see zipl(8)). ++.PP ++ ++.B targetgeometry ++= ++.I cylinders,heads,sectors ++(configuration and menu) ++.IP ++.B Configuration and menu section: ++.br ++Specify the number of cylinders, heads and sectors for the physical device. ++ ++This parameter is required when working with logical devices (see zipl(8)). ++.PP ++ ++.B targetblocksize ++= ++.I size ++(configuration and menu) ++.IP ++.B Configuration and menu section: ++.br ++Specify the number of bytes per block for the physical device. ++ ++This parameter is required when working with logical devices (see zipl(8)). ++.PP ++ ++.B targetoffset ++= ++.I offset ++(configuration and menu) ++.IP ++.B Configuration and menu section: ++.br ++Specify the starting block number of the logical device on the physical device. ++ ++This parameter is required when working with logical devices (see zipl(8)). ++.PP ++ + .B timeout + = + .I menu-timeout +diff --git a/zipl/src/Makefile b/zipl/src/Makefile +index 234464b..f95bb55 100644 +--- a/zipl/src/Makefile ++++ b/zipl/src/Makefile +@@ -17,6 +17,7 @@ zipl: $(objects) + install: all + $(INSTALL) -d -m 755 $(BINDIR) + $(INSTALL) -c zipl $(BINDIR) ++ $(INSTALL) -m 755 $(wildcard zipl_helper.*) $(TOOLS_LIBDIR) + + clean: + rm -f *.o zipl +diff --git a/zipl/src/bootmap.c b/zipl/src/bootmap.c +index 566e59d..526aa48 100644 +--- a/zipl/src/bootmap.c ++++ b/zipl/src/bootmap.c +@@ -2,7 +2,7 @@ + * s390-tools/zipl/src/bootmap.c + * Functions to build the bootmap file. + * +- * Copyright IBM Corp. 2001, 2006. ++ * Copyright IBM Corp. 2001, 2009. + * + * Author(s): Carsten Otte + * Peter Oberparleiter +@@ -298,7 +298,8 @@ struct component_loc { + static int + add_component_file(int fd, const char* filename, address_t load_address, + off_t offset, void* component, int add_files, +- struct disk_info* info, struct component_loc *location) ++ struct disk_info* info, struct job_target_data* target, ++ struct component_loc *location) + { + struct disk_info* file_info; + struct component_loc loc; +@@ -336,7 +337,7 @@ add_component_file(int fd, const char* filename, address_t load_address, + } + } else { + /* Make sure file is on correct device */ +- rc = disk_get_info_from_file(filename, &file_info); ++ rc = disk_get_info_from_file(filename, target, &file_info); + if (rc) + return -1; + if (file_info->device != info->device) { +@@ -472,7 +473,7 @@ check_component_overlap(const char *name[], struct component_loc *loc, int num) + static int + add_ipl_program(int fd, struct job_ipl_data* ipl, disk_blockptr_t* program, + int verbose, int add_files, component_header_type type, +- struct disk_info* info) ++ struct disk_info* info, struct job_target_data* target) + { + struct stat stats; + void* table; +@@ -500,7 +501,7 @@ add_ipl_program(int fd, struct job_ipl_data* ipl, disk_blockptr_t* program, + } + rc = add_component_file(fd, ipl->image, ipl->image_addr, + KERNEL_HEADER_SIZE, VOID_ADD(table, offset), +- add_files, info, &comp_loc[0]); ++ add_files, info, target, &comp_loc[0]); + if (rc) { + error_text("Could not add image file '%s'", ipl->image); + free(table); +@@ -542,7 +543,7 @@ add_ipl_program(int fd, struct job_ipl_data* ipl, disk_blockptr_t* program, + rc = add_component_file(fd, ipl->ramdisk, + ipl->ramdisk_addr, 0, + VOID_ADD(table, offset), +- add_files, info, &comp_loc[2]); ++ add_files, info, target, &comp_loc[2]); + if (rc) { + error_text("Could not add ramdisk '%s'", + ipl->ramdisk); +@@ -594,7 +595,8 @@ add_ipl_program(int fd, struct job_ipl_data* ipl, disk_blockptr_t* program, + static int + add_segment_program(int fd, struct job_segment_data* segment, + disk_blockptr_t* program, int verbose, int add_files, +- component_header_type type, struct disk_info* info) ++ component_header_type type, struct disk_info* info, ++ struct job_target_data* target) + { + const char *comp_name[1] = {"segment file"}; + struct component_loc comp_loc[1]; +@@ -618,7 +620,7 @@ add_segment_program(int fd, struct job_segment_data* segment, + } + rc = add_component_file(fd, segment->segment, segment->segment_addr, 0, + VOID_ADD(table, offset), add_files, info, +- &comp_loc[0]); ++ target, &comp_loc[0]); + if (rc) { + error_text("Could not add segment file '%s'", + segment->segment); +@@ -661,14 +663,15 @@ create_dump_fs_parmline(const char* parmline, const char* root_dev, + + static int + get_dump_fs_parmline(char* partition, char* parameters, uint64_t mem, +- char** result, struct disk_info* target_info) ++ struct disk_info* target_info, ++ struct job_target_data* target, char** result) + { + char* buffer; + struct disk_info* info; + int rc; + + /* Get information about partition */ +- rc = disk_get_info(partition, &info); ++ rc = disk_get_info(partition, target, &info); + if (rc) { + error_text("Could not get information for dump partition '%s'", + partition); +@@ -700,7 +703,7 @@ static int + add_dump_fs_program(int fd, struct job_dump_fs_data* dump_fs, + disk_blockptr_t* program, int verbose, + int add_files, component_header_type type, +- struct disk_info* info) ++ struct disk_info* info, struct job_target_data* target) + { + struct job_ipl_data ipl; + int rc; +@@ -725,12 +728,12 @@ add_dump_fs_program(int fd, struct job_dump_fs_data* dump_fs, + + /* Get file system dump parmline */ + rc = get_dump_fs_parmline(dump_fs->partition, dump_fs->parmline, +- dump_fs->mem, &ipl.parmline, info); ++ dump_fs->mem, info, target, &ipl.parmline); + if (rc) + return rc; + ipl.parm_addr = DEFAULT_PARMFILE_ADDRESS; + return add_ipl_program(fd, &ipl, program, verbose, 1, +- type, info); ++ type, info, target); + } + + +@@ -763,7 +766,7 @@ build_program_table(int fd, struct job_data* job, disk_blockptr_t* pointer, + rc = add_ipl_program(fd, &job->data.ipl, &table[0], + verbose || job->command_line, + job->add_files, component_header_ipl, +- info); ++ info, &job->target); + break; + case job_segment: + if (job->command_line) +@@ -774,7 +777,7 @@ build_program_table(int fd, struct job_data* job, disk_blockptr_t* pointer, + rc = add_segment_program(fd, &job->data.segment, &table[0], + verbose || job->command_line, + job->add_files, component_header_ipl, +- info); ++ info, &job->target); + break; + case job_dump_fs: + if (job->command_line) +@@ -785,7 +788,7 @@ build_program_table(int fd, struct job_data* job, disk_blockptr_t* pointer, + rc = add_dump_fs_program(fd, &job->data.dump_fs, &table[0], + verbose || job->command_line, + job->add_files, component_header_dump, +- info); ++ info, &job->target); + break; + case job_menu: + printf("Building menu '%s'\n", job->name); +@@ -804,7 +807,7 @@ build_program_table(int fd, struct job_data* job, disk_blockptr_t* pointer, + &table[job->data.menu.entry[i].pos], + verbose || job->command_line, + job->add_files, component_header_ipl, +- info); ++ info, &job->target); + break; + case job_dump_fs: + printf("Adding #%d: fs-dump section '%s'%s\n", +@@ -818,7 +821,7 @@ build_program_table(int fd, struct job_data* job, disk_blockptr_t* pointer, + &table[job->data.menu.entry[i].pos], + verbose || job->command_line, + job->add_files, component_header_dump, +- info); ++ info, &job->target); + break; + case job_print_usage: + case job_print_version: +@@ -888,9 +891,9 @@ bootmap_create(struct job_data* job, disk_blockptr_t* program_table, + size_t stage2_size; + int fd; + int rc; +- + /* Get full path of bootmap file */ +- filename = misc_make_path(job->bootmap_dir, BOOTMAP_TEMPLATE_FILENAME); ++ filename = misc_make_path(job->target.bootmap_dir, ++ BOOTMAP_TEMPLATE_FILENAME); + if (filename == NULL) + return -1; + /* Create temporary bootmap file */ +@@ -904,32 +907,14 @@ bootmap_create(struct job_data* job, disk_blockptr_t* program_table, + /* Retrieve target device information. Note that we have to + * call disk_get_info_from_file() to also get the file system + * block size. */ +- rc = disk_get_info_from_file(filename, &info); ++ rc = disk_get_info_from_file(filename, &job->target, &info); + if (rc) { + close(fd); + free(filename); + return -1; + } + /* Check for supported disk and driver types */ +- switch (info->type) { +- case disk_type_scsi: +- case disk_type_fba: +- break; +- case disk_type_eckd_classic: +- case disk_type_eckd_compatible: +- /* Check for valid CHS geometry data. */ +- if ((info->geo.cylinders == 0) || (info->geo.heads == 0) || +- (info->geo.sectors == 0)) { +- error_reason("Invalid disk geometry (CHS=%d/%d/%d)", +- info->geo.cylinders, info->geo.heads, +- info->geo.sectors); +- disk_free_info(info); +- close(fd); +- free(filename); +- return -1; +- } +- break; +- case disk_type_diag: ++ if ((info->source == source_auto) && (info->type == disk_type_diag)) { + error_reason("Unsupported disk type (%s)", + disk_get_type_name(info->type)); + disk_free_info(info); +@@ -959,7 +944,7 @@ bootmap_create(struct job_data* job, disk_blockptr_t* program_table, + return rc; + } + } +- printf("Building bootmap in '%s'%s\n", job->bootmap_dir, ++ printf("Building bootmap in '%s'%s\n", job->target.bootmap_dir, + job->add_files ? " (files will be added to bootmap file)" : + ""); + /* Write bootmap header */ +@@ -1046,7 +1031,8 @@ bootmap_create(struct job_data* job, disk_blockptr_t* program_table, + "file %s!\n", filename); + } else { + /* Rename to final bootmap name */ +- mapname = misc_make_path(job->bootmap_dir, BOOTMAP_FILENAME); ++ mapname = misc_make_path(job->target.bootmap_dir, ++ BOOTMAP_FILENAME); + if (mapname == NULL) { + misc_free_temp_dev(device); + disk_free_info(info); +diff --git a/zipl/src/disk.c b/zipl/src/disk.c +index 08f0c64..9392968 100644 +--- a/zipl/src/disk.c ++++ b/zipl/src/disk.c +@@ -2,13 +2,14 @@ + * s390-tools/zipl/src/disk.c + * Functions to handle disk layout specific operations. + * +- * Copyright IBM Corp. 2001, 2006. ++ * Copyright IBM Corp. 2001, 2009. + * + * Author(s): Carsten Otte + * Peter Oberparleiter + */ + + #include "disk.h" ++#include "job.h" + + #include + #include +@@ -84,16 +85,34 @@ disk_determine_dasd_type(struct disk_info *data, + return 0; + } + ++/* Return non-zero for ECKD type. */ + int +-disk_get_info(const char* device, struct disk_info** info) ++disk_is_eckd(disk_type_t type) ++{ ++ return (type == disk_type_eckd_classic || ++ type == disk_type_eckd_compatible); ++} ++ ++int ++disk_get_info(const char* device, struct job_target_data* target, ++ struct disk_info** info) + { + struct stat stats; ++ struct stat script_stats; + struct proc_part_entry part_entry; + struct proc_dev_entry dev_entry; + struct dasd_information dasd_info; + struct disk_info *data; + int fd; + long devsize; ++ FILE *fh; ++ char *script_pre = "/lib/s390-tools/zipl_helper."; ++ char script_file[80]; ++ char ppn_cmd[80]; ++ char buffer[80]; ++ char value[40]; ++ int majnum, minnum; ++ int checkparm; + + /* Get file information */ + if (stat(device, &stats)) { +@@ -113,37 +132,140 @@ disk_get_info(const char* device, struct disk_info** info) + return -1; + } + memset((void *) data, 0, sizeof(struct disk_info)); +- /* Get disk geometry. Note: geo.start contains a sector number +- * offset measured in physical blocks, not sectors (512 bytes) */ +- if (ioctl(fd, HDIO_GETGEO, &data->geo)) { +- error_reason("Could not get disk geometry"); +- free(data); +- close(fd); +- return -1; +- } + /* Try to get device driver name */ + if (proc_dev_get_entry(stats.st_rdev, 1, &dev_entry) == 0) { + data->drv_name = misc_strdup(dev_entry.name); + proc_dev_free_entry(&dev_entry); ++ } else { ++ fprintf(stderr, "Warning: Could not determine driver name for " ++ "major %d from /proc/devices\n", major(stats.st_rdev)); ++ fprintf(stderr, "Warning: Preparing a logical device for boot " ++ "might fail\n"); ++ } ++ data->source = source_user; ++ /* Check if targetbase script is available */ ++ strcpy(script_file, script_pre); ++ if (data->drv_name) { ++ strcat(script_file, data->drv_name); ++ } ++ if ((target->targetbase == NULL) && ++ (!stat(script_file, &script_stats))) { ++ data->source = source_script; ++ /* Run targetbase script */ ++ strcpy(ppn_cmd, script_file); ++ strcat(ppn_cmd, " "); ++ strcat(ppn_cmd, target->bootmap_dir); ++ printf("Run %s\n", ppn_cmd); ++ fh = popen(ppn_cmd, "r"); ++ if (fh == NULL) { ++ error_reason("Failed to run popen(%s,\"r\",)"); ++ goto out_close; ++ } ++ checkparm = 0; ++ while (fgets(buffer, 80, fh) != NULL) { ++ if (sscanf(buffer, "targetbase=%s", value) == 1) { ++ target->targetbase = misc_strdup(value); ++ checkparm++; ++ } ++ if (sscanf(buffer, "targettype=%s", value) == 1) { ++ type_from_target(value, &target->targettype); ++ checkparm++; ++ } ++ if (sscanf(buffer, "targetgeometry=%s", value) == 1) { ++ target->targetcylinders = ++ atoi(strtok(value, ",")); ++ target->targetheads = atoi(strtok(NULL, ",")); ++ target->targetsectors = atoi(strtok(NULL, ",")); ++ checkparm++; ++ } ++ if (sscanf(buffer, "targetblocksize=%s", value) == 1) { ++ target->targetblocksize = atoi(value); ++ checkparm++; ++ } ++ if (sscanf(buffer, "targetoffset=%s", value) == 1) { ++ target->targetoffset = atol(value); ++ checkparm++; ++ } ++ } ++ switch (pclose(fh)) { ++ case 0 : ++ /* success */ ++ break; ++ case -1 : ++ error_reason("Failed to run pclose"); ++ goto out_close; ++ default : ++ error_reason("Script could not determine target " ++ "parameters"); ++ goto out_close; ++ } ++ if ((!disk_is_eckd(target->targettype) && checkparm < 4) || ++ (disk_is_eckd(target->targettype) && checkparm != 5)) { ++ error_reason("Target parameters missing from script"); ++ goto out_close; ++ } + } +- /* Get DASD information */ +- if (ioctl(fd, BIODASDINFO, &dasd_info)) ++ ++ /* Get disk geometry. Note: geo.start contains a sector number ++ * offset measured in physical blocks, not sectors (512 bytes) */ ++ if (target->targetbase != NULL) { ++ data->geo.heads = target->targetheads; ++ data->geo.sectors = target->targetsectors; ++ data->geo.cylinders = target->targetcylinders; ++ data->geo.start = target->targetoffset; ++ } else { ++ data->source = source_auto; ++ if (ioctl(fd, HDIO_GETGEO, &data->geo)) { ++ error_reason("Could not get disk geometry"); ++ goto out_close; ++ } ++ } ++ if ((data->source == source_user) || (data->source == source_script)) { + data->devno = -1; +- else +- data->devno = dasd_info.devno; +- /* Get physical block size */ +- if (ioctl(fd, BLKSSZGET, &data->phy_block_size)) { +- error_reason("Could not get blocksize"); +- free(data); +- close(fd); +- return -1; ++ data->phy_block_size = target->targetblocksize; ++ } else { ++ /* Get DASD information */ ++ if (ioctl(fd, BIODASDINFO, &dasd_info)) ++ data->devno = -1; ++ else ++ data->devno = dasd_info.devno; ++ /* Get physical block size */ ++ if (ioctl(fd, BLKSSZGET, &data->phy_block_size)) { ++ error_reason("Could not get blocksize"); ++ goto out_close; ++ } + } + /* Get size of device in sectors (512 byte) */ + if (ioctl(fd, BLKGETSIZE, &devsize)) { + error_reason("Could not get device size"); +- close(fd); +- free(data); +- return -1; ++ goto out_close; ++ } ++ if ((data->source == source_user) || (data->source == source_script)) { ++ data->type = target->targettype; ++ data->partnum = 0; ++ /* Get file information */ ++ if (sscanf(target->targetbase, "%d:%d", &majnum, &minnum) ++ == 2) { ++ data->device = makedev(majnum, minnum); ++ data->targetbase = defined_as_device; ++ } ++ else { ++ if (stat(target->targetbase, &stats)) { ++ error_reason(strerror(errno)); ++ error_text("Could not get information for " ++ "file '%s'", target->targetbase); ++ goto out_close; ++ } ++ if (!S_ISBLK(stats.st_mode)) { ++ error_reason("Target base device '%s' is not " ++ "a block device", ++ target->targetbase); ++ goto out_close; ++ } ++ data->device = stats.st_rdev; ++ data->targetbase = defined_as_name; ++ } ++ goto type_determined; + } + /* Determine disk type */ + if (!data->drv_name) { +@@ -194,6 +316,15 @@ disk_get_info(const char* device, struct disk_info** info) + goto out_close; + } + ++type_determined: ++ /* Check for valid CHS geometry data. */ ++ if (disk_is_eckd(data->type) && (data->geo.cylinders == 0 || ++ data->geo.heads == 0 || data->geo.sectors == 0)) { ++ error_reason("Invalid disk geometry (CHS=%d/%d/%d)", ++ data->geo.cylinders, data->geo.heads, ++ data->geo.sectors); ++ goto out_close; ++ } + /* Convert device size to size in physical blocks */ + data->phy_blocks = devsize / (data->phy_block_size / 512); + if (data->partnum != 0) +@@ -221,7 +352,8 @@ out_close: + + + int +-disk_get_info_from_file(const char* filename, struct disk_info** info) ++disk_get_info_from_file(const char* filename, struct job_target_data* target, ++ struct disk_info** info) + { + struct stat stats; + char* device; +@@ -251,7 +383,7 @@ disk_get_info_from_file(const char* filename, struct disk_info** info) + if (rc) + return -1; + /* Get device info */ +- rc = disk_get_info(device, info); ++ rc = disk_get_info(device, target, info); + if (rc == 0) + (*info)->fs_block_size = blocksize; + /* Clean up */ +@@ -523,8 +655,14 @@ disk_is_large_volume(struct disk_info* info) + void + disk_print_info(struct disk_info* info) + { ++ char footnote[4] = ""; ++ if ((info->source == source_user) || (info->source == source_script)) ++ strcpy(footnote, " *)"); ++ + printf(" Device..........................: "); + disk_print_devt(info->device); ++ if (info->targetbase == defined_as_device) ++ printf("%s", footnote); + printf("\n"); + if (info->partnum != 0) { + printf(" Partition.......................: "); +@@ -532,45 +670,55 @@ disk_print_info(struct disk_info* info) + printf("\n"); + } + if (info->name) { +- printf(" Device name.....................: %s\n", ++ printf(" Device name.....................: %s", + info->name); ++ if (info->targetbase == defined_as_name) ++ printf("%s", footnote); ++ printf("\n"); + } + if (info->drv_name) { + printf(" Device driver name..............: %s\n", + info->drv_name); + } +- if ((info->type == disk_type_fba) || +- (info->type == disk_type_diag) || +- (info->type == disk_type_eckd_classic) || +- (info->type == disk_type_eckd_compatible)) { ++ if (((info->type == disk_type_fba) || ++ (info->type == disk_type_diag) || ++ (info->type == disk_type_eckd_classic) || ++ (info->type == disk_type_eckd_compatible)) && ++ (info->source == source_auto)) { + printf(" DASD device number..............: %04x\n", + info->devno); + } + printf(" Type............................: disk %s\n", + (info->partnum != 0) ? "partition" : "device"); +- printf(" Disk layout.....................: %s\n", +- disk_get_type_name(info->type)); +- printf(" Geometry - heads................: %d\n", +- info->geo.heads); +- printf(" Geometry - sectors..............: %d\n", +- info->geo.sectors); +- if (disk_is_large_volume(info)) { +- /* ECKD large volume. There is not enough information +- * available in INFO to calculate disk cylinder size. */ +- printf(" Geometry - cylinders............: > 65534\n"); +- } else { +- printf(" Geometry - cylinders............: %d\n", +- info->geo.cylinders); ++ printf(" Disk layout.....................: %s%s\n", ++ disk_get_type_name(info->type), footnote); ++ if (disk_is_eckd(info->type)) { ++ printf(" Geometry - heads................: %d%s\n", ++ info->geo.heads, footnote); ++ printf(" Geometry - sectors..............: %d%s\n", ++ info->geo.sectors, footnote); ++ if (disk_is_large_volume(info)) { ++ /* ECKD large volume. There is not enough information ++ * available in INFO to calculate disk cylinder size. */ ++ printf(" Geometry - cylinders............: > 65534\n"); ++ } else { ++ printf(" Geometry - cylinders............: %d%s\n", ++ info->geo.cylinders, footnote); ++ } + } +- printf(" Geometry - start................: %ld\n", +- info->geo.start); ++ printf(" Geometry - start................: %ld%s\n", ++ info->geo.start, footnote); + if (info->fs_block_size >= 0) + printf(" File system block size..........: %d\n", + info->fs_block_size); +- printf(" Physical block size.............: %d\n", +- info->phy_block_size); ++ printf(" Physical block size.............: %d%s\n", ++ info->phy_block_size, footnote); + printf(" Device size in physical blocks..: %ld\n", + (long) info->phy_blocks); ++ if (info->source == source_user) ++ printf(" *) Data provided by user.\n"); ++ if (info->source == source_script) ++ printf(" *) Data provided by script.\n"); + } + + +diff --git a/zipl/src/install.c b/zipl/src/install.c +index 55b0dd3..ec84821 100644 +--- a/zipl/src/install.c ++++ b/zipl/src/install.c +@@ -2,7 +2,7 @@ + * s390-tools/zipl/src/install.c + * Functions handling the installation of the boot loader code onto disk. + * +- * Copyright IBM Corp. 2001, 2006. ++ * Copyright IBM Corp. 2001, 2009. + * + * Author(s): Carsten Otte + * Peter Oberparleiter +@@ -944,7 +944,7 @@ install_dump_tape(int fd, uint64_t mem) + + + int +-install_dump(const char* device, uint64_t mem) ++install_dump(const char* device, struct job_target_data* target, uint64_t mem) + { + struct disk_info* info; + char* tempdev; +@@ -985,7 +985,7 @@ install_dump(const char* device, uint64_t mem) + } + close(fd); + /* This is a disk device */ +- rc = disk_get_info(device, &info); ++ rc = disk_get_info(device, target, &info); + if (rc) { + error_text("Could not get information for dump target " + "'%s'", device); +@@ -1063,7 +1063,8 @@ install_dump(const char* device, uint64_t mem) + + + int +-install_mvdump(char* const device[], int count, uint64_t mem, uint8_t force) ++install_mvdump(char* const device[], struct job_target_data* target, int count, ++ uint64_t mem, uint8_t force) + { + struct disk_info* info[MAX_DUMP_VOLUMES] = {0}; + struct mvdump_parm_table parm; +@@ -1095,7 +1096,7 @@ install_mvdump(char* const device[], int count, uint64_t mem, uint8_t force) + } + close(fd); + /* This is a disk device */ +- rc = disk_get_info(device[i], &info[i]); ++ rc = disk_get_info(device[i], target, &info[i]); + if (rc) { + error_text("Could not get information for dump target " + "'%s'", device[i]); +diff --git a/zipl/src/job.c b/zipl/src/job.c +index 89c8c23..a65e8c1 100644 +--- a/zipl/src/job.c ++++ b/zipl/src/job.c +@@ -3,7 +3,7 @@ + * Functions and data structures representing the actual 'job' that the + * user wants us to execute. + * +- * Copyright IBM Corp. 2001, 2006. ++ * Copyright IBM Corp. 2001, 2009. + * + * Author(s): Carsten Otte + * Peter Oberparleiter +@@ -29,6 +29,11 @@ + static struct option options[] = { + { "config", required_argument, NULL, 'c'}, + { "target", required_argument, NULL, 't'}, ++ { "targetbase", required_argument, NULL, 0xaa}, ++ { "targettype", required_argument, NULL, 0xab}, ++ { "targetgeometry", required_argument, NULL, 0xac}, ++ { "targetblocksize", required_argument, NULL, 0xad}, ++ { "targetoffset", required_argument, NULL, 0xae}, + { "image", required_argument, NULL, 'i'}, + { "ramdisk", required_argument, NULL, 'r'}, + { "parmfile", required_argument, NULL, 'p'}, +@@ -71,6 +76,12 @@ struct command_line { + + /* Global variable for default boot target. Ugly but necessary... */ + static char *default_target; ++static char *default_targetbase; ++static char *default_targettype; ++static char *default_targetgeometry; ++static char *temp_targetgeometry; ++static char *default_targetblocksize; ++static char *default_targetoffset; + + static int + store_option(struct command_line* cmdline, enum scan_keyword_id keyword, +@@ -171,6 +182,32 @@ get_command_line(int argc, char* argv[], struct command_line* line) + rc = store_option(&cmdline, scan_keyword_target, + optarg); + break; ++ case 0xaa: ++ is_keyword = 1; ++ rc = store_option(&cmdline, scan_keyword_targetbase, ++ optarg); ++ break; ++ case 0xab: ++ is_keyword = 1; ++ rc = store_option(&cmdline, scan_keyword_targettype, ++ optarg); ++ break; ++ case 0xac: ++ is_keyword = 1; ++ rc = store_option(&cmdline, scan_keyword_targetgeometry, ++ optarg); ++ break; ++ case 0xad: ++ is_keyword = 1; ++ rc = store_option(&cmdline, ++ scan_keyword_targetblocksize, ++ optarg); ++ break; ++ case 0xae: ++ is_keyword = 1; ++ rc = store_option(&cmdline, scan_keyword_targetoffset, ++ optarg); ++ break; + case 'T': + is_keyword = 1; + cmdline.automenu = 0; +@@ -288,6 +325,9 @@ get_command_line(int argc, char* argv[], struct command_line* line) + } + return rc; + } ++ rc = scan_check_target_data(cmdline.data, NULL); ++ if (rc) ++ return rc; + } + *line = cmdline; + return 0; +@@ -295,6 +335,13 @@ get_command_line(int argc, char* argv[], struct command_line* line) + + + static void ++free_target_data(struct job_target_data* data) ++{ ++ if (data->targetbase != NULL) ++ free(data->targetbase); ++} ++ ++static void + free_ipl_data(struct job_ipl_data* data) + { + if (data->image != NULL) +@@ -388,8 +435,9 @@ free_mvdump_data(struct job_mvdump_data* data) + void + job_free(struct job_data* job) + { +- if (job->bootmap_dir != NULL) +- free(job->bootmap_dir); ++ if (job->target.bootmap_dir != NULL) ++ free(job->target.bootmap_dir); ++ free_target_data(&job->target); + if (job->name != NULL) + free(job->name); + switch (job->id) { +@@ -667,16 +715,16 @@ check_job_data(struct job_data* job) + int rc; + + /* Check for missing information */ +- if (job->bootmap_dir != NULL) { +- rc = misc_check_writable_directory(job->bootmap_dir); ++ if (job->target.bootmap_dir != NULL) { ++ rc = misc_check_writable_directory(job->target.bootmap_dir); + if (rc) { + if (job->name == NULL) { + error_text("Target directory '%s'", +- job->bootmap_dir); ++ job->target.bootmap_dir); + } else { + error_text("Target directory '%s' in section " + "'%s'", +- job->bootmap_dir, job->name); ++ job->target.bootmap_dir, job->name); + } + return rc; + } +@@ -854,6 +902,28 @@ get_parmline(char* filename, char* line, char** parmline, address_t* address, + + #define MEGABYTE_MASK (1024LL * 1024LL - 1LL) + ++int ++type_from_target(char *target, disk_type_t *type) ++{ ++ switch (scan_get_target_type(target)) { ++ case target_type_scsi: ++ *type = disk_type_scsi; ++ return 0; ++ case target_type_fba: ++ *type = disk_type_fba; ++ return 0; ++ case target_type_ldl: ++ *type = disk_type_eckd_classic; ++ return 0; ++ case target_type_cdl: ++ *type = disk_type_eckd_compatible; ++ return 0; ++ default: ++ return -1; ++ } ++} ++ ++ + static int + get_job_from_section_data(char* data[], struct job_data* job, char* section) + { +@@ -869,11 +939,76 @@ get_job_from_section_data(char* data[], struct job_data* job, char* section) + error_text("Unable to find default section in your config file."); + break; + } +- job->bootmap_dir = misc_strdup(default_target); ++ job->target.bootmap_dir = misc_strdup(default_target); + } else +- job->bootmap_dir = misc_strdup(data[(int) scan_keyword_target]); +- if (job->bootmap_dir == NULL) ++ job->target.bootmap_dir = misc_strdup(data[(int) scan_keyword_target]); ++ if (job->target.bootmap_dir == NULL) + return -1; ++ /* Fill in target */ ++ if (data[(int) scan_keyword_targetbase] != NULL) { ++ job->target.targetbase = ++ misc_strdup(data[(int) ++ scan_keyword_targetbase]); ++ if (job->target.targetbase == NULL) ++ return -1; ++ } else { ++ if ((data[(int) scan_keyword_target] == NULL) && ++ (default_targetbase != NULL)) { ++ job->target.targetbase = ++ misc_strdup(default_targetbase); ++ if (job->target.targetbase == NULL) ++ return -1; ++ } ++ } ++ if (data[(int) scan_keyword_targettype] != NULL) { ++ if (type_from_target( ++ data[(int) scan_keyword_targettype], ++ &job->target.targettype)) ++ return -1; ++ } else { ++ if ((data[(int) scan_keyword_target] == NULL) && ++ (default_targettype != NULL)) ++ type_from_target(default_targettype, ++ &job->target.targettype); ++ } ++ if (data[(int) scan_keyword_targetgeometry] != NULL) { ++ job->target.targetcylinders = ++ atoi(strtok(data[(int) ++ scan_keyword_targetgeometry], ",")); ++ job->target.targetheads = atoi(strtok(NULL, ",")); ++ job->target.targetsectors = atoi(strtok(NULL, ",")); ++ } else { ++ if ((data[(int) scan_keyword_target] == NULL) && ++ (default_targetgeometry != NULL)) { ++ temp_targetgeometry = ++ misc_strdup(default_targetgeometry); ++ if (temp_targetgeometry == NULL) ++ return -1; ++ job->target.targetcylinders = ++ atoi(strtok(temp_targetgeometry, ",")); ++ job->target.targetheads = atoi(strtok(NULL, ",")); ++ job->target.targetsectors = atoi(strtok(NULL, ",")); ++ free(temp_targetgeometry); ++ } ++ } ++ if (data[(int) scan_keyword_targetblocksize] != NULL) ++ job->target.targetblocksize = ++ atoi(data[(int) scan_keyword_targetblocksize]); ++ else { ++ if ((data[(int) scan_keyword_target] == NULL) && ++ (default_targetblocksize != NULL)) ++ job->target.targetblocksize = ++ atoi(default_targetblocksize); ++ } ++ if (data[(int) scan_keyword_targetoffset] != NULL) ++ job->target.targetoffset = ++ atol(data[(int) scan_keyword_targetoffset]); ++ else { ++ if ((data[(int) scan_keyword_target] == NULL) && ++ (default_targetoffset != NULL)) ++ job->target.targetoffset = ++ atol(default_targetoffset); ++ } + /* Fill in name and address of image file */ + job->data.ipl.image = misc_strdup( + data[(int) scan_keyword_image]); +@@ -942,8 +1077,9 @@ get_job_from_section_data(char* data[], struct job_data* job, char* section) + /* SEGMENT LOAD job */ + job->id = job_segment; + /* Fill in name of bootmap directory */ +- job->bootmap_dir = misc_strdup(data[(int) scan_keyword_target]); +- if (job->bootmap_dir == NULL) ++ job->target.bootmap_dir = ++ misc_strdup(data[(int) scan_keyword_target]); ++ if (job->target.bootmap_dir == NULL) + return -1; + /* Fill in segment filename */ + job->data.segment.segment = +@@ -979,8 +1115,9 @@ get_job_from_section_data(char* data[], struct job_data* job, char* section) + /* DUMP TO FILESYSTEM job */ + job->id = job_dump_fs; + /* Fill in name of bootmap directory */ +- job->bootmap_dir = misc_strdup(data[(int) scan_keyword_target]); +- if (job->bootmap_dir == NULL) ++ job->target.bootmap_dir = ++ misc_strdup(data[(int) scan_keyword_target]); ++ if (job->target.bootmap_dir == NULL) + return -1; + /* Fill in partition name */ + job->data.dump_fs.partition = +@@ -1085,11 +1222,43 @@ get_menu_job(struct scan_token* scan, char* menu, struct job_data* job) + atol(scan[i].content.keyword.value); + break; + case scan_keyword_target: +- job->bootmap_dir = misc_strdup( ++ job->target.bootmap_dir = misc_strdup( + scan[i].content.keyword.value); +- if (job->bootmap_dir == NULL) ++ if (job->target.bootmap_dir == NULL) + return -1; + break; ++ case scan_keyword_targetbase: ++ job->target.targetbase = misc_strdup( ++ scan[i].content.keyword.value); ++ if (job->target.targetbase == NULL) ++ return -1; ++ break; ++ case scan_keyword_targettype: ++ if (type_from_target( ++ scan[i].content.keyword.value, ++ &job->target.targettype)) ++ return -1; ++ break; ++ case scan_keyword_targetgeometry: ++ job->target.targetcylinders = ++ atoi(strtok( ++ scan[i].content.keyword.value, ++ ",")); ++ job->target.targetheads = ++ atoi(strtok(NULL, ",")); ++ job->target.targetsectors = ++ atoi(strtok(NULL, ",")); ++ break; ++ case scan_keyword_targetblocksize: ++ job->target.targetblocksize = ++ atoi( ++ scan[i].content.keyword.value); ++ break; ++ case scan_keyword_targetoffset: ++ job->target.targetoffset = ++ atol( ++ scan[i].content.keyword.value); ++ break; + default: + /* Should not happen */ + break; +@@ -1142,7 +1311,8 @@ get_menu_job(struct scan_token* scan, char* menu, struct job_data* job) + return -1; + memset((void *) temp_job, 0, sizeof(struct job_data)); + if (data[(int) scan_keyword_target] == NULL) +- data[(int) scan_keyword_target] = misc_strdup(job->bootmap_dir); ++ data[(int) scan_keyword_target] = ++ misc_strdup(job->target.bootmap_dir); + rc = get_job_from_section_data(data, temp_job, + job->data.menu.entry[current].name); + if (rc) { +@@ -1254,6 +1424,56 @@ get_section_job(struct scan_token* scan, char* section, struct job_data* job, + scan[i].content.keyword.keyword == scan_keyword_target && + !strcmp(DEFAULTBOOT_SECTION, name)) + default_target = misc_strdup(scan[i].content.keyword.value); ++ if (scan[i].id == scan_id_keyword_assignment && ++ scan[i].content.keyword.keyword == ++ scan_keyword_targetbase && ++ scan[i].content.keyword.value != NULL && ++ !strcmp(DEFAULTBOOT_SECTION, name)) { ++ default_targetbase = ++ misc_strdup(scan[i].content.keyword.value); ++ if (default_targetbase == NULL) ++ return -1; ++ } ++ if (scan[i].id == scan_id_keyword_assignment && ++ scan[i].content.keyword.keyword == ++ scan_keyword_targettype && ++ scan[i].content.keyword.value != NULL && ++ !strcmp(DEFAULTBOOT_SECTION, name)) { ++ default_targettype = ++ misc_strdup(scan[i].content.keyword.value); ++ if (default_targettype == NULL) ++ return -1; ++ } ++ if (scan[i].id == scan_id_keyword_assignment && ++ scan[i].content.keyword.keyword == ++ scan_keyword_targetgeometry && ++ scan[i].content.keyword.value != NULL && ++ !strcmp(DEFAULTBOOT_SECTION, name)) { ++ default_targetgeometry = ++ misc_strdup(scan[i].content.keyword.value); ++ if (default_targetgeometry == NULL) ++ return -1; ++ } ++ if (scan[i].id == scan_id_keyword_assignment && ++ scan[i].content.keyword.keyword == ++ scan_keyword_targetblocksize && ++ scan[i].content.keyword.value != NULL && ++ !strcmp(DEFAULTBOOT_SECTION, name)) { ++ default_targetblocksize = ++ misc_strdup(scan[i].content.keyword.value); ++ if (default_targetblocksize == NULL) ++ return -1; ++ } ++ if (scan[i].id == scan_id_keyword_assignment && ++ scan[i].content.keyword.keyword == ++ scan_keyword_targetoffset && ++ scan[i].content.keyword.value != NULL && ++ !strcmp(DEFAULTBOOT_SECTION, name)) { ++ default_targetoffset = ++ misc_strdup(scan[i].content.keyword.value); ++ if (default_targetoffset == NULL) ++ return -1; ++ } + } + } + if (strcmp(section, DEFAULTBOOT_SECTION) == 0) { +@@ -1335,16 +1555,25 @@ create_fake_menu(struct scan_token *scan) + int i, j, pos, numsec, size, defaultpos; + char *name; + char *target; ++ char *targetbase; ++ char *targettype; ++ char *targetgeometry; ++ char *targetblocksize; ++ char *targetoffset; + char *timeout; + char *seclist[1024]; + char *defaultsection; + char buf[1024]; + struct scan_token *tmp; +- + /* Count # of sections */ + numsec = 0; + name = NULL; + target = NULL; ++ targetbase = NULL; ++ targettype = NULL; ++ targetgeometry = NULL; ++ targetblocksize = NULL; ++ targetoffset = NULL; + timeout = NULL; + for (i = 0; (int) scan[i].id != 0; i++) { + if (scan[i].id == scan_id_section_heading) { +@@ -1364,6 +1593,36 @@ create_fake_menu(struct scan_token *scan) + target = scan[i].content.keyword.value; + + if (scan[i].id == scan_id_keyword_assignment && ++ scan[i].content.keyword.keyword == ++ scan_keyword_targetbase && ++ !strcmp(DEFAULTBOOT_SECTION, name)) ++ targetbase = scan[i].content.keyword.value; ++ ++ if (scan[i].id == scan_id_keyword_assignment && ++ scan[i].content.keyword.keyword == ++ scan_keyword_targettype && ++ !strcmp(DEFAULTBOOT_SECTION, name)) ++ targettype = scan[i].content.keyword.value; ++ ++ if (scan[i].id == scan_id_keyword_assignment && ++ scan[i].content.keyword.keyword == ++ scan_keyword_targetgeometry && ++ !strcmp(DEFAULTBOOT_SECTION, name)) ++ targetgeometry = scan[i].content.keyword.value; ++ ++ if (scan[i].id == scan_id_keyword_assignment && ++ scan[i].content.keyword.keyword == ++ scan_keyword_targetblocksize && ++ !strcmp(DEFAULTBOOT_SECTION, name)) ++ targetblocksize = scan[i].content.keyword.value; ++ ++ if (scan[i].id == scan_id_keyword_assignment && ++ scan[i].content.keyword.keyword == ++ scan_keyword_targetoffset && ++ !strcmp(DEFAULTBOOT_SECTION, name)) ++ targetoffset = scan[i].content.keyword.value; ++ ++ if (scan[i].id == scan_id_keyword_assignment && + scan[i].content.keyword.keyword == scan_keyword_timeout) + timeout = scan[i].content.keyword.value; + } +@@ -1380,8 +1639,33 @@ create_fake_menu(struct scan_token *scan) + } + + default_target = misc_strdup(target); ++ if (targetbase != NULL) { ++ default_targetbase = misc_strdup(targetbase); ++ if (default_targetbase == NULL) ++ return NULL; ++ } ++ if (targettype != NULL) { ++ default_targettype = misc_strdup(targettype); ++ if (default_targettype == NULL) ++ return NULL; ++ } ++ if (targetgeometry != NULL) { ++ default_targetgeometry = misc_strdup(targetgeometry); ++ if (default_targetgeometry == NULL) ++ return NULL; ++ } ++ if (targetblocksize != NULL) { ++ default_targetblocksize = misc_strdup(targetblocksize); ++ if (default_targetblocksize == NULL) ++ return NULL; ++ } ++ if (targetoffset != NULL) { ++ default_targetoffset = misc_strdup(targetoffset); ++ if (default_targetoffset == NULL) ++ return NULL; ++ } + +- size = i+6+numsec; ++ size = i+11+numsec; + tmp = (struct scan_token *) misc_malloc(size * sizeof(struct scan_token)); + if (tmp == NULL) { + error_text("Couldn't allocate memory for menu entries"); +@@ -1408,6 +1692,46 @@ create_fake_menu(struct scan_token *scan) + scan[i].line = i; + scan[i].content.keyword.keyword = scan_keyword_target; + scan[i++].content.keyword.value = misc_strdup(target); ++ if ( targetbase) { ++ scan[i].id = scan_id_keyword_assignment; ++ scan[i].line = i; ++ scan[i].content.keyword.keyword = scan_keyword_targetbase; ++ scan[i++].content.keyword.value = misc_strdup(targetbase); ++ if (scan[i - 1].content.keyword.value == NULL) ++ return NULL; ++ } ++ if ( targettype) { ++ scan[i].id = scan_id_keyword_assignment; ++ scan[i].line = i; ++ scan[i].content.keyword.keyword = scan_keyword_targettype; ++ scan[i++].content.keyword.value = misc_strdup(targettype); ++ if (scan[i - 1].content.keyword.value == NULL) ++ return NULL; ++ } ++ if ( targetgeometry) { ++ scan[i].id = scan_id_keyword_assignment; ++ scan[i].line = i; ++ scan[i].content.keyword.keyword = scan_keyword_targetgeometry; ++ scan[i++].content.keyword.value = misc_strdup(targetgeometry); ++ if (scan[i - 1].content.keyword.value == NULL) ++ return NULL; ++ } ++ if ( targetblocksize) { ++ scan[i].id = scan_id_keyword_assignment; ++ scan[i].line = i; ++ scan[i].content.keyword.keyword = scan_keyword_targetblocksize; ++ scan[i++].content.keyword.value = misc_strdup(targetblocksize); ++ if (scan[i - 1].content.keyword.value == NULL) ++ return NULL; ++ } ++ if ( targetoffset) { ++ scan[i].id = scan_id_keyword_assignment; ++ scan[i].line = i; ++ scan[i].content.keyword.keyword = scan_keyword_targetoffset; ++ scan[i++].content.keyword.value = misc_strdup(targetoffset); ++ if (scan[i - 1].content.keyword.value == NULL) ++ return NULL; ++ } + scan[i].id = scan_id_keyword_assignment; + scan[i].line = i; + scan[i].content.keyword.keyword = scan_keyword_default; +diff --git a/zipl/src/scan.c b/zipl/src/scan.c +index caca3cf..16da9b3 100644 +--- a/zipl/src/scan.c ++++ b/zipl/src/scan.c +@@ -2,7 +2,7 @@ + * s390-tools/zipl/src/scan.c + * Scanner for zipl.conf configuration files + * +- * Copyright IBM Corp. 2001, 2006. ++ * Copyright IBM Corp. 2001, 2009. + * + * Author(s): Carsten Otte + * Peter Oberparleiter +@@ -31,21 +31,33 @@ enum scan_key_state scan_key_table[SCAN_SECTION_NUM][SCAN_KEYWORD_NUM] = { + /* defa dump dump imag para parm ramd segm targ prom time defa tape mv + * ult to tofs e mete file isk ent et pt out ultm dump + * rs enu ++ * ++ * targ targ targ targ targ ++ * etba etty etge etbl etof ++ * se pe omet ocks fset ++ * ry ize + */ + /* defaultboot */ +- {opt, inv, inv, inv, inv, inv, inv, inv, req, inv, opt, opt, inv, inv}, ++ {opt, inv, inv, inv, inv, inv, inv, inv, req, inv, opt, opt, inv, inv, ++ opt, opt, opt, opt, opt}, + /* ipl */ +- {inv, inv, inv, req, opt, opt, opt, inv, opt, inv, inv, inv, inv, inv}, ++ {inv, inv, inv, req, opt, opt, opt, inv, opt, inv, inv, inv, inv, inv, ++ opt, opt, opt, opt, opt}, + /* segment load */ +- {inv, inv, inv, inv, inv, inv, inv, req, req, inv, inv, inv, inv, inv}, ++ {inv, inv, inv, inv, inv, inv, inv, req, req, inv, inv, inv, inv, inv, ++ inv, inv, inv, inv, inv}, + /* part dump */ +- {inv, req, inv, inv, inv, inv, inv, inv, opt, inv, inv, inv, inv, inv}, ++ {inv, req, inv, inv, inv, inv, inv, inv, opt, inv, inv, inv, inv, inv, ++ inv, inv, inv, inv, inv}, + /* fs dump */ +- {inv, inv, req, inv, opt, opt, inv, inv, req, inv, inv, inv, inv, inv}, ++ {inv, inv, req, inv, opt, opt, inv, inv, req, inv, inv, inv, inv, inv, ++ inv, inv, inv, inv, inv}, + /* ipl tape */ +- {inv, inv, inv, req, opt, opt, opt, inv, inv, inv, inv, inv, req, inv}, ++ {inv, inv, inv, req, opt, opt, opt, inv, inv, inv, inv, inv, req, inv, ++ inv, inv, inv, inv, inv}, + /* multi volume dump */ +- {inv, inv, inv, inv, inv, inv, inv, inv, inv, inv, inv, inv, inv, req} ++ {inv, inv, inv, inv, inv, inv, inv, inv, inv, inv, inv, inv, inv, req, ++ inv, inv, inv, inv, inv} + }; + + /* Mapping of keyword IDs to strings */ +@@ -63,13 +75,17 @@ static const struct { + { "parmfile", scan_keyword_parmfile }, + { "ramdisk", scan_keyword_ramdisk }, + { "segment", scan_keyword_segment }, ++ { "targetbase", scan_keyword_targetbase}, ++ { "targettype", scan_keyword_targettype}, ++ { "targetgeometry", scan_keyword_targetgeometry}, ++ { "targetblocksize", scan_keyword_targetblocksize}, ++ { "targetoffset", scan_keyword_targetoffset}, + { "target", scan_keyword_target}, + { "prompt", scan_keyword_prompt}, + { "timeout", scan_keyword_timeout}, + { "tape", scan_keyword_tape} + }; + +- + /* Retrieve name of keyword identified by ID. */ + char * + scan_keyword_name(enum scan_keyword_id id) +@@ -608,6 +624,19 @@ scan_get_section_type(char* keyword[]) + return section_invalid; + } + ++enum scan_target_type ++scan_get_target_type(char *type) ++{ ++ if (strcasecmp(type, "SCSI") == 0) ++ return target_type_scsi; ++ else if (strcasecmp(type, "FBA") == 0) ++ return target_type_fba; ++ else if (strcasecmp(type, "LDL") == 0) ++ return target_type_ldl; ++ else if (strcasecmp(type, "CDL") == 0) ++ return target_type_cdl; ++ return target_type_invalid; ++} + + #define MAX(a,b) ((a)>(b)?(a):(b)) + +@@ -643,9 +672,13 @@ scan_check_section_data(char* keyword[], int* line, char* name, + } else if (keyword[(int) scan_keyword_mvdump]) { + *type = section_mvdump; + main_keyword = scan_keyword_name(scan_keyword_mvdump); +- } else +- /* Incomplete section data */ ++ } else { ++ error_reason("Line %d: section '%s' must contain " ++ "either one of keywords 'image', " ++ "'segment', 'dumpto', 'dumptofs', " ++ "'mvdump' or 'tape'", section_line, name); + return -1; ++ } + } + /* Check keywords */ + for (i=0; i < SCAN_KEYWORD_NUM; i++) { +@@ -734,6 +767,174 @@ scan_check_section_data(char* keyword[], int* line, char* name, + } + + ++static int ++check_blocksize(int size) ++{ ++ switch (size) { ++ case 512: ++ case 1024: ++ case 2048: ++ case 4096: ++ return 0; ++ } ++ return -1; ++} ++ ++ ++int ++scan_check_target_data(char* keyword[], int* line) ++{ ++ int cylinders, heads, sectors; ++ char dummy; ++ int number; ++ enum scan_keyword_id errid; ++ ++ if ((keyword[(int) scan_keyword_targetbase] != 0) && ++ (keyword[(int) scan_keyword_target] == 0)) { ++ if (line != NULL) ++ error_reason("Line %d: keyword 'target' required " ++ "when specifying 'targetbase'", ++ line[(int) scan_keyword_targetbase]); ++ else ++ error_reason("Option 'target' required when " ++ "specifying 'targetbase'"); ++ return -1; ++ } ++ if (keyword[(int) scan_keyword_targetbase] == 0) { ++ if (keyword[(int) scan_keyword_targettype] != 0) ++ errid = scan_keyword_targettype; ++ else if ((keyword[(int) scan_keyword_targetgeometry] != 0)) ++ errid = scan_keyword_targetgeometry; ++ else if ((keyword[(int) scan_keyword_targetblocksize] != 0)) ++ errid = scan_keyword_targetblocksize; ++ else if ((keyword[(int) scan_keyword_targetoffset] != 0)) ++ errid = scan_keyword_targetoffset; ++ else ++ return 0; ++ if (line != NULL) ++ error_reason("Line %d: keyword 'targetbase' required " ++ "when specifying '%s'", ++ line[(int) errid], scan_keyword_name(errid)); ++ else ++ error_reason("Option 'targetbase' required when " ++ "specifying '%s'", ++ scan_keyword_name(errid)); ++ return -1; ++ } ++ if (keyword[(int) scan_keyword_targettype] == 0) { ++ if (line != NULL) ++ error_reason("Line %d: keyword 'targettype' " ++ "required when specifying 'targetbase'", ++ line[(int) scan_keyword_targetbase]); ++ else ++ error_reason("Option 'targettype' required " ++ "when specifying 'targetbase'"); ++ return -1; ++ } ++ switch (scan_get_target_type(keyword[(int) scan_keyword_targettype])) { ++ case target_type_cdl: ++ case target_type_ldl: ++ if ((keyword[(int) scan_keyword_targetgeometry] != 0)) ++ break; ++ if (line != NULL) ++ error_reason("Line %d: keyword 'targetgeometry' " ++ "required when specifying 'targettype' %s", ++ line[(int) scan_keyword_targettype], ++ keyword[(int) scan_keyword_targettype]); ++ else ++ error_reason("Option 'targetgeometry' required when " ++ "specifying 'targettype' %s", ++ keyword[(int) scan_keyword_targettype]); ++ return -1; ++ case target_type_scsi: ++ case target_type_fba: ++ if ((keyword[(int) scan_keyword_targetgeometry] == 0)) ++ break; ++ if (line != NULL) ++ error_reason("Line %d: keyword " ++ "'targetgeometry' not allowed for " ++ "'targettype' %s", ++ line[(int) scan_keyword_targetgeometry], ++ keyword[(int) scan_keyword_targettype]); ++ else ++ error_reason("Keyword 'targetgeometry' not " ++ "allowed for 'targettype' %s", ++ keyword[(int) scan_keyword_targettype]); ++ return -1; ++ case target_type_invalid: ++ if (line != NULL) ++ error_reason("Line %d: Unrecognized 'targettype' value " ++ "'%s'", ++ line[(int) scan_keyword_targettype], ++ keyword[(int) scan_keyword_targettype]); ++ else ++ error_reason("Unrecognized 'targettype' value '%s'", ++ keyword[(int) scan_keyword_targettype]); ++ return -1; ++ } ++ if (keyword[(int) scan_keyword_targetgeometry] != 0) { ++ if ((sscanf(keyword[(int) scan_keyword_targetgeometry], ++ "%d,%d,%d %c", &cylinders, &heads, §ors, &dummy) ++ != 3) || (cylinders <= 0) || (heads <= 0) || ++ (sectors <= 0)) { ++ if (line != NULL) ++ error_reason("Line %d: Invalid target geometry " ++ "'%s'", line[ ++ (int) scan_keyword_targetgeometry], ++ keyword[ ++ (int) scan_keyword_targetgeometry]); ++ else ++ error_reason("Invalid target geometry '%s'", ++ keyword[ ++ (int) scan_keyword_targetgeometry]); ++ return -1; ++ } ++ } ++ if (keyword[(int) scan_keyword_targetblocksize] == 0) { ++ if (line != NULL) ++ error_reason("Line %d: Keyword 'targetblocksize' " ++ "required when specifying 'targetbase'", ++ line[(int) scan_keyword_targetbase]); ++ else ++ error_reason("Option 'targetblocksize' required when " ++ "specifying 'targetbase'"); ++ return -1; ++ } ++ if ((sscanf(keyword[(int) scan_keyword_targetblocksize], "%d %c", ++ &number, &dummy) != 1) || check_blocksize(number)) { ++ if (line != NULL) ++ error_reason("Line %d: Invalid target blocksize '%s'", ++ line[(int) scan_keyword_targetblocksize], ++ keyword[(int) scan_keyword_targetblocksize]); ++ else ++ error_reason("Invalid target blocksize '%s'", ++ keyword[(int) scan_keyword_targetblocksize]); ++ return -1; ++ } ++ if (keyword[(int) scan_keyword_targetoffset] == 0) { ++ if (line != NULL) ++ error_reason("Line %d: Keyword 'targetoffset' " ++ "required when specifying 'targetbase'", ++ line[(int) scan_keyword_targetbase]); ++ else ++ error_reason("Option 'targetoffset' required when " ++ "specifying 'targetbase'"); ++ return -1; ++ } ++ if (sscanf(keyword[(int) scan_keyword_targetoffset], "%d %c", ++ &number, &dummy) != 1) { ++ if (line != NULL) ++ error_reason("Line %d: Invalid target offset '%s'", ++ line[(int) scan_keyword_targetoffset], ++ keyword[(int) scan_keyword_targetoffset]); ++ else ++ error_reason("Invalid target offset '%s'", ++ keyword[(int) scan_keyword_targetoffset]); ++ return -1; ++ } ++ return 0; ++} ++ + /* Check section at INDEX for compliance with config file rules. Upon success, + * return zero and advance INDEX to point to the end of the section. Return + * non-zero otherwise. */ +@@ -764,6 +965,7 @@ check_section(struct scan_token* scan, int* index) + else + type = section_invalid; + memset(keyword, 0, sizeof(keyword)); ++ memset(keyword_line, 0, sizeof(keyword_line)); + line = scan[i].line; + /* Account for keywords */ + for (i++; (int) scan[i].id != 0; i++) { +@@ -802,13 +1004,10 @@ check_section(struct scan_token* scan, int* index) + } + } + rc = scan_check_section_data(keyword, keyword_line, name, line, &type); +- /* Check for missing keyword */ +- if (type == section_invalid) { +- error_reason("Line %d: section '%s' must contain either one " +- "of keywords 'image', 'segment', 'dumpto', " +- "'dumptofs', 'mvdump' or 'tape'", line, name); +- return -1; +- } ++ if (rc) ++ return rc; ++ /* Check target data */ ++ rc = scan_check_target_data(keyword, keyword_line); + if (rc) + return rc; + /* Advance index to end of section */ +@@ -840,6 +1039,8 @@ find_num_assignment(struct scan_token* scan, int num, int offset) + static int + check_menu(struct scan_token* scan, int* index) + { ++ char* keyword[SCAN_KEYWORD_NUM]; ++ int keyword_line[SCAN_KEYWORD_NUM]; + enum scan_keyword_id key_id; + char* name; + char* str; +@@ -852,6 +1053,7 @@ check_menu(struct scan_token* scan, int* index) + int is_default; + int is_prompt; + int is_timeout; ++ int rc; + + i = *index; + name = scan[i].content.menu.name; +@@ -862,6 +1064,8 @@ check_menu(struct scan_token* scan, int* index) + scan[line].line, name); + return -1; + } ++ memset(keyword, 0, sizeof(keyword)); ++ memset(keyword_line, 0, sizeof(keyword_line)); + line = scan[i].line; + is_num = 0; + is_target = 0; +@@ -886,6 +1090,24 @@ check_menu(struct scan_token* scan, int* index) + } + is_target = 1; + break; ++ case scan_keyword_targetbase: ++ case scan_keyword_targettype: ++ case scan_keyword_targetgeometry: ++ case scan_keyword_targetblocksize: ++ case scan_keyword_targetoffset: ++ key_id = scan[i].content.keyword.keyword; ++ keyword_line[key_id] = scan[i].line; ++ /* Rule 5 */ ++ if (keyword[(int) key_id] != NULL) { ++ error_reason("Line %d: keyword '%s' " ++ "already specified", ++ scan[i].line, ++ scan_keyword_name(key_id)); ++ return -1; ++ } ++ keyword[(int) key_id] = ++ scan[i].content.keyword.value; ++ break; + case scan_keyword_default: + if (is_default) { + error_reason("Line %d: keyword '%s' " +@@ -1044,6 +1266,10 @@ check_menu(struct scan_token* scan, int* index) + name); + return -1; + } ++ /* Check target data */ ++ rc = scan_check_target_data(keyword, keyword_line); ++ if (rc) ++ return rc; + /* Advance index to end of menu section */ + *index = i - 1; + return 0; +diff --git a/zipl/src/zipl.c b/zipl/src/zipl.c +index 4d9fd36..3a4c18c 100644 +--- a/zipl/src/zipl.c ++++ b/zipl/src/zipl.c +@@ -2,7 +2,7 @@ + * s390-tools/zipl/src/zipl.c + * zSeries Initial Program Loader tool. + * +- * Copyright IBM Corp. 2001, 2006. ++ * Copyright IBM Corp. 2001, 2009. + * + * Author(s): Carsten Otte + * Peter Oberparleiter +@@ -41,7 +41,7 @@ int dry_run = 1; + static const char tool_name[] = "zipl: zSeries Initial Program Loader"; + + /* Copyright notice */ +-static const char copyright_notice[] = "Copyright IBM Corp. 2001, 2008"; ++static const char copyright_notice[] = "Copyright IBM Corp. 2001, 2009"; + + /* Usage information */ + static const char* usage_text[] = { +@@ -55,6 +55,11 @@ static const char* usage_text[] = { + "-c, --config CONFIGFILE Read configuration from CONFIGFILE", + "-t, --target TARGETDIR Write bootmap file to TARGETDIR and install", + " bootloader on device containing TARGETDIR", ++" --targetbase BASEDEVICE Install bootloader on BASEDEVICE", ++" --targettype TYPE Use device type: CDL, LDL, FBA, SCSI", ++" --targetgeometry C,H,S Use disk geometry: cylinders,heads,sectors", ++" --targetblocksize SIZE Use number of bytes per block", ++" --targetoffset OFFSET Use offset between logical and physical disk", + "-i, --image IMAGEFILE[,ADDR] Install Linux kernel image from IMAGEFILE", + "-r, --ramdisk RAMDISK[,ADDR] Install initial ramdisk from file RAMDISK", + "-p, --parmfile PARMFILE[,ADDR] Use kernel parmline stored in PARMFILE", +@@ -190,10 +195,12 @@ main(int argc, char* argv[]) + break; + case job_dump_partition: + /* Retrieve target device information */ +- rc = install_dump(job->data.dump.device, job->data.dump.mem); ++ rc = install_dump(job->data.dump.device, &job->target, ++ job->data.dump.mem); + break; + case job_mvdump: + rc = install_mvdump(job->data.mvdump.device, ++ &job->target, + job->data.mvdump.device_count, + job->data.mvdump.mem, + job->data.mvdump.force); +diff --git a/zipl/src/zipl_helper.device-mapper b/zipl/src/zipl_helper.device-mapper +new file mode 100644 +index 0000000..669f3e3 +--- /dev/null ++++ b/zipl/src/zipl_helper.device-mapper +@@ -0,0 +1,716 @@ ++#!/usr/bin/perl -w ++# ++# zipl_helper.device-mapper: print zipl parameters for a device-mapper device ++# ++# Copyright IBM Corp. 2009 ++# ++# Author(s): Peter Oberparleiter ++# ++# Usage: zipl_helper.device-mapper ++# ++# This tool attempts to obtain zipl parameters for a target directory located ++# on a device-mapper device. It assumes that the device-mapper table for this ++# device conforms to the following rules: ++# - directory is located on a device consisting of a single device-mapper ++# target ++# - only linear, mirror and multipath targets are supported ++# - supported physical device types are DASD and SCSI devices ++# - all of the device which contains the directory must be located on a single ++# physical device (which may be mirrorred or accessed through a multipath ++# target) ++# - any mirror in the device-mapper setup must include block 0 of the ++# physical device ++# ++ ++use strict; ++use File::Basename; ++ ++# Required tools ++our $dmsetup = "dmsetup"; ++our $mknod = "mknod"; ++our $dasdview = "dasdview"; ++our $blockdev = "blockdev"; ++ ++# Constants ++our $SECTOR_SIZE = 512; ++our $DASD_PARTN_MASK = 0x03; ++our $SCSI_PARTN_MASK = 0x0f; ++ ++# Internal constants ++our $DEV_TYPE_CDL = 0; ++our $DEV_TYPE_LDL = 1; ++our $DEV_TYPE_FBA = 2; ++our $DEV_TYPE_SCSI = 3; ++ ++our $TARGET_START = 0; ++our $TARGET_LENGTH = 1; ++our $TARGET_TYPE = 2; ++our $TARGET_DATA = 3; ++ ++our $TARGET_TYPE_LINEAR = 0; ++our $TARGET_TYPE_MIRROR = 1; ++our $TARGET_TYPE_MULTIPATH = 2; ++ ++our $LINEAR_MAJOR = 0; ++our $LINEAR_MINOR = 1; ++our $LINEAR_START_SECTOR = 2; ++ ++our $MIRROR_MAJOR = 0; ++our $MIRROR_MINOR = 1; ++our $MIRROR_START_SECTOR = 2; ++ ++our $MULTIPATH_MAJOR = 0; ++our $MULTIPATH_MINOR = 1; ++ ++sub get_physical_device($); ++sub get_major_minor($); ++sub get_table($$); ++sub get_linear_data($$); ++sub get_mirror_data($$); ++sub get_multipath_data($$); ++sub filter_table($$$); ++sub get_target_start($); ++sub get_target_major_minor($); ++sub create_temp_device_node($$$); ++sub get_blocksize($); ++sub get_dasd_info($); ++sub get_partition_start($); ++sub is_dasd($); ++sub get_partition_base($$$); ++sub get_device_characteristics($$); ++sub get_type_name($); ++sub check_for_mirror($@); ++sub get_target_base($$$$@); ++sub get_device_name($$); ++ ++my $phy_geometry; # Disk geometry of physical device ++my $phy_blocksize; # Blocksize of physical device ++my $phy_offset; # Offset in 512-byte sectors between start of physical ++ # device and start of filesystem ++my $phy_type; # Type of physical device ++my $phy_bootsectors; # Size of boot record in 512-byte sectors ++my $phy_partstart; # Partition offset of physical device ++my $phy_major; # Major device number of physical device ++my $phy_minor; # Minor device number of physical device ++my @target_list; # List of dm-targets between filesystem and physical ++ # device. ++my $base_major; # Major device number of base device. ++my $base_minor; # Minor device number of base device ++my $directory; # Command line parameter ++my $toolname; # Name of tool ++ ++# Start ++$toolname = basename($0); ++$directory = $ARGV[0]; ++if (!defined($directory)) { ++ die("Usage: $toolname \n"); ++} ++ ++# Determine physical (non-dm) device on which directory is located ++($phy_major, $phy_minor, $phy_offset, @target_list) = ++ get_physical_device($directory); ++# Determine type and characteristics of physical device ++($phy_type, $phy_blocksize, $phy_geometry, $phy_bootsectors, $phy_partstart) = ++ get_device_characteristics($phy_major, $phy_minor); ++ ++# Handle partitions ++if ($phy_partstart > 0) { ++ # Only the partition of the physical device is mapped so only the ++ # physical device can provide access to the boot record. ++ ($base_major, $base_minor) = ++ get_partition_base($phy_type, $phy_major, $phy_minor); ++ # Check for mirror ++ check_for_mirror(scalar(@target_list) - 1, @target_list); ++ # Adjust filesystem offset ++ $phy_offset += $phy_partstart * ($phy_blocksize / $SECTOR_SIZE); ++ $phy_partstart = 0; ++ # Update device geometry ++ (undef, undef, $phy_geometry, undef, undef) = ++ get_device_characteristics($base_major, $base_minor); ++} else { ++ # All of the device is mapped, so the base device is the top most ++ # dm device which provides access to boot sectors ++ ($base_major, $base_minor) = ++ get_target_base($phy_major, $phy_minor, 0, $phy_bootsectors, ++ @target_list); ++} ++ ++# Check for valid offset of file system ++if (($phy_offset % ($phy_blocksize / $SECTOR_SIZE)) != 0) { ++ die("Error: File system not aligned on physical block size\n"); ++} ++ ++# Print resulting information ++print("targetbase=$base_major:$base_minor\n"); ++print("targettype=".get_type_name($phy_type)."\n"); ++if (defined($phy_geometry)) { ++ print("targetgeometry=$phy_geometry\n"); ++} ++print("targetblocksize=$phy_blocksize\n"); ++print("targetoffset=".($phy_offset / ($phy_blocksize / $SECTOR_SIZE))."\n"); ++ ++exit(0); ++ ++# get_physical_device(directory) ++# Returns (phy_major, phy_minor, phy_offset, @target_list). ++# target_list: [target_data1, target_data2, ..., target_datan] ++# target_data: [major, minor, target] ++sub get_physical_device($) ++{ ++ my ($directory) = @_; ++ my $major; ++ my $minor; ++ my $table; ++ my $target; ++ my $start; ++ my $length; ++ my @target_list; ++ ++ # Get information about device containing filesystem ++ ($major, $minor) = get_major_minor($directory); ++ $table = get_table($major, $minor); ++ if (scalar(@$table) == 0) { ++ die("Error: Could not retrieve device-mapper information for ". ++ "device '".get_device_name($major, $minor)."'\n"); ++ } ++ # Filesystem must be on a single dm target ++ if (scalar(@$table) != 1) { ++ die("Error: Unsupported setup: Directory '$directory' is ". ++ "located on a multi-target device-mapper device\n"); ++ } ++ ++ $target = $table->[0]; ++ push(@target_list, [$major, $minor, $target]); ++ $start = $target->[$TARGET_START]; ++ $length = $target->[$TARGET_LENGTH]; ++ while (1) { ++ # Convert fs_start to offset on parent dm device ++ $start += get_target_start($target); ++ ($major, $minor) = get_target_major_minor($target); ++ $table = get_table($major, $minor); ++ if (scalar(@$table) == 0) { ++ # Found non-dm device ++ return ($major, $minor, $start, @target_list); ++ } ++ # Get target in parent table which contains filesystem ++ $table = filter_table($table, $start, $length); ++ if (scalar(@$table) != 1) { ++ die("Error: Unsupported setup: Could not map ". ++ "directory '$directory' to a single physical ". ++ "device\n"); ++ } ++ $target = $table->[0]; ++ push(@target_list, [$major, $minor, $target]); ++ # Convert fs_start to offset on parent target ++ $start -= $target->[$TARGET_START]; ++ } ++} ++ ++# get_major_minor(filename) ++# Returns: (device major, device minor) of the device containing the ++# specified file. ++sub get_major_minor($) ++{ ++ my ($filename) = @_; ++ my @stat; ++ my $dev; ++ my $major; ++ my $minor; ++ ++ @stat = stat($filename); ++ if (!@stat) { ++ die("Error: Could not stat '$filename'\n"); ++ } ++ $dev = $stat[0]; ++ $major = ($dev & 0xfff00) >> 8; ++ $minor = ($dev & 0xff) | (($dev >> 12) & 0xfff00); ++ ++ return ($major, $minor); ++} ++ ++# get_table(major, minor) ++# Returns: [target1, target2, ..., targetn] ++# target: [start, length, type, data] ++# data: linear_data|mirror_data|multipath_data ++sub get_table($$) ++{ ++ my ($major, $minor) = @_; ++ my @table; ++ my $dev_name = get_device_name($major, $minor); ++ local *HANDLE; ++ ++ open(HANDLE, "$dmsetup table -j $major -m $minor 2>/dev/null|") or ++ return undef; ++ while () { ++ if (!(/^(\d+)\s+(\d+)\s+(\S+)\s+(\S.*)$/)) { ++ die("Error: Unrecognized device-mapper table format ". ++ "for device '$dev_name'\n"); ++ } ++ my ($start, $length, $target_type, $args) = ($1, $2, $3, $4); ++ my $data; ++ my $type; ++ ++ if ($target_type eq "linear") { ++ $type = $TARGET_TYPE_LINEAR; ++ $data = get_linear_data($dev_name, $args); ++ } elsif ($target_type eq "mirror") { ++ $type = $TARGET_TYPE_MIRROR; ++ $data = get_mirror_data($dev_name, $args); ++ } elsif ($target_type eq "multipath") { ++ $type = $TARGET_TYPE_MULTIPATH; ++ $data = get_multipath_data($dev_name, $args); ++ } else { ++ die("Error: Unsupported setup: Unsupported ". ++ "device-mapper target type '$target_type' for ". ++ "device '$dev_name'\n"); ++ } ++ push(@table, [$start, $length, $type, $data]); ++ } ++ close(HANDLE); ++ return \@table; ++} ++ ++# get_linear_data(dev_name, args) ++# Returns: [major, minor, start_sector] ++sub get_linear_data($$) ++{ ++ my ($dev_name, $args) = @_; ++ ++ if (!($args =~ /^(\d+):(\d+)\s+(\d+)$/)) { ++ die("Error: Unrecognized device-mapper table format for ". ++ "device '$dev_name'\n"); ++ } ++ return [$1, $2, $3]; ++} ++ ++# get_mirror_data(dev_name, args) ++# Returns [[major1, minor1, start_sector1], [major2, minor2, start_sector2], ..] ++sub get_mirror_data($$) ++{ ++ my ($dev_name, $args) = @_; ++ my @argv = split(/\s+/, $args); ++ my @data; ++ my $offset; ++ ++ # Remove log_type + #logargs + logargs + #devs ++ splice(@argv, 0, $argv[1] + 3); ++ if (!@argv) { ++ goto out_error; ++ } ++ while (@argv) { ++ if (!($argv[0] =~ /^(\d+):(\d+)$/)) { ++ goto out_error; ++ } ++ push(@data, [$1, $2, $argv[1]]); ++ if (!defined($offset)) { ++ $offset = $argv[1]; ++ } elsif ($argv[1] != $offset) { ++ die("Error: Unsupported setup: Mirror target on ". ++ "device '$dev_name' contains entries with varying ". ++ "sector offsets\n"); ++ } ++ splice(@argv, 0, 2); ++ } ++ if (!scalar(@data)) { ++ goto out_error; ++ } ++ return \@data; ++ ++out_error: ++ die("Error: Unrecognized device-mapper table format for device ". ++ "'$dev_name'\n"); ++} ++ ++# get_multipath_data(dev_name, args) ++# Returns [[major1, minor1], [major2, minor2], ..] ++sub get_multipath_data($$) ++{ ++ my ($dev_name, $args) = @_; ++ my @argv = split(/\s+/, $args); ++ my @data; ++ ++ # Remove #features + features ++ splice(@argv, 0, $argv[0] + 1); ++ if (!@argv) { ++ goto out_error; ++ } ++ # Remove #handlerargs + handlerargs ++ splice(@argv, 0, $argv[0] + 1); ++ if (!@argv) { ++ goto out_error; ++ } ++ # Remove #pathgroups + pathgroup ++ splice(@argv, 0, 2); ++ while (@argv) { ++ # Remove pathselector + #selectorargs + selectorargs ++ splice(@argv, 0, 2 + $argv[1]); ++ if (!@argv) { ++ goto out_error; ++ } ++ my $num_paths = $argv[0]; ++ my $num_path_args = $argv[1]; ++ # Remove #paths + #pathargs ++ splice(@argv, 0, 2); ++ while ($num_paths-- > 0) { ++ if (!@argv) { ++ goto out_error; ++ } ++ if (!($argv[0] =~ /(\d+):(\d+)/)) { ++ goto out_error; ++ } ++ push(@data, [$1, $2]); ++ # Remove device + deviceargs ++ splice(@argv, 0, 1 + $num_path_args); ++ } ++ } ++ if (!@data) { ++ goto out_error; ++ } ++ return \@data; ++ ++out_error: ++ die("Error: Unrecognized device-mapper table format for device ". ++ "'$dev_name'\n"); ++} ++ ++# filter_table(table, start, length) ++# Returns table containing only targets between start and start + length - 1. ++sub filter_table($$$) ++{ ++ my ($table, $start, $length) = @_; ++ my $end = $start + $length - 1; ++ my @result; ++ my $target; ++ ++ foreach $target (@$table) { ++ my $target_start = $target->[$TARGET_START]; ++ my $target_end = $target_start + $target->[$TARGET_LENGTH] - 1; ++ ++ if (!(($target_end < $start) || ($target_start > $end))) { ++ push(@result, $target); ++ } ++ } ++ return \@result; ++} ++ ++# get_target_start(target) ++# Returns the start sector of target. ++sub get_target_start($) ++{ ++ my ($target) = @_; ++ my $type = $target->[$TARGET_TYPE]; ++ my $data = $target->[$TARGET_DATA]; ++ ++ if ($type == $TARGET_TYPE_LINEAR) { ++ return $data->[$LINEAR_START_SECTOR]; ++ } elsif ($type == $TARGET_TYPE_MIRROR) { ++ my $mirror_data = $data->[0]; ++ return $mirror_data->[$MIRROR_START_SECTOR]; ++ } else { ++ return 0; ++ } ++} ++ ++# get_target_major_minor(target) ++# Returns (major, minor) of target of target. ++sub get_target_major_minor($) ++{ ++ my ($target) = @_; ++ my $type = $target->[$TARGET_TYPE]; ++ my $data = $target->[$TARGET_DATA]; ++ my $major; ++ my $minor; ++ ++ if ($type == $TARGET_TYPE_LINEAR) { ++ $major = $data->[$LINEAR_MAJOR]; ++ $minor = $data->[$LINEAR_MINOR]; ++ } elsif ($type == $TARGET_TYPE_MIRROR) { ++ # Use data of first device in list ++ my $mirror_data = $data->[0]; ++ $major = $mirror_data->[$MIRROR_MAJOR]; ++ $minor = $mirror_data->[$MIRROR_MINOR]; ++ } elsif ($type == $TARGET_TYPE_MULTIPATH) { ++ # Use data of first device in list ++ my $multipath_data = $data->[0]; ++ $major = $multipath_data->[$MULTIPATH_MAJOR]; ++ $minor = $multipath_data->[$MULTIPATH_MINOR]; ++ } ++ return ($major, $minor); ++} ++ ++# create_temp_device_node(type, major, minor) ++# Returns the name of a temporary device node. ++sub create_temp_device_node($$$) ++{ ++ my ($type, $major, $minor) = @_; ++ my $path = "/dev"; ++ my $name; ++ my $num; ++ ++ for ($num = 0; $num < 100; $num++) { ++ $name = sprintf("$path/zipl-dm-temp-%02d", $num); ++ if (-e $name) { ++ next; ++ } ++ if (system("$mknod $name $type $major $minor --mode 0600 ". ++ "2>/dev/null")) { ++ next; ++ } ++ return $name; ++ } ++ die("Error: Could not create temporary device node in '$path'\n"); ++} ++ ++# get_blocksize(device) ++# # Return blocksize in bytes for device. ++sub get_blocksize($) ++{ ++ my ($dev) = @_; ++ my $blocksize; ++ local *HANDLE; ++ ++ open(HANDLE, "$blockdev --getss $dev 2>/dev/null|") or ++ return undef; ++ $blocksize = ; ++ chomp($blocksize); ++ close(HANDLE); ++ ++ return $blocksize; ++} ++ ++# get_dasd_info(device) ++# Returns (type, cylinders, heads, sectors) ++sub get_dasd_info($) ++{ ++ my ($dev) = @_; ++ my $disk_type; ++ my $format; ++ my $cyl; ++ my $heads; ++ my $sectors; ++ my $type; ++ local *HANDLE; ++ ++ open(HANDLE, "$dasdview -x -f $dev 2>/dev/null|") or ++ # dasdview returned with an error ++ return undef; ++ while () { ++ if (/^number of cylinders.*\s(\d+)\s*$/) { ++ $cyl = $1; ++ } elsif (/^tracks per cylinder.*\s(\d+)\s*$/) { ++ $heads = $1; ++ } elsif (/^blocks per track.*\s(\d+)\s*$/) { ++ $sectors = $1; ++ } elsif (/^type\s+:\s+(\S+)\s*$/) { ++ $disk_type = $1; ++ } elsif (/^format.*\s+dec\s(\d+)\s/) { ++ $format = $1; ++ } ++ } ++ close(HANDLE); ++ if (!defined($cyl) || !defined($heads) || !defined($sectors) || ++ !defined($disk_type) || !defined($format)) { ++ # Unrecognized dadsview output format ++ return undef; ++ } ++ if ($disk_type eq "FBA") { ++ $type = $DEV_TYPE_FBA; ++ } elsif ($disk_type eq "ECKD") { ++ if ($format == 1) { ++ $type = $DEV_TYPE_LDL; ++ } elsif ($format == 2) { ++ $type = $DEV_TYPE_CDL; ++ } ++ } ++ ++ return ($type, $cyl, $heads, $sectors); ++} ++ ++# get_partition_start(device) ++# Return the partition offset of device. ++sub get_partition_start($) ++{ ++ my ($dev) = @_; ++ my $line; ++ my $offset; ++ local *HANDLE; ++ ++ open(HANDLE, "$blockdev --report $dev 2>/dev/null|") or ++ return undef; ++ $line = ; ++ if ($line =~ /RO\s+RA\s+SSZ\s+BSZ\s+StartSec\s+Size\s+Device/) { ++ $line = ; ++ if ($line =~ /^\S+\s+\d+\s+\d+\s+\d+\s+(\d+)/) { ++ $offset = $1; ++ } ++ } ++ close(HANDLE); ++ return $offset; ++} ++ ++# is_dasd(type) ++# Return whether disk with type is a DASD. ++sub is_dasd($) ++{ ++ my ($type) = @_; ++ ++ return ($type == $DEV_TYPE_CDL) || ($type == $DEV_TYPE_LDL) || ++ ($type == $DEV_TYPE_FBA); ++} ++ ++# get_partition_base(type, major, minor) ++# Return (major, minor) of the base device on which the partition is located. ++sub get_partition_base($$$) ++{ ++ my ($type, $major, $minor) = @_; ++ ++ if (is_dasd($type)) { ++ return ($major, $minor & ~$DASD_PARTN_MASK); ++ } else { ++ return ($major, $minor & ~$SCSI_PARTN_MASK); ++ } ++} ++ ++# get_device_characteristics(major, minor) ++# Returns (type, blocksize, geometry, bootsectors, partstart) for device. ++sub get_device_characteristics($$) ++{ ++ my ($major, $minor) = @_; ++ my $dev; ++ my $blocksize; ++ my $type; ++ my $cyl; ++ my $heads; ++ my $sectors; ++ my $geometry; ++ my $bootsectors; ++ my $partstart; ++ ++ $dev = create_temp_device_node("b", $major, $minor); ++ $blocksize = get_blocksize($dev); ++ if (!defined($blocksize)) { ++ unlink($dev); ++ die("Error: Could not get block size for ". ++ get_device_name($major, $minor)."\n"); ++ } ++ ($type, $cyl, $heads, $sectors) = get_dasd_info($dev); ++ if (defined($type)) { ++ $geometry = "$cyl,$heads,$sectors"; ++ if ($type == $DEV_TYPE_CDL) { ++ # First track contains IPL records ++ $bootsectors = $blocksize * $sectors / $SECTOR_SIZE; ++ } elsif ($type == $DEV_TYPE_LDL) { ++ # First two blocks contain IPL records ++ $bootsectors = $blocksize * 2 / $SECTOR_SIZE; ++ } elsif ($type == $DEV_TYPE_FBA) { ++ # First block contains IPL records ++ $bootsectors = $blocksize / $SECTOR_SIZE; ++ } ++ } else { ++ # Assume SCSI if get_dasd_info failed ++ $type = $DEV_TYPE_SCSI; ++ # First block contains IPL records ++ $bootsectors = $blocksize / $SECTOR_SIZE; ++ } ++ $partstart = get_partition_start($dev); ++ unlink($dev); ++ if (!defined($partstart)) { ++ die("Error: Could not determine partition start for ". ++ get_device_name($major, $minor)."\n"); ++ } ++ return ($type, $blocksize, $geometry, $bootsectors, $partstart); ++} ++ ++# get_type_name(type) ++# Return textual representation of device type. ++sub get_type_name($) ++{ ++ my ($type) = @_; ++ ++ if ($type == $DEV_TYPE_CDL) { ++ return "CDL"; ++ } elsif ($type == $DEV_TYPE_LDL) { ++ return "LDL"; ++ } elsif ($type == $DEV_TYPE_FBA) { ++ return "FBA"; ++ } elsif ($type == $DEV_TYPE_SCSI) { ++ return "SCSI"; ++ } ++ return undef; ++} ++ ++ ++# check_for_mirror(index, target_list) ++# Die if there is a mirror target between index and 0. ++sub check_for_mirror($@) ++{ ++ my ($i, @target_list) = @_; ++ ++ for (;$i >= 0; $i--) { ++ my $entry = $target_list[$i]; ++ my ($major, $minor, $target) = @$entry; ++ ++ if ($target->[$TARGET_TYPE] == $TARGET_TYPE_MIRROR) { ++ # IPL records are not mirrored. ++ die("Error: Unsupported setup: Block 0 is not ". ++ "mirrored in device '". ++ get_device_name($major, $minor)."'\n"); ++ } ++ } ++} ++ ++# get_target_base(bottom_major, bottom_minor, start, length, target_list) ++# Return (major, minor) for the top most target in the target list that maps ++# the region on (bottom_major, bottom_minor) defined by start and length at ++# offset 0. ++sub get_target_base($$$$@) ++{ ++ my ($bot_major, $bot_minor, $start, $length, @target_list) = @_; ++ my $entry; ++ my $top_major; ++ my $top_minor; ++ my $i; ++ ++ # Pre-initialize with bottom major-minor ++ $top_major = $bot_major; ++ $top_minor = $bot_minor; ++ # Process all entries starting with the last one ++ for ($i = scalar(@target_list) - 1; $i >= 0; $i--) { ++ my $entry = $target_list[$i]; ++ my ($major, $minor, $target) = @$entry; ++ ++ if (($target->[$TARGET_START] != 0) || ++ (get_target_start($target) != 0) || ++ ($target->[$TARGET_LENGTH] < $length)) { ++ last; ++ } ++ $top_major = $major; ++ $top_minor = $minor; ++ } ++ # Check for mirrorring between base device and fs device. ++ check_for_mirror($i, @target_list); ++ return ($top_major, $top_minor); ++} ++ ++# get_device_name(major, minor) ++# Return the name of the device specified by major and minor. ++sub get_device_name($$) ++{ ++ my ($major, $minor) = @_; ++ my $name; ++ local *HANDLE; ++ ++ $name = "$major:$minor"; ++ open(HANDLE, ") { ++ if (/^\s*(\d+)\s+(\d+)\s+\d+\s+(\S+)\s*$/) { ++ if (($major == $1) && ($minor == $2)) { ++ $name = $3; ++ last; ++ } ++ } ++ } ++ close(HANDLE); ++out: ++ return $name; ++} +-- +1.6.3.3 + diff --git a/0016-s390tools-1.8.2-lsreipl-nss.patch b/0016-s390tools-1.8.2-lsreipl-nss.patch new file mode 100644 index 0000000..e2b3413 --- /dev/null +++ b/0016-s390tools-1.8.2-lsreipl-nss.patch @@ -0,0 +1,376 @@ +From 62fb535a68f1df693869e4361150259b42c6f211 Mon Sep 17 00:00:00 2001 +From: =?utf-8?q?Dan=20Hor=C3=A1k?= +Date: Thu, 10 Dec 2009 18:30:52 +0100 +Subject: [PATCH 16/16] s390tools-1.8.2-lsreipl-nss + +--- + ipl_tools/ccw.c | 42 ++++++++++++++++--------------------- + ipl_tools/chreipl.h | 9 +++++-- + ipl_tools/fcp.c | 13 ++++++----- + ipl_tools/ipl.c | 57 +++++++++++++++++++++++++++++++------------------- + ipl_tools/main.c | 25 +++++++++++++++++----- + ipl_tools/system.c | 3 +- + 6 files changed, 87 insertions(+), 62 deletions(-) + +diff --git a/ipl_tools/ccw.c b/ipl_tools/ccw.c +index 7959831..eef4550 100644 +--- a/ipl_tools/ccw.c ++++ b/ipl_tools/ccw.c +@@ -52,22 +52,19 @@ int isccwdev(const char *devno) + } + + +-int get_ccw_devno_old_sysfs(char *device, char *devno) ++int get_ccw_devno_old_sysfs(char *device) + { + FILE *filp; +- int len, errorpath, rc; ++ int errorpath; + char path1[4096]; + char buf[4096]; +- char *match, *s1, *s2; ++ char *match = NULL, *s1, *s2; + + errorpath = 1; +- rc = 0; + sprintf(path1, "/sys/block/%s/uevent", device); + filp = fopen(path1, "r"); +- if (!filp) { +- rc = -1; +- return rc; +- } ++ if (!filp) ++ return -1; + /* + * the uevent file contains an entry like this: + * PHYSDEVPATH=/devices/css0/0.0.206a/0.0.7e78 +@@ -77,16 +74,16 @@ int get_ccw_devno_old_sysfs(char *device, char *devno) + if (match != NULL) + break; + } ++ fclose(filp); ++ if (!match) ++ return -1; + s1 = strchr(buf, '/'); + s2 = strrchr(buf, '/'); +- len = s2-s1; +- strncpy(devno, s2 + 1, sizeof(devno)); +- devno[len] = '\0'; +- fclose(filp); ++ strncpy(devno, s2 + 1, sizeof(devno) - 1); + return 0; + } + +-int get_ccw_devno_new_sysfs(char *device, char *devno) ++int get_ccw_devno_new_sysfs(char *device) + { + int len, errorpath, rc; + char path2[4096]; +@@ -119,8 +116,7 @@ int get_ccw_devno_new_sysfs(char *device, char *devno) + return rc; + } + } +- strncpy(devno, s2 + 1, sizeof(devno)); +- devno[len] = '\0'; ++ strncpy(devno, s2 + 1, sizeof(devno) - 1); + return 0; + } + +@@ -134,16 +130,14 @@ int get_ccw_devno_new_sysfs(char *device, char *devno) + * + * This does not work when booting from tape + */ +-int get_ccw_devno(char *device, char *devno) ++int get_ccw_devno(char *device) + { +- if (get_ccw_devno_old_sysfs(device, devno) != 0) { +- if (get_ccw_devno_new_sysfs(device, devno) != 0) { +- fprintf(stderr, "%s: Failed to lookup the device number\n", +- name); +- return -1; +- } +- } +- return 0; ++ if (get_ccw_devno_old_sysfs(device) == 0) ++ return 0; ++ if (get_ccw_devno_new_sysfs(device) == 0) ++ return 0; ++ fprintf(stderr, "%s: Failed to lookup the device number\n", name); ++ return -1; + } + + int get_ccw_dev(char *partition, char *device) +diff --git a/ipl_tools/chreipl.h b/ipl_tools/chreipl.h +index 19a83eb..37807a7 100644 +--- a/ipl_tools/chreipl.h ++++ b/ipl_tools/chreipl.h +@@ -34,6 +34,9 @@ extern char saction[8]; + extern char name[256]; + extern int action; + ++#define IPL_TYPE_LEN_MAX 100 ++#define NSS_NAME_LEN_MAX 8 ++ + #define ACT_CCW 1 + #define ACT_FCP 2 + #define ACT_NODE 3 +@@ -63,10 +66,10 @@ int is_valid_case(char *c); + int is_valid_action(char *action); + void parse_shutdown_options(int argc, char **argv); + void strlow(char *s); +-int get_ccw_devno(char *device, char *devno); +-int get_reipl_type(void); ++int get_ccw_devno(char *device); ++int get_reipl_type(char *reipltype); + void parse_lsreipl_options(int argc, char **argv); +-int get_ipl_type(); ++int get_ipl_type(char *reipltype); + int get_ipl_loadparam(void); + void print_ipl_settings(void); + int get_sa(char *action, char *file); +diff --git a/ipl_tools/fcp.c b/ipl_tools/fcp.c +index 86fa95b..7a8b4c5 100644 +--- a/ipl_tools/fcp.c ++++ b/ipl_tools/fcp.c +@@ -33,12 +33,11 @@ + + /* + * return the current reipl type from /sys/firmware/reipl/reipl_type +- * 0 = fcp, 1 = ccw, -1, error ++ * 0 = fcp, 1 = ccw, 2 = nss, -1 = unknown + */ +-int get_reipl_type(void) ++int get_reipl_type(char *reipltype) + { + FILE *filp; +- char reipltype[4]; + char path[4096]; + int rc; + +@@ -49,7 +48,7 @@ int get_reipl_type(void) + fprintf(stderr, "%s: Can not open /sys/firmware/" + "reipl/reipl_type: ", name); + fprintf(stderr, "%s\n", strerror(errno)); +- return -1; ++ exit(1); + } + rc = fscanf(filp, "%s", reipltype); + fclose(filp); +@@ -57,17 +56,19 @@ int get_reipl_type(void) + fprintf(stderr, "%s: Failed to read " + "/sys/firmware/reipl/reipl_type:", name); + fprintf(stderr, "%s\n", strerror(errno)); +- return -1; ++ exit(1); + } + if (strncmp(reipltype, "fcp", strlen("fcp")) == 0) + return T_FCP; + else if (strncmp(reipltype, "ccw", strlen("ccw")) == 0) + return T_CCW; +- /* TODO: add NSS support */ ++ else if (strncmp(reipltype, "nss", strlen("nss")) == 0) ++ return T_NSS; + } else { + fprintf(stderr, "%s: Can not open /sys/firmware/reipl/" + "reipl_type:", name); + fprintf(stderr, " %s\n", strerror(errno)); ++ exit(1); + } + return -1; + } +diff --git a/ipl_tools/ipl.c b/ipl_tools/ipl.c +index 2bf817a..8cca700 100644 +--- a/ipl_tools/ipl.c ++++ b/ipl_tools/ipl.c +@@ -33,12 +33,11 @@ + + /* + * return the ipl type based on /sys/firmware/ipl/ipl_type +- * returns 0 in case of fcp and 1 in case of ccw, -1 otherwise ++ * returns 0 in case of fcp and 1 in case of ccw, 2 for nss and -1 otherwise + */ +-int get_ipl_type() ++int get_ipl_type(char *reipltype) + { + FILE *filp; +- char reipltype[4]; + char path[4096]; + int rc; + +@@ -49,7 +48,7 @@ int get_ipl_type() + fprintf(stderr, "%s: Can not open /sys/firmware/ipl/" + "ipl_type: ", name); + fprintf(stderr, "%s\n", strerror(errno)); +- return -1; ++ exit(1); + } + rc = fscanf(filp, "%s", reipltype); + fclose(filp); +@@ -57,12 +56,14 @@ int get_ipl_type() + fprintf(stderr, "%s: Failed to read " + "/sys/firmware/ipl/ipl_type: ", name); + fprintf(stderr, "%s\n", strerror(errno)); +- return -1; ++ exit(1); + } + if (strncmp(reipltype, "fcp", strlen("fcp")) == 0) + return T_FCP; + else if (strncmp(reipltype, "ccw", strlen("ccw")) == 0) + return T_CCW; ++ else if (strncmp(reipltype, "nss", strlen("nss")) == 0) ++ return T_NSS; + } else { + fprintf(stderr, "%s: Can not open /sys/firmware/ipl/" + "ipl_type:", name); +@@ -111,30 +112,38 @@ int get_ipl_loadparam(void) + void print_ipl_settings(void) + { + int rc, type; +- char bootprog[1024], lba[1024]; ++ char bootprog[1024], lba[1024], nss_name[NSS_NAME_LEN_MAX + 1]; ++ char reipltype[IPL_TYPE_LEN_MAX + 1]; + +- type = get_ipl_type(); +- /* +- * TODO: add nss support +- */ +- if (type == 1) ++ type = get_ipl_type(reipltype); ++ switch (type) { ++ case T_NSS: ++ printf("IPL type: nss\n"); ++ rc = strrd(nss_name, "/sys/firmware/ipl/name"); ++ if (rc != 0) ++ exit(1); ++ printf("Name: %s\n", nss_name); ++ break; ++ case T_CCW: + printf("IPL type: ccw\n"); +- if (type == 0) +- printf("IPL type: fcp\n"); +- rc = strrd(devno, "/sys/firmware/ipl/device"); +- if (rc != 0) +- exit(1) /* the error msg comes from get_ipl_device */; +- if (strlen(devno) > 0) +- printf("Device: %s\n", devno); +- if (type == 1) { ++ rc = strrd(devno, "/sys/firmware/ipl/device"); ++ if (rc != 0) ++ exit(1); ++ if (strlen(devno) > 0) ++ printf("Device: %s\n", devno); + rc = get_ipl_loadparam(); + if (rc != -1) + printf("Loadparm: %d\n", rc); + else + printf("Loadparm: \n"); +- } +- if (type == 0) { +- /* these settings are only available for fcp */ ++ break; ++ case T_FCP: ++ printf("IPL type: fcp\n"); ++ rc = strrd(devno, "/sys/firmware/ipl/device"); ++ if (rc != 0) ++ exit(1); ++ if (strlen(devno) > 0) ++ printf("Device: %s\n", devno); + rc = strrd(wwpn, "/sys/firmware/reipl/fcp/wwpn"); + if (rc != -1 && strlen(wwpn) > 0) + printf("WWPN: %s\n", wwpn); +@@ -147,6 +156,10 @@ void print_ipl_settings(void) + rc = strrd(lba, "/sys/firmware/ipl/br_lba"); + if (rc != -1 && strlen(lba) > 0) + printf("br_lba: %s\n", lba); ++ break; ++ default: ++ printf("IPL type: %s (unknown)\n", reipltype); ++ break; + } + exit(0); + } +diff --git a/ipl_tools/main.c b/ipl_tools/main.c +index 2eaa043..bcebabe 100644 +--- a/ipl_tools/main.c ++++ b/ipl_tools/main.c +@@ -57,13 +57,22 @@ int action; /* either CCW, FCP or NODE */ + int lsreipl(int argc, char *argv[]) + { + int rc; +- char bootprog[1024], lba[1024], val[9]; ++ char bootprog[1024], lba[1024], val[9], reipltype[IPL_TYPE_LEN_MAX + 1]; ++ char nss_name[NSS_NAME_LEN_MAX + 1]; + + /* parse the command line options in getop.c */ + parse_lsreipl_options(argc, argv); + +- rc = get_reipl_type(); +- if (rc == 0) { ++ rc = get_reipl_type(reipltype); ++ switch (rc) { ++ case T_NSS: ++ printf("Re-IPL type: nss\n"); ++ rc = strrd(nss_name, "/sys/firmware/reipl/nss/name"); ++ if (rc != 0) ++ exit(1); ++ printf("Name: %s\n", nss_name); ++ break; ++ case T_FCP: + printf("Re-IPL type: fcp\n"); + rc = strrd(wwpn, "/sys/firmware/reipl/fcp/wwpn"); + if (rc != 0) +@@ -90,8 +99,8 @@ int lsreipl(int argc, char *argv[]) + printf("bootprog: %s\n", bootprog); + if (strlen(lba) > 0) + printf("br_lba: %s\n", lba); +- } +- if (rc == 1) { ++ break; ++ case T_CCW: + printf("Re-IPL type: ccw\n"); + rc = strrd(devno, "/sys/firmware/reipl/ccw/device"); + if (rc != 0) +@@ -106,6 +115,10 @@ int lsreipl(int argc, char *argv[]) + printf("Loadparm: %s\n", val); + else + printf("Loadparm: \n"); ++ break; ++ default: ++ printf("Re-IPL type: %s (unknown)\n", reipltype); ++ break; + } + return 0; + } +@@ -134,7 +147,7 @@ int reipl(int argc, char *argv[]) + "partition: %s\n", name, partition); + exit(1); + } +- rc = get_ccw_devno(device, devno); ++ rc = get_ccw_devno(device); + if (rc != 0) { + fprintf(stderr, "%s: Unable to lookup device" + " number for device %s\n", name, +diff --git a/ipl_tools/system.c b/ipl_tools/system.c +index fd5b76b..ca6c5af 100644 +--- a/ipl_tools/system.c ++++ b/ipl_tools/system.c +@@ -174,7 +174,7 @@ int strrd(char *string, char *file) + fprintf(stderr, "%s\n", strerror(errno)); + exit(1); + } +- rc = fread(string, 4096, 1, filp); ++ rc = fread(string, 1, 4096, filp); + fclose(filp); + /* + * special handling is required for +@@ -193,6 +193,7 @@ int strrd(char *string, char *file) + fprintf(stderr, "%s\n", strerror(errno)); + return -1; + } else { ++ string[rc] = 0; + if (string[strlen(string) - 1] == '\n') + string[strlen(string) - 1] = 0; + return 0; +-- +1.6.3.3 + diff --git a/0017-qualified-return-codes-and-further-error-handling-in.patch b/0017-qualified-return-codes-and-further-error-handling-in.patch new file mode 100644 index 0000000..bc325c0 --- /dev/null +++ b/0017-qualified-return-codes-and-further-error-handling-in.patch @@ -0,0 +1,1215 @@ +From 4725dd1a67185ab4296674fcd3b2cf17f2b1cf21 Mon Sep 17 00:00:00 2001 +From: =?utf-8?q?Dan=20Hor=C3=A1k?= +Date: Thu, 17 Dec 2009 17:08:22 +0100 +Subject: [PATCH] qualified return codes and further error handling in znetconf + +Description: znetconf: qualified return codes and further error handling +Symptom: always returned 1 in case errors +Problem: wrapper tools not able to generate qualified error msgs +Solution: return codes +--- + zconf/znetconf | 324 ++++++++++++++++++++++++++++++++---------------------- + zconf/znetconf.8 | 219 +++++++++++++++++++++++++++++++------ + 2 files changed, 375 insertions(+), 168 deletions(-) + +diff --git a/zconf/znetconf b/zconf/znetconf +index 4edf6fb..873124a 100755 +--- a/zconf/znetconf ++++ b/zconf/znetconf +@@ -2,14 +2,58 @@ + # + # znetconf - list and configure network devices + # +-# Tool for the automatic and semi-automatic configuration of network devices ++# Tool for the automatic and semi-automatic configuration of network devices + # from ccw devices, including network device option handling and network + # device removal. + # +-# Copyright IBM Corp. 2009 ++# Copyright IBM Corp. 2009 + # Author(s): Einar Lueck + # Steffen Maier + # ++# 9 Could not group devices ++readonly RC_COULD_NOT_GROUP_DEVICES=9 ++# 10 Could not set device online ++readonly RC_COULD_NOT_SET_DEV_ONLINE=10 ++# 11 Could not set device offline ++readonly RC_COULD_NOT_SET_DEV_OFFLINE=11 ++# 12 Invalid attribute value pair ++readonly RC_INVALID_ATTRIBUTE_VALUE_PAIR=12 ++# 13 Missing component (broken installation) ++readonly RC_BROKEN_INSTALLATION=13 ++# 14 Missing device ID ++readonly RC_MISSING_DEVICE_ID=14 ++# 15 Invalid device ID format ++readonly RC_INVALID_DEVICE_ID_FORMAT=15 ++# 16 Driver name expected ++readonly RC_DRIVER_NAME_EXPECTED=16 ++# 17 Unknown driver ++readonly RC_UNKNOWN_DRIVER=17 ++# 18 Missing attribute value pair for -o|--option ++readonly RC_MISSING_ATTRIBUTE_VALUE_PAIR=18 ++# 19 Invalid argument ++readonly RC_INVALID_ARGUMENT=19 ++# 20 Too much arguments ++readonly RC_TOO_MUCH_ARGUMENTS=20 ++# 21 No configuration found for device ID ++readonly RC_NO_CONFIG_FOUND_FOR_DEV=21 ++# 22 Device is not configured ++readonly RC_DEVICE_NOT_CONFIGURED=22 ++# 23 Could not ungroup device ++readonly RC_COULD_NOT_UNGROUP_DEVICE=23 ++# 24 At least one option could not be configured ++readonly RC_OPTION_NOT_CONFIGURED=24 ++# 25 Missing value for attribute ++readonly RC_MISSING_VALUE=25 ++# 26 Device does not exist ++readonly RC_DEVICE_DOES_NOT_EXIST=26 ++# 27 Device already in use ++readonly RC_DEVICE_ALREADY_IN_USE=27 ++# 28 Net device did not come online ++readonly RC_NET_DEVICE_NOT_ONLINE=28 ++# 29 Some devices could not be added or failed ++readonly RC_SOME_DEVICES_FAILED=29 ++# 99 internal error, this should never happen ++readonly RC_INTERNAL_ERROR=99 + + #============================================================================== + # constants +@@ -29,6 +73,7 @@ else + fi + SYSFSDIR=$(cat /proc/mounts|awk '$3=="sysfs"{print $2; exit}') + CCWGROUPBUS_DIR=$SYSFSDIR/bus/ccwgroup ++CCWDEV_DIR=$SYSFSDIR/bus/ccw/devices + CCWGROUPBUS_DEVICEDIR=$CCWGROUPBUS_DIR/devices + CCWGROUPBUS_DRIVERDIR=$CCWGROUPBUS_DIR/drivers + DEVNOSEP="," +@@ -290,15 +335,14 @@ function lookup_layer() + #============================================================================== + + # +-# group_device ++# group_device + # $1: ccwdevid[;ccwdevid][;ccwdevid] + # $2: ccwgroupdevid + # $3: driver +-# returns ++# returns + # 0 success +-# 1 group file not found +-# 2 grouping failed +-# ++# RC_COULD_NOT_GROUP_DEVICES ++# + function group_device() + { + local DEVICES=$1 +@@ -307,13 +351,13 @@ function group_device() + local GROUPFILE=$CCWGROUPBUS_DRIVERDIR/$DRIVER/group + local CTCMGROUPFILE=$CCWGROUPBUS_DRIVERDIR/ctcm/group + local CTCGROUPFILE=$CCWGROUPBUS_DRIVERDIR/ctc/group +- ++ + # check if group file exists +- if [ ! -e $GROUPFILE ] ++ if [ ! -e $GROUPFILE ] + then + # try to load driver + if ! modprobe $DRIVER &> /dev/null +- then ++ then + if [ $DRIVER = "ctc" ] + then + # check if ctcm driver exists +@@ -329,7 +373,7 @@ function group_device() + GROUPFILE=$CTCGROUPFILE + fi + fi +- fi ++ fi + fi + if [ -e $GROUPFILE ] + then +@@ -340,13 +384,13 @@ function group_device() + *) + print_error "Could not group devices" \ + "$DEVICES" +- return 2 ++ return $RC_COULD_NOT_GROUP_DEVICES + ;; + esac + else + print_error "$GROUPFILE does not exist" +- +- return 1 ++ ++ return $RC_COULD_NOT_GROUP_DEVICES + fi + return 0 + } +@@ -354,14 +398,13 @@ function group_device() + #============================================================================== + + # +-# ungroup_device ++# ungroup_device + # $1: ccwgroupdevid + # $2: network device name (just for display purposes) +-# returns ++# returns + # 0 success +-# 1 group file not found +-# 2 ungrouping failed +-# ++# RC_COULD_NOT_UNGROUP_DEVICE ++# + function ungroup_device() + { + local TARGET_DEVID="$1" +@@ -378,12 +421,12 @@ function ungroup_device() + ;; + *) + print_error "Failed to ungroup $TARGET_DEVID" +- return 2 ++ return $RC_COULD_NOT_UNGROUP_DEVICE + ;; + esac + else + print_error "$DEVICE_UNGROUPFILE does not exist." +- return 1 ++ return $RC_COULD_NOT_UNGROUP_DEVICE + fi + return 0 + } +@@ -393,12 +436,12 @@ function ungroup_device() + # + # try_read_netdevname + # $1: ccwgroupdevno +-# returns ++# returns + # 0 success + # 1 failed. giving up after retries + # stdout + # in case of success: device name +-# ++# + function try_read_netdevname() + { + local CCWGROUPDEVNO="$1" +@@ -406,7 +449,7 @@ function try_read_netdevname() + local NET_SUBDIR="$CCWGROUPBUS_DEVICEDIR/$CCWGROUPDEVNO/net/" + local IF_NAME="" + local rc=1 +- ++ + # check if interface file containing the name exists + if [ -e "$IF_NAME_FILE" ] + then +@@ -417,7 +460,7 @@ function try_read_netdevname() + IF_NAME=$(ls $NET_SUBDIR) + else + # if the file does not exist +- local LINKNAME=$(find $CCWGROUPBUS_DEVICEDIR/$CCWGROUPDEVNO/ -type l -name net*) ++ local LINKNAME=$(find $CCWGROUPBUS_DEVICEDIR/$CCWGROUPDEVNO/ -type l -name net*) + if [[ ! -z $LINKNAME ]] + then + IF_NAME=$(readlink $LINKNAME) +@@ -434,10 +477,10 @@ function try_read_netdevname() + # + # wait_for_net_device + # $1: ccwgroupdevno +-# returns ++# returns + # 0 success + # 1 failed. giving up after retries +-# ++# + function wait_for_net_device() + { + local CCWGROUPDEVNO="$1" +@@ -447,7 +490,7 @@ function wait_for_net_device() + local IF_NAME="" + local CMD_FINDNETLINK="find $CCWGROUPBUS_DEVICEDIR/$CCWGROUPDEVNO/ -type l -name net*" + local LINKNAME="" +- ++ + # polling loop to wait for net device to become available + if [ -e $UDEVSETTLE ] + then +@@ -460,7 +503,7 @@ function wait_for_net_device() + fi + while [[ -z "$IF_NAME" ]] && [[ retries -lt MAX_RETRIES ]] + do +- sleep 1 ++ sleep 1 + retries=$retries+1 + IF_NAME=$(try_read_netdevname $CCWGROUPDEVNO) + done +@@ -468,8 +511,8 @@ function wait_for_net_device() + then + echo "Successfully configured device $CCWGROUPDEVNO ($IF_NAME)" + else +- print_error "Failed to make $CCWGROUPDEVNO online." +- return 1 ++ print_error "Failed to make $CCWGROUPDEVNO online." ++ return 1 + fi + } + +@@ -479,11 +522,11 @@ function wait_for_net_device() + # switch_device + # $1: ccwgroupdevno + # $2: 1|0 (online|offline) +-# returns ++# returns + # 0 success + # 1 command to make device online/offline returned error + # 2 online file does not exist +-# ++# + function switch_device() + { + local CCWGROUPDEVNO="$1" +@@ -491,7 +534,7 @@ function switch_device() + local DEVICE_DIRECTORY="$CCWGROUPBUS_DEVICEDIR/$CCWGROUPDEVNO" + local ONLINE_FILE="$DEVICE_DIRECTORY/online" + local STATESTR="online" +- ++ + if [ $SWITCHVALUE -eq 0 ] + then + STATESTR="offline" +@@ -513,7 +556,7 @@ function switch_device() + print_error "$ONLINE_FILE does not exist." + return 2 + fi +- ++ + return 0 + } + +@@ -524,12 +567,12 @@ function switch_device() + # $1: ccwgroupdevid + # $2: option_name + # $3: option_value +-# returns ++# returns + # 0 success + # 1 option not allowed to be set (e.g. online) + # 2 unknown option + # 3 configuration failed +-# ++# + function configure_ccwgroupdev_option() + { + local CCWGROUPDEVID="$1" +@@ -539,10 +582,10 @@ function configure_ccwgroupdev_option() + # filter some attributes away + if [ "$OPTION_NAME" == "online" ] + then +- print_error "Ignoring option $OPTION_NAME=$OPTION_VALUE" ++ print_error "Ignoring option $OPTION_NAME=$OPTION_VALUE" + return 1 + fi +- ++ + # check if attribute exists + local ATTRFILE="$CCWGROUPBUS_DEVICEDIR/$CCWGROUPDEVID/$OPTION_NAME" + if [ -f $ATTRFILE ] +@@ -574,13 +617,13 @@ function configure_ccwgroupdev_option() + # $4: opt_count + # $5..$(5+opt_count): opt_name_array + # $5+opt_count..5+2*opt_count: opt_value_array +-# returns ++# returns + # 0 success +-# 1 grouping failed +-# 2 failed to make device online +-# 3 net device did not become available +-# 4 device online but some option could not be set +-# ++# RC_COULD_NOT_GROUP_DEVICES ++# RC_COULD_NOT_SET_DEV_ONLINE ++# RC_NET_DEVICE_NOT_ONLINE ++# RC_OPTION_NOT_CONFIGURED ++# + function add_net_device() + { + local DEVICES="$1" +@@ -591,10 +634,9 @@ function add_net_device() + local OPT_NAME_ARRAY=("${RAW[@]:4:$OPT_COUNT}") + local OPT_VALUE_ARRAY=("${RAW[@]:$[4 + $OPT_COUNT]:$OPT_COUNT}") + +- group_device $DEVICES $CCWGROUPDEVID $DRIVER +- if [ $? -ne 0 ] ++ if ! group_device $DEVICES $CCWGROUPDEVID $DRIVER + then +- return 1 ++ return $? + fi + + local i=0 +@@ -602,9 +644,8 @@ function add_net_device() + local HAS_LAYER2_OPTION=0 + while [ $i -lt $OPT_COUNT ] + do +- configure_ccwgroupdev_option $CCWGROUPDEVID \ ++ if ! configure_ccwgroupdev_option $CCWGROUPDEVID \ + ${OPT_NAME_ARRAY[$i]} ${OPT_VALUE_ARRAY[$i]} +- if [ $? -ne 0 ] + then + SOMEOPTION_FAILED=1 + fi +@@ -628,22 +669,20 @@ function add_net_device() + "layer2" "$LAYER2" + fi + fi +- +- switch_device $CCWGROUPDEVNO 1 +- if [ $? -ne 0 ] ++ ++ if ! switch_device $CCWGROUPDEVNO 1 + then +- return 2 ++ return $RC_COULD_NOT_SET_DEV_ONLINE + fi + +- wait_for_net_device $CCWGROUPDEVNO +- if [ $? -ne 0 ] ++ if ! wait_for_net_device $CCWGROUPDEVNO + then +- return 3 ++ return $RC_NET_DEVICE_NOT_ONLINE + fi + + if [ $SOMEOPTION_FAILED -ne 0 ] + then +- return 4 ++ return $RC_OPTION_NOT_CONFIGURED + fi + + return 0 +@@ -655,26 +694,24 @@ function add_net_device() + # remove_net_device + # $1: ccwgroupdevid + # $2: network interface name (just for display purposes) +-# returns ++# returns + # 0 success +-# 1 making device offline failed +-# 2 ungrouping device failed +-# ++# RC_COULD_NOT_SET_DEV_OFFLINE ++# RC_COULD_NOT_UNGROUP_DEVICE ++# + function remove_net_device() + { + local DEVICE_TO_REMOVE="$1" + local DEVNAME="$2" + +- switch_device $DEVICE_TO_REMOVE 0 +- if [ $? -ne 0 ] ++ if ! switch_device $DEVICE_TO_REMOVE 0 + then +- return 1 ++ return $RC_COULD_NOT_SET_DEV_OFFLINE + fi + +- ungroup_device $DEVICE_TO_REMOVE $DEVNAME +- if [ $? -ne 0 ] ++ if ! ungroup_device $DEVICE_TO_REMOVE $DEVNAME + then +- return 2 ++ return $RC_COULD_NOT_UNGROUP_DEVICE + fi + return 0 + } +@@ -684,9 +721,9 @@ function remove_net_device() + # + # list_configured + # $1 supress_header +-# returns ++# returns + # 0 success +-# ++# + function list_configured() + { + supress_header=0 +@@ -723,11 +760,11 @@ function list_configured() + + # read all links and parse driver, device name and ccw device + # bus-ids +- ls -l $d/ | grep '^l' | +- { ++ ls -l $d/ | grep '^l' | ++ { + +- while read line +- do ++ while read line ++ do + local LINKNAME=${line// ->*/""} + LINKNAME=${LINKNAME##* } + if [ "$LINKNAME" = "driver" ] +@@ -742,14 +779,14 @@ function list_configured() + then + DEVNAME=${line##* -> */} + fi +- done ++ done + + local CUTYPE="" + if [ -e $d/cdev0/cutype ] + then + read CUTYPE < $d/cdev0/cutype + fi +- ++ + read ONLINE < $d/online + if [ $ONLINE -eq 1 ] + then +@@ -795,15 +832,15 @@ function print_list_unconf_header() + + # + # list_unconfigured +-# returns ++# returns + # 0 success +-# ++# + function list_unconfigured() + { + local PRINTED_HEADLINES=0 + local LIST_FORMATSTR="%-26.26s %-7.7s %-14.14s %5.5s %-4.4s \n" + print_scanning_4_nwdevices +- ++ + $LSZNET_CALL | + { + while read no cutype chp devtype devdrv devname chlist cardtype +@@ -824,29 +861,29 @@ function list_unconfigured() + # + # store_option + # $1: attribute=value +-# returns ++# returns + # 0 success + # 1 attribute starts with a - / or is invalid + # 2 missing value +-# ++# + function store_option() + { + local OPTIONSTRING="$1" + + # ensure that there is no option intepreted as an +- # attribute value pair ++ # attribute value pair + [[ "$OPTIONSTRING" =~ ^- ]] + case $? in + 0) + print_error "$OPTIONSTRING is not a valid attribute" \ +- "value pair" ++ "value pair" + exit 1 + ;; + 1) + # option considered ok + ;; + 2) +- print_error "Internal error" ++ print_error "Internal error" + exit 1 + esac + +@@ -874,17 +911,17 @@ function store_option() + # + # is_complete_ccwdevbusid + # $1: possibly correct ccw device bus id +-# returns ++# returns + # 0 if the given string is a correctly formatted ccw device bus id + # 1 else +-# ++# + function is_complete_ccwdevbusid() + { + local DEV="$1" + [[ "$DEV" =~ $FORMAT_FULLDEVNO ]] +- case $? in ++ case $? in + 0) +- return 0 ++ return 0 + ;; + 1) + return 1 +@@ -902,41 +939,41 @@ function is_complete_ccwdevbusid() + # + # is_partial_ccwdevbusid + # $1: possibly correct partial ccw device bus id +-# returns ++# returns + # 0 if the given string is a correctly formatted partial ccw device + # bus id + # 1 else +-# ++# + function is_partial_ccwdevbusid() + { + local DEV="$1" + [[ "$DEV" =~ $FORMAT_PARTDEVNO ]] + case $? in + 0) +- return 0 ++ return 0 + ;; + 1) +- return 1 ++ return 1 + ;; + 2) + print_error "Internal error" + exit 1 + ;; + esac +-} ++} + + #============================================================================== + + # + # is_ccwdevbusid_list + # $1: possibly correct list of ccw device bus ids +-# returns ++# returns + # 0 if the given string is a correctly formatted list of ccw device + # bus ids + # 1 else +-# ++# + function is_ccwdevbusid_list() +-{ ++{ + local DEVLIST="$1" + [[ "$DEVLIST" =~ $FORMAT_DEVLIST ]] + case $? in +@@ -959,13 +996,13 @@ function is_ccwdevbusid_list() + # + # is_shortccwdevbusid_list + # $1: possibly correct list of short ccw device bus ids +-# returns ++# returns + # 0 if the given string is a correctly formatted list of short ccw device + # bus ids + # 1 else +-# ++# + function is_shortccwdevbusid_list() +-{ ++{ + local DEVLIST="$1" + [[ "$DEVLIST" =~ $FORMAT_SHORTDEVLIST ]] + case $? in +@@ -987,14 +1024,14 @@ function is_shortccwdevbusid_list() + # + # is_supported_driver + # $1: possibly supported driver +-# returns +-# 0 if the given string denotes a supported driver ++# returns ++# 0 if the given string denotes a supported driver + # 1 else +-# ++# + function is_supported_driver() + { + local DRIVER="$1" +- [[ "$DRIVER" =~ "^(qeth|lcs|ctc|ctcm)$" ]] ++ [[ "$DRIVER" =~ "^(qeth|lcs|ctc|ctcm)$" ]] + case $? in + 0) + return 0 +@@ -1081,7 +1118,7 @@ DEVICE_TO_REMOVE="" + DO_REMOVEALL=0 + NONINTERACTIVE=0 + EXCEPT="" +-if [ $# -gt 0 ] ++if [ $# -gt 0 ] + then + while [ $# -gt 0 ] + do +@@ -1092,7 +1129,7 @@ then + ;; + -v|--version) + print_version +- exit 0 ++ exit 0 + ;; + -A|--add-all) + DO_ADDALL=1 +@@ -1103,15 +1140,15 @@ then + if [ $# -lt 1 ] + then + print_error "Device ID expected" +- exit 1 ++ exit $RC_MISSING_DEVICE_ID + fi + +- # get parameter expected to be a +- # ccw device bus id ++ # get parameter expected to be a ++ # ccw device bus id + DEVICE_TO_ADD="$1" + shift + +- # check syntax of ccw device bus id ++ # check syntax of ccw device bus id + if is_complete_ccwdevbusid "$DEVICE_TO_ADD" || + is_ccwdevbusid_list "$DEVICE_TO_ADD" + then +@@ -1127,9 +1164,9 @@ then + DO_ADD=1 + else + print_error "Invalid device ID format" \ +- "$DEVICE_TO_ADD" +- +- exit 1 ++ "$DEVICE_TO_ADD" ++ ++ exit $RC_INVALID_DEVICE_ID_FORMAT + fi + + ;; +@@ -1142,18 +1179,18 @@ then + if [ $# -lt 1 ] + then + print_error "Driver name expected" +- exit 1 ++ exit $RC_DRIVER_NAME_EXPECTED + fi + + # ensure driver is supported + DRIVER="$1" + shift + if [ "$DRIVER" != "" ] && \ +- ! is_supported_driver "$DRIVER" ++ ! is_supported_driver "$DRIVER" + then + # unknown driver + print_error "Unknown driver $DRIVER" +- exit 1 ++ exit $RC_UNKNOWN_DRIVER + fi + ;; + -o|--option) +@@ -1164,7 +1201,7 @@ then + print_error "Missing attrtibute" \ + "value pair for -o|--" \ + "option" +- exit 1 ++ exit $RC_MISSING_ATTRIBUTE_VALUE_PAIR + fi + + # get option string +@@ -1174,26 +1211,26 @@ then + # store option + if ! store_option $OPTIONSTRING + then +- exit $? ++ exit $RC_INVALID_ATTRIBUTE_VALUE_PAIR + fi + ;; + -r|--remove) + DO_REMOVE=1 + shift +- ++ + # ensure there is a further parameter + if [ $# -lt 1 ] + then + print_error "Expecting "\ + "of device to be removed" +- exit 1 ++ exit $RC_MISSING_ATTRIBUTE_VALUE_PAIR + fi + + # get device to be removed + DEVICE_TO_REMOVE="$1" + shift +- +- # validate it is a ++ ++ # validate it is a + # ccw dev bus id (short or long) + if is_partial_ccwdevbusid "$DEVICE_TO_REMOVE" + then +@@ -1203,7 +1240,7 @@ then + then + print_error "Invalid device ID format" \ + "$DEVICE_TO_REMOVE" +- exit 1 ++ exit $RC_INVALID_DEVICE_ID_FORMAT + fi + ;; + -R|--remove-all) +@@ -1219,7 +1256,7 @@ then + then + print_error " missing"\ + "for -e|--except" +- exit 1 ++ exit $RC_MISSING_DEVICE_ID + fi + + # get device to be removed +@@ -1236,7 +1273,7 @@ then + then + print_error "Invalid device ID format" \ + "$EXCEPT_DEVNO" +- exit 1 ++ exit $RC_INVALID_DEVICE_ID_FORMAT + fi + + # create a filter statement +@@ -1258,7 +1295,7 @@ then + *) + echo "$CMD: Invalid option $1" + echo "Try '$CMD --help' for more information." +- exit 1 ++ exit $RC_INVALID_ARGUMENT + ;; + esac + done +@@ -1271,7 +1308,7 @@ if [ $(($DO_ADD + $DO_ADDALL + $DO_LIST_UNCONFIGURED + $DO_LIST_CONFIGURED + \ + then + print_error "Too much arguments" + echo "Try '$CMD --help' for more information." +- exit 1 ++ exit $RC_TOO_MUCH_ARGUMENTS + fi + + # react to parsed options +@@ -1290,12 +1327,31 @@ then + then + print_error "No configuration found for device ID" \ + "$DEVICE_TO_ADD" +- exit 1 ++ exit $RC_NO_CONFIG_FOUND_FOR_DEV + fi + else +- # define set of device numbers to be used ++ # define set of device numbers to be used + DEVICES="$DEVICE_TO_ADD" +- ++ ++ # ensure none of the CCW devices is already in use ++ CCW_DEVS=${DEVICES//,/ } ++ for CCW_DEVNO in $CCW_DEVS ++ do ++ CCW_DEV_ONLINEFILE="$CCWDEV_DIR/$CCW_DEVNO/online" ++ if [ ! -e $CCW_DEV_ONLINEFILE ] ++ then ++ print_error "Device $CCW_DEVNO does not exist" ++ exit $RC_DEVICE_DOES_NOT_EXIST ++ fi ++ ++ read CCW_DEV_ONLINE < $CCW_DEV_ONLINEFILE ++ if [ "$CCW_DEV_ONLINE" == "1" ] ++ then ++ print_error "$CCW_DEVNO is already in use" ++ exit $RC_DEVICE_ALREADY_IN_USE ++ fi ++ done ++ + # try to find a driver for the given set of device numbers + CANDIDATE=$($LSZNET_CALL| + awk "\$7~/${DEVICE_TO_ADD//,// && \$7~/}/ {print \$5}") +@@ -1305,7 +1361,7 @@ then + # compute the expected group device number + CCWGROUPDEVNO=${DEVICES%%,*} + +- # check whether an appropriate driver was determined automatically or ++ # check whether an appropriate driver was determined automatically or + # not, if not, one has to be given by the user via -d + if [ "$DRIVER" == "" ] + then +@@ -1345,7 +1401,7 @@ then + $ATTRIBUTE_COUNT "${ATTRIBUTE_NAME[@]}" \ + "${ATTRIBUTE_VALUE[@]}" + then +- ADDALL_RC=1 ++ ADDALL_RC=$RC_SOME_DEVICES_FAILED + fi + done + exit "$ADDALL_RC" +@@ -1363,9 +1419,9 @@ then + if [[ -z "$CCWGROUPDEVID_TO_REMOVE" ]] + then + print_error "$DEVICE_TO_REMOVE is not a configured device" +- exit 1 ++ exit $RC_DEVICE_NOT_CONFIGURED + fi +- ++ + echo "Remove network device $CCWGROUPDEVID_TO_REMOVE" \ + "($CCWDEVBUSIDS_TO_REMOVE)?" + echo "Warning: this may affect network connectivity!" +@@ -1403,7 +1459,7 @@ then + fi + if [ $DO_LIST_UNCONFIGURED -eq 1 ] + then +- list_unconfigured ++ list_unconfigured + exit 0 + fi + if [ $DO_LIST_CONFIGURED -eq 1 ] +diff --git a/zconf/znetconf.8 b/zconf/znetconf.8 +index 3af8565..a6da42c 100644 +--- a/zconf/znetconf.8 ++++ b/zconf/znetconf.8 +@@ -1,6 +1,6 @@ + .TH ZNETCONF 8 "Mar 2009" "s390-tools" + +-.SH NAME ++.SH NAME + znetconf \- list and configure network devices for System z network adapters + + .SH SYNOPSIS +@@ -8,10 +8,10 @@ znetconf \- list and configure network devices for System z network adapters + .B [-h|--help] [-v|--version] + .br + +-.br +-.B znetconf -u | -c + .br +-.B znetconf -a [,...]{2} [-o =]+ [-d ] ++.B znetconf -u | -c ++.br ++.B znetconf -a [,...]{2} [-o =]+ [-d ] + .br + .B znetconf -A [-o =]+ [-d ] [-e ]+ + .br +@@ -27,12 +27,12 @@ Based on these lists, it automatically adds or removes network devices. + For automatic configuration, znetconf builds a channel command word + (CCW) group device from sensed CCW devices, configures any specified + option through the sensed network device driver and sets the new +-network device online. ++network device online. + .P + During automatic removal, znetconf sets the device offline and removes it. + Be aware that removing all network devices leads to the +-complete loss of network connectivity. So a terminal session (e.g. 3270) +-might be required to restore. ++complete loss of network connectivity. So a terminal session (e.g. 3270) ++might be required to restore. + + .SH OPTIONS + .TP 8 +@@ -43,30 +43,30 @@ Print help text. + .BR -v | --version + Print the version of the s390-tools package and the znetconf command. + +-.TP +-.BR -u | --unconfigured ++.TP ++.BR -u | --unconfigured + List potential network devices that are not yet configured. + For each device, the following data is provided: + .RS + .TP 4 +-* +-Device IDs (device bus bus-IDs) of the CCW devices constituting the network ++* ++Device IDs (device bus bus-IDs) of the CCW devices constituting the network + device + .TP +-* ++* + Type of control unit (e.g. 1731/01) + .TP +-* ++* + Network card type (e.g. OSA (QDIO)) + .TP + * +-Channel path identifier (CHPID) ++Channel path identifier (CHPID) + .TP + * + Device driver (qeth, lcs, ctc, ctcm) + .RE +-.TP +-.BR -c | --configured ++.TP ++.BR -c | --configured + List configured network devices. For each device, the following data is + provided: + .RS +@@ -104,7 +104,7 @@ device_bus_id can be any of the device + IDs listed as part of the potential network device list (argument + .BR -u ")." + For example, if znetconf +-.BR -u ++.BR -u + lists 0.0.f503,0.0.f504,0.0.f505 for a potential network device, device_bus_id + may be 0.0.f503 or 0.0.f504 or 0.0.f505. + If a device bus-ID begins with 0.0., you can abbreviate it to the final 4 +@@ -115,11 +115,11 @@ If attribute value pairs are given with + .BR -o ", " + these pairs are configured for the created network device. The + device is then set online regardless of whether the given attribute value pairs +-were applied successfully. ++were applied successfully. + .br + Finally, the corresponding network interface name (e.g. eth1) is displayed. + .br +-If more then one device_bus_id is given, the given set of devices is configured as a network device. znetconf tries to sense the required device driver ++If more then one device_bus_id is given, the given set of devices is configured as a network device. znetconf tries to sense the required device driver + automatically. If the device driver cannot be sensed, you must specify it with + -d. + .BR -d "." +@@ -145,7 +145,7 @@ znetconf continues with the next remaining potential network device. + + .TP + .BR -r | --remove " [-n | --non-interactive]" +-Remove the network device identified by device_bus_id. device_bus_id is one of ++Remove the network device identified by device_bus_id. device_bus_id is one of + the device IDs of the network device. They are listed as part of znetconf + .BR -c "." + znetconf sets the device offline and removes it. If +@@ -164,21 +164,105 @@ with + .TP + \fB\fR + Specify a device option. The option must match a sysfs attribute for the device +-to be configured. ++to be configured. For a detailed description of the semantics of sysfs ++attributes please refer to the Device Drivers, Features, and Commands book for ++Linux on System z. The attributes are: ++ ++.RS ++.B qeth ++.br ++broadcast_mode ++.br ++buffer_count ++.br ++canonical_macaddr ++.br ++checksumming ++.br ++fake_broadcast ++.br ++ipa_takeover/add4 ++.br ++ipa_takeover/add6 ++.br ++ipa_takeover/del4 ++.br ++ipa_takeover/del6 ++.br ++ipa_takeover/enable ++.br ++ipa_takeover/invert4 ++.br ++ipa_takeover/invert6 ++.br ++isolation ++.br ++large_send ++.br ++layer2 ++.br ++performance_stats ++.br ++portname ++.br ++portno ++.br ++priority_queueing ++.br ++route4 ++.br ++route6 ++.br ++rxip/add4 ++.br ++rxip/add6 ++.br ++rxip/del4 ++.br ++rxip/del6 ++.br ++vipa/add4 ++.br ++vipa/add6 ++.br ++vipa/del4 ++.br ++vipa/del ++.RE ++ ++.RS ++.B ctc(m) ++.br ++buffer ++.br ++loglevel ++.br ++protocol ++.br ++stats ++.RE ++ ++.RS ++.B lcs ++.br ++portno ++.br ++lancmd_timeout ++.RE + + .TP +-\fB\fR ++\fB\fR + Specify the device bus-ID of a CCW device. Device bus-IDs have the form + ([A-Fa-f0-9].[A-Fa-f0-9].)[A-Fa-f0-9]{4}. + +-If a device bus-ID begins with 0.0., you can abbreviate it to the final 4 ++If a device bus-ID begins with 0.0., you can abbreviate it to the final 4 + hexadecimal digits. + + For example, you can abbreviate 0.0.f503 to f503. + + .TP + \fB\fR +-Specify the device driver for the device. Valid values are qeth, lcs, ctc, or ++Specify the device driver for the device. Valid values are qeth, lcs, ctc, or + ctcm. + + .SH EXAMPLES +@@ -242,9 +326,9 @@ Shows the list of potential network devices. Example output: + Device IDs Type Card Type CHPID Drv. + .br + -------------------------------------------------------- +-0.0.f500,0.0.f501,0.0.f502 1731/01 OSA (QDIO) 00 qeth ++0.0.f500,0.0.f501,0.0.f502 1731/01 OSA (QDIO) 00 qeth + .br +-0.0.f503,0.0.f504,0.0.f505 1731/01 OSA (QDIO) 01 qeth ++0.0.f503,0.0.f504,0.0.f505 1731/01 OSA (QDIO) 01 qeth + .RE + .P + \fBznetconf -a 0.0.f503\fR +@@ -258,13 +342,13 @@ lists the new network device. + .P + \fBznetconf -a f503\fR + .RS +-This command is equivalent to \fBznetconf -a 0.0.f503\fR. ++This command is equivalent to \fBznetconf -a 0.0.f503\fR. + .RE + .P + \fBznetconf -a f503 -o layer2=0 -o portname=myname\fR + .RS +-Adds the potential network device +-with 0.0.f503 as one of its device bus-IDs ++Adds the potential network device ++with 0.0.f503 as one of its device bus-IDs + and configures the options layer2 with value 0 and + portname with myname. + .RE +@@ -288,9 +372,9 @@ Device IDs Type Card Type CHPID Drv. Name State + + \fBznetconf -r 0.0.f503\fR + .RS +-Removes the network device with 0.0.f503 as one of its device bus-IDs. ++Removes the network device with 0.0.f503 as one of its device bus-IDs. + You can only remove configured devices as listed by znetconf +-.BR -c "." ++.BR -c "." + After successfully running this command the corresponding device appears in the + list of potential network devices as listed by znetconf + .BR -u "." +@@ -303,9 +387,76 @@ This command is equivalent to \fBznetconf -r 0.0.f503\fR. + .P + + .SH DIAGNOSTICS +-If znetconf runs successfully, the exit status is 0. In case of errors, 1 is +-returned. +- ++If znetconf runs successfully, the exit status is 0. In case of errors, the following codes are returned: ++.TP ++.BR 0 ++success ++.TP ++.BR 9 ++could not group devices ++.TP ++.BR 10 ++could not set device online ++.TP ++.BR 11 ++could not set device offline ++.TP ++.BR 12 ++invalid attribute value pair ++.TP ++.BR 13 ++missing component (broken installation) ++.TP ++.BR 14 ++missing device ID ++.TP ++.BR 15 ++invalid device ID format ++.TP ++.BR 16 ++driver name expected ++.TP ++.BR 17 ++unknown driver ++.TP ++.BR 18 ++missing attribute value pair for -o|--option ++.TP ++.BR 19 ++invalid argument ++.TP ++.BR 20 ++too much arguments ++.TP ++.BR 21 ++no configuration found for device ID ++.TP ++.BR 22 ++device is not configured ++.TP ++.BR 23 ++could not ungroup device ++.TP ++.BR 24 ++at least one option could not be configured ++.TP ++.BR 25 ++missing value for attribute ++.TP ++.BR 26 ++device does not exist ++.TP ++.BR 27 ++device already in use ++.TP ++.BR 28 ++net device did not come online ++.TP ++.BR 29 ++some devices could not be added or failed ++.TP ++.BR 99 ++internal znetconf bug + .SH AUTHOR + .nf + This man-page was written by Einar Lueck . +-- +1.6.3.3 + diff --git a/0018-fix-uppercase-conversion-in-lscss.patch b/0018-fix-uppercase-conversion-in-lscss.patch new file mode 100644 index 0000000..9c5b945 --- /dev/null +++ b/0018-fix-uppercase-conversion-in-lscss.patch @@ -0,0 +1,38 @@ +From a8bcc744ec941c3b34c22c7a7729b52a390c7a08 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Dan=20Hor=C3=A1k?= +Date: Wed, 13 Jan 2010 08:39:09 +0100 +Subject: [PATCH] fix uppercase conversion in lscss + +Description: lscss: fix uppercase conversion +Symptom: when invoking the -u option, lscss will fail with the message "tr: missing operand" +Problem: the bash option "nullglob" interferes with the tr operands +Solution: avoid expanding of those operands by placing quotes around them +--- + zconf/lscss | 4 ++-- + 1 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/zconf/lscss b/zconf/lscss +index efdb9ca..fc40fe6 100755 +--- a/zconf/lscss ++++ b/zconf/lscss +@@ -354,7 +354,7 @@ if [ $SCH_IO ] ;then + echo "----------------------------------------------------------------------" + fi + print_io | if [ $UPPERCASE ] ;then +- tr [:lower:] [:upper:] ++ tr "[:lower:]" "[:upper:]" + else + cat - + fi +@@ -368,7 +368,7 @@ if [ $SCH_CHSC ] ;then + echo "Device Subchan." + echo "-----------------" + print_chsc | if [ $UPPERCASE ] ;then +- tr [:lower:] [:upper:] ++ tr "[:lower:]" "[:upper:]" + else + cat - + fi +-- +1.6.5.2 + diff --git a/0019-ziorep-fix-return-codes.patch b/0019-ziorep-fix-return-codes.patch new file mode 100644 index 0000000..f2037a0 --- /dev/null +++ b/0019-ziorep-fix-return-codes.patch @@ -0,0 +1,53 @@ +From a8ffd7242da2adcc4ab5b0f23193cfe764dc376d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Dan=20Hor=C3=A1k?= +Date: Wed, 20 Jan 2010 08:42:52 +0100 +Subject: [PATCH 19/22] ziorep: fix return codes + +Description: ziomon: ziorep tools return 1 when using options -h and -v +Symptom: Using ziorep_traffic/utilization with these options give an +error. +Problem: 1 as been introduced as rc for parse_parms besides error codes, +but is not distinguished from them when parse_params is called. +Solution: After calling parse_parms check for rc 1 and substitute through 0. +--- + ziomon/ziorep_traffic.cpp | 5 ++++- + ziomon/ziorep_utilization.cpp | 5 ++++- + 2 files changed, 8 insertions(+), 2 deletions(-) + +diff --git a/ziomon/ziorep_traffic.cpp b/ziomon/ziorep_traffic.cpp +index 1461e55..20ee32f 100644 +--- a/ziomon/ziorep_traffic.cpp ++++ b/ziomon/ziorep_traffic.cpp +@@ -529,8 +529,11 @@ int main(int argc, char **argv) + verbose = 0; + + init_opts(&opts); +- if ( (rc = parse_params(argc, argv, &opts)) ) ++ if ( (rc = parse_params(argc, argv, &opts)) ) { ++ if (rc == 1) ++ rc = 0; + goto out; ++ } + if ( (rc = check_opts(&opts, &cfg)) ) + goto out; + +diff --git a/ziomon/ziorep_utilization.cpp b/ziomon/ziorep_utilization.cpp +index 3f57a47..ac4576f 100644 +--- a/ziomon/ziorep_utilization.cpp ++++ b/ziomon/ziorep_utilization.cpp +@@ -352,8 +352,11 @@ int main(int argc, char **argv) + verbose = 0; + + init_opts(&opts); +- if ( (rc = parse_params(argc, argv, &opts)) ) ++ if ( (rc = parse_params(argc, argv, &opts)) ) { ++ if (rc == 1) ++ rc = 0; + goto out; ++ } + if ( (rc = check_opts(&opts, &cfg)) ) + goto out; + +-- +1.6.5.2 + diff --git a/0020-lstape-fix-return-code.patch b/0020-lstape-fix-return-code.patch new file mode 100644 index 0000000..77aed72 --- /dev/null +++ b/0020-lstape-fix-return-code.patch @@ -0,0 +1,31 @@ +From 72ec5b5bd9a7fd23e2d1aaed455df8f2bda952ca Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Dan=20Hor=C3=A1k?= +Date: Wed, 20 Jan 2010 08:44:43 +0100 +Subject: [PATCH 20/22] lstape: fix return code + +Description: lstape: help function returns 1, although it was successful +Symptom: Issuing "lstape -h" or "lstape --help" and then looking for the +error code on the console through e.g. "echo $?" shows 1. Which +looks like an error. +Problem: exit 1, where we chould have exit 0. +Solution: Return 0 after calling the help function with exit 0. +--- + zconf/lstape | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +diff --git a/zconf/lstape b/zconf/lstape +index efacfc9..5671315 100755 +--- a/zconf/lstape ++++ b/zconf/lstape +@@ -90,7 +90,7 @@ while [ $# -ne 0 ]; do + case $1 in + -h|--help) + PrintUsage +- exit 1 ++ exit 0 + ;; + -t|--type) + if [ $# -lt 2 ]; then +-- +1.6.5.2 + diff --git a/0021-cpuplugd-fix-reading-the-size-of-proc-sys-vm-cmm_pag.patch b/0021-cpuplugd-fix-reading-the-size-of-proc-sys-vm-cmm_pag.patch new file mode 100644 index 0000000..9fb5604 --- /dev/null +++ b/0021-cpuplugd-fix-reading-the-size-of-proc-sys-vm-cmm_pag.patch @@ -0,0 +1,32 @@ +From d3c4eb2ced3a8e3c8f7a528f88721324028534e9 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Dan=20Hor=C3=A1k?= +Date: Wed, 20 Jan 2010 08:46:14 +0100 +Subject: [PATCH 21/22] cpuplugd: fix reading the size of /proc/sys/vm/cmm_pages + +Description: cpuplugd: fix fscanf file handling in get_cmmpages_size +Symptom: cpuplugd was not able to correctly read the size of the +/proc/sys/vm/cmm_pages file. This prevented cpuplugd from using +the cmm feature correctly. +Problem: The code checked for the wrong return code (!= 0 instead of ==0) +Solution: Check for the right return code in the get_cmmpages_size error +handling function. +--- + cpuplugd/mem.c | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +diff --git a/cpuplugd/mem.c b/cpuplugd/mem.c +index a8f2a8e..8d5f05f 100644 +--- a/cpuplugd/mem.c ++++ b/cpuplugd/mem.c +@@ -230,7 +230,7 @@ int get_cmmpages_size() + return -1; + } + rc = fscanf(filp, "%d", &size); +- if (rc != 0) { ++ if (rc == 0) { + fprintf(stderr, "Can not read /proc/sys/vm/cmm_pages: %s\n", + strerror(errno)); + if (foreground == 0) +-- +1.6.5.2 + diff --git a/0022-lsqeth-support-new-attributes.patch b/0022-lsqeth-support-new-attributes.patch new file mode 100644 index 0000000..6556adc --- /dev/null +++ b/0022-lsqeth-support-new-attributes.patch @@ -0,0 +1,74 @@ +From c986172e782ae2afa41209e7c238315175d589e1 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Dan=20Hor=C3=A1k?= +Date: Wed, 20 Jan 2010 08:48:52 +0100 +Subject: [PATCH 22/22] lsqeth: support new attributes + +Description: lsqeth: add recent qeth attributes +Symptom: no information about "isolation" and "sniffer" values +Problem: new sysfs attributes "isolation" and "sniffer" not mentioned in +lsqeth output. +Solution: add attributes "isolation" and "sniffer" to lsqeth. +--- + README | 2 ++ + zconf/lsqeth | 11 +++++++---- + 2 files changed, 9 insertions(+), 4 deletions(-) + +diff --git a/README b/README +index 30ba06f..7c75563 100644 +--- a/README ++++ b/README +@@ -192,6 +192,8 @@ Release History: + + - lscss: Also show devices on the defunct subchannel. + ++ - lsqeth: add attributes "isolation" and "sniffer" ++ + - all: Reworked s390-tools build process. + + Bug Fixes: +diff --git a/zconf/lsqeth b/zconf/lsqeth +index 9b155e9..b1c2809 100755 +--- a/zconf/lsqeth ++++ b/zconf/lsqeth +@@ -3,7 +3,7 @@ + # File...........: lsqeth + # Author(s)......: Steffen Thoss + # Peter Tiedemann +-# Copyright IBM Corp. 2004, 2009 ++# Copyright IBM Corp. 2004, 2010 + # + # History of changes: + # +@@ -63,7 +63,9 @@ output_array=( if_name + buffer_count + add_hhlen + layer2 +- large_send ) ++ large_send ++ isolation ++ sniffer ) + # Array for sysfs values + sysfs_entries=( "sw checksumming" "hw checksumming" "no checksumming" + "always queue 0" "always queue 1" +@@ -87,7 +89,7 @@ parp_array=0 + function PrintVersion + { + echo "$script_name: version %S390_TOOLS_VERSION%" +- echo "Copyright IBM Corp. 2003, 2009" ++ echo "Copyright IBM Corp. 2003, 2010" + } + + +@@ -308,7 +310,8 @@ function __print_normal_format + function __layer2_print + { + del_layer2=( route4 route6 +- fake_ll fake_broadcast ) ++ fake_ll fake_broadcast ++ sniffer ) + + for l in ${del_layer2[@]} + do +-- +1.6.5.2 + diff --git a/0023-znetconf-use-hex-index-for-chpidtype-table.patch b/0023-znetconf-use-hex-index-for-chpidtype-table.patch new file mode 100644 index 0000000..6fed2eb --- /dev/null +++ b/0023-znetconf-use-hex-index-for-chpidtype-table.patch @@ -0,0 +1,47 @@ +From 3ca0d01240ab14ab3217985bf8ed9c89111e36c9 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Dan=20Hor=C3=A1k?= +Date: Wed, 3 Feb 2010 13:17:41 +0100 +Subject: [PATCH] znetconf: use hex index for chpidtype table + +Description: znetconf: index into chpidtype lookup table must be hex. +Symptom: Network subchannels with CHPID type containing non-decimal digits, + i.e. a-f, cause lsznet.raw errors like the following: + 1a: value too great for base (error token is "1a") +Problem: The value of the sysfs attribute "type" of a CHPID is hex, + but the lookup table index in the bash script must be decimal. +Solution: Interpret "type" as hex number when used as lookup table index. +--- + zconf/lsznet.raw | 10 +++++----- + 1 files changed, 5 insertions(+), 5 deletions(-) + +diff --git a/zconf/lsznet.raw b/zconf/lsznet.raw +index e5643ee..9821ba3 100755 +--- a/zconf/lsznet.raw ++++ b/zconf/lsznet.raw +@@ -68,10 +68,10 @@ readonly -a CU_GROUPCHANNELS=( + ) + + readonly -a CHPIDTYPES=( +- [10]=OSE +- [11]=OSD +- [15]=OSN +- [24]=IQD ++ [0x10]=OSE ++ [0x11]=OSD ++ [0x15]=OSN ++ [0x24]=IQD + ) + + # whitelist of network devices for TCP/IP stack, e.g. for Linux installers +@@ -116,7 +116,7 @@ function search_cu_tcpip() { + # Always succeeds and returns 0. + function search_chpt() { + local chpidtype_number=$1 +- chpidtype_symbolic=${CHPIDTYPES[$chpidtype_number]} ++ chpidtype_symbolic=${CHPIDTYPES[$((0x$chpidtype_number))]} + if [ "$chpidtype_symbolic" == "" ]; then + chpidtype_symbolic="?" + fi +-- +1.6.6 + diff --git a/0024-zipl-handle-SSCH-status.patch b/0024-zipl-handle-SSCH-status.patch new file mode 100644 index 0000000..3b1b54f --- /dev/null +++ b/0024-zipl-handle-SSCH-status.patch @@ -0,0 +1,230 @@ +From 9c94d906621e775f005fa34583671f08000f1723 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Dan=20Hor=C3=A1k?= +Date: Thu, 4 Feb 2010 13:07:30 +0100 +Subject: [PATCH] zipl: handle SSCH status + +Description: zipl: handle status during IPL SSCH +Symptom: System enters disabled wait during IPL of DASD disk when an + unexpected status (e.g. triggered by a flashcopy operation) + is recognized on the IPL device. +Problem: Unexpected status is not handled correctly during the SSCH + portion of the IPL code. +Solution: Introduce a more robust SSCH result handling which performs + retries and clears status when encountering errors. +--- + zipl/boot/common.S | 163 +++++++++++++++++++++++++++++++++++----------------- + zipl/boot/eckd2.S | 1 - + zipl/boot/fba2.S | 1 - + 3 files changed, 110 insertions(+), 55 deletions(-) + +diff --git a/zipl/boot/common.S b/zipl/boot/common.S +index fa45e5a..108dbbf 100644 +--- a/zipl/boot/common.S ++++ b/zipl/boot/common.S +@@ -249,69 +249,126 @@ _disable_device: + .endm + + .macro io_subroutines ++ ++ ++__LC_IO_NEW_PSW = 0x78 ++__LC_SUBCHANNEL_ID = 0xb8 ++ ++# ++# Wait for I/O interrupt. ++# ++# Wait until status for the specified subchannel is available. ++# ++# %r2 : subchannel id ++# %r3 : address of irb ++# ++ ++_wait_for_int: ++ lr %r1,%r2 ++ basr %r4,0 # get base register ++0: ++ mvc __LC_IO_NEW_PSW(8),4f-0b(%r4) # set i/o new psw ++1: # wait ++ lpsw 3f-0b(%r4) ++2: # continue ++ tsch 0(%r3) # get status ++ brc 4,1b # if cc=1 goto wait ++ br %r14 # return ++ .align 8 ++3: ++ .long 0x020a0000,0x80000000+1b # enabled wait psw ++4: ++ .long 0x00080000,0x80000000+2b # io new psw ++ + # + # Start I/O +-# %r2 : device subchannel id ++# ++# Attempt to start I/O defined by ORB on specified subchannel. Retry I/O ++# 256 times per path (recommended error recovery procedure for IFCCs) unless ++# a permanent path error condition is indicated. Try all paths twice to try to ++# work around "link flapping" (paths going down once each in the same order as ++# they are tried). Perform CLEAR SUBCHANNEL when switching paths to clear any ++# improper subchannel status. ++# ++# %r2 : subchannel id + # %r3 : address of orb + # %r4 : address of irb +-# %r5 : retry count + # + _ssch: +- stm %r6,%r15,24(%r15) +- basr %r13,0 # base register +-0: s %r15,6f-0b(%r13) # create stack frame +- lr %r12,%r2 # save subchannel id +- lr %r11,%r3 # save orb +- lr %r10,%r4 # save irb +- lr %r9,%r5 # save retry count +- ic %r0,.Llpm-0b(%r13) # copy lpm to orb lpm +- stc %r0,6(%r3) +-1: lr %r1,%r12 +- ssch 0(%r11) # go +- bnz 4f-0b(%r13) # houston, we have a problem +-2: lr %r2,%r12 # call _wait4de with subchannel id +- lr %r3,%r10 # and irb address as parameters +- bas %r14,_wait4de-0b(%r13) # wait until DE or error +- tm 9(%r10),0xff # test channel status +- bnz 4f-0b(%r13) +- tm 8(%r10),0xf3 # test device status +- bz 5f-0b(%r13) +- bct %r9,1b-0b(%r13) # something went wrong, retry. +-4: l %r2,7f-0b(%r13) +- bas %r4,_panik-0b(%r13) # won't return +-5: lm %r6,%r15,120(%r15) +- br %r14 +-6: .long 96 +-7: .long ESSCH ++ stm %r6,%r15,24(%r15) ++ basr %r13,0 # get base register ++0: ++ ahi %r15,-96 # create stack frame ++ lr %r6,%r2 # r6: sid ++ lr %r7,%r3 # r7: orb ++ lr %r8,%r4 # r8: irb ++ sr %r9,%r9 # r9: initial lpm ++ ic %r9,.Llpm-0b(%r13) ++ l %r10,.Lmask-0b(%r13) # r10: path mask ++1: # restart_all ++ lhi %r11,256 # r11: retry counter ++2: # restart ++ stc %r9,6(%r7) # store initial lpm in orb ++ ltr %r9,%r9 # if non-zero initial lpm ++ jne 3f # then use initial lpm ++ stc %r10,6(%r7) # else use current path mask ++3: # gotlpm ++ lr %r1,%r6 # get sid ++ ssch 0(%r7) # start subchannel ++ brc 1,7f # if cc==3 goto next_path ++ brc 7,6f # if cc!=0 goto retry ++4: # wait_for_int_loop ++ lr %r2,%r6 # get sid ++ lr %r3,%r8 # get irb ++ bras %r14,_wait_for_int # wait for interrupt ++ jnz 9f # if cc!=0 goto panic ++ tm 0(%r8),0x3 # test irb deferred cc ++ brc 1,7f # if cc==3 goto next_path ++ jz 5f # if cc==0 goto no_stctl_check ++ tm 3(%r8),0x10 # test irb status control ++ jnz 6f # if alert goto retry ++5: # no_stctl_check ++ tm 9(%r8),0xff # test irb subchannel status ++ jnz 6f # if status!=0 goto retry ++ tm 8(%r8),0xf3 # test irb unusual device status ++ jnz 6f # if status!=0 goto retry ++ tm 8(%r8),0x4 # test irb device end ++ jz 4b # if !device_end goto wait_for_int_loop ++ lm %r6,%r15,120(%r15) ++ br %r14 # return ++ ++6: # retry ++ lr %r1,%r6 # get sid ++ tsch 0(%r8) # clear status if necessary ++ brct %r11,2b # if --retries>0 goto restart ++7: # next_path ++ ltr %r9,%r9 # if initial lpm != 0 ++ jnz 8f # then goto noshift ++ srl %r10,1 # path_mask >>= 1 ++ ltr %r10,%r10 # if path_mask==0 ++ jz 9f # then goto panic ++8: # noshift ++ sr %r9,%r9 # clear initial lpm ++ lr %r1,%r6 # get sid ++ csch # clear subchannel ++ brc 7,9f # if cc!=0 goto panic ++ lr %r2,%r6 # get sid ++ lr %r3,%r8 # get irb ++ bras %r14,_wait_for_int # wait for interrupt ++ j 1b # goto restart_all ++9: # panic ++ l %r2,.Lerrno-0b(%r13) # get error code ++ bras %r14,_panik # panic ++ ++.Lerrno: ++ .long ESSCH ++.Lmask: ++ .long 0x8080 + .Llpm: +- .byte 0xff ++ .byte 0x00 + .align 2 + + # +-# Wait for interrupt subroutine +-# %r2 : device subchannel id +-# %r3 : address of irb +-# +-_wait4de: +- lr %r1,%r2 +- basr %r4,0 +-0: mvc 0x78(8),5f-0b(%r4) # set i/o new psw +-1: lpsw 4f-0b(%r4) +-2: c %r1,0xb8 # compare subchannel id +- bne 1b-0b(%r4) # unequal -> continue waiting +- tsch 0(%r3) +- tm 9(%r3),0xff # test channel status +- bnz 3f-0b(%r4) +- tm 8(%r3),0xf3 # got something unusual ? +- bnz 3f-0b(%r4) +- tm 8(%r3),0x04 # got device end ? +- bz 1b-0b(%r4) # still busy -> continue waiting +-3: br %r14 +- .align 8 +-4: .long 0x020a0000,0x80000000+1b +-5: .long 0x00080000,0x80000000+2b # io new psw +- +-# + # Panik routine. Loads a disabled wait psw + # %r2 : panik code + # +diff --git a/zipl/boot/eckd2.S b/zipl/boot/eckd2.S +index ba71db9..b59ab0e 100644 +--- a/zipl/boot/eckd2.S ++++ b/zipl/boot/eckd2.S +@@ -85,7 +85,6 @@ _load_direct: + la %r3,.Lorb-.Lbase(%r13) # pass address of orb + la %r4,.Lirb-.Lbase(%r13) # and pass address of irb + lr %r2,%r11 # pass subchannel id +- la %r5,5 # 5 retries + bas %r14,_ssch-.Lbase(%r13) # read records + .Lexit: + lr %r2,%r12 # return updated load address +diff --git a/zipl/boot/fba2.S b/zipl/boot/fba2.S +index 82b1447..90bb2cd 100644 +--- a/zipl/boot/fba2.S ++++ b/zipl/boot/fba2.S +@@ -98,7 +98,6 @@ _load_direct: + lr %r2,%r11 # pass subchannel id + la %r3,.Lorb-.Lbase(%r13) # pass address of orb + la %r4,.Lirb-.Lbase(%r13) # and pass address of irb +- la %r5,5 # 5 retries + bas %r14,_ssch-.Lbase(%r13) # read up to 128 blocks + b .Lmain-.Lbase(%r13) + .Lexit: lr %r2,%r12 # return updated load address +-- +1.6.6 + diff --git a/0025-vmconvert-shows-garbage-in-progress-bar.patch b/0025-vmconvert-shows-garbage-in-progress-bar.patch new file mode 100644 index 0000000..7c13c59 --- /dev/null +++ b/0025-vmconvert-shows-garbage-in-progress-bar.patch @@ -0,0 +1,39 @@ +From 04859d2270d1327873e1e8825bdd9d0eaf73f5cc Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Dan=20Hor=C3=A1k?= +Date: Wed, 10 Mar 2010 11:52:18 +0100 +Subject: [PATCH] vmconvert shows garbage in progress bar + +Description: vmconvert: Progress bar shows garbage +Symptom: The progress bar shows control characters at end of line. +Problem: One variable responsible for the progress bar has not been +initialized. +Solution: Initialize variable. +--- + vmconvert/dump.cpp | 3 ++- + 1 files changed, 2 insertions(+), 1 deletions(-) + +diff --git a/vmconvert/dump.cpp b/vmconvert/dump.cpp +index f306b27..b4c97d6 100644 +--- a/vmconvert/dump.cpp ++++ b/vmconvert/dump.cpp +@@ -46,8 +46,8 @@ ProgressBar::initProgress(void) + void + ProgressBar::displayProgress(uint64_t value, uint64_t maxValue) + { ++ char progress_bar[51]; + int j; +- char progress_bar[50]; + + if (progressPercentage == (int) (value * 100 / maxValue)) + fprintf(stderr, "%6lld of %6lld |\r", +@@ -58,6 +58,7 @@ ProgressBar::displayProgress(uint64_t value, uint64_t maxValue) + progress_bar[j] = '#'; + for (j = progressPercentage / 2; j < 50; j++) + progress_bar[j] = '-'; ++ progress_bar[50] = 0; + fprintf(stderr, "%6lld of %6lld |%s| %3d%% \r", + (long long) value, (long long) maxValue, + progress_bar, progressPercentage); +-- +1.6.6.1 + diff --git a/0026-zipl-zfcp-dump-partition-error.patch b/0026-zipl-zfcp-dump-partition-error.patch new file mode 100644 index 0000000..5864c85 --- /dev/null +++ b/0026-zipl-zfcp-dump-partition-error.patch @@ -0,0 +1,32 @@ +From 18bc3ce1055c350aaa50696e53baad984f573697 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Dan=20Hor=C3=A1k?= +Date: Thu, 11 Mar 2010 08:34:32 +0100 +Subject: [PATCH] zipl: zfcp dump partition error + +Description: zipl: zfcp dump partition error +Symptom: When configuring the zfcp dump partition in zipl.conf the +partition information may be wrong. +Problem: The info data structure is used after it was freed. +Solution: Free the info structure when it is not used any more. +--- + zipl/src/bootmap.c | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +diff --git a/zipl/src/bootmap.c b/zipl/src/bootmap.c +index 526aa48..043a562 100644 +--- a/zipl/src/bootmap.c ++++ b/zipl/src/bootmap.c +@@ -689,9 +689,9 @@ get_dump_fs_parmline(char* partition, char* parameters, uint64_t mem, + disk_free_info(info); + return -1; + } +- disk_free_info(info); + buffer = create_dump_fs_parmline(parameters, "/dev/ram0", info->partnum, + mem, 1); ++ disk_free_info(info); + if (buffer == NULL) + return -1; + *result = buffer; +-- +1.6.6.1 + diff --git a/0027-zfcpdump-disable-memory-cgroups.patch b/0027-zfcpdump-disable-memory-cgroups.patch new file mode 100644 index 0000000..2a7db37 --- /dev/null +++ b/0027-zfcpdump-disable-memory-cgroups.patch @@ -0,0 +1,34 @@ +From cc672d10ef6ee3da060649fa595ed9d980e5e60e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Dan=20Hor=C3=A1k?= +Date: Mon, 22 Mar 2010 12:58:13 +0100 +Subject: [PATCH] zfcpdump - disable memory cgroups + +Description: zipl/zfcpdump: Use "cgroup_disable=memory" kernel parameter +Symptom: Out of memory kernel panic during SCSI dump. +Problem: The zfcpdump kernel has to run within a 32 MB limit. When + using "memory cgroups" about 2.6 MB are allocated, which leads + to memory problems for zfcpdump. +Solution: For zfcpdump we do not need "memory cgroups". Therefore this patch + adds the kernel parameter "cgroup_disable=memory" to save 2.5 MB + of memory. +--- + zipl/src/bootmap.c | 3 ++- + 1 files changed, 2 insertions(+), 1 deletions(-) + +diff --git a/zipl/src/bootmap.c b/zipl/src/bootmap.c +index 043a562..69f721e 100644 +--- a/zipl/src/bootmap.c ++++ b/zipl/src/bootmap.c +@@ -653,7 +653,8 @@ create_dump_fs_parmline(const char* parmline, const char* root_dev, + if (!result) + return NULL; + snprintf(result, DUMP_PARAM_MAX_LEN, "%s%sroot=%s dump_part=%d " +- "dump_mem=%lld maxcpus=%d", parmline ? parmline : "", ++ "dump_mem=%lld maxcpus=%d cgroup_disable=memory", ++ parmline ? parmline : "", + parmline ? " " : "", root_dev, part_num, + (unsigned long long) mem, max_cpus); + result[DUMP_PARAM_MAX_LEN - 1] = 0; +-- +1.6.6.1 + diff --git a/0028-fix-df-usage-in-ziomon.patch b/0028-fix-df-usage-in-ziomon.patch new file mode 100644 index 0000000..24e7d4e --- /dev/null +++ b/0028-fix-df-usage-in-ziomon.patch @@ -0,0 +1,29 @@ +From b0238ed360f65ecbf095d89c43c420ed036e4ff0 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Dan=20Hor=C3=A1k?= +Date: Mon, 22 Mar 2010 15:21:55 +0100 +Subject: [PATCH] fix df usage in ziomon + +Description: ziomon: Fix 'df' command usage +Symptom: Long device names could not be parsed properly. +Problem: Long device names were split accross multiple lines. +Solution: Use df with the right options. +--- + ziomon/ziomon | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +diff --git a/ziomon/ziomon b/ziomon/ziomon +index 924c1dd..ea910fc 100755 +--- a/ziomon/ziomon ++++ b/ziomon/ziomon +@@ -709,7 +709,7 @@ function check_size_requirements() { + (( estimated_size=$total_num_records * $size_per_record )); + debug " estimated size: $estimated_size Bytes"; + (( estimated_size=$estimated_size / 1000000 )); +- (( free_space = `df -k $logpath | tail -n 1 | awk '{print $4}'` / 1024 )); ++ free_space=`df -mP $logpath | tail -n 1 | awk '{print $4}'`; + debug " free space on '$logpath': $free_space MBytes"; + if [ "$WRP_SIZE" == "" ]; then + echo "NOTE: No size limit specified, run without a limit."; +-- +1.6.6.1 + diff --git a/0029-ziomon-remove-check-for-ziorep_config-availability.patch b/0029-ziomon-remove-check-for-ziorep_config-availability.patch new file mode 100644 index 0000000..2925582 --- /dev/null +++ b/0029-ziomon-remove-check-for-ziorep_config-availability.patch @@ -0,0 +1,102 @@ +From 2ec256f9dab30a57f60c83f7cd9b127c25b6cdd6 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Dan=20Hor=C3=A1k?= +Date: Thu, 25 Mar 2010 14:11:31 +0100 +Subject: [PATCH] ziomon: remove check for ziorep_config availability + +Description: ziomon: Remove check for ziorep_config availability +Symptom: ziorep_config could not be found +Problem: The path for ziorep_config was hardcoded and checked + for to detect install errors. However, as distributions + install these files in varying directories, install issues + should be avoided by distributors to begin with, and + especially since the debug trace helps to detect these, + this check is not really necessary and obviously causing + more harm than it helps. +Solution: Config is read from PATH. +--- + ziomon/ziorep_cfgreader.cpp | 24 +++++------------------- + ziomon/ziorep_cfgreader.hpp | 2 -- + 2 files changed, 5 insertions(+), 21 deletions(-) + +diff --git a/ziomon/ziorep_cfgreader.cpp b/ziomon/ziorep_cfgreader.cpp +index c64c150..a8f424f 100644 +--- a/ziomon/ziorep_cfgreader.cpp ++++ b/ziomon/ziorep_cfgreader.cpp +@@ -18,7 +18,7 @@ + #include "ziorep_utils.hpp" + + #define ZIOREP_CFG_EXTENSION ".cfg" +-#define ZIOREP_CONFIG_PATH "/sbin/ziorep_config" ++#define ZIOREP_CONFIG "ziorep_config" + + extern const char *toolname; + extern int verbose; +@@ -158,18 +158,6 @@ int ConfigReader::filter_unused_devices(const char *filename) + } + + +-int ConfigReader::check_ziorep_config() const +-{ +- if (access(ZIOREP_CONFIG_PATH, F_OK | R_OK | X_OK)) { +- fprintf(stderr, "%s: Cannot access " ZIOREP_CONFIG_PATH +- ". Please check your installation and try again.\n", toolname); +- return -1; +- } +- +- return 0; +-} +- +- + int ConfigReader::check_config_file(const char *fname) const + { + char *tmp; +@@ -204,8 +192,6 @@ int ConfigReader::extract_config_data(const char *fname) + + // Try to extract to .config first, which will be permanently cached + verbose_msg("No data cached, extract\n"); +- if (check_ziorep_config()) +- return -1; + + fprintf(stdout, "Extracting config data..."); + fflush(stdout); +@@ -215,8 +201,8 @@ int ConfigReader::extract_config_data(const char *fname) + if (extract_tmp(fname)) { + fprintf(stderr, "%s: Could not extract" + " configuration data. Check the integrity of" +- " %s%s with %s and retry.", toolname, fname, +- ZIOREP_CFG_EXTENSION, ZIOREP_CONFIG_PATH); ++ " %s%s with %s and retry.\n", toolname, fname, ++ ZIOREP_CFG_EXTENSION, ZIOREP_CONFIG); + return -1; + } + } +@@ -286,11 +272,11 @@ int ConfigReader::extract(const char *fname) + char *cmd = NULL; + + // /sbin/ziorep_config -I -i > 2>/dev/null +- cmd = (char*)malloc(strlen(ZIOREP_CONFIG_PATH) + 7 + strlen(fname) ++ cmd = (char*)malloc(strlen(ZIOREP_CONFIG) + 7 + strlen(fname) + + strlen(ZIOREP_CFG_EXTENSION) + 3 + strlen(m_tmp_file) + + 12 + 1); + +- sprintf(cmd, "%s -I -i %s%s > %s 2>/dev/null", ZIOREP_CONFIG_PATH, fname, ++ sprintf(cmd, "%s -I -i %s%s > %s 2>/dev/null", ZIOREP_CONFIG, fname, + ZIOREP_CFG_EXTENSION, m_tmp_file); + + verbose_msg("Issue command: %s\n", cmd); +diff --git a/ziomon/ziorep_cfgreader.hpp b/ziomon/ziorep_cfgreader.hpp +index 94e612b..3053633 100644 +--- a/ziomon/ziorep_cfgreader.hpp ++++ b/ziomon/ziorep_cfgreader.hpp +@@ -138,8 +138,6 @@ private: + * in the actual data, and remove anything that is unused */ + int filter_unused_devices(const char *filename); + +- int check_ziorep_config() const; +- + int check_config_file(const char *fname) const; + + int extract_config_data(const char *fname); +-- +1.6.6.1 + diff --git a/0030-ziomon-fix-multipathing.patch b/0030-ziomon-fix-multipathing.patch new file mode 100644 index 0000000..f636f19 --- /dev/null +++ b/0030-ziomon-fix-multipathing.patch @@ -0,0 +1,46 @@ +From 3aa5fa943cea0f01beb63c90a5b0255a797ac117 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Dan=20Hor=C3=A1k?= +Date: Wed, 31 Mar 2010 10:19:50 +0200 +Subject: [PATCH] ziomon - fix multipathing + +Description: ziomon: Fix problem with multipath command output +Symptom: Number of LUNs does not mach number of devices: E.g. 12 devices + and 10 LUNs. +Problem: Some version of the multipath command use characters that can + break parsing of its output. +Solution: Use proper parsing of the multipath -l output. +--- + ziomon/ziomon | 16 ++++++++-------- + 1 files changed, 8 insertions(+), 8 deletions(-) + +diff --git a/ziomon/ziomon b/ziomon/ziomon +index ea910fc..b4c6e36 100755 +--- a/ziomon/ziomon ++++ b/ziomon/ziomon +@@ -499,15 +499,15 @@ function check_for_multipath_devices() { + WRP_DEVICES[$j]=""; + devices_basenames[$j]=""; + clean_devices; +- (( i+=3 )); ++ (( i+=2 )); + while [[ ! "${mp_arr[$i]:0:1}" =~ "[0-9a-zA-Z]" ]] && [ $i -lt ${#mp_arr[@]} ]; do +- checked_devs[${#checked_devs[@]}]=`echo ${mp_arr[$i]} | awk '{print "/dev/"$3}'`; +- ddebug " add ${checked_devs[${#checked_devs[@]}-1]}"; +- line=${mp_arr[$i]#* }; +- line=${line%%:*}; +- line=`echo $line | sed 's/ //g'`; +- WRP_HOST_ADAPTERS[${#WRP_HOST_ADAPTERS[@]}]="host$line"; +- WRP_LUNS[${#WRP_LUNS[@]}]=`echo ${mp_arr[$i]#* } | awk '{print $1}'`; ++ if [ `echo ${mp_arr[$i]} | grep -e "[0-9]\{1,\}:[0-9]\{1,\}:[0-9]\{1,\}:[0-9]\{1,\}" | wc -l` -ne 0 ]; then ++ line="`echo ${mp_arr[$i]} | sed 's/.*\([0-9]\{1,\}:[0-9]\{1,\}:[0-9]\{1,\}:[0-9]\{1,\}\)/\1/'`"; ++ checked_devs[${#checked_devs[@]}]=`echo $line | awk '{print "/dev/"$2}'`; ++ ddebug " add ${checked_devs[${#checked_devs[@]}-1]}"; ++ WRP_HOST_ADAPTERS[${#WRP_HOST_ADAPTERS[@]}]="host${line%%:*}"; ++ WRP_LUNS[${#WRP_LUNS[@]}]=`echo $line | awk '{print $1}'`; ++ fi + (( i++ )); + done; + (( --i )); +-- +1.6.6.1 + diff --git a/0031-mismatch-between-man-and-h-in-chshut.patch b/0031-mismatch-between-man-and-h-in-chshut.patch new file mode 100644 index 0000000..8f8cddd --- /dev/null +++ b/0031-mismatch-between-man-and-h-in-chshut.patch @@ -0,0 +1,66 @@ +From 37e697ae95b3c03f962ac7bb2dd591f00b6de87b Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Dan=20Hor=C3=A1k?= +Date: Wed, 28 Apr 2010 10:24:41 +0200 +Subject: [PATCH] mismatch between man and -h in chshut + +Description: chshut: Mismatch between man and -h +Symptom: Option -h stills show "panic" as a valid state. +Problem: Although it should not be used it is possible to use the + command with a "panic" state. +Solution: Remove "panic" from the list of valid states. + Provide an explanatory message in case it is used anyhow. +--- + ipl_tools/getopt.c | 11 ----------- + ipl_tools/sa.c | 7 +++++-- + 2 files changed, 5 insertions(+), 13 deletions(-) + +diff --git a/ipl_tools/getopt.c b/ipl_tools/getopt.c +index abd0cc2..d729379 100644 +--- a/ipl_tools/getopt.c ++++ b/ipl_tools/getopt.c +@@ -60,7 +60,6 @@ const char *const usage_sa = + " 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" +-" panic System has been shut down after a kernel panic\n" + " Note: Depending on the distribution, \"halt\" might be mapped to \"poff\".\n" + "\n" + "ACTION specifies the action to be performed:\n" +@@ -638,16 +637,6 @@ void parse_shutdown_options(int argc, char **argv) + "/sys/firmware/vmcmd/on_reboot"); + } + break; +- case 3: +- rc = strwrt(argv[2], +- "/sys/firmware/shutdown_actions/on_panic"); +- if (action == 4 && rc == 0) { +- /*rc = ustrwrt(argv[3], +- "/sys/firmware/vmcmd/on_reboot"); */ +- rc = ustrwrt(argv[3], +- "/sys/firmware/vmcmd/on_panic"); +- } +- break; + } + if (rc != 0) { + fprintf(stderr, "%s: Failed to change shutdown" +diff --git a/ipl_tools/sa.c b/ipl_tools/sa.c +index 0232a47..d6b72bb 100644 +--- a/ipl_tools/sa.c ++++ b/ipl_tools/sa.c +@@ -83,8 +83,11 @@ int is_valid_case(char *action) + rc = 1; + if (strncmp(action, "reboot", 6) >= 0 && length == 6) + rc = 2; +- if (strncmp(action, "panic", 5) >= 0 && length == 5) +- rc = 3; ++ if (strncmp(action, "panic", 5) >= 0 && length == 5) { ++ fprintf(stderr, "%s: Please use \"service dumpconf\" for " ++ "configuring the panic action\n", name); ++ exit(1); ++ } + return rc; + } + +-- +1.6.6.1 + diff --git a/0032-lsdasd-update-man-page.patch b/0032-lsdasd-update-man-page.patch new file mode 100644 index 0000000..9dab991 --- /dev/null +++ b/0032-lsdasd-update-man-page.patch @@ -0,0 +1,48 @@ +From c3fc4200d7913b50fb8b501681a0f44e51833a81 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Dan=20Hor=C3=A1k?= +Date: Wed, 28 Apr 2010 20:57:17 +0200 +Subject: [PATCH] lsdasd - update man page + +Description: lsdasd: add missing description of option -b to man page +Symptom: Option -b/--base is described in lsdasd --help, but not in + the respective man page. +Problem: Man page is missing the description. +Solution: Add description. +--- + zconf/lsdasd.8 | 6 +++++- + 1 files changed, 5 insertions(+), 1 deletions(-) + +diff --git a/zconf/lsdasd.8 b/zconf/lsdasd.8 +index f37c957..9c13644 100644 +--- a/zconf/lsdasd.8 ++++ b/zconf/lsdasd.8 +@@ -10,6 +10,7 @@ lsdasd \- list channel attached direct access storage devices (DASD). + .TP 8 + .B lsdasd + .RB [ -a ] ++.RB [ -b ] + .RB [ -s ] + .RB [ -v ] + .RB [ -l ] +@@ -19,7 +20,7 @@ lsdasd \- list channel attached direct access storage devices (DASD). + .RI [ " [" "] ...]]" + + .SH DESCRIPTION +-The lsdasd command provides an overview of available DASD devices. ++The lsdasd command provides an overview of available DASD devices. + + .SH OPTIONS + .TP 8 +@@ -32,6 +33,9 @@ Supresses leading "0.0." for bus IDs. + .BR -a | --offline + Include all (offline) devices. + .TP ++.BR -b | --base ++Include only base devices. ++.TP + .BR -c | --compat + Old output of lsdasd for compatibility. + .TP +-- +1.6.6.1 + diff --git a/0033-reinitialize-array-in-lsqeth.patch b/0033-reinitialize-array-in-lsqeth.patch new file mode 100644 index 0000000..331d7e9 --- /dev/null +++ b/0033-reinitialize-array-in-lsqeth.patch @@ -0,0 +1,79 @@ +From edd35870b833548853b4c739cee1a7c0bce1fa55 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Dan=20Hor=C3=A1k?= +Date: Mon, 3 May 2010 10:14:08 +0200 +Subject: [PATCH] reinitialize array in lsqeth + +Description: lsqeth: add clearing of print array for every qeth device +Symptom: lsqeth without parameters displays information of all qeth + devices. For layer2 devices information from a previously + displayed layer3 device may show up. +Problem: A structure used for printing is not cleared after + information for the previous device is written. +Solution: Add clearing of print array before collecting display + information for a single qeth device.. +--- + README | 3 +++ + zconf/lsqeth | 18 ++++++++++++++++-- + 2 files changed, 19 insertions(+), 2 deletions(-) + +diff --git a/README b/README +index 7c75563..ffd5e54 100644 +--- a/README ++++ b/README +@@ -253,6 +253,9 @@ Release History: + Fix printing of vmcmd shutdown action: Also print CP commands that + have more than one word. + ++ - lsqeth: ++ * clear print array for every device displayed ++ + - all: + Fixed a lot of build warnings and minor bugs. + +diff --git a/zconf/lsqeth b/zconf/lsqeth +index b1c2809..19d49cd 100755 +--- a/zconf/lsqeth ++++ b/zconf/lsqeth +@@ -168,6 +168,19 @@ fi + } + + ++# ++# initialize format_array_print ++# ++function __init_format_array_print ++{ ++ local k=0 ++ ++ while [ $k -lt ${#output_array[@]} ]; ++ do ++ format_array_print[$k]='' ++ k=$((k+1)) ++ done ++} + + # + # search value in format_array +@@ -309,9 +322,9 @@ function __print_normal_format + # + function __layer2_print + { +- del_layer2=( route4 route6 ++ del_layer2=( route4 route6 large_send + fake_ll fake_broadcast +- sniffer ) ++ checksumming sniffer ) + + for l in ${del_layer2[@]} + do +@@ -358,6 +371,7 @@ fi + # + for k in ${device_list} + do ++ __init_format_array_print + if_name="`cat $device_dir/$k/if_name`" + if [ -z "$if_name" ]; then + if_name=0 +-- +1.6.6.1 + diff --git a/0034-check-the-length-of-the-parameters-line.patch b/0034-check-the-length-of-the-parameters-line.patch new file mode 100644 index 0000000..86107bc --- /dev/null +++ b/0034-check-the-length-of-the-parameters-line.patch @@ -0,0 +1,50 @@ +From 78a9e00a3a9885298f09079c026bf5415c137cca Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Dan=20Hor=C3=A1k?= +Date: Thu, 20 May 2010 16:19:17 +0200 +Subject: [PATCH] check the length of the parameters line + +The value of the parameters variable in zipl.conf that is passed as to the kernel +into /proc/cmdline is silently truncated to 896 bytes (it matches the value of +BOOT_PARM_LENGTH from boot/menu.S). Thus we add a check into zipl and end with +an error if the line is longer. +--- + zipl/include/zipl.h | 3 +++ + zipl/src/job.c | 8 ++++++++ + 2 files changed, 11 insertions(+), 0 deletions(-) + +diff --git a/zipl/include/zipl.h b/zipl/include/zipl.h +index d2d26dd..5e02f13 100644 +--- a/zipl/include/zipl.h ++++ b/zipl/include/zipl.h +@@ -40,6 +40,9 @@ + + #define MAX_DUMP_VOLUMES 32 + ++/* defined in boot/menu.S as MENU_PARM_LENGTH */ ++#define PARMLINE_LENGTH 896 ++ + /* Internal component load address type */ + typedef uint64_t address_t; + +diff --git a/zipl/src/job.c b/zipl/src/job.c +index a65e8c1..76ed5df 100644 +--- a/zipl/src/job.c ++++ b/zipl/src/job.c +@@ -894,6 +894,14 @@ get_parmline(char* filename, char* line, char** parmline, address_t* address, + return -1; + + } else result = NULL; ++ /* check the maximum possible length */ ++ if (result) { ++ len = strlen(result); ++ if (len > PARMLINE_LENGTH) { ++ error_text("The length of parameters line (%d bytes) exceeds the allowed maximum (%d bytes)", len, PARMLINE_LENGTH); ++ return -1; ++ } ++ } + *parmline = result; + *address = addr; + return 0; +-- +1.6.6.1 + diff --git a/0035-ziorep-follow-symlink.patch b/0035-ziorep-follow-symlink.patch new file mode 100644 index 0000000..dbe821a --- /dev/null +++ b/0035-ziorep-follow-symlink.patch @@ -0,0 +1,28 @@ +From fabce87ca9d586e6da7ed0bd371f2102408c721c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Dan=20Hor=C3=A1k?= +Date: Fri, 4 Jun 2010 12:05:19 +0200 +Subject: [PATCH 35/36] ziorep - follow symlink + +Description: ziomon: fix the execution of stat to follow symlinks. +Symptom: The device mapper report is failing with a script error. +Solution: Add parameter to stat execution to follow symlinks. +--- + ziomon/ziorep_config | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +diff --git a/ziomon/ziorep_config b/ziomon/ziorep_config +index de60379..f2ad35c 100755 +--- a/ziomon/ziorep_config ++++ b/ziomon/ziorep_config +@@ -159,7 +159,7 @@ sub get_mapper_devices + next; + } + my $tf = catfile($c_src, "$dev"); +- my $mm = `stat -c%t:%T $tf`; ++ my $mm = `stat -L -c%t:%T $tf`; + chomp($mm); + $mm = join(":", map { hex($_) } split(":", $mm)); + $mapper_dev{$mm} = $dev; +-- +1.6.6.1 + diff --git a/0036-ts-shell-do-not-restrict-group-names-to-be-alphanume.patch b/0036-ts-shell-do-not-restrict-group-names-to-be-alphanume.patch new file mode 100644 index 0000000..7a42d73 --- /dev/null +++ b/0036-ts-shell-do-not-restrict-group-names-to-be-alphanume.patch @@ -0,0 +1,36 @@ +From 379f76e4084a0d1875e1f98b2d975600639f6574 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Dan=20Hor=C3=A1k?= +Date: Fri, 4 Jun 2010 12:06:38 +0200 +Subject: [PATCH 36/36] ts-shell: do not restrict group names to be alphanumeric + +Description: ts-shell: do not restrict group names to be alphanumeric +Symptom: ts-shell does not add authorizations assigned to groups + which contain non-alphanumeric characters, for instance, + a hyphen (-) sign. +Problem: ts-shell uses a regular expression to parse group names. + This regular expression uses the alphanumeric character + class (\w) to match group names. Using group names like + "ts-user" are ignored, because hyphen signs are not + included in the alphanumeric character class. +Solution: Make the regular expression less restrictive through + permitting all characters that are not whitespaces (\S). +--- + iucvterm/bin/ts-shell.in | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +diff --git a/iucvterm/bin/ts-shell.in b/iucvterm/bin/ts-shell.in +index 654d0c6..5fdf66c 100755 +--- a/iucvterm/bin/ts-shell.in ++++ b/iucvterm/bin/ts-shell.in +@@ -219,7 +219,7 @@ sub loadAuthorization(\%) + $authorized = 1; + log_debug "Found user: $key"; + +- } elsif ($key =~ /^@(\w+)$/) { ++ } elsif ($key =~ /^@(\S+)$/) { + my $group = $1; + $authorized = 1 if grep {/^${group}$/} @{$cfg->{groups}}; + log_debug "Found group: $key" if $authorized; +-- +1.6.6.1 + diff --git a/0037-znetconf-unknown-driver-for-qeth.patch b/0037-znetconf-unknown-driver-for-qeth.patch new file mode 100644 index 0000000..97f2b5a --- /dev/null +++ b/0037-znetconf-unknown-driver-for-qeth.patch @@ -0,0 +1,30 @@ +From 41d606899d4029f8ac9f3415ebd21142cb223d70 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Dan=20Hor=C3=A1k?= +Date: Tue, 22 Jun 2010 13:25:32 +0200 +Subject: [PATCH 37/40] znetconf: unknown driver for qeth + +Description: znetconf: --drive|-d option returning "unknown driver" for qeth +Symptom: qeth classified as unknown if specified for -d +Problem: bash reg. expression interpretation changed in new bash versions +Solution: used backward and "forward" compatible expression +--- + zconf/znetconf | 3 ++- + 1 files changed, 2 insertions(+), 1 deletions(-) + +diff --git a/zconf/znetconf b/zconf/znetconf +index 873124a..e1b48b3 100755 +--- a/zconf/znetconf ++++ b/zconf/znetconf +@@ -1031,7 +1031,8 @@ function is_shortccwdevbusid_list() + function is_supported_driver() + { + local DRIVER="$1" +- [[ "$DRIVER" =~ "^(qeth|lcs|ctc|ctcm)$" ]] ++ local DRVEXPR='^(qeth|lcs|ctc|ctcm)$' ++ [[ "$DRIVER" =~ $DRVEXPR ]] + case $? in + 0) + return 0 +-- +1.6.6.1 + diff --git a/0038-cpuplugd-fix-stack-overflow.patch b/0038-cpuplugd-fix-stack-overflow.patch new file mode 100644 index 0000000..58084eb --- /dev/null +++ b/0038-cpuplugd-fix-stack-overflow.patch @@ -0,0 +1,90 @@ +From b0192c18160e5ea35889794895becab99890bca3 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Dan=20Hor=C3=A1k?= +Date: Tue, 22 Jun 2010 13:27:27 +0200 +Subject: [PATCH 38/40] cpuplugd: fix stack overflow + +Description: cpuplugd: fix stack overwrite +Symptom: cpuplugd will terminate with "stack smashing" error on systems + with more than 30 CPUs. +Problem: NULL termination of a read buffer will write beyond the buffer + if a previous read() filled out the whole buffer. +Solution: Only read max. buffer size - 1 bytes. +--- + cpuplugd/daemon.c | 2 +- + cpuplugd/main.c | 1 + + cpuplugd/mem.c | 4 ++-- + cpuplugd/vmstat.c | 4 ++-- + 4 files changed, 6 insertions(+), 5 deletions(-) + +diff --git a/cpuplugd/daemon.c b/cpuplugd/daemon.c +index f1af263..391acba 100644 +--- a/cpuplugd/daemon.c ++++ b/cpuplugd/daemon.c +@@ -287,7 +287,7 @@ int check_lpar() + , strerror(errno)); + clean_up(); + } +- bytes_read = fread(buffer, 1, sizeof(buffer), filp); ++ bytes_read = fread(buffer, 1, sizeof(buffer) - 1, filp); + if (bytes_read == 0) { + fprintf(stderr, "Reading /proc/cpuinfo failed:"); + fprintf(stderr, "%s\n", strerror(errno)); +diff --git a/cpuplugd/main.c b/cpuplugd/main.c +index c280342..f8f9dfa 100644 +--- a/cpuplugd/main.c ++++ b/cpuplugd/main.c +@@ -347,6 +347,7 @@ int main(int argc, char *argv[]) + syslog(LOG_INFO, "Out of memory: Aborting.\n"); + clean_up(); + } ++ memset(vs, 0, sizeof(struct vmstat)); + /* + * If the thread routine requires multiple arguments, they must be + * passed bundled up in an array or a structure +diff --git a/cpuplugd/mem.c b/cpuplugd/mem.c +index 8d5f05f..13f902d 100644 +--- a/cpuplugd/mem.c ++++ b/cpuplugd/mem.c +@@ -70,7 +70,7 @@ int get_vmstats(struct vm_info *v) + rc = -1; + goto out; + } +- bytes_read = fread(buffer, 1, sizeof(buffer), filp); ++ bytes_read = fread(buffer, 1, sizeof(buffer) - 1, filp); + /* + * Bail if read failed or the buffer isn't big enough + */ +@@ -314,7 +314,7 @@ int get_free_memsize() + ":%s\n", strerror(errno)); + clean_up(); + } +- bytes_read = fread(buffer, 1, sizeof(buffer), filp); ++ bytes_read = fread(buffer, 1, sizeof(buffer) - 1, filp); + /* + * Bail if read failed or the buffer isn't big enough + */ +diff --git a/cpuplugd/vmstat.c b/cpuplugd/vmstat.c +index 8428cce..d5a0036 100644 +--- a/cpuplugd/vmstat.c ++++ b/cpuplugd/vmstat.c +@@ -76,7 +76,7 @@ void get_cpu_stats(struct cpustat *s) + syslog(LOG_ERR, "Can not open /proc/stat" + ":%s\n", strerror(errno)); + } else { +- bytes_read = fread(buffer, 1, sizeof(buffer), filp); ++ bytes_read = fread(buffer, 1, sizeof(buffer) - 1, filp); + fclose(filp); + /* + * Bail if read failed or the buffer isn't big enough +@@ -118,7 +118,7 @@ void get_cpu_stats(struct cpustat *s) + * softirq: servicing softirqs + * steal: the cpu time spent in involuntary wait + */ +- sscanf(match, "cpu %du %du %du %du %du %du %du %du", ++ sscanf(match, "cpu %d %d %d %d %d %d %d %d", + &s->cpu_user, + &s->cpu_nice, + &s->cpu_sys, +-- +1.6.6.1 + diff --git a/0039-cpuplugd-fix-cmm-limits-checks.patch b/0039-cpuplugd-fix-cmm-limits-checks.patch new file mode 100644 index 0000000..d620813 --- /dev/null +++ b/0039-cpuplugd-fix-cmm-limits-checks.patch @@ -0,0 +1,106 @@ +From 664177c0fe57f671ad0d1eeed18374d77233d4b4 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Dan=20Hor=C3=A1k?= +Date: Tue, 22 Jun 2010 13:28:45 +0200 +Subject: [PATCH 39/40] cpuplugd: fix cmm limits checks + +Description: cpuplugd: fix cmm_min/max limit checks. +Symptom: The cmm_min and cmm_max limits are not enforced correctly + when starting the daemon without the -V option, or when + cmm_pages is set manually below or above the limits. +Problem: Part of the cmm_min/max checks is only done when -V option + is specified. Values above/below the max/min limits are also + not identified correctly. +Solution: Make checks independent from -V option and check for cmm_pages + values beyond the limit. +--- + cpuplugd/main.c | 54 +++++++++++++++--------------------------------------- + 1 files changed, 15 insertions(+), 39 deletions(-) + +diff --git a/cpuplugd/main.c b/cpuplugd/main.c +index f8f9dfa..3738a5f 100644 +--- a/cpuplugd/main.c ++++ b/cpuplugd/main.c +@@ -226,26 +226,6 @@ void eval_mem_rules(struct config *cfg) + } + /* Evaluate the memunplug rule. */ + if (cfg->memunplug && eval_term(cfg->memunplug, &symbols)) { +- /* +- * case where cmm has asynchronously increased +- * cmm_pages after cpuplugd reset it to cmm_max +- * at cpuplugd startup. +- * +- */ +- if (cmmpages_size > cfg->cmm_max) { +- if (debug) { +- if (foreground == 1) +- printf("Found cmm_pages above Limit. " +- "Resetting value to %d\n" +- , cfg->cmm_max); +- if (foreground == 0) +- syslog(LOG_INFO, "Found cmm_pages above" +- "Limit. Resetting value to %d\n" +- , cfg->cmm_max); +- } +- set_cmm_pages(cfg->cmm_max); +- return; +- } + /* check memory limit */ + if (cmmpages_size + cfg->cmm_inc > cfg->cmm_max) { + if (debug) { +@@ -256,18 +236,16 @@ void eval_mem_rules(struct config *cfg) + syslog(LOG_INFO, "maximum memory" + " limit is reached\n"); + } +- if (cmmpages_size < cfg->cmm_max) { +- /* if the next increment would exceed +- * the maximum we advance to the +- * maximum +- */ ++ /* if the next increment would exceed ++ * the maximum we advance to the ++ * maximum ++ */ ++ if (cmmpages_size != cfg->cmm_max) + set_cmm_pages(cfg->cmm_max); +- return; +- } +- } else { +- memunplug(cfg->cmm_inc); + return; + } ++ memunplug(cfg->cmm_inc); ++ return; + } + /* Evaluate the memplug rule. */ + if (cfg->memplug && eval_term(cfg->memplug, &symbols)) { +@@ -280,19 +258,17 @@ void eval_mem_rules(struct config *cfg) + if (foreground == 0) + syslog(LOG_INFO, "minimum memory" + " limit is reached\n"); +- if (cmmpages_size > cfg->cmm_min) { +- /* if the next increment would exceed +- * the minimum we advance to the +- * minimum +- */ +- set_cmm_pages(cfg->cmm_min); +- return; +- } + } +- } else { +- memplug(cfg->cmm_inc); ++ /* if the next increment would exceed ++ * the minimum we advance to the ++ * minimum ++ */ ++ if (cmmpages_size != cfg->cmm_min) ++ set_cmm_pages(cfg->cmm_min); + return; + } ++ memplug(cfg->cmm_inc); ++ return; + } + } + +-- +1.6.6.1 + diff --git a/0040-cpuplugd-set-cpu_min-to-1-by-default.patch b/0040-cpuplugd-set-cpu_min-to-1-by-default.patch new file mode 100644 index 0000000..572f9e4 --- /dev/null +++ b/0040-cpuplugd-set-cpu_min-to-1-by-default.patch @@ -0,0 +1,39 @@ +From 4a2b6aa7b2a873be78c27d2abe010cd7e73d9640 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Dan=20Hor=C3=A1k?= +Date: Tue, 22 Jun 2010 13:33:36 +0200 +Subject: [PATCH 40/40] cpuplugd: set cpu_min to 1 by default + +Description: cpuplugd: set cpu_min to 1 by default. +Symptom: With a cpu_min default value of 2, the "cpu ping pong" effect + may still be visible with low system load, i.e. expensive cpu + signaling may occur if the workload is spread on 2 under-worked + cpus. +Problem: The default value for cpu_min is 2. +Solution: Set the default value of cpu_min to 1. +--- + etc/sysconfig/cpuplugd | 6 ++---- + 1 files changed, 2 insertions(+), 4 deletions(-) + +diff --git a/etc/sysconfig/cpuplugd b/etc/sysconfig/cpuplugd +index c807232..efafa20 100644 +--- a/etc/sysconfig/cpuplugd ++++ b/etc/sysconfig/cpuplugd +@@ -6,13 +6,11 @@ + # It does not contain shell environment variables. + + ## Type: integer +-## Default: 2 ++## Default: 1 + # + # The minimum number of cpus. +-# This means in this example, that every time at least two cpus +-# will be available + # +-CPU_MIN="2" ++CPU_MIN="1" + + ## Type: integer + ## Default: 2 +-- +1.6.6.1 + diff --git a/0041-fix-dates-option-on-zfcpdbf.patch b/0041-fix-dates-option-on-zfcpdbf.patch new file mode 100644 index 0000000..1f39594 --- /dev/null +++ b/0041-fix-dates-option-on-zfcpdbf.patch @@ -0,0 +1,40 @@ +From e30dc240e7417b83957507f1da6b34c31f18afb5 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Dan=20Hor=C3=A1k?= +Date: Tue, 29 Jun 2010 22:23:50 +0200 +Subject: [PATCH] fix --dates option on zfcpdbf + +Description: zfcpdbf: Fix --dates option +Symptom: Running zfcpdbf with the option --dates returns "Unknown + option: dates". +Problem: The code expects --date, not the documented --dates option. +Solution: Change zfcpdbf to expect --dates, as documented in the + man page and in the usage information. +--- + scripts/zfcpdbf | 4 ++-- + 1 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/scripts/zfcpdbf b/scripts/zfcpdbf +index 3693d71..0b75c43 100755 +--- a/scripts/zfcpdbf ++++ b/scripts/zfcpdbf +@@ -139,7 +139,7 @@ GetOptions( + 'V|verbose' => \$OPT_VERBOSE, + 'h|help' => \$OPT_HELP, + 'v|version' => \$OPT_VERSION, +- 'D|date=s' => \$OPT_DATE, ++ 'D|dates=s' => \$OPT_DATE, + 's|singleline' => \$OPT_SINGLELINE + ) or print_usage(); + +@@ -555,7 +555,7 @@ sub print_san { + + # + # Converts the Unix time to localtime an returns it +-# depending on the --date option. ++# depending on the --dates option. + # + # \param UNIX Timestamp to convert + # \return Formated Localtime +-- +1.6.6.1 + diff --git a/0042-lsluns-uninitialized-value-on-adapter-offline.patch b/0042-lsluns-uninitialized-value-on-adapter-offline.patch new file mode 100644 index 0000000..080912f --- /dev/null +++ b/0042-lsluns-uninitialized-value-on-adapter-offline.patch @@ -0,0 +1,36 @@ +From 76e25ac419c3f23c0cdbfcd2db64bf196d806994 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Dan=20Hor=C3=A1k?= +Date: Tue, 13 Jul 2010 15:27:26 +0200 +Subject: [PATCH 42/43] lsluns: uninitialized value on adapter offline + +Description: lsluns: uninitialized value on adapter offline. +Symptom: An error message is presented stating that some values + are not initialized while an operation is due. +Problem: The program execution is not reflection the offline adapter + status. +Solution: Account for offlined adapter status and show an appropriate + message. +--- + zconf/lsluns | 6 +++++- + 1 files changed, 5 insertions(+), 1 deletions(-) + +diff --git a/zconf/lsluns b/zconf/lsluns +index 9227f64..769b846 100755 +--- a/zconf/lsluns ++++ b/zconf/lsluns +@@ -211,7 +211,11 @@ sub show_attached_lun_info + print "\tport = $p\n"; + foreach my $l (sort keys %{$lun_hash{$a}{$p}}) { + my $sg_dev = "/dev/".$lun_hash{$a}{$p}{$l}; +- my $inq = `sg_inq -r $sg_dev`; ++ my $inq = `sg_inq -r $sg_dev 2>/dev/null`; ++ if (!$inq) { ++ print("\t\tlun = $l [offline]\n"); ++ next; ++ } + (my $vend = substr($inq, 0x8, 0x8)) =~ s/\s*//g; + (my $mod = substr($inq, 0x10, 0x10)) =~ s/\s*//g; + my $type = ord(substr($inq, 0x0, 0x1)); +-- +1.7.1.1 + diff --git a/0043-zfcpdbf-Fix-Use-of-uninitialized-value-and-output-is.patch b/0043-zfcpdbf-Fix-Use-of-uninitialized-value-and-output-is.patch new file mode 100644 index 0000000..b88a4e0 --- /dev/null +++ b/0043-zfcpdbf-Fix-Use-of-uninitialized-value-and-output-is.patch @@ -0,0 +1,78 @@ +From e1f4564972a7d280badf24568d56c063b6ce0ca7 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Dan=20Hor=C3=A1k?= +Date: Tue, 13 Jul 2010 15:29:42 +0200 +Subject: [PATCH 43/43] zfcpdbf: Fix "Use of uninitialized value" and output issues + +Description: zfcpdbf: Fix "Use of uninitialized value" and output issues +Symptom: zfcpdbf outputs the error "Use of uninitialized value". +Problem: zfcpdbf tried to output attributes for "status read" + commands that do not exist. It also tried to output the + attribute port_handle for ELS requests that does not exist. +Solution: Exit early for "status read" requests, there is no additional + FSF command data. Remove output of LS field for ELS requests. + It was wrong, and newer dbf does not have this redundant field. + For consistency, add devno and timestamp to output of "status + read". +--- + scripts/zfcpdbf | 20 +++++++++++++------- + 1 files changed, 13 insertions(+), 7 deletions(-) + +diff --git a/scripts/zfcpdbf b/scripts/zfcpdbf +index 0b75c43..f82044d 100755 +--- a/scripts/zfcpdbf ++++ b/scripts/zfcpdbf +@@ -375,11 +375,13 @@ sub print_hba { + } + elsif(defined($hba_hash{'tag2'}) && + $hba_hash{'tag2'} eq "dism") { +- print "status read request dissmissed"; ++ print "$adapter $hba_hash{'timestamp'} " . ++ "status read request dismissed"; + } + elsif(defined($hba_hash{'tag2'}) && + $hba_hash{'tag2'} eq "fail") { +- print "status read request failed"; ++ print "$adapter $hba_hash{'timestamp'} " . ++ "status read request failed"; + } + } + elsif(defined($hba_hash{'tag'}) && $hba_hash{'tag'} eq "resp") { +@@ -398,9 +400,14 @@ sub print_hba { + } + } + else { +- next; ++ return; + } +- ++ ++ if ($hba_hash{'tag'} eq 'stat') { ++ print "\n"; ++ return; ++ } ++ + if($OPT_VERBOSE) { + print "protocol status qualifier=" . + "'$hba_hash{'fsf_prot_status_qual'}'" . $endl . +@@ -410,7 +417,7 @@ sub print_hba { + "'$hba_hash{'fsf_req_status'}'" . $endl . + "SBAL=$hba_hash{'sbal_first'}/$hba_hash{ + 'sbal_last'}/$hba_hash{'sbal_response'} " . +- "(fist/last/response)" . $endl; ++ "(first/last/response)" . $endl; + } + + if($hba_hash{'fsf_command'} eq '0x00000002') { +@@ -432,8 +439,7 @@ sub print_hba { + " LUN handle=$hba_hash{'lun_handle'}"; + } + elsif($hba_hash{'fsf_command'} eq '0x0000000b' ) { +- print "D_ID=$hba_hash{'d_id'} LS " . +- "code=$hba_hash{'port_handle'}"; ++ print "D_ID=$hba_hash{'d_id'}"; + } + print"\n"; + } +-- +1.7.1.1 + diff --git a/1000-ziomon-linker.patch b/1000-ziomon-linker.patch new file mode 100644 index 0000000..8405d47 --- /dev/null +++ b/1000-ziomon-linker.patch @@ -0,0 +1,12 @@ +diff -up s390-tools-1.8.2/ziomon/Makefile.linker s390-tools-1.8.2/ziomon/Makefile +--- s390-tools-1.8.2/ziomon/Makefile.linker 2010-06-10 08:54:55.000000000 +0200 ++++ s390-tools-1.8.2/ziomon/Makefile 2010-06-10 08:55:48.000000000 +0200 +@@ -21,7 +21,7 @@ ziomon_util: ziomon_util_main.o ziomon_t + ziomon_zfcpdd_main.o: ziomon_zfcpdd.c ziomon_zfcpdd.h + $(CC) -DWITH_MAIN $(CFLAGS) $(CPPFLAGS) -c $< -o $@ + ziomon_zfcpdd: ziomon_zfcpdd_main.o ziomon_tools.o +- $(LINK) $^ -o $@ -lm -lrt ++ $(LINK) $^ -o $@ -lm -lrt -lpthread + + ziorep_traffic: ziorep_traffic.o ziorep_framer.o ziorep_frameset.o \ + ziorep_printers.o ziomon_dacc.o ziomon_util.o \ diff --git a/ccw.udev b/ccw.udev new file mode 100644 index 0000000..2c6a805 --- /dev/null +++ b/ccw.udev @@ -0,0 +1,12 @@ +ACTION!="add|change", GOTO="ccw_end" +SUBSYSTEM!="ccw", GOTO="ccw_end" +SYSFS{cutype}=="1731/01", RUN+="ccw_init" +SYSFS{cutype}=="1731/05", RUN+="ccw_init" +SYSFS{cutype}=="1731/06", RUN+="ccw_init" +SYSFS{cutype}=="3088/01", RUN+="ccw_init" +SYSFS{cutype}=="3088/08", RUN+="ccw_init" +SYSFS{cutype}=="3088/60", RUN+="ccw_init" +SYSFS{cutype}=="3088/61", RUN+="ccw_init" +SYSFS{cutype}=="3088/1E", RUN+="ccw_init" +SYSFS{cutype}=="3088/1F", RUN+="ccw_init" +LABEL="ccw_end" diff --git a/ccw_init b/ccw_init new file mode 100644 index 0000000..8eabbe2 --- /dev/null +++ b/ccw_init @@ -0,0 +1,176 @@ +#! /bin/sh + +[ -z "$DEVPATH" ] && exit 0 +[ "$SUBSYSTEM" != "ccw" ] && exit 0 + +[ -e /etc/ccw.conf ] && MODE="dracut" || MODE="normal" +OLD_IFS="$IFS" + +get_config_line_by_subchannel() +{ + local CHANNEL + CHANNEL="$1" + while read line; do + IFS="," + set $line + IFS="$OLD_IFS" + for i in $@; do + if [ "$CHANNEL" = "$i" ]; then + echo $line + return 0 + fi + done + done < /etc/ccw.conf + return 1 +} + +CHANNEL=${DEVPATH##*/} + +if [ $MODE = "dracut" ]; then + CONFIG_LINE=$(get_config_line_by_subchannel $CHANNEL) + + [ $? -ne 0 -o -z "$CONFIG_LINE" ] && break + + IFS="," + set $CONFIG_LINE + IFS="$OLD_IFS" + NETTYPE=$1 + shift + SUBCHANNELS="$1" + OPTIONS="" + shift + while [ $# -gt 0 ]; do + case $1 in + *=*) OPTIONS="$OPTIONS $1";; + [0-9]*) SUBCHANNELS="$SUBCHANNELS,$1";; + esac + shift + done +elif [ $MODE = "normal" ]; then + NOLOCALE="yes" + + . /etc/sysconfig/network-scripts/network-functions + + CONFIG_FILE=$(get_config_by_subchannel $CHANNEL) + + if [ -n "$CONFIG_FILE" ]; then + . $CONFIG_FILE + else + exit 1 + fi +else + echo "Unknown mode=$MODE" + exit 1 +fi + + +# now we have extracted these variables from the config files: +# SUBCHANNELS +# OPTIONS + +# put LAYER2 option into its own variable +set $OPTIONS +OPTIONS="" +while [ $# -gt 0 ]; do + case $1 in + layer2=*) LAYER2=${1##layer2=};; + *=*) OPTIONS="$OPTIONS $1";; + esac + shift +done + +# translate variables from the interface config files to OPTIONS +if [ -n "$PORTNAME" ]; then + if [ "$NETTYPE" = "lcs" ]; then + OPTIONS="$OPTIONS portno=$PORTNAME" + else + OPTIONS="$OPTIONS portname=$PORTNAME" + fi +fi +if [ "$NETTYPE" = "ctc" -a -n "$CTCPROT" ]; then + OPTIONS="$OPTIONS protocol=$CTCPROTO" +fi + +# SUBCHANNELS is only set on mainframe ccwgroup devices +[ -z "$SUBCHANNELS" -o -z "$NETTYPE" ] && exit 0 +if [ "$NETTYPE" = "ctc" ]; then + DIR="/sys/bus/ccwgroup/drivers/ctcm" +else + DIR="/sys/bus/ccwgroup/drivers/$NETTYPE" +fi + +i=0 +while [ $i -lt 20 ]; do + [ -e $DIR ] && break + sleep 0.1 + i=$(($i+1)) +done + +# driver missing or not loaded +[ ! -e $DIR ] && exit 0 + +IFS="," +set $SUBCHANNELS +IFS="$OLD_IFS" +CHANNEL1=$1 +CHANNEL2=$2 +SYSDIR="$DIR/$CHANNEL1" + +[ -e $SYSDIR ] && exit 0 + +# check if the interface is already online +if [ -e $SYSDIR/online ]; then + read on <$SYSDIR/online + [ "$on" = "1" ] && exit 0 +fi + +DRIVER=$(readlink $DEVPATH/driver) +DRIVER=${DRIVER##*/} +if [ "$DRIVER" = "lcs" -a "$NETTYPE" = "ctc" ]; then + echo "$CHANNEL" > /sys/bus/ccw/drivers/lcs/unbind + echo "$CHANNEL" > /sys/bus/ccw/drivers/ctcm/bind + echo "$CHANNEL2" > /sys/bus/ccw/drivers/lcs/unbind + echo "$CHANNEL2" > /sys/bus/ccw/drivers/ctcm/bind +fi +if [ "$DRIVER" = "ctcm" -a "$NETTYPE" = "lcs" ]; then + echo "$CHANNEL" > /sys/bus/ccw/drivers/ctcm/unbind + echo "$CHANNEL" > /sys/bus/ccw/drivers/lcs/bind + echo "$CHANNEL2" > /sys/bus/ccw/drivers/ctcm/unbind + echo "$CHANNEL2" > /sys/bus/ccw/drivers/lcs/bind +fi + +if [ ! -e $SYSDIR ]; then + echo "$SUBCHANNELS" > $DIR/group + i=0 + while [ $i -lt 20 ]; do + [ -e $SYSDIR ] && break + sleep 0.1 + i=$(($i+1)) + done + + [ ! -e $SYSDIR ] && exit 1 +fi + +# check if the interface is already online +if [ -e $SYSDIR/online ]; then + read on <$SYSDIR/online + [ "$on" = "1" ] && exit 0 +fi + +# first set layer2, other options may depend on it +[ -n "$LAYER2" ] && echo $LAYER2 > $SYSDIR/layer2 + +if [ -n "$OPTIONS" ]; then + for i in $OPTIONS; do + OPT=${i%%=*} + VAL=${i##*=} + if [ -e "$SYSDIR/$OPT" ]; then + echo "$VAL" > "$SYSDIR/$OPT" || \ + echo "Could not set value \"$VAL\" for OPTION \"$OPT\" with SUBCHANNELS \"$SUBCHANNELS\"" + else + echo "OPTION \"$OPT\" does not exist for SUBCHANNELS \"$SUBCHANNELS\"" + fi + done +fi + +[ -e $SYSDIR/online ] && echo 1 > $SYSDIR/online diff --git a/cmsfs-1.1.8-kernel26.patch b/cmsfs-1.1.8-kernel26.patch new file mode 100644 index 0000000..04b0e0d --- /dev/null +++ b/cmsfs-1.1.8-kernel26.patch @@ -0,0 +1,12 @@ +diff -urN cmsfs-1.1.8/cmsfssed.sh cmsfs-1.1.8_/cmsfssed.sh +--- cmsfs-1.1.8/cmsfssed.sh 2003-02-28 17:52:59.000000000 -0500 ++++ cmsfs-1.1.8_/cmsfssed.sh 2004-05-28 16:36:22.000000000 -0400 +@@ -85,7 +85,7 @@ + DRIVER_SOURCE="cmsfs22x.c" + MODULES_DIRECTORY="/lib/modules/`uname -r`/fs" + ;; +- 2.4*|2.5*) ++ 2.4*|2.5*|2.6*) + LINUX_RELEASE="2.4" + # ln -s cmsfs24x.c cmsfsvfs.c + INCLUDES="-I/lib/modules/`uname -r`/build/include" diff --git a/cmsfs-1.1.8-warnings.patch b/cmsfs-1.1.8-warnings.patch new file mode 100644 index 0000000..cb1501d --- /dev/null +++ b/cmsfs-1.1.8-warnings.patch @@ -0,0 +1,11 @@ +--- cmsfs-1.1.8/cmsfsvol.c.warnings 2003-07-18 01:38:57.000000000 +0200 ++++ cmsfs-1.1.8/cmsfsvol.c 2005-09-06 16:57:15.000000000 +0200 +@@ -52,7 +52,7 @@ + + /* print a header; looks like CMS */ + (void) printf("LABEL VDEV M STAT CYL TYPE \ +-BLKSZ FILES BLKS USED-(%) BLKS LEFT BLK TOTAL\n"); ++BLKSZ FILES BLKS USED-(%%) BLKS LEFT BLK TOTAL\n"); + + for ( ; i < argc ; i++) + { diff --git a/cpi.initd b/cpi.initd new file mode 100644 index 0000000..80977fb --- /dev/null +++ b/cpi.initd @@ -0,0 +1,130 @@ +#!/bin/sh +# +# Copyright 2009 Red Hat, Inc. +# License: GPLv2 +# Author: Dan Horák +# +# cpi Set Control Program Identification on IBM zSeries +# +# chkconfig: 12345 80 20 +# description: Set Control Program Identification on IBM zSeries \ +# that's reported on a Linux LPAR + +### BEGIN INIT INFO +# Provides: cpi +# Required-Start: +# Required-Stop: +# Should-Start: +# Should-Stop: +# Default-Start: 1 2 3 4 5 +# Default-Stop: 0 6 +# Short-Description: Set control program identification on IBM zSeries +# Description: Set Control Program Identification on IBM zSeries \ +# that's reported on a Linux LPAR +### END INIT INFO + +# Source function library. +. /etc/init.d/functions + +prog="cpi" + +[ -e /etc/sysconfig/$prog ] && . /etc/sysconfig/$prog + +cpipath=/sys/firmware/cpi + +start() { + [ `id -u` -eq 0 ] || return 4 + + echo -n $"Starting $prog: " + + if [ -d $cpipath ]; then + retval=0 + echo LINUX > $cpipath/system_type 2> /dev/null || retval=1 + [ $retval -eq 0 ] && echo "$SYSTEM_NAME" > $cpipath/system_name 2> /dev/null || retval=1 + [ $retval -eq 0 ] && echo "$SYSPLEX_NAME" > $cpipath/sysplex_name 2> /dev/null || retval=1 + level_maj=`uname -r | cut -d '-' -f 1 | cut -d '.' -f 1` + level_min=`uname -r | cut -d '-' -f 1 | cut -d '.' -f 2` + level_mic=`uname -r | cut -d '-' -f 1 | cut -d '.' -f 3` + level=`printf '%02x%02x%02x' $level_maj $level_min $level_mic` + [ $retval -eq 0 ] && echo $level > $cpipath/system_level 2> /dev/null || retval=1 + + [ $retval -eq 0 ] && echo 1 > $cpipath/set 2> /dev/null || retval=1 + else + retval=1 + fi + + [ $retval -eq 0 ] && success || failure + echo + return $retval +} + +stop() { + echo -n $"Stopping $prog: " + + # nothing to do + success + echo + return 0 +} + +restart() { + stop + start +} + +reload() { + restart +} + +force_reload() { + restart +} + +rh_status() { + if [ -d $cpipath ]; then + echo -n "System type: "; cat $cpipath/system_type + echo -n "System level: "; cat $cpipath/system_level + echo -n "System name: "; cat $cpipath/system_name + echo -n "Sysplex name: "; cat $cpipath/sysplex_name + retval=0 + else + echo "Control Program Identification system interface doesn't exist." + retval=1 + fi + return $retval +} + +rh_status_q() { + rh_status >/dev/null 2>&1 +} + + +case "$1" in + start) + $1 + ;; + stop) + $1 + ;; + restart) + $1 + ;; + reload) + rh_status_q || exit 7 + $1 + ;; + force-reload) + force_reload + ;; + status) + rh_status + ;; + condrestart|try-restart) + rh_status_q || exit 0 + restart + ;; + *) + echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload}" + exit 2 +esac +exit $? diff --git a/cpi.sysconfig b/cpi.sysconfig new file mode 100644 index 0000000..22f7bc3 --- /dev/null +++ b/cpi.sysconfig @@ -0,0 +1,5 @@ +# Define a system name (8 chars maximum) +SYSTEM_NAME= + +# Define a sysplex name (8 chars maximum) +SYSPLEX_NAME= diff --git a/cpuplugd.initd b/cpuplugd.initd new file mode 100644 index 0000000..4e6ad9f --- /dev/null +++ b/cpuplugd.initd @@ -0,0 +1,114 @@ +#! /bin/sh +# +# chkconfig: 2345 90 10 +# description: Start the cpu hotplug daemon for Linux on System z +# processname: cpuplugd +# config: /etc/sysconfig/cpuplugd +# pidfile: /var/run/cpuplugd.pid + +### BEGIN INIT INFO +# Provides: cpuplugd +# Required-Start: $local_fs $remote_fs +# Required-Stop: $local_fs $remote_fs +# Should-Start: +# Should-Stop: +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: Start the cpu hotplug daemon for Linux on System z +# Description: Starts the cpuplugd. It uses the configuration +# file /etc/sysconfig/cpuplugd +### END INIT INFO + +# Source function library. +. /etc/rc.d/init.d/functions + +exec="/usr/sbin/cpuplugd" +prog="cpuplugd" +config="/etc/sysconfig/cpuplugd" + +lockfile=/var/lock/subsys/$prog + +start() { + [ -x $exec ] || exit 5 + [ -f $config ] || exit 6 + [ `id -u` -eq 0 ] || exit 4 + echo -n $"Starting $prog: " + daemon $exec -c $config + retval=$? + echo + [ $retval -eq 0 ] && touch $lockfile + return $retval +} + +stop() { + [ `id -u` -eq 0 ] || exit 4 + echo -n $"Stopping $prog: " + killproc $exec + retval=$? + echo + [ $retval -eq 0 ] && rm -f $lockfile + return $retval +} + +restart() { + stop + # + # We have to wait 2-3 seconds here. When the daemon is stopped it takes + # the time we sleep to reactivate cpus. If we restart to fast and + # cpuplugd wasn't able to restore some settings we may get a undesired + # online cpu count after cpuplugd shutdown + # + sleep 4 + start +} + +reload() { + restart +} + +force_reload() { + restart +} + +rh_status() { + # run checks to determine if the service is running or use generic status +# status -l $prog $exec + status $exec +} + +rh_status_q() { + rh_status >/dev/null 2>&1 +} + + +case "$1" in + start) + rh_status_q && exit 0 + $1 + ;; + stop) + rh_status_q || exit 0 + $1 + ;; + restart) + $1 + ;; + reload) + rh_status_q || exit 7 + $1 + ;; + force-reload) + force_reload + ;; + status) + rh_status + ;; + condrestart|try-restart) + rh_status_q || exit 0 + restart + ;; + *) + echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload}" + exit 2 +esac +exit $? diff --git a/dasd.udev b/dasd.udev new file mode 100644 index 0000000..5364935 --- /dev/null +++ b/dasd.udev @@ -0,0 +1,16 @@ +ACTION=="add", SUBSYSTEM=="drivers", KERNEL=="dasd-eckd", RUN+="/sbin/dasdconf.sh" +ACTION=="add", SUBSYSTEM=="drivers", KERNEL=="dasd-fba", RUN+="/sbin/dasdconf.sh" + +# This list should be autogenerated with "modinfo dasd_{eckd,fba}_mod" +ACTION=="add", SUBSYSTEM=="ccw", ATTR{modalias}=="ccw:t1750m*dt3380dm*", RUN+="/sbin/dasdconf.sh" +ACTION=="add", SUBSYSTEM=="ccw", ATTR{modalias}=="ccw:t1750m*dt3390dm*", RUN+="/sbin/dasdconf.sh" +ACTION=="add", SUBSYSTEM=="ccw", ATTR{modalias}=="ccw:t2107m*dt3380dm*", RUN+="/sbin/dasdconf.sh" +ACTION=="add", SUBSYSTEM=="ccw", ATTR{modalias}=="ccw:t2107m*dt3390dm*", RUN+="/sbin/dasdconf.sh" +ACTION=="add", SUBSYSTEM=="ccw", ATTR{modalias}=="ccw:t9343m*dt9345dm*", RUN+="/sbin/dasdconf.sh" +ACTION=="add", SUBSYSTEM=="ccw", ATTR{modalias}=="ccw:t2105m*dt3380dm*", RUN+="/sbin/dasdconf.sh" +ACTION=="add", SUBSYSTEM=="ccw", ATTR{modalias}=="ccw:t3990m*dt3380dm*", RUN+="/sbin/dasdconf.sh" +ACTION=="add", SUBSYSTEM=="ccw", ATTR{modalias}=="ccw:t3880m*dt3390dm*", RUN+="/sbin/dasdconf.sh" +ACTION=="add", SUBSYSTEM=="ccw", ATTR{modalias}=="ccw:t2105m*dt3390dm*", RUN+="/sbin/dasdconf.sh" +ACTION=="add", SUBSYSTEM=="ccw", ATTR{modalias}=="ccw:t3990m*dt3390dm*", RUN+="/sbin/dasdconf.sh" +ACTION=="add", SUBSYSTEM=="ccw", ATTR{modalias}=="ccw:t3880m*dt3370dm*", RUN+="/sbin/dasdconf.sh" +ACTION=="add", SUBSYSTEM=="ccw", ATTR{modalias}=="ccw:t6310m*dt9336dm*", RUN+="/sbin/dasdconf.sh" diff --git a/dasdconf.sh b/dasdconf.sh new file mode 100644 index 0000000..2be5276 --- /dev/null +++ b/dasdconf.sh @@ -0,0 +1,94 @@ +#!/bin/sh + +# config file syntax: +# deviceno sysfs_opts... +# +# Examples: +# 0.0.0203 readonly=1 failfast=1 +# 0.0.0204 +# 0.0.0205 erplog=1 + +[ -z "$DEVPATH" ] && exit 0 +[ "$ACTION" != "add" ] && exit 0 + +CHANNEL=${DEVPATH##*/} + +CONFIG=/etc/dasd.conf +PATH=/sbin:/bin +export PATH + +warn() { + [ -e /dev/kmsg ] && echo "<4>dasdconf.sh Warning: $@" > /dev/kmsg + echo "dasdconf.sh Warning: $@" >&2 +} + +if [ -f "$CONFIG" ]; then + if [ ! -d /sys/bus/ccw/drivers/dasd-eckd ] && [ ! -d /sys/bus/ccw/drivers/dasd-fba ]; then + #warn "No dasd-eckd or dasd-eckd loaded" + exit 0 + fi + sed 'y/ABCDEF/abcdef/' < $CONFIG | while read line; do + case $line in + \#*) ;; + *) + [ -z "$line" ] && continue + set $line + + # if we are in single add mode, only add the new CHANNEL + [ "$SUBSYSTEM" = "ccw" ] && [ "$1" != "$CHANNEL" ] && continue + + DEVICE=$1 + SYSFSPATH= + + if [ -r "/sys/bus/ccw/drivers/dasd-eckd/$DEVICE" ]; then + SYSFSPATH="/sys/bus/ccw/drivers/dasd-eckd/$DEVICE" + elif [ -r "/sys/bus/ccw/drivers/dasd-fba/$DEVICE" ]; then + SYSFSPATH="/sys/bus/ccw/drivers/dasd-fba/$DEVICE" + else + # if we are in single add mode, this is a failure! + [ "$SUBSYSTEM" = "ccw" ] && warn "Could not find $DEVICE in sysfs" + continue + fi + + # skip already onlined devices + if [ "$(cat $SYSFSPATH/online)" = "1" ]; then + if [ "$SUBSYSTEM" = "ccw" ]; then + # if we are in single add mode, we should not touch the device + warn "$DEVICE is already online, not configuring" + exit 0 + fi + continue + fi + + shift + while [ -n "$1" ]; do + ( + attribute="$1" + IFS="=" + set $attribute + + if [ "$1" = "use_diag" ]; then + # this module better only returns after + # all sysfs entries have the "use_diag" file + modprobe dasd_diag_mod + fi + + if [ -r "$SYSFSPATH/$1" ]; then + echo $2 > $SYSFSPATH/$1 || warn "Could not set $1=$2 for $DEVICE" + else + warn "$1 does not exist for $DEVICE" + fi + ) + shift + done + + # Now, put the device online + echo 1 > $SYSFSPATH/online || echo "Could not activate $DEVICE" + + # if we are in single add mode, we are done + [ "$SUBSYSTEM" = "ccw" ] && exit 0 + ;; + esac + done +fi +exit 0 diff --git a/dead.package b/dead.package deleted file mode 100644 index de91ae3..0000000 --- a/dead.package +++ /dev/null @@ -1 +0,0 @@ -This package was retired due to no active owner on 2011-02-23 diff --git a/device_cio_free b/device_cio_free new file mode 100644 index 0000000..416224b --- /dev/null +++ b/device_cio_free @@ -0,0 +1,305 @@ +#!/bin/sh +# +# Copyright 2009, 2010 Red Hat, Inc. +# License: GPLv2 +# Author: Dan Horák +# +# unblock devices listed in various config files and wait until they are ready +# +# it uses dasd and zfcp config file +# config file syntax: +# deviceno options +# or +# deviceno WWPN FCPLUN +# +# also processes the system ccw config file and network interface configurations +# +# requires: echo, sleep, modprobe, grep, printf, sed. +# +# it is used in +# anaconda +# dracut generated initramfs +# normal system startup driven by upstart +# + +DASDCONFIG=/etc/dasd.conf +ZFCPCONFIG=/etc/zfcp.conf +ZNETCONFIG=/etc/ccw.conf +BLACKLIST=/proc/cio_ignore +VERBOSE= +PATH=/bin:/sbin +DEVICE= # list of devices given on command line +ALL_DEVICES= # list of all unblocked devices +WAITING_TIMEOUT=60 # maximum time to wait for all devices to appear +WAITING_TOTAL=0 # actual time spent waiting for devices + +usage() +{ + echo "Usage: $CMD [-h|--help] [-V|--verbose] [-d|--device ]" + echo " -h|--help print this message" + echo " -V|--verbose be verbose" + echo " -d|--device unblock and wait for specified device" + exit 1 +} + +# accepts single device, comma-separated lists and dash separated ranges and their combinations +# the comma separated list is split so we minimize the effect of unsuccessful freeing +free_device() +{ + local DEV DEV_LIST + + [ -z "$1" ] && return + + DEV_LIST=$(echo "$1" | sed 'y/ABCDEF/abcdef/' | sed 's/,/ /g') + + for DEV in $DEV_LIST; do + [ $VERBOSE ] && echo "Freeing device(s) $DEV" + if ! echo "free $DEV" > $BLACKLIST 2> /dev/null ; then + echo "Error: can't free device(s) $DEV" + else + if [ -z $ALL_DEVICES ]; then + ALL_DEVICES="$DEV" + else + ALL_DEVICES="$ALL_DEVICES,$DEV" + fi + fi + done +} + +# wait until a device appears on the ccw bus +wait_on_single_device() +{ + local DEVICE_ONLINE DEV + + [ -z "$1" ] && return + + DEV="$1" + DEVICE_ONLINE="/sys/bus/ccw/devices/$DEV/online" + + [ $VERBOSE ] && echo "Waiting on device $DEV" + [ -f "$DEVICE_ONLINE" ] && return + + for t in 1 2 3 4 5 + do + if [ $WAITING_TOTAL -ge $WAITING_TIMEOUT ]; then + [ $VERBOSE ] && echo "Waiting timeout of $WAITING_TIMEOUT seconds reached" + break + fi + WAITING_TOTAL=$(($WAITING_TOTAL + $t)) + [ $VERBOSE ] && echo "Waiting additional $t second(s) and $WAITING_TOTAL second(s) in total" + sleep $t + [ -f "$DEVICE_ONLINE" ] && return + done + echo "Error: device $DEV still not ready" +} + +# wait until recently unblocked devices are ready +# at this point we know the content of ALL_DEVICES is syntacticly correct +wait_on_devices() +{ + OLD_IFS=$IFS + IFS="," + set $ALL_DEVICES + for DEV in $* + do + IFS="." + + # get the lower bound for range or get the single device + LOWER=${DEV%%-*} + set $LOWER + if [ $# -eq 1 ]; then + L0=0 + L1=0 + L2=$(printf "%d" "0x$1") + else + L0=$(printf "%d" "0x$1") + L1=$(printf "%d" "0x$2") + L2=$(printf "%d" "0x$3") + fi + + # get the upper bound for range or get the single device + UPPER=${DEV##*-} + set $UPPER + if [ $# -eq 1 ]; then + U0=0 + U1=0 + U2=$(printf "%d" "0x$1") + else + U0=$(printf "%d" "0x$1") + U1=$(printf "%d" "0x$2") + U2=$(printf "%d" "0x$3") + fi + + IFS=$OLD_IFS + + # iterate thru all devices + i=$L0 + while [ $i -le $U0 ]; do + [ $i -eq $L0 ] && LJ=$L1 || LJ=0 + [ $i -eq $U0 ] && UJ=$U1 || UJ=3 + + j=$LJ + while [ $j -le $UJ ]; do + [ $i -eq $L0 -a $j -eq $L1 ] && LK=$L2 || LK=0 + [ $i -eq $U0 -a $j -eq $U1 ] && UK=$U2 || UK=65535 + + k=$LK + while [ $k -le $UK ]; do + wait_on_single_device "$(printf %x.%x.%04x $i $j $k)" + k=$(($k + 1)) + done + j=$(($j + 1)) + done + i=$(($i + 1)) + done + done +} + +process_config_file() +{ + local CONFIG + + [ -z "$1" ] && return + + CONFIG="$1" + if [ -f "$CONFIG" ]; then + while read line; do + case $line in + \#*) ;; + *) + [ -z "$line" ] && continue + set $line + free_device $1 + ;; + esac + done < "$CONFIG" + fi +} + +# check how we were called +CMD=${0##*/} +DIR=${0%/*} +ARGS=$@ +case $CMD in + "dasd_cio_free") + MODE_DASD="yes" + ;; + "zfcp_cio_free") + MODE_ZFCP="yes" + ;; + "znet_cio_free") + MODE_ZNET="yes" + ;; + "device_cio_free") + MODE_DASD="yes" + MODE_ZFCP="yes" + MODE_ZNET="yes" + ;; + *) + echo "Error: unknown alias '$CMD'." + echo "Supported aliases are dasd_cio_free, zfcp_cio_free and znet_cio_free." + exit 1 + ;; +esac + +# process command line options +while [ $# -gt 0 ]; do + case $1 in + -V|--verbose) + VERBOSE=yes + ;; + -h|--help) + usage + ;; + -d|--device) + shift + if [ "$1" ]; then + if [ "$DEVICE" ]; then + DEVICE="$DEVICE,$1" + else + DEVICE=$1 + fi + else + echo "Error: no device given" + usage + fi + ;; + *) + echo "Error: unknown option $1" + usage + ;; + esac + shift +done + +if [ ! -f $BLACKLIST ]; then + echo "Error: $BLACKLIST kernel interface doesn't exist" + exit 2 +fi + +if [ "$DEVICE" ]; then + [ $VERBOSE ] && echo "Freeing specific devices" + free_device $DEVICE + wait_on_devices + exit 0 +fi + +if [ $VERBOSE ]; then + echo -n "Freeing devices:" + [ $MODE_DASD ] && echo -n " dasd" + [ $MODE_ZFCP ] && echo -n " zfcp" + [ $MODE_ZNET ] && echo -n " znet" + echo +fi + +[ $MODE_DASD ] && process_config_file $DASDCONFIG +[ $MODE_ZFCP ] && process_config_file $ZFCPCONFIG + +if [ $MODE_DASD ]; then + # process the device list defined as option for the dasd module + DEVICES=$(modprobe --showconfig | LANG=C grep "options[[:space:]]\+dasd_mod" | \ + sed -e 's/.*[[:space:]]dasd=\([^[:space:]]*\).*/\1/' -e 's/([^)]*)//g' \ + -e 's/nopav\|nofcx\|autodetect\|probeonly//g' -e 's/,,/,/g' -e 's/^,//' -e 's/,$//') + + for DEVRANGE in $(echo $DEVICES | sed 's/,/ /g'); do + free_device $DEVRANGE + done +fi + +if [ $MODE_ZNET ]; then + # process the config file + if [ -f "$ZNETCONFIG" ]; then + while read line; do + case $line in + \#*) ;; + *) + [ -z "$line" ] && continue + # grep 2 or 3 channels from each ",," line + DEVICES=$(echo $line | LANG=C grep -E -i -o "([0-9]\.[0-9]\.[a-f0-9]+,){1,2}([0-9]\.[0-9]\.[a-f0-9]+)") + free_device $DEVICES + ;; + esac + done < "$ZNETCONFIG" + fi + # process channels from network interface configurations + if [ -z "$__sed_discard_ignored_files" ]; then + if [ -f /etc/init.d/functions ]; then + . /etc/init.d/functions + else + # default value copied from initscripts 9.03.10 + __sed_discard_ignored_files='/\(~\|\.bak\|\.orig\|\.rpmnew\|\.rpmorig\|\.rpmsave\)$/d' + fi + fi + for line in $(LANG=C grep -E -i -h \ + "^[[:space:]]*SUBCHANNELS=['\"]?([0-9]\.[0-9]\.[a-f0-9]+,){1,2}([0-9]\.[0-9]\.[a-f0-9]+)['\"]?([[:space:]]+#|[[:space:]]*$)" \ + $( (ls /etc/sysconfig/network-scripts/ifcfg-* 2> /dev/null || echo "__no_config_file") | \ + LC_ALL=C sed -e "$__sed_discard_ignored_files") 2> /dev/null) + do + eval "$line" + free_device $SUBCHANNELS + done +fi + +[ -z "$ALL_DEVICES" ] && exit 0 + +wait_on_devices diff --git a/device_cio_free.conf b/device_cio_free.conf new file mode 100644 index 0000000..8d61531 --- /dev/null +++ b/device_cio_free.conf @@ -0,0 +1,11 @@ +# +# free all devices on startup +# + +start on starting rcS + +task + +console output + +exec /sbin/device_cio_free diff --git a/lib-zfcp-hbaapi-2.0-module.patch b/lib-zfcp-hbaapi-2.0-module.patch new file mode 100644 index 0000000..01ad7a9 --- /dev/null +++ b/lib-zfcp-hbaapi-2.0-module.patch @@ -0,0 +1,25 @@ +diff -up lib-zfcp-hbaapi-2.0/Makefile.am.orig lib-zfcp-hbaapi-2.0/Makefile.am +--- lib-zfcp-hbaapi-2.0/Makefile.am.orig 2009-11-05 17:22:58.000000000 +0100 ++++ lib-zfcp-hbaapi-2.0/Makefile.am 2009-11-09 14:07:17.000000000 +0100 +@@ -66,6 +66,9 @@ libzfcphbaapi_la_LDFLAGS = \ + -lpthread -Wl,-init,_initvlib,-fini,_finivlib \ + -export-symbols $(SYMFILE) + ++if VENDORLIB ++libzfcphbaapi_la_LDFLAGS += -module -avoid-version -release $(VERSION) ++endif + + if DOCS + man_MANS = libzfcphbaapi.3 dox/man/man3/SupportedHBAAPIs.3 \ +diff -up lib-zfcp-hbaapi-2.0/Makefile.in.orig lib-zfcp-hbaapi-2.0/Makefile.in +--- lib-zfcp-hbaapi-2.0/Makefile.in.orig 2009-11-09 14:06:58.000000000 +0100 ++++ lib-zfcp-hbaapi-2.0/Makefile.in 2009-11-09 14:08:40.000000000 +0100 +@@ -254,6 +254,8 @@ libzfcphbaapi_la_LDFLAGS = \ + -lpthread -Wl,-init,_initvlib,-fini,_finivlib \ + -export-symbols $(SYMFILE) + ++@VENDORLIB_TRUE@libzfcphbaapi_la_LDFLAGS += -module -avoid-version -release $(VERSION) ++ + @DOCS_FALSE@man_MANS = libzfcphbaapi.3 + @DOCS_TRUE@man_MANS = libzfcphbaapi.3 dox/man/man3/SupportedHBAAPIs.3 \ + @DOCS_TRUE@ dox/man/man3/UnSupportedHBAAPIs.3 dox/man/man3/hbaapi.h.3 diff --git a/lib-zfcp-hbaapi-2.0-sgutils.patch b/lib-zfcp-hbaapi-2.0-sgutils.patch new file mode 100644 index 0000000..a292ae4 --- /dev/null +++ b/lib-zfcp-hbaapi-2.0-sgutils.patch @@ -0,0 +1,36 @@ +diff -Nrup lib-zfcp-hbaapi-2.0.orig/Makefile.am lib-zfcp-hbaapi-2.0/Makefile.am +--- lib-zfcp-hbaapi-2.0.orig/Makefile.am 2008-11-21 15:08:13.000000000 +0100 ++++ lib-zfcp-hbaapi-2.0/Makefile.am 2009-09-25 12:30:07.000000000 +0200 +@@ -60,7 +60,7 @@ lib_LTLIBRARIES = libzfcphbaapi.la + + libzfcphbaapi_la_SOURCES = vlib.c vlib_callbacks.c vlib_aux.c vlib_sysfs.c \ + vlib_sg.c +-libzfcphbaapi_la_LIBADD = -lsysfs -lsgutils ++libzfcphbaapi_la_LIBADD = -lsysfs -lsgutils2 + libzfcphbaapi_la_LDFLAGS = \ + -version-info $(LIB_CURRENT):$(LIB_REVISION):$(LIB_AGE) \ + -lpthread -Wl,-init,_initvlib,-fini,_finivlib \ +diff -Nrup lib-zfcp-hbaapi-2.0.orig/Makefile.in lib-zfcp-hbaapi-2.0/Makefile.in +--- lib-zfcp-hbaapi-2.0.orig/Makefile.in 2008-11-21 15:08:18.000000000 +0100 ++++ lib-zfcp-hbaapi-2.0/Makefile.in 2009-09-25 13:22:04.000000000 +0200 +@@ -248,7 +248,7 @@ lib_LTLIBRARIES = libzfcphbaapi.la + libzfcphbaapi_la_SOURCES = vlib.c vlib_callbacks.c vlib_aux.c vlib_sysfs.c \ + vlib_sg.c + +-libzfcphbaapi_la_LIBADD = -lsysfs -lsgutils ++libzfcphbaapi_la_LIBADD = -lsysfs -lsgutils2 + libzfcphbaapi_la_LDFLAGS = \ + -version-info $(LIB_CURRENT):$(LIB_REVISION):$(LIB_AGE) \ + -lpthread -Wl,-init,_initvlib,-fini,_finivlib \ +diff -Nrup lib-zfcp-hbaapi-2.0.orig/vlib_sg.c lib-zfcp-hbaapi-2.0/vlib_sg.c +--- lib-zfcp-hbaapi-2.0.orig/vlib_sg.c 2008-11-20 10:23:34.000000000 +0100 ++++ lib-zfcp-hbaapi-2.0/vlib_sg.c 2009-09-25 13:21:52.000000000 +0200 +@@ -19,6 +19,8 @@ + * @brief All calls that use sg_utils library. + */ + ++#include ++#include + #include "vlib.h" + + #define INTERVAL 10000000 diff --git a/mon_statd.initd b/mon_statd.initd new file mode 100644 index 0000000..089572b --- /dev/null +++ b/mon_statd.initd @@ -0,0 +1,172 @@ +#! /bin/sh +# +# chkconfig: 2345 90 10 +# description: Configure the mon_fsstatd and mon_procd daemons. + +### BEGIN INIT INFO +# Provides: mon_statd +# Required-Start: $local_fs $remote_fs +# Required-Stop: $local_fs $remote_fs +# Should-Start: +# Should-Stop: +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: Configure the mon_fsstatd and mon_procd daemons. +# Description: Configures the mon_fsstatd and mon_procd daemons. It uses the +# configuration file /etc/sysconfig/mon_statd. +### END INIT INFO + +# Source function library. +. /etc/rc.d/init.d/functions + +exec_fsstat="/usr/sbin/mon_fsstatd" +prog_fsstat="mon_fsstatd" +exec_proc="/usr/sbin/mon_procd" +prog_proc="mon_procd" + +config="/etc/sysconfig/mon_statd" +g_retval=0 + +lockfile_fsstat=/var/lock/subsys/$prog_fsstat +lockfile_proc=/var/lock/subsys/$prog_proc + +[ -e $config ] && . $config || exit 6 + +load_kernel_module() +{ + if [ ! -e /dev/monwriter ]; then + echo "Loading monwriter module..." + modprobe monwriter 2>&1 + if [ $? -ne 0 ]; then + exit 1 + fi + udevsettle + if [ $? -ne 0 ]; then + exit 1 + fi + fi +} + +start_fsstat() { + [ `id -u` -eq 0 ] || exit 4 + load_kernel_module + [ -x $exec_fsstat ] || exit 5 + echo -n $"Starting $prog_fsstat: " + daemon $exec_fsstat -i $FSSTAT_INTERVAL + retval=$? + echo + [ $retval -eq 0 ] && touch $lockfile_fsstat + return $retval +} + +start_proc() { + [ `id -u` -eq 0 ] || exit 4 + load_kernel_module + [ -x $exec_proc ] || exit 5 + echo -n $"Starting $prog_proc: " + daemon $exec_proc -i $PROC_INTERVAL + retval=$? + echo + [ $retval -eq 0 ] && touch $lockfile_proc + return $retval +} + +stop_fsstat() { + [ `id -u` -eq 0 ] || exit 4 + echo -n $"Stopping $prog_fsstat: " + killproc $exec_fsstat + retval=$? + echo + [ $retval -eq 0 ] && rm -f $lockfile_fsstat + return $retval +} + +stop_proc() { + [ `id -u` -eq 0 ] || exit 4 + echo -n $"Stopping $prog_proc: " + killproc $exec_proc + retval=$? + echo + [ $retval -eq 0 ] && rm -f $lockfile_proc + return $retval +} + +restart_fsstat() { + stop_fsstat + start_fsstat +} + +restart_proc() { + stop_proc + start_proc +} + +reload_fsstat() { + restart_fsstat +} + +reload_proc() { + restart_proc +} + +force_reload_fsstat() { + restart_fsstat +} + +force_reload_proc() { + restart_proc +} + +rh_status_fsstat() { + # run checks to determine if the service is running or use generic status + status $exec_fsstat +} + +rh_status_proc() { + # run checks to determine if the service is running or use generic status + status $exec_proc +} + +rh_status_fsstat_q() { + rh_status_fsstat >/dev/null 2>&1 +} + +rh_status_proc_q() { + rh_status_proc >/dev/null 2>&1 +} + + +case "$1" in + start) + [ $FSSTAT = "yes" ] && { rh_status_fsstat_q || { start_fsstat ; g_retval=$? ; } || { g_retval=0 ; } } + [ $PROC = "yes" ] && { rh_status_proc_q || { start_proc ; g_retval=$? ; } || { g_retval=0 ; } } + ;; + stop) + [ $FSSTAT = "yes" ] && { rh_status_fsstat_q && { stop_fsstat ; g_retval=$? ; } || { g_retval=0 ; } } + [ $PROC = "yes" ] && { rh_status_proc_q && { stop_proc ; g_retval=$? ; } || { g_retval=0 ; } } + ;; + restart) + [ $FSSTAT = "yes" ] && { restart_fsstat ; g_retval=$? ; } + [ $PROC = "yes" ] && { restart_proc ; g_retval=$? ; } + ;; + reload) + [ $FSSTAT = "yes" ] && { rh_status_fsstat_q && { reload_fsstat ; g_retval=$? ; } || { g_retval=7 ; } } + [ $PROC = "yes" ] && { rh_status_proc_q && { reload_proc ; g_retval=$? ; } || { g_retval=7 ; } } + ;; + force-reload) + [ $FSSTAT = "yes" ] && { force_reload_fsstat ; g_retval=$? ; } + [ $PROC = "yes" ] && { force_reload_proc ; g_retval=$? ; } + ;; + status) + [ $FSSTAT = "yes" ] && { rh_status_fsstat ; g_retval=$? ; } + [ $PROC = "yes" ] && { rh_status_proc ; g_retval=$? ; } + ;; + condrestart|try-restart) + [ $FSSTAT = "yes" ] && { rh_status_fsstat_q && { restart_fsstat ; g_retval=$? ; } || { g_retval=0 ; } } + [ $PROC = "yes" ] && { rh_status_proc_q && { restart_proc ; g_retval=$? ; } || { g_retval=0 ; } } + ;; + *) + echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload}" + exit 2 +esac +exit $g_retval diff --git a/s390.csh b/s390.csh new file mode 100644 index 0000000..b98b7a5 --- /dev/null +++ b/s390.csh @@ -0,0 +1,5 @@ +# /etc/profile.d/s390.csh - set TERM variable + +if ( `/sbin/consoletype stdout` == "serial" ) then + setenv TERM dumb +endif diff --git a/s390.sh b/s390.sh new file mode 100644 index 0000000..6e2707a --- /dev/null +++ b/s390.sh @@ -0,0 +1,6 @@ +# /etc/profile.d/s390.sh - set TERM variable + +contype=`/sbin/consoletype stdout` +if [ "$contype" == "serial" ]; then + export TERM=dumb +fi diff --git a/s390utils.spec b/s390utils.spec new file mode 100644 index 0000000..bf51522 --- /dev/null +++ b/s390utils.spec @@ -0,0 +1,1512 @@ +%define cmsfsver 1.1.8c +%define vipaver 2.0.4 +%define hbaapiver 2.0 + +%{!?_initddir: %define _initddir %{_initrddir}} + +Name: s390utils +Summary: Utilities and daemons for IBM System/z +Group: System Environment/Base +Version: 1.8.2 +Release: 30%{?dist} +Epoch: 2 +License: GPLv2 and GPLv2+ and CPL +Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) +ExclusiveArch: s390 s390x +URL: http://www.ibm.com/developerworks/linux/linux390/s390-tools.html +# http://www.ibm.com/developerworks/linux/linux390/s390-tools-%{version}.html +Source0: http://download.boulder.ibm.com/ibmdl/pub/software/dw/linux390/ht_src/s390-tools-%{version}.tar.bz2 +Source2: s390.sh +Source3: s390.csh +Source4: http://www.linuxvm.org/Patches/S390/cmsfs-%{cmsfsver}.tar.gz +Source5: zfcpconf.sh +# http://www.ibm.com/developerworks/linux/linux390/src_vipa-%{vipaver}.html +Source6: http://download.boulder.ibm.com/ibmdl/pub/software/dw/linux390/ht_src/src_vipa-%{vipaver}.tar.gz +Source7: zfcp.udev +# http://www.ibm.com/developerworks/linux/linux390/zfcp-hbaapi-%{hbaapiver}.html +Source9: http://download.boulder.ibm.com/ibmdl/pub/software/dw/linux390/ht_src/lib-zfcp-hbaapi-%{hbaapiver}.tar.gz +# files for the Control Program Identification (Linux Call Home) feature (#463282) +Source10: cpi.initd +Source11: cpi.sysconfig +# files for DASD initialization +Source12: dasd.udev +Source13: dasdconf.sh +Source14: device_cio_free +Source15: device_cio_free.conf +Source16: ccw_init +Source17: ccw.udev +Source18: cpuplugd.initd +Source19: mon_statd.initd + +Patch1: 0001-s390-tools-1.5.3-zipl-zfcpdump-2.patch +Patch2: 0002-s390-tools-1.8.1-zipl-automenu.patch +Patch3: 0003-s390-tools-1.8.1-fdasd-su.patch +Patch4: 0004-s390-tools-1.8.1-fdasd-raid-lvm.patch +Patch5: 0005-don-t-create-automenu-when-default-menu-exists.patch +Patch6: 0006-s390-tools-1.8.1-zipl-kdump-man.patch +Patch7: 0007-s390-tools-1.8.1-lszfcp-perf.patch +Patch8: 0008-fix-string-overflow-in-vtoc_volume_label_init.patch +Patch9: 0009-change-default-load-address-for-ramdisk.patch +Patch10: 0010-improve-mon_statd-init-script.patch +Patch11: 0011-update-readahead-value-for-better-performance.patch +Patch12: 0012-fix-multipath-device-detection-in-ziomon.patch +Patch13: 0013-zipl-handle-status-during-ipl.patch +Patch14: 0014-dasdview-fdasd-fix-floating-point-error-for-unformat.patch +Patch15: 0015-s390tools-1.8.2-zipl-dm.patch +Patch16: 0016-s390tools-1.8.2-lsreipl-nss.patch +Patch17: 0017-qualified-return-codes-and-further-error-handling-in.patch +Patch18: 0018-fix-uppercase-conversion-in-lscss.patch +Patch19: 0019-ziorep-fix-return-codes.patch +Patch20: 0020-lstape-fix-return-code.patch +Patch21: 0021-cpuplugd-fix-reading-the-size-of-proc-sys-vm-cmm_pag.patch +Patch22: 0022-lsqeth-support-new-attributes.patch +Patch23: 0023-znetconf-use-hex-index-for-chpidtype-table.patch +Patch24: 0024-zipl-handle-SSCH-status.patch +Patch25: 0025-vmconvert-shows-garbage-in-progress-bar.patch +Patch26: 0026-zipl-zfcp-dump-partition-error.patch +Patch27: 0027-zfcpdump-disable-memory-cgroups.patch +Patch28: 0028-fix-df-usage-in-ziomon.patch +Patch29: 0029-ziomon-remove-check-for-ziorep_config-availability.patch +Patch30: 0030-ziomon-fix-multipathing.patch +Patch31: 0031-mismatch-between-man-and-h-in-chshut.patch +Patch32: 0032-lsdasd-update-man-page.patch +Patch33: 0033-reinitialize-array-in-lsqeth.patch +Patch34: 0034-check-the-length-of-the-parameters-line.patch +Patch35: 0035-ziorep-follow-symlink.patch +Patch36: 0036-ts-shell-do-not-restrict-group-names-to-be-alphanume.patch +Patch37: 0037-znetconf-unknown-driver-for-qeth.patch +Patch38: 0038-cpuplugd-fix-stack-overflow.patch +Patch39: 0039-cpuplugd-fix-cmm-limits-checks.patch +Patch40: 0040-cpuplugd-set-cpu_min-to-1-by-default.patch +Patch41: 0041-fix-dates-option-on-zfcpdbf.patch +Patch42: 0042-lsluns-uninitialized-value-on-adapter-offline.patch +Patch43: 0043-zfcpdbf-Fix-Use-of-uninitialized-value-and-output-is.patch + +Patch1000: 1000-ziomon-linker.patch + +Patch100: cmsfs-1.1.8-warnings.patch +Patch101: cmsfs-1.1.8-kernel26.patch + +Patch200: src_vipa-2.0.4-locations.patch + +Patch300: lib-zfcp-hbaapi-2.0-sgutils.patch +Patch301: lib-zfcp-hbaapi-2.0-module.patch + +Requires: s390utils-base = %{epoch}:%{version}-%{release} +Requires: s390utils-osasnmpd = %{epoch}:%{version}-%{release} +Requires: s390utils-cpuplugd = %{epoch}:%{version}-%{release} +Requires: s390utils-mon_statd = %{epoch}:%{version}-%{release} +Requires: s390utils-iucvterm = %{epoch}:%{version}-%{release} +Requires: s390utils-ziomon = %{epoch}:%{version}-%{release} +Requires: s390utils-cmsfs = %{epoch}:%{version}-%{release} + + +%description +This is a meta package for installing the default s390-tools sub packages. +If you do not need all default sub packages, it is recommended to install the +required sub packages separately. + +The s390utils packages contain a set of user space utilities that should to +be used together with the zSeries (s390) Linux kernel and device drivers. + +%prep +%setup -q -n s390-tools-%{version} -a 4 -a 6 -a 9 + +# Use rpm PATH variables for installation and set correct zfcpdump path +%patch1 -p1 -b .common-mak + +# Patch to maintain backwards compatibility with older zipl multiboot feature +%patch2 -p1 -b .zipl-automenu + +# Fix to honor the silent flag for wrongly formated disks +%patch3 -p1 -b .fdasd-su + +# Enhancement to add raid partiton support to dasds +%patch4 -p1 -b .fdasd-raid-lvm + +# Don't build automenu iff default menu exists (#486444) +%patch5 -p1 -b .defaultmenu + +# Update zipl man page +%patch6 -p1 -b .zipl-kdump-man + +# Check only ZFCP devices in lszfcp (#518669) +%patch7 -p1 -b .lszfcp-perf + +# Fix string overflow in vtoc_volume_label_init (#525318) +%patch8 -p1 -b .vtoc-label + +# Change default load address for ramdisk (#526339) +%patch9 -p1 -b .ramdisk-address + +# Improve mon_statd init script +%patch10 -p1 -b .improve-mon_statd + +# Update readahead value for better performance +%patch11 -p1 -b .readahead + +# Fix multipath device detection in ziomon (#533955) +%patch12 -p1 -b .ziomon-multipath + +# Handle status during ipl in zipl (#537142) +%patch13 -p1 -b .zipl-status + +# Fix floating point error for unformatted devices in fdasd and dasdview (#537144) +%patch14 -p1 -b .dasd-zero-division + +# Add device-mapper support into zipl (#546280) +%patch15 -p1 -b .zipl-dm + +# Add missing check and print NSS name in case an NSS has been IPLed (#546297) +%patch16 -p1 -b .lsreipl-nss + +# Add qualified return codes and further error handling in znetconf (#548487) +%patch17 -p1 -b .znetconf-returncodes + +# Fixed uppercase conversion in lscss (#554768) +%patch18 -p1 -b .uppercase + +# Fixed return codes in ziorep (#556849) +%patch19 -p1 -b .ziorep-returncodes + +# Fixed return code in lstape (#556910) +%patch20 -p1 -b .lstape-returncode + +# Fixed reading the size of /proc/sys/vm/cmm_pages in cpuplugd (#556911) +%patch21 -p1 -b .cpuplugd-fscanf + +# Support new attributes in lsqeth (#556915) +%patch22 -p1 -b .lsqeth-new-attrs + +# Use hex index for chpidtype table in znetconf (#561056) +%patch23 -p1 -b .znetconf-hex-chpidtype + +# Handle status during IPL SSCH (#559250) +%patch24 -p1 -b .zipl-handle-ssch-status + +# Don't show garbage in vmconvert's progress bar (#567681) +%patch25 -p1 -b .vmconvert-progress-bar + +# Fix zfcp dump partition error (#572313) +%patch26 -p1 -b .zfcp-dump-partition + +# Don't use memory cgroups in zfcpdump kernel (#575183) +%patch27 -p1 -b .zfcpdump-cgroups + +# Fix df usage in ziomon (#575833) +%patch28 -p1 -b .ziomon-df + +# Remove check for ziorep_config availability (#576579) +%patch29 -p1 -b .ziorep_config + +# Fix multipathing in ziomon (#577318) +%patch30 -p1 -b .ziomon-multipath-2 + +# Fixed mismatch between man and -h in chshut (#563625) +%patch31 -p1 -b .man-mismatch + +# Update lsdasd man page (#587044) +%patch32 -p1 -b .lsdasd-man + +# Reinitialize array in lsqeth (#587599) +%patch33 -p1 -b .lsqeth-reinit-array + +# Check the length of the parameters line (#594031) +%patch34 -p1 -b .zipl-max-parmline + +# Follow symlinks in ziorep (#598574) +%patch35 -p1 -b .ziorep-follow-symlinks + +# Do not restrict group names to be alphanumeric in ts-shell (#598641) +%patch36 -p1 -b .ts-shell-groups + +# znetconf --drive|-d option returning 'unknown driver' for qeth (#601846) +%patch37 -p1 -b .znetconf-driver-option + +# Fix stack overwrite in cpuplugd (#601847) +%patch38 -p1 -b .cpuplugd-stack-overwrite + +# Fix cmm_min/max limit checks in cpuplugd (#606366) +%patch39 -p1 -b .cpuplugd-cmm-limits + +# Set cpu_min to 1 by default in cpuplugd (#606416) +%patch40 -p1 -b .cpuplugd-cpu_min + +# Fix --dates option in zfcpdbf (#609092) +%patch41 -p1 -b .zfcpdbf-dates + +# lsluns: uninitialized value on adapter offline (#611795) +%patch42 -p1 -b .lsluns-adapter-offline + +# zfcpdbf: Fix 'Use of uninitialized value' and output issues (#612622) +%patch43 -p1 -b .zfcpdbf-uninitialized-value + +# Fix linking with --no-add-needed +%patch1000 -p1 -b .linker + +# +# cmsfs +# +pushd cmsfs-%{cmsfsver} +# Patch to fix a couple of code bugs +%patch100 -p1 -b .warnings + +# build on kernel-2.6, too +%patch101 -p1 -b .cmsfs26 +popd + +# +# src_vipa +# +pushd src_vipa-%{vipaver} +# fix location of the library +%patch200 -p1 -b .locations +popd + +# +# lib-zfcp-hbaapi +# +pushd lib-zfcp-hbaapi-%{hbaapiver} +# fix for newer sg3_utils and missing function declarations +%patch300 -p1 -b .sgutils + +# build the library as a module +%patch301 -p1 -b .module +popd + +# remove --strip from install +find . -name Makefile | xargs sed -i 's/$(INSTALL) -s/$(INSTALL)/g' + +pushd cmsfs-%{cmsfsver} +# cmdfs: fix encoding +iconv -f ISO8859-1 -t UTF-8 -o README.new README +touch -r README README.new +mv README.new README +# prepare docs +mv README README.cmsfs +mv CREDITS CREDITS.cmsfs +popd + + +pushd lib-zfcp-hbaapi-%{hbaapiver} +# lib-zfcp-hbaapi: fix perms +chmod a-x *.h AUTHORS README ChangeLog LICENSE +popd + + +%build +make OPT_FLAGS="$RPM_OPT_FLAGS -fno-strict-aliasing" DISTRELEASE=%{release} V=1 + +pushd cmsfs-%{cmsfsver} +./configure +make CC="gcc $RPM_OPT_FLAGS -fno-strict-aliasing" +popd + +pushd src_vipa-%{vipaver} +make CC_FLAGS="$RPM_OPT_FLAGS -fPIC" LIBDIR=%{_libdir} +popd + +pushd lib-zfcp-hbaapi-%{hbaapiver} +%configure --disable-static +make EXTRA_CFLAGS="$RPM_OPT_FLAGS -fno-strict-aliasing" +popd + + +%install +rm -rf ${RPM_BUILD_ROOT} + +mkdir -p $RPM_BUILD_ROOT{%{_lib},%{_libdir},/sbin,/bin,/boot,%{_mandir}/man1,%{_mandir}/man8,%{_sbindir},%{_bindir},%{_sysconfdir}/{profile.d,udev/rules.d,sysconfig},%{_initddir}} + +# workaround an issue in the zipl-device-mapper patch +rm -f zipl/src/zipl_helper.device-mapper.* + +make install \ + INSTROOT=$RPM_BUILD_ROOT \ + MANDIR=$RPM_BUILD_ROOT%{_mandir} \ + LIBDIR=${RPM_BUILD_ROOT}/%{_lib} \ + DISTRELEASE=%{release} \ + V=1 + +install -p -m 644 zipl/boot/tape0.bin $RPM_BUILD_ROOT/boot/tape0 +install -p -m 644 %{SOURCE2} $RPM_BUILD_ROOT%{_sysconfdir}/profile.d +install -p -m 644 %{SOURCE3} $RPM_BUILD_ROOT%{_sysconfdir}/profile.d +install -p -m 755 %{SOURCE5} $RPM_BUILD_ROOT/sbin +install -p -m 755 %{SOURCE13} $RPM_BUILD_ROOT/sbin +install -p -m 644 %{SOURCE7} $RPM_BUILD_ROOT%{_sysconfdir}/udev/rules.d/56-zfcp.rules +install -p -m 644 %{SOURCE12} $RPM_BUILD_ROOT%{_sysconfdir}/udev/rules.d/56-dasd.rules + +touch $RPM_BUILD_ROOT%{_sysconfdir}/{zfcp.conf,dasd.conf} + +install -p -m 644 etc/sysconfig/dumpconf ${RPM_BUILD_ROOT}%{_sysconfdir}/sysconfig +install -p -m 755 etc/init.d/dumpconf ${RPM_BUILD_ROOT}%{_initddir}/dumpconf + +install -p -m 644 etc/sysconfig/mon_statd ${RPM_BUILD_ROOT}%{_sysconfdir}/sysconfig +install -p -m 755 %{SOURCE19} ${RPM_BUILD_ROOT}%{_initddir}/mon_statd + +install -p -m 644 etc/sysconfig/cpuplugd ${RPM_BUILD_ROOT}%{_sysconfdir}/sysconfig +install -p -m 755 %{SOURCE18} ${RPM_BUILD_ROOT}%{_initddir}/cpuplugd + +install -Dp -m 644 etc/udev/rules.d/*.rules ${RPM_BUILD_ROOT}%{_sysconfdir}/udev/rules.d + +# cmsfs tools must be available in /sbin +install -p -m 755 cmsfs-%{cmsfsver}/cmsfscat $RPM_BUILD_ROOT/sbin +install -p -m 755 cmsfs-%{cmsfsver}/cmsfslst $RPM_BUILD_ROOT/sbin +install -p -m 755 cmsfs-%{cmsfsver}/cmsfsvol $RPM_BUILD_ROOT/sbin +install -p -m 755 cmsfs-%{cmsfsver}/cmsfscp $RPM_BUILD_ROOT/sbin +install -p -m 755 cmsfs-%{cmsfsver}/cmsfsck $RPM_BUILD_ROOT/sbin +install -p -m 644 cmsfs-%{cmsfsver}/cmsfscat.8 $RPM_BUILD_ROOT%{_mandir}/man8 +install -p -m 644 cmsfs-%{cmsfsver}/cmsfslst.8 $RPM_BUILD_ROOT%{_mandir}/man8 +install -p -m 644 cmsfs-%{cmsfsver}/cmsfsvol.8 $RPM_BUILD_ROOT%{_mandir}/man8 +install -p -m 644 cmsfs-%{cmsfsver}/cmsfscp.8 $RPM_BUILD_ROOT%{_mandir}/man8 +install -p -m 644 cmsfs-%{cmsfsver}/cmsfsck.8 $RPM_BUILD_ROOT%{_mandir}/man8 + +# src_vipa +pushd src_vipa-%{vipaver} +make install LIBDIR=%{_libdir} SBINDIR=%{_bindir} INSTROOT=$RPM_BUILD_ROOT +popd + +# lib-zfcp-hbaapi +pushd lib-zfcp-hbaapi-%{hbaapiver} +%makeinstall docdir=$RPM_BUILD_ROOT%{_docdir}/lib-zfcp-hbaapi-%{hbaapiver} +popd +# keep only html docs +rm -rf $RPM_BUILD_ROOT%{_docdir}/lib-zfcp-hbaapi-%{hbaapiver}/latex +# remove unwanted files +rm -f $RPM_BUILD_ROOT%{_libdir}/libzfcphbaapi.* + +# install usefull headers for devel subpackage +mkdir -p $RPM_BUILD_ROOT%{_includedir}/%{name} +install -p -m 644 include/vtoc.h $RPM_BUILD_ROOT%{_includedir}/%{name} + +# CPI +install -p -m 644 %{SOURCE11} ${RPM_BUILD_ROOT}%{_sysconfdir}/sysconfig/cpi +install -p -m 755 %{SOURCE10} ${RPM_BUILD_ROOT}%{_initddir}/cpi + +# device_cio_free +install -p -m 755 %{SOURCE14} ${RPM_BUILD_ROOT}/sbin +pushd ${RPM_BUILD_ROOT}/sbin +for lnk in dasd zfcp znet; do + ln -sf device_cio_free ${lnk}_cio_free +done +popd +mkdir -p ${RPM_BUILD_ROOT}%{_sysconfdir}/init +install -p -m 644 %{SOURCE15} ${RPM_BUILD_ROOT}%{_sysconfdir}/init + +# ccw +mkdir -p ${RPM_BUILD_ROOT}/lib/udev/rules.d +install -p -m 755 %{SOURCE16} ${RPM_BUILD_ROOT}/lib/udev/ccw_init +install -p -m 644 %{SOURCE17} ${RPM_BUILD_ROOT}/lib/udev/rules.d/81-ccw.rules + + +%clean +rm -rf ${RPM_BUILD_ROOT} + + +%files +%defattr(-,root,root,-) +%doc README + +# +# ************************* s390-tools base package ************************* +# +%package base +# src_vipa is CPL, the rest is GPLv2 or GPLv2+ +License: GPLv2 and GPLv2+ and CPL +Summary: S390 base tools +Group: System Environment/Base +Requires: perl gawk sed coreutils +Requires: sysfsutils +Requires: sg3_utils +Requires(pre): chkconfig +Requires(preun): chkconfig +Requires(preun): initscripts + + +%description base +s390 base tools. This collection provides the following utilities: + * dasdfmt: + Low-level format ECKD DASDs with the classical linux disk layout or the + new z/OS compatible disk layout. + + * fdasd: + Create or modify partitions on ECKD DASDs formatted with the z/OS + compatible disk layout. + + * dasdview: + Display DASD and VTOC information or dump the contents of a DASD to the + console. + + * dasdinfo: + Display unique DASD ID, either UID or volser. + + * udev rules: + - 59-dasd.rules: rules for unique DASD device nodes created in /dev/disk/. + + * zipl: + Make DASDs or tapes bootable for system IPL or system dump. + + * zgetdump: + Retrieve system dumps from either tapes or DASDs. + + * qetharp: + Read and flush the ARP cache on OSA Express network cards. + + * tape390_display: + Display information on the message display facility of a zSeries tape + device. + + * tape390_crypt: + Control and query crypto settings for 3592 zSeries tape devices. + + * qethconf: + bash shell script simplifying the usage of qeth IPA (IP address + takeover), VIPA (Virtual IP address) and Proxy ARP. + + * dbginfo.sh: + Shell script collecting useful information about the current system for + debugging purposes. + + * zfcpdump: + Dump tool to create system dumps on fibre channel attached SCSI disks. + It is installed using the zipl command. + + * zfcpdump_v2: + Version 2 of the zfcpdump tool. Now based on the upstream 2.6.26 Linux + kernel. + + * ip_watcher: + Provides HiperSockets Network Concentrator functionality. + It looks for addresses in the HiperSockets and sets them as Proxy ARP + on the OSA cards. It also adds routing entries for all IP addresses + configured on active HiperSockets devices. + Use start_hsnc.sh to start HiperSockets Network Concentrator. + + * tunedasd: + Adjust tunable parameters on DASD devices. + + * vmconvert: + Convert system dumps created by the z/VM VMDUMP command into dumps with + LKCD format. These LKCD dumps can then be analyzed with the dump analysis + tool lcrash. + + * vmcp: + Allows Linux users to send commands to the z/VM control program (CP). + The normal usage is to invoke vmcp with the command you want to + execute. The response of z/VM is written to the standard output. + + * vmur: + Allows to work with z/VM spool file queues (reader, punch, printer). + + * zfcpdbf: + Display debug data of zfcp. zfcp provides traces via the s390 debug + feature. Those traces are filtered with the zfcpdbf script, i.e. merge + several traces, make it more readable etc. + + * scsi_logging_level: + Create, get or set the logging level for the SCSI logging facility. + + * zconf: + Set of scripts to configure and list status information of Linux for + zSeries IO devices. + - chccwdev: Modify generic attributes of channel attached devices. + - lscss: List channel subsystem devices. + - lsdasd: List channel attached direct access storage devices (DASD). + - lsqeth: List all qeth-based network devices with their corresponding + settings. + - lstape: List tape devices, both channel and FCP attached. + - lszfcp: Shows information contained in sysfs about zfcp adapters, + ports and units that are online. + - lschp: List information about available channel-paths. + - chchp: Modify channel-path state. + - lsluns: List available SCSI LUNs depending on adapter or port. + - lszcrypt: Show Information about zcrypt devices and configuration. + - chzcrypt: Modify zcrypt configuration. + - znetconf: List and configure network devices for System z network + adapters. + - cio_ignore: Query and modify the contents of the CIO device driver + blacklist. + + * dumpconf: + Allows to configure the dump device used for system dump in case a kernel + panic occurs. This tool can also be used as an init script for etc/init.d. + Prerequisite for dumpconf is a Linux kernel with the "dump on panic" + feature. + + * ipl_tools: + Tools set to configure and list reipl and shutdown actions. + - lsreipl: List information of reipl device. + - chreipl: Change reipl device settings. + - lsshut: List actions which will be done in case of halt, poff, reboot + or panic. + - chshut: Change actions which should be done in case of halt, poff, + reboot or panic. + + * cpi: + Allows to set the system and sysplex names from the Linux guest to + the HMC/SE using the Control Program Identification feature. + +For more information refer to the following publications: + * "Device Drivers, Features, and Commands" chapter "Useful Linux commands" + * "Using the dump tools" + +%post base +/sbin/chkconfig --add dumpconf +/sbin/chkconfig --add cpi + +%preun base +if [ $1 = 0 ]; then + # not for updates + /sbin/service dumpconf stop > /dev/null 2>&1 + /sbin/chkconfig --del dumpconf + /sbin/service cpi stop > /dev/null 2>&1 + /sbin/chkconfig --del cpi +fi +: + +%files base +%defattr(-,root,root,-) +%doc README +%doc LICENSE +/sbin/zipl +/sbin/dasdfmt +/sbin/dasdinfo +/sbin/dasdview +/sbin/fdasd +/sbin/chccwdev +/sbin/chchp +/sbin/chzcrypt +/sbin/cio_ignore +/sbin/lschp +/sbin/lscss +/sbin/lsdasd +/sbin/lsluns +/sbin/lsqeth +/sbin/lstape +/sbin/lszcrypt +/sbin/lszfcp +/sbin/scsi_logging_level +/sbin/zfcpdbf +/sbin/qetharp +/sbin/qethconf +/sbin/tape390_display +/sbin/tape390_crypt +/sbin/tunedasd +/sbin/vmcp +/sbin/zgetdump +/sbin/znetconf +/sbin/dbginfo.sh +%{_sbindir}/lsreipl +%{_sbindir}/lsshut +%{_sbindir}/chreipl +%{_sbindir}/chshut +%{_sbindir}/ip_watcher.pl +%{_sbindir}/start_hsnc.sh +%{_sbindir}/vmur +%{_sbindir}/xcec-bridge +%{_bindir}/vmconvert +%{_initddir}/dumpconf +%config(noreplace) %{_sysconfdir}/sysconfig/dumpconf +/lib/s390-tools +%{_mandir}/man1/zfcpdbf.1* +%{_mandir}/man4/prandom.4* +%{_mandir}/man5/zipl.conf.5* +%{_mandir}/man8/chccwdev.8* +%{_mandir}/man8/chchp.8* +%{_mandir}/man8/chreipl.8* +%{_mandir}/man8/chshut.8* +%{_mandir}/man8/chzcrypt.8* +%{_mandir}/man8/cio_ignore.8* +%{_mandir}/man8/dasdfmt.8* +%{_mandir}/man8/dasdinfo.8* +%{_mandir}/man8/dasdview.8* +%{_mandir}/man8/dumpconf.8* +%{_mandir}/man8/fdasd.8* +%{_mandir}/man8/lschp.8* +%{_mandir}/man8/lscss.8* +%{_mandir}/man8/lsdasd.8* +%{_mandir}/man8/lsluns.8* +%{_mandir}/man8/lsqeth.8* +%{_mandir}/man8/lsreipl.8* +%{_mandir}/man8/lsshut.8* +%{_mandir}/man8/lstape.8* +%{_mandir}/man8/lszcrypt.8* +%{_mandir}/man8/lszfcp.8* +%{_mandir}/man8/qetharp.8* +%{_mandir}/man8/qethconf.8* +%{_mandir}/man8/tape390_crypt.8* +%{_mandir}/man8/tape390_display.8* +%{_mandir}/man8/tunedasd.8* +%{_mandir}/man8/vmconvert.8* +%{_mandir}/man8/vmcp.8* +%{_mandir}/man8/vmur.8* +%{_mandir}/man8/zgetdump.8* +%{_mandir}/man8/znetconf.8* +%{_mandir}/man8/zipl.8* + +# Additional Redhat specific stuff +/boot/tape0 +%{_sysconfdir}/profile.d/s390.csh +%{_sysconfdir}/profile.d/s390.sh +%config(noreplace) %{_sysconfdir}/udev/rules.d/56-zfcp.rules +%config(noreplace) %{_sysconfdir}/udev/rules.d/56-dasd.rules +%config(noreplace) %{_sysconfdir}/udev/rules.d/59-dasd.rules +%config(noreplace) %{_sysconfdir}/udev/rules.d/60-readahead.rules +%ghost %config(noreplace) %{_sysconfdir}/dasd.conf +%ghost %config(noreplace) %{_sysconfdir}/zfcp.conf +%{_initddir}/cpi +%config(noreplace) %{_sysconfdir}/sysconfig/cpi +/sbin/dasdconf.sh +/sbin/zfcpconf.sh +/sbin/dasd_cio_free +/sbin/device_cio_free +/sbin/zfcp_cio_free +/sbin/znet_cio_free +%{_sysconfdir}/init/device_cio_free.conf +/lib/udev/ccw_init +/lib/udev/rules.d/81-ccw.rules + +# src_vipa +%{_bindir}/src_vipa.sh +%{_libdir}/src_vipa.so +%{_mandir}/man8/src_vipa.8* + +# +# *********************** s390-tools osasnmpd package *********************** +# +%package osasnmpd +License: GPLv2+ +Summary: SNMP sub-agent for OSA-Express cards +Group: System Environment/Daemons +Requires: net-snmp +BuildRequires: net-snmp-devel openssl-devel + +%description osasnmpd +UCD-SNMP/NET-SNMP sub-agent implementing MIBs provided by OSA-Express +features Fast Ethernet, Gigabit Ethernet, High Speed Token Ring and +ATM Ethernet LAN Emulation in QDIO mode. + +%files osasnmpd +%defattr(-,root,root,-) +%{_sbindir}/osasnmpd +%config(noreplace) %{_sysconfdir}/udev/rules.d/57-osasnmpd.rules +%{_mandir}/man8/osasnmpd.8* + +# +# *********************** s390-tools mon_statd package ********************** +# +%package mon_statd +License: GPLv2 +Summary: Monitoring daemons for Linux in z/VM +Group: System Environment/Daemons +Requires: coreutils +Requires(pre): chkconfig +Requires(preun): chkconfig +Requires(preun): initscripts + +%description mon_statd +Monitoring daemons for Linux in z/VM: + + - mon_fsstatd: Daemon that writes file system utilization data to the + z/VM monitor stream. + + - mon_procd: Daemon that writes process information data to the z/VM + monitor stream. + +%post mon_statd +/sbin/chkconfig --add mon_statd + +%preun mon_statd +if [ $1 = 0 ]; then + # not for updates + /sbin/service mon_statd stop > /dev/null 2>&1 + /sbin/chkconfig --del mon_statd +fi +: + +%files mon_statd +%defattr(-,root,root,-) +%{_sbindir}/mon_fsstatd +%{_sbindir}/mon_procd +%config(noreplace) %{_sysconfdir}/sysconfig/mon_statd +%{_initddir}/mon_statd +%{_mandir}/man8/mon_fsstatd.8* +%{_mandir}/man8/mon_procd.8* + +# +# *********************** s390-tools cpuplugd package *********************** +# +%package cpuplugd +License: GPLv2+ +Summary: Daemon that manages CPU and memory resources +Group: System Environment/Daemons +Requires: coreutils +Requires(pre): chkconfig +Requires(preun): chkconfig +Requires(preun): initscripts + +%description cpuplugd +Daemon that manages CPU and memory resources based on a set of rules. +Depending on the workload CPUs can be enabled or disabled. The amount of +memory can be increased or decreased exploiting the CMM1 feature. + +%post cpuplugd +/sbin/chkconfig --add cpuplugd + +%preun cpuplugd +if [ $1 = 0 ]; then + # not for updates + /sbin/service cpuplugd stop > /dev/null 2>&1 + /sbin/chkconfig --del cpuplugd +fi +: + +%files cpuplugd +%defattr(-,root,root,-) +%{_initddir}/cpuplugd +%config(noreplace) %{_sysconfdir}/sysconfig/cpuplugd +%{_sbindir}/cpuplugd +%{_mandir}/man5/cpuplugd.conf.5* +%{_mandir}/man8/cpuplugd.8* + +# +# *********************** s390-tools ziomon package ************************* +# +%package ziomon +License: GPLv2 +Summary: S390 ziomon tools +Group: Applications/System +Requires: perl lsscsi coreutils blktrace >= 1.0.1 + +%description ziomon +Tool set to collect data for zfcp performance analysis and report. + +%files ziomon +%defattr(-,root,root,-) +%{_sbindir}/ziomon +%{_sbindir}/ziomon_fcpconf +%{_sbindir}/ziomon_mgr +%{_sbindir}/ziomon_util +%{_sbindir}/ziomon_zfcpdd +%{_sbindir}/ziorep_config +%{_sbindir}/ziorep_traffic +%{_sbindir}/ziorep_utilization +%{_mandir}/man8/ziomon.8* +%{_mandir}/man8/ziomon_fcpconf.8* +%{_mandir}/man8/ziomon_mgr.8* +%{_mandir}/man8/ziomon_util.8* +%{_mandir}/man8/ziomon_zfcpdd.8* +%{_mandir}/man8/ziorep_config.8* +%{_mandir}/man8/ziorep_traffic.8* +%{_mandir}/man8/ziorep_utilization.8* + +# +# *********************** s390-tools iucvterm package ************************* +# +%package iucvterm +License: GPLv2 +Summary: z/VM IUCV terminal applications +Group: Applications/System +BuildRequires: gettext + +%description iucvterm +A set of applications to provide terminal access via the z/VM Inter-User +Communication Vehicle (IUCV). The terminal access does not require an +active TCP/IP connection between two Linux guest operating systems. + +- iucvconn: Application to establish a terminal connection via z/VM IUCV. +- iucvtty: Application to provide terminal access via z/VM IUCV. +- ts-shell: Terminal server shell to authorize and control IUCV terminal + connections for individual Linux users. + +%pre iucvterm +# check for ts-shell group and create it +getent group ts-shell > /dev/null || groupadd -r ts-shell + +%post iucvterm +# /etc/shells is provided by "setup" +grep -q '^/usr/bin/ts-shell$' /etc/shells \ + || echo "/usr/bin/ts-shell" >> /etc/shells + +%postun iucvterm +if [ $1 = 0 ] +then + # remove ts-shell from /etc/shells on uninstall + grep -v '^/usr/bin/ts-shell$' /etc/shells > /etc/shells.ts-new + mv /etc/shells.ts-new /etc/shells + chmod 0644 /etc/shells +fi + +%files iucvterm +%defattr(-,root,root,-) +%dir %{_sysconfdir}/iucvterm +%config(noreplace) %attr(0640,root,ts-shell) %{_sysconfdir}/iucvterm/ts-audit-systems.conf +%config(noreplace) %attr(0640,root,ts-shell) %{_sysconfdir}/iucvterm/ts-authorization.conf +%config(noreplace) %attr(0640,root,ts-shell) %{_sysconfdir}/iucvterm/ts-shell.conf +%config(noreplace) %attr(0640,root,ts-shell) %{_sysconfdir}/iucvterm/unrestricted.conf +%{_bindir}/iucvconn +%{_bindir}/iucvtty +%{_bindir}/ts-shell +%{_sbindir}/chiucvallow +%{_sbindir}/lsiucvallow +%dir %attr(2770,root,ts-shell) /var/log/ts-shell +%doc iucvterm/doc/ts-shell +%{_mandir}/man1/iucvconn.1* +%{_mandir}/man1/iucvtty.1* +%{_mandir}/man1/ts-shell.1* +%{_mandir}/man7/af_iucv.7* +%{_mandir}/man8/chiucvallow.8* +%{_mandir}/man9/hvc_iucv.9* + +# +# *********************** libzfcphbaapi package *********************** +# +%package libzfcphbaapi +License: CPL +Summary: ZFCP HBA API Library -- HBA API for the zfcp device driver +Group: System Environment/Libraries +URL: http://www.ibm.com/developerworks/linux/linux390/zfcp-hbaapi.html +BuildRequires: automake autoconf +BuildRequires: doxygen libsysfs-devel +BuildRequires: sg3_utils-devel +Requires: libhbaapi +Obsoletes: %{name}-libzfcphbaapi-devel < 2:1.8.2-4 + + +%description libzfcphbaapi +ZFCP HBA API Library is an implementation of FC-HBA (see www.t11.org ) for +the zfcp device driver. + +%files libzfcphbaapi +%defattr (-,root,root,-) +%doc lib-zfcp-hbaapi-%{hbaapiver}/README +%doc lib-zfcp-hbaapi-%{hbaapiver}/COPYING +%doc lib-zfcp-hbaapi-%{hbaapiver}/ChangeLog +%doc lib-zfcp-hbaapi-%{hbaapiver}/AUTHORS +%doc lib-zfcp-hbaapi-%{hbaapiver}/LICENSE +%{_libdir}/libzfcphbaapi-%{hbaapiver}.so +%{_mandir}/man3/libzfcphbaapi.3* +%{_mandir}/man3/SupportedHBAAPIs.3* +%{_mandir}/man3/UnSupportedHBAAPIs.3* +%exclude %{_mandir}/man3/hbaapi.h.3* + +# +# *********************** libzfcphbaapi-devel package *********************** +# +%package libzfcphbaapi-docs +License: CPL +Summary: ZFCP HBA API Library -- Documentation +Group: Development/Libraries +URL: http://www.ibm.com/developerworks/linux/linux390/zfcp-hbaapi.html +Requires: %{name}-libzfcphbaapi = %{epoch}:%{version}-%{release} + +%description libzfcphbaapi-docs +Documentation for the ZFCP HBA API Library. + + +%files libzfcphbaapi-docs +%defattr (-,root,root,-) +%docdir %{_docdir}/lib-zfcp-hbaapi-%{hbaapiver} +%{_docdir}/lib-zfcp-hbaapi-%{hbaapiver}/ + +# +# *********************** cmsfs package *********************** +# +%package cmsfs +License: GPLv2 +Summary: CMS file system tools +Group: System Environment/Base +URL: http://www.casita.net/pub/cmsfs/cmsfs.html +# Requires: + +%description cmsfs +This package contains the CMS file system tools. + +%files cmsfs +%defattr(-,root,root,-) +/sbin/cmsfscat +/sbin/cmsfsck +/sbin/cmsfscp +/sbin/cmsfslst +/sbin/cmsfsvol +%{_mandir}/man8/cmsfscat.8* +%{_mandir}/man8/cmsfsck.8* +%{_mandir}/man8/cmsfscp.8* +%{_mandir}/man8/cmsfslst.8* +%{_mandir}/man8/cmsfsvol.8* + +# +# *********************** devel package *********************** +# +%package devel +License: GPLv2 +Summary: Development files +Group: Development/Libraries + +%description devel +User-space development files for the s390/s390x architecture. + +%files devel +%defattr(-,root,root,-) +%{_includedir}/%{name} + + +%changelog +* Wed Feb 09 2011 Fedora Release Engineering - 2:1.8.2-30 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild + +* Tue Jul 13 2010 Dan Horák 2:1.8.2-29 +- lsluns: uninitialized value on adapter offline (#611795) +- zfcpdbf: Fix 'Use of uninitialized value' and output issues (#612622) + +* Wed Jul 7 2010 Dan Horák 2:1.8.2-28 +- fix linking with --no-add-needed + +* Tue Jun 29 2010 Dan Horák 2:1.8.2-27 +- make znet_cio_free work also when no interface config files exists (#609073) +- fix --dates option in zfcpdbf (#609092) + +* Mon Jun 28 2010 Dan Horák 2:1.8.2-26 +- follow symlinks in ziorep (#598574) +- do not restrict group names to be alphanumeric in ts-shell (#598641) +- znetconf --drive|-d option returning 'unknown driver' for qeth (#601846) +- fix stack overwrite in cpuplugd (#601847) +- fix cmm_min/max limit checks in cpuplugd (#606366) +- set cpu_min to 1 by default in cpuplugd (#606416) +- build with -fno-strict-aliasing (#599396) +- remove reference to z/VM from the cpi initscript (#601753) +- fix return values for the mon_statd initscript (#606805) +- ignore backup and similar config files in device_cio_free (#533494) + +* Fri May 28 2010 Dan Horák 2:1.8.2-25 +- fixed device_cio_free command line handling (#595569) + +* Thu May 20 2010 Dan Horák 2:1.8.2-24 +- added a check for the length of the parameters line (#594031) + +* Wed May 19 2010 Dan Horák 2:1.8.2-23 +- make ccw_init compatible with posix shell (#546615) + +* Wed May 5 2010 Dan Horák 2:1.8.2-22 +- scripts can't depend on stuff from /usr (#587364) + +* Mon May 3 2010 Dan Horák 2:1.8.2-21 +- updated patch for the "reinitialize array in lsqeth" issue (#587757) + +* Fri Apr 30 2010 Dan Horák 2:1.8.2-20 +- updated lsdasd man page (#587044) +- reinitialize array in lsqeth (#587599) + +* Wed Apr 28 2010 Dan Horák 2:1.8.2-19 +- fixed mismatch between man and -h in chshut (#563625) +- use the merged ccw_init script (#533494, #561814) + +* Thu Apr 22 2010 Dan Horák 2:1.8.2-18 +- lsluns utility from the base subpackage requires sg3_utils + +* Wed Apr 21 2010 Dan Horák 2:1.8.2-17 +- updated device_cio_free script (#576015) + +* Wed Mar 31 2010 Dan Horák 2:1.8.2-16 +- updated device_cio_free upstart config file (#578260) +- fix multipathing in ziomon (#577318) + +* Mon Mar 29 2010 Dan Horák 2:1.8.2-15 +- remove check for ziorep_config availability (#576579) +- install upstart event file into /etc/init (#561339) +- device_cio_free updates + - don't use basename/dirname + - correctly parse /etc/ccw.conf (#533494) + +* Mon Mar 22 2010 Dan Horák 2:1.8.2-14 +- don't use memory cgroups in zfcpdump kernel (#575183) +- fix df usage in ziomon (#575833) + +* Thu Mar 11 2010 Dan Horák 2:1.8.2-13 +- dropped dependency on redhat-lsb (#542702) + +* Wed Mar 10 2010 Dan Horák 2:1.8.2-12 +- run device_cio_free on startup (#561339) +- use hex index for chpidtype table in znetconf (#561056) +- handle status during IPL SSCH (#559250) +- don't show garbage in vmconvert's progress bar (#567681) +- don't print enviroment when there are no devices to wait for (#570763) +- fix zfcp dump partition error (#572313) +- switched to new initscripts for cpuplugd and fsstatd/procd (#524218, #524477) + +* Tue Feb 16 2010 Dan Horák 2:1.8.2-11 +- moved ccw udev stuff from initscripts to s390utils +- updated ccw_init with delay loops and layer2 handling (#561926) + +* Fri Jan 22 2010 Dan Horák 2:1.8.2-10.1 +- really update zfcpconf.sh script from dracut + +* Wed Jan 20 2010 Dan Horák 2:1.8.2-10 +- fixed return codes in ziorep (#556849) +- fixed return code in lstape (#556910) +- fixed reading the size of /proc/sys/vm/cmm_pages in cpuplugd (#556911) +- support new attributes in lsqeth (#556915) + +* Wed Jan 13 2010 Dan Horák 2:1.8.2-9 +- updated device_cio_free script (#533494) +- fixed uppercase conversion in lscss (#554768) + +* Fri Jan 8 2010 Dan Horák 2:1.8.2-8 +- updated device_cio_free script (#533494) + +* Fri Jan 8 2010 Dan Horák 2:1.8.2-7 +- updated device_cio_free script (#533494) + +* Tue Dec 22 2009 Dan Horák 2:1.8.2-6.1 +- fixed return value in cpi initscript (#541389) + +* Tue Dec 22 2009 Dan Horák 2:1.8.2-6 +- fixed return value in cpi initscript (#541389) +- updated zfcpconf.sh script from dracut +- added device-mapper support into zipl (#546280) +- added missing check and print NSS name in case an NSS has been IPLed (#546297) +- added device_cio_free script and its symlinks (#533494) +- added qualified return codes and further error handling in znetconf (#548487) + +* Fri Nov 13 2009 Dan Horák 2:1.8.2-5 +- added multiple fixes from IBM (#533955, #537142, #537144) + +* Thu Nov 12 2009 Dan Horák 2:1.8.2-4 +- added udev rules and script for dasd initialization (#536966) +- added ghosted zfcp and dasd config files, fixes their ownership on the system +- fixed upgrade path for libzfcphbaapi-devel subpackage + +* Mon Nov 9 2009 Dan Horák 2:1.8.2-3 +- added files for the CPI feature (#463282) +- built lib-zfcp-hbaabi library as vendor lib, switched from -devel (no devel content now) to -docs subpackage (#532707) + +* Fri Oct 30 2009 Dan Horák 2:1.8.2-2 +- install dasd udev rules provided by the s390-tools +- added patch for setting readahead value + +* Thu Oct 8 2009 Dan Horák 2:1.8.2-1 +- added patch for improving mon_statd behaviour +- rebased to 1.8.2 + +* Fri Oct 2 2009 Dan Horák 2:1.8.1-8 +- really changed ramdisk load address (#526339) +- change the required and optional subpackages for the meta package + +* Wed Sep 30 2009 Dan Horák 2:1.8.1-7 +- changed ramdisk load address (#526339) +- updated zfcpconf.sh script to new sysfs interface (#526324) +- added 1.8.1 fixes from IBM (#525495) + +* Fri Sep 25 2009 Dan Horák 2:1.8.1-6 +- fix issues in lib-zfcp-hbaapi with a patch + +* Thu Sep 24 2009 Dan Horák 2:1.8.1-5 +- drop support for Fedora < 10 + +* Thu Sep 24 2009 Dan Horák 2:1.8.1-4 +- fixed string overflow in vtoc_volume_label_init (#525318) + +* Thu Sep 3 2009 Dan Horák 2:1.8.1-3 +- create devel subpackage with some useful headers +- preserving timestamps on installed files + +* Wed Aug 26 2009 Dan Horák 2:1.8.1-2 +- Fix byte check for disk encryption check in lsluns (#510032) +- Fix cmm configuration file value initialization parser in cpuplugd (#511379) +- Check only ZFCP devices in lszfcp (#518669) + +* Mon Jun 29 2009 Dan Horák 2:1.8.1-1 +- update to 1.8.1 +- drop upstreamed patches +- create iucvterm subpackage +- update src_vipa locations patch +- install cmsfs tools into /sbin +- add post 1.8.1 fixes from IBM + +* Fri Apr 17 2009 Dan Horák 2:1.8.0-6 +- fix build with newer kernels + +* Wed Mar 25 2009 Dan Horák 2:1.8.0-5 +- reword the summaries a bit +- add downloadable URLs for Sources +- fix CFLAGS usage + +* Fri Mar 13 2009 Dan Horák 2:1.8.0-4 +- next round of clean-up for compliance with Fedora + +* Sun Mar 8 2009 Dan Horák 2:1.8.0-3 +- little clean-up for compliance with Fedora + +* Fri Dec 12 2008 Hans-Joachim Picht 2:1.8.0-2 +- Adapted package for F9 + +* Tue Dec 8 2008 Michael Holzheu 2:1.8.0-1 +- Changed spec file to create sub packages +- Updated to zfcphbaapi version 2.0 + +* Tue Oct 28 2008 Dan Horák 2:1.7.0-4 +- disable build-id feature in zipl (#468017) + +* Wed Sep 24 2008 Dan Horák 2:1.7.0-3 +- drop the mon_tools patch (mon_statd service starts both mon_procd and mon_fsstatd since 1.7.0) + +* Thu Aug 28 2008 Dan Horák 2:1.7.0-2 +- preserve timestamps on installed files +- add proper handling of initscripts +- fix permissions for some files + +* Tue Aug 12 2008 Dan Horák 2:1.7.0-1 +- update to s390-tools 1.7.0, src_vipa 2.0.4 and cmsfs 1.1.8c +- rebase or drop RHEL5 patches + +* Fri Jul 25 2008 Dan Horák 2:1.5.3-19.el5 +- fix use "vmconvert" directly on the vmur device node (#439389) +- fix the Linux Raid partition type is not retained when changed through fdasd (#445271) +- include missing files into the package (#442584) +- Resolves: #439389, #445271, #442584 + +* Fri Jul 25 2008 Dan Horák 2:1.5.3-18.el5 +- split the warnings patch into s390-tools and cmsfs parts +- mismatch between installed /etc/zfcp.conf and zfcpconf.sh expected format (#236016) +- dbginfo.sh exits before running all tests and drops errors (#243299) +- updates for cleanup SCSI dumper code for upstream integration - tool (#253118) +- fix segfault when using LD_PRELOAD=/usr/lib64/src_vipa.so (#282751) +- add support for timeout parameter in /etc/zipl.conf (#323651) +- fixes not listing all the dasds passed as arguments to lsdasd command (#369891) +- fix for zipl fail when section is specified and target is not repeated for all sections (#381201) +- fix for dasdview -s option fails to ignore the garbage value passed (#412951) +- update documentation for zfcpdump (#437477) +- update documentation for lsqeth (#455908) +- Resolves: #236016, #243299, #253118, #282751, #323651, #369891, #381201, #412951, #437477, #455908 + +* Fri Mar 28 2008 Phil Knirsch 2:1.5.3-17.el5 +- Fix error messages and proc/0 entry are not handled correctly (#438819) + +* Wed Feb 06 2008 Phil Knirsch 2:1.5.3-16.el5 +- Fixed a build problem with the mon_tools patch (#253029) + +* Mon Feb 04 2008 Phil Knirsch 2:1.5.3-14.el5 +- Added zfcpdump kernel symlink to dumpconf init script (#430550) + +* Fri Jan 18 2008 Phil Knirsch 2:1.5.3-13.el5 +- Fix tape390_crypt query shows wrong msg 'Kernel does not support tape encryption' (#269181) + +* Wed Jan 16 2008 Phil Knirsch 2:1.5.3-12.el5 +- Add System z guest file system size in Monitor APPLDATA (#253029) +- Add Dynamic CHPID reconfiguration via SCLP - tools (#253076) +- Add z/VM unit-record device driver - tools (#253078) +- Cleanup SCSI dumper code for upstream integration - tool (#253118) + +* Tue Jan 08 2008 Phil Knirsch 2:1.5.3-11.el5 +- Fix installer LVM partitions that show up as "unknown" in fdasd (#250176) +- Fixed zfcpconf.sh failure if / and /usr are separated (#279201) + +* Mon Sep 24 2007 Phil Knirsch 2:1.5.3-10.el5.14 +- Added missing openssl-devel buildrequires (#281361) + +* Thu Aug 23 2007 Phil Knirsch 2:1.5.3-10.el5.13 +- Last updage for -t parameter patch (#202086) + +* Tue Aug 14 2007 Phil Knirsch 2:1.5.3-10.el5.12 +- Fix handling of external timer interrupts (#250352) + +* Tue Jul 31 2007 Phil Knirsch 2:1.5.3-10.el5.11 +- Update fix for -t parameter for image operations (#202086) + +* Fri Jul 27 2007 Phil Knirsch 2:1.5.3-10.el5.10 +- Fixed udev regression from RHEL 4 with /dev/dasd/ (#208189) +- Fixed missing -d option for zgetdump (#228094) + +* Thu Jun 28 2007 Phil Knirsch 2:1.5.3-10.el5.9 +- Fix optional -t parameter for image operations (#202086) + +* Wed Jun 27 2007 Phil Knirsch 2:1.5.3-10.el5.8 +- Fix wrong manpage (#202250) +- Fix zfcp devices not showing up after boot (#223569) +- Fix help menu of lsqeth showing wrong file (#225159) +- Add tape encryption userspace tool (#228080) +- Add dump on panic initscript and sysconf (#228094) +- Fix a off-by-one error in zfcpdbf (#230527) +- Fix zipl aborting with floating point exception if the target specified is a logical volume (#231240) +- Fix boot menu use wrong conversion table for input on LPAR (#240399) + +* Mon Jan 22 2007 Phil Knirsch 2:1.5.3-10.el5.6 +- Fixed problem with invisible zfcp devices after boot (#223569) + +* Mon Jan 15 2007 Phil Knirsch 2:1.5.3-10.el5.5 +- Extended fix for automenu bug (#202086) + +* Thu Jan 11 2007 Phil Knirsch 2:1.5.3-10.el5.4 +- Updated dbginfo.sh patch to final fix from IBM (#214805) + +* Wed Nov 29 2006 Phil Knirsch 2:1.5.3-10.el5.3 +- Fixed problem with missing debugfs for dbginfo.sh (#214805) + +* Thu Nov 09 2006 Phil Knirsch 2:1.5.3-10.el5.2 +- Fixed lszfcp bug related to sysfsutils (#210515) + +* Tue Nov 07 2006 Phil Knirsch 2:1.5.3-10.el5.1 +- Removed wrong additional $ in src_vipa.sh (#213395) +- Release and Buildroot specfile fixes + +* Wed Sep 13 2006 Phil Knirsch 2:1.5.3-10 +- Needed to bump release + +* Tue Sep 12 2006 Phil Knirsch 2:1.5.3-9 +- Added libsysfs requirement (#201863) +- Fixed zipl problem with missing default target for automenus (#202086) + +* Thu Aug 10 2006 Phil Knirsch 2:1.5.3-8 +- Added missing sysfsutils requirement for lszfcp (#201863) + +* Tue Jul 25 2006 Phil Knirsch 2:1.5.3-7 +- Included zfcpdbf, dbginfo.sh and the man1 manpages to package (#184812) + +* Tue Jul 18 2006 Phil Knirsch 2:1.5.3-6 +- Disabled sysfs support due to API changes in sysfs-2.0.0 + +* Fri Jul 14 2006 Karsten Hopp 2:1.5.3-5 +- buildrequire net-snmp-devel + +* Fri Jul 14 2006 Jesse Keating - 2:1.5.3-4 +- rebuild +- Add missing br libsysfs-devel, indent, zlib-devel + +* Wed May 17 2006 Phil Knirsch 2:1.5.3-1 +- Made src_vipa build on current toolchain again + +* Tue May 16 2006 Phil Knirsch +- Update to s390-tools-1.5.3 from IBM +- Included vmconvert +- Dropped obsolete asm patch + +* Tue Feb 07 2006 Jesse Keating - 2:1.5.0-2.1 +- rebuilt for new gcc4.1 snapshot and glibc changes + +* Mon Jan 30 2006 Phil Knirsch 2:1.5.0-2 +- Fixed problem with s390-tools-1.5.0-fdasd-raid.patch +- Don't try to remove the non empty _bindir +- Some more install cleanups + +* Thu Jan 26 2006 Phil Knirsch +- Fixed some .macro errors in zipl/boot + +* Fri Dec 09 2005 Jesse Keating +- rebuilt + +* Thu Oct 20 2005 Phil Knirsch 2:1.5.0-1 +- Large update from 1.3.2 to 1.5.0 +- Include osasnmpd and vmcp now by default + +* Tue Sep 06 2005 Phil Knirsch 2:1.3.2-7 +- Fixed a couple of code bugs (#143808) + +* Fri Jul 29 2005 Phil Knirsch 2:1.3.2-6 +- Corrected filelist for libdir to only include *.so files + +* Tue Jun 21 2005 Phil Knirsch 2:1.3.2-5 +- Added src_vipa to s390utils + +* Wed Mar 02 2005 Phil Knirsch 2:1.3.2-4 +- bump release and rebuild with gcc 4 + +* Tue Oct 26 2004 Phil Knirsch 2:1.3.2-3 +- Put binaries for system recovery in /sbin again. + +* Fri Oct 15 2004 Phil Knirsch 2:1.3.2-1 +- Update to s390-tools-1.3.2 +- Added qetharp, qethconf, ip_watcher, tunedasd and various other tools to + improve functionality on s390(x). + +* Wed Oct 06 2004 Phil Knirsch 2:1.3.1-7 +- Made the raid patch less verbose (#129656) + +* Thu Sep 16 2004 Phil Knirsch 2:1.3.1-6 +- Added prompt=1 and timeout=15 to automatically generated menu + +* Tue Aug 31 2004 Karsten Hopp 2:1.3.1-5 +- install zfcpconf.sh into /sbin + +* Tue Aug 24 2004 Karsten Hopp 2:1.3.1-4 +- add zfcpconf.sh to read /etc/zfcp.conf and configure the zfcp + devices + +* Thu Jun 24 2004 Phil Knirsch 2:1.3.1-3 +- Fixed another automenu bug with dumpto and dumptofs (#113204). + +* Thu Jun 17 2004 Phil Knirsch 2:1.3.1-2 +- Fixed automenu patch. +- Fixed problem with installation from tape (#121788). + +* Wed Jun 16 2004 Phil Knirsch 2:1.3.1-1 +- Updated to latest upstream version s390-tools-1.3.1 + +* Tue Jun 15 2004 Elliot Lee +- rebuilt + +* Mon Jun 07 2004 Karsten Hopp +- add cmsfs utils + +* Tue Mar 02 2004 Elliot Lee +- rebuilt + +* Thu Feb 19 2004 Phil Knirsch 2:1.2.4-4 +- Fixed rebuilt on fc2. + +* Thu Feb 19 2004 Phil Knirsch 2:1.2.4-3 +- Fixed automenu patch, was allocating 1 line to little. + +* Mon Feb 16 2004 Phil Knirsch 2:1.2.4-2 +- rebuilt + +* Mon Feb 16 2004 Phil Knirsch 2:1.2.4-1 +- Updated to latest developerworks release 1.2.4 +- Disabled zfcpdump build until i find a way to build it as none-root. + +* Fri Feb 13 2004 Elliot Lee 2:1.2.3-3 +- rebuilt + +* Thu Dec 04 2003 Phil Knirsch 2:1.2.3-2 +- Fixed zfcpdump build. + +* Fri Nov 28 2003 Phil Knirsch 2:1.2.3-1 +- New bugfix release 1.2.3 came out today, updated again. + +* Wed Nov 26 2003 Phil Knirsch 2:1.2.2-1 +- Updated to latest Developerworks version 1.2.2 +- Cleaned up specfile and patches a little. + +* Wed Nov 12 2003 Phil Knirsch 2:1.2.1-4.1 +- rebuilt + +* Wed Nov 12 2003 Phil Knirsch 2:1.2.1-4 +- Another fix for the new automenu patch. Target was an optional parameter in + old s390utils, provided compatibility behaviour. + +* Mon Oct 20 2003 Phil Knirsch 2:1.2.1-3.1 +- rebuilt + +* Mon Oct 20 2003 Phil Knirsch 2:1.2.1-3 +- Small fix for the new automenu patch, default section didn't work correctly + +* Mon Oct 20 2003 Phil Knirsch 2:1.2.1-2.1 +- rebuilt + +* Fri Oct 17 2003 Phil Knirsch 2:1.2.1-2 +- Patched new zipl to be backwards compatible to old multiboot feature. + +* Thu Oct 9 2003 Harald Hoyer 2:1.2.1-1 +- second round at updating to 1.2.1 + +* Thu Oct 09 2003 Florian La Roche +- first round at updating to 1.2.1 + +* Sat Sep 27 2003 Florian La Roche +- add /boot/tape0 for .tdf tape boots + +* Fri Jul 25 2003 Florian La Roche +- apply dasdfmt patch from 1.2.1 + +* Fri Jun 20 2003 Phil Knirsch 1.1.7-1 +- Updated to latest upstream version 1.1.7 + +* Fri May 02 2003 Pete Zaitcev 1.1.6-7 +- Fix usage of initialized permissions for bootmap. + +* Tue Apr 29 2003 Florian La Roche +- add extra tape loader from Pete Zaitcev + +* Mon Apr 14 2003 Karsten Hopp 2:1.1.6-5 +- drop cpint support + +* Mon Mar 24 2003 Karsten Hopp 1.1.6-4 +- use multiboot as default +- add option to disable multiboot + +* Sat Mar 22 2003 Karsten Hopp 1.1.6-3 +- add multiboot patch + +* Mon Mar 10 2003 Karsten Hopp 1.1.6-2 +- added percentage patch (used by anaconda to display progress bars) + +* Thu Feb 27 2003 Phil Knirsch 1.1.6-1 +- Updated to newest upstream version 1.1.6 + +* Tue Feb 04 2003 Phil Knirsch 1.1.5-1 +- Updated to newest upstream version 1.1.5 + +* Tue Feb 04 2003 Karsten Hopp 1.1.4-3 +- install libraries in /lib*, not /usr/lib*, they are required + by some tools in /sbin + +* Sun Feb 02 2003 Florian La Roche +- fix filelist to not include debug files + +* Fri Jan 24 2003 Phil Knirsch 1.1.4-1 +- Updated to latest upstream version of IBM. +- Removed all unecessary patches and updated still needed patches. +- Fixed version number. Needed to introduce epoch though. +- A little specfile cleanup. +- Dropped oco-setver and oco-convert as we don't need them anymore. + +* Wed Jan 22 2003 Phil Knirsch 20020226-4 +- Added ExclusiveArch tag. + +* Mon Oct 21 2002 Phil Knirsch 20020226-3 +- Removed fdisk -> fdasd symlink. Is now provided by util-linux. +- Disabled f5 patch for s390x for now. Enable it later for newer kernels again. + +* Mon May 27 2002 Phil Knirsch +- Fixed dasdview to build on kernels > 2.4.18. + +* Wed Apr 24 2002 Karsten Hopp +- add IBM 5 patch + +* Tue Jan 29 2002 Karsten Hopp +- add IBM 4 patch +- add profile.d scripts to set correct TERM in 3270 console + +* Thu Dec 18 2001 Karsten Hopp +- add cpint programs + +* Mon Nov 26 2001 Harald Hoyer 20011012-6 +- fix for #56720 + +* Thu Nov 15 2001 Karsten Hopp +- add fdisk - > fdasd symlink + +* Thu Nov 12 2001 Karsten Hopp +- add IBM patch (11/09/2001) and redo percentage patch + +* Thu Nov 08 2001 Karsten Hopp +- re-enable DASD if dasdfmt is interrupted with Ctrl-C + +* Mon Nov 05 2001 Harald Hoyer 20011012-4 +- added s390-tools-dasdfmt-percentage.patch + +* Mon Oct 22 2001 Karsten Hopp +- remove postinstall script + +* Mon Oct 15 2001 Karsten Hopp +- add IBM's s390-utils-2.patch +- add console to securetty + +* Mon Oct 01 2001 Karsten Hopp +- added oco-setkver and oco-convert + +* Fri Aug 31 2001 Karsten Hopp +- don't write error message in silent mode + +* Thu Aug 23 2001 Harald Hoyer +- added s390-tools-dasdfmt-status.patch + +* Tue Aug 21 2001 Karsten Hopp +- update to the version from Aug 20 + +* Tue Aug 14 2001 Karsten Hopp +- fix permissions + +* Mon Aug 13 2001 Karsten Hopp +- rename package to s390utils. s390-tools is no longer needed. + +* Thu Aug 02 2001 Karsten Hopp +- initial build diff --git a/sources b/sources new file mode 100644 index 0000000..ac05290 --- /dev/null +++ b/sources @@ -0,0 +1,4 @@ +856ecdd42ad358433eb3fcc886b58a89 s390-tools-1.8.2.tar.bz2 +71a8ee5918f2c44c385fcfe8350cdc98 cmsfs-1.1.8c.tar.gz +2cbfffca3f07c61420899f45d221d451 lib-zfcp-hbaapi-2.0.tar.gz +ba42772e5b305b5e147344442cd70826 src_vipa-2.0.4.tar.gz diff --git a/src_vipa-2.0.4-locations.patch b/src_vipa-2.0.4-locations.patch new file mode 100644 index 0000000..799b0f4 --- /dev/null +++ b/src_vipa-2.0.4-locations.patch @@ -0,0 +1,74 @@ +From b2f1bf78400c686bbdbcf4c29fbbb93367abe409 Mon Sep 17 00:00:00 2001 +From: =?utf-8?q?Dan=20Hor=C3=A1k?= +Date: Wed, 25 Mar 2009 09:36:08 +0100 +Subject: [PATCH] fix location of the library + +--- + Makefile | 7 +++---- + 1 files changed, 3 insertions(+), 4 deletions(-) + +diff --git a/Makefile b/Makefile +index 669b6c6..d395fa8 100644 +--- a/Makefile ++++ b/Makefile +@@ -20,7 +20,8 @@ INSTALL=install + VERSION=2.0.4 + + # the path to the .so +-SRC_VIPA_PATH=$(INSTROOT)/usr/lib ++LIBDIR=/usr/lib ++SRC_VIPA_PATH=$(INSTROOT)$(LIBDIR) + # the path to the starter script + SRC_VIPA_STARTER_PATH=$(INSTROOT)/usr/sbin + # path to man page +@@ -34,8 +35,7 @@ src_vipa.so: src_vipa.c + + src_vipa.sh: + echo '#!/bin/bash' > src_vipa.sh +- echo 'export LD_LIBRARY_PATH=$(SRC_VIPA_PATH):$$LD_LIBRARY_PATH' >> src_vipa.sh +- echo 'export LD_PRELOAD=$(SRC_VIPA_PATH)/src_vipa.so' >> src_vipa.sh ++ echo 'export LD_PRELOAD=$(LIBDIR)/src_vipa.so' >> src_vipa.sh + echo 'exec $$@' >> src_vipa.sh + chmod 755 src_vipa.sh + +@@ -44,7 +44,6 @@ install: src_vipa.so src_vipa.sh + $(INSTALL) -m 755 src_vipa.so $(SRC_VIPA_PATH) + $(INSTALL) -m 755 src_vipa.sh $(SRC_VIPA_STARTER_PATH) + $(INSTALL) -m 644 src_vipa.8 $(SRC_VIPA_MANPAGE_PATH)/man8 +- ldconfig + + clean: + rm -f src_vipa.{i,s,o,sh,so} core src_vipa-$(VERSION).tar.gz +-- +1.6.0.6 + +From 5c21f29f4d9e82942a997775c111280b85d01bb8 Mon Sep 17 00:00:00 2001 +From: =?utf-8?q?Dan=20Hor=C3=A1k?= +Date: Wed, 22 Apr 2009 12:53:55 +0200 +Subject: [PATCH] make the man page path and script path configurable + +--- + Makefile | 6 ++++-- + 1 files changed, 4 insertions(+), 2 deletions(-) + +diff --git a/Makefile b/Makefile +index d395fa8..365472b 100644 +--- a/Makefile ++++ b/Makefile +@@ -23,9 +23,11 @@ VERSION=2.0.4 + LIBDIR=/usr/lib + SRC_VIPA_PATH=$(INSTROOT)$(LIBDIR) + # the path to the starter script +-SRC_VIPA_STARTER_PATH=$(INSTROOT)/usr/sbin ++SBINDIR=/usr/sbin ++SRC_VIPA_STARTER_PATH=$(INSTROOT)$(SBINDIR) + # path to man page +-SRC_VIPA_MANPAGE_PATH=$(INSTROOT)/usr/share/man ++MANDIR=/usr/share/man ++SRC_VIPA_MANPAGE_PATH=$(INSTROOT)$(MANDIR) + + all: src_vipa.so src_vipa.sh + +-- +1.6.0.6 + diff --git a/zfcp.udev b/zfcp.udev new file mode 100644 index 0000000..5e846a4 --- /dev/null +++ b/zfcp.udev @@ -0,0 +1 @@ +KERNEL=="zfcp_cfdc", RUN+="/sbin/zfcpconf.sh" diff --git a/zfcpconf.sh b/zfcpconf.sh new file mode 100644 index 0000000..ff8506f --- /dev/null +++ b/zfcpconf.sh @@ -0,0 +1,55 @@ +#!/bin/sh + +# config file syntax: +# deviceno WWPN FCPLUN +# +# Example: +# 0.0.4000 0x5005076300C213e9 0x5022000000000000 +# 0.0.4001 0x5005076300c213e9 0x5023000000000000 +# +# +# manual setup: +# modprobe zfcp +# echo 1 > /sys/bus/ccw/drivers/zfcp/0.0.4000/online +# echo LUN > /sys/bus/ccw/drivers/zfcp/0.0.4000/WWPN/unit_add +# +# Example: +# modprobe zfcp +# echo 1 > /sys/bus/ccw/drivers/zfcp/0.0.4000/online +# echo 0x5022000000000000 > /sys/bus/ccw/drivers/zfcp/0.0.4000/0x5005076300c213e9/unit_add + +CONFIG=/etc/zfcp.conf +PATH=/bin:/sbin + +if [ -f "$CONFIG" ]; then + if [ ! -d /sys/bus/ccw/drivers/zfcp ]; then + modprobe zfcp + fi + if [ ! -d /sys/bus/ccw/drivers/zfcp ]; then + return + fi + sed 'y/ABCDEF/abcdef/' < $CONFIG | while read line; do + case $line in + \#*) ;; + *) + [ -z "$line" ] && continue + set $line + if [ $# -eq 5 ]; then + DEVICE=$1 + SCSIID=$2 + WWPN=$3 + SCSILUN=$4 + FCPLUN=$5 + echo "Warning: Deprecated values in /etc/zfcp.conf, ignoring SCSI ID $SCSIID and SCSI LUN $SCSILUN" + elif [ $# -eq 3 ]; then + DEVICE=${1##*0x} + WWPN=$2 + FCPLUN=$3 + fi + echo 1 > /sys/bus/ccw/drivers/zfcp/${DEVICE}/online + [ ! -d /sys/bus/ccw/drivers/zfcp/${DEVICE}/${WWPN}/${FCPLUN} ] \ + && echo $FCPLUN > /sys/bus/ccw/drivers/zfcp/${DEVICE}/${WWPN}/unit_add + ;; + esac + done +fi