From 4ea3cbdd493f53552fe4e4c93e7cd97f8fbc6079 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dan=20Hor=C3=A1k?= Date: Wed, 30 Sep 2009 20:09:33 +0000 Subject: [PATCH] - changed ramdisk load address (#526339) - updated zfcpconf.sh script to new sysfs interface (#526324) - added 1.8.1 fixes from IBM (#525495) --- ...nge-default-load-address-for-ramdisk.patch | 27 ++ 0024-s390-tools-1.8.1-cpuplugd-limits.patch | 106 +++++ 0025-s390-tools-1.8.1-misc-bugfixes.patch | 363 ++++++++++++++++++ s390utils.spec | 19 +- zfcpconf.sh | 9 +- 5 files changed, 517 insertions(+), 7 deletions(-) create mode 100644 0023-change-default-load-address-for-ramdisk.patch create mode 100644 0024-s390-tools-1.8.1-cpuplugd-limits.patch create mode 100644 0025-s390-tools-1.8.1-misc-bugfixes.patch diff --git a/0023-change-default-load-address-for-ramdisk.patch b/0023-change-default-load-address-for-ramdisk.patch new file mode 100644 index 0000000..a6d9456 --- /dev/null +++ b/0023-change-default-load-address-for-ramdisk.patch @@ -0,0 +1,27 @@ +From bfe74e60ab6529986a7c251042d17d57a3ccf675 Mon Sep 17 00:00:00 2001 +From: =?utf-8?q?Dan=20Hor=C3=A1k?= +Date: Wed, 30 Sep 2009 18:19:23 +0200 +Subject: [PATCH 23/25] change default load address for ramdisk + +The default load address for the initial ramdisk is changed from +0x100000 to 0x200000 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..0f04072 100644 +--- a/zipl/include/zipl.h ++++ b/zipl/include/zipl.h +@@ -21,7 +21,7 @@ + #define ZIPL_STAGE3_ENTRY_ADDRESS 0xa028LL + #define DEFAULT_PARMFILE_ADDRESS 0x1000LL + #define DEFAULT_STAGE3_ADDRESS 0xa000LL +-#define DEFAULT_IMAGE_ADDRESS 0x10000LL ++#define DEFAULT_IMAGE_ADDRESS 0x20000LL + #define DEFAULT_RAMDISK_ADDRESS 0x800000LL + + #define PSW_ADDRESS_MASK 0x000000007fffffffLL +-- +1.6.3.3 + diff --git a/0024-s390-tools-1.8.1-cpuplugd-limits.patch b/0024-s390-tools-1.8.1-cpuplugd-limits.patch new file mode 100644 index 0000000..104c504 --- /dev/null +++ b/0024-s390-tools-1.8.1-cpuplugd-limits.patch @@ -0,0 +1,106 @@ +From 0b02dbdbd248ca51583e9dce3bd57025b965534d Mon Sep 17 00:00:00 2001 +From: =?utf-8?q?Dan=20Hor=C3=A1k?= +Date: Wed, 30 Sep 2009 18:22:15 +0200 +Subject: [PATCH 24/25] s390-tools-1.8.1-cpuplugd-limits + +Description: cpuplugd: fix cmm_pages allocation outside min and max range +Symptom: cpuplugd might instruct CMM to operated outside the predefined limits +Problem: This problem is basically caused by a missing new line separator at + the interface between the daemon and the proc file. +Solution: Add newline to the end of each line when writing to /proc/sys/vm/cmm_pages +Problem-ID: 55472 +--- + cpuplugd/config.c | 15 +++++++++++++-- + cpuplugd/daemon.c | 11 ----------- + cpuplugd/mem.c | 6 +++--- + 3 files changed, 16 insertions(+), 16 deletions(-) + +diff --git a/cpuplugd/config.c b/cpuplugd/config.c +index c013a65..bd3cb43 100644 +--- a/cpuplugd/config.c ++++ b/cpuplugd/config.c +@@ -494,7 +494,7 @@ void check_config(struct config *cfg) + if (memory == 1) { + /* + * check that the initial value of cmm_pages is not below +- * cmm_min ++ * cmm_min or above cmm_max + */ + cmm_pagesize_start = get_cmmpages_size(); + if (cmm_pagesize_start < cfg->cmm_min) { +@@ -506,7 +506,18 @@ void check_config(struct config *cfg) + syslog(LOG_INFO, "cmm_pages is below minimum " + "and will be increased\n"); + } +- memunplug(cfg->cmm_min); ++ set_cmm_pages(cfg->cmm_min); ++ } ++ if (cmm_pagesize_start > cfg->cmm_max) { ++ if (debug && foreground == 1) { ++ printf("cmm_pages is above the maximum and will " ++ "be decreased.\n"); ++ } ++ if (debug && foreground == 0) { ++ syslog(LOG_INFO, "cmm_pages is above the maximum " ++ "and will be decreased\n"); ++ } ++ set_cmm_pages(cfg->cmm_max); + } + } + } +diff --git a/cpuplugd/daemon.c b/cpuplugd/daemon.c +index d0769f3..e1ef623 100644 +--- a/cpuplugd/daemon.c ++++ b/cpuplugd/daemon.c +@@ -260,17 +260,6 @@ void check_max(struct config *cfg) + cpuid++; + } + } +- if (memory && get_cmmpages_size() > cfg->cmm_max) { +- if (debug && foreground == 1) { +- printf("cmm_pages is above the maximum and will " +- "be decreased.\n"); +- } +- if (debug && foreground == 0) { +- syslog(LOG_INFO, "cmm_pages is above the maximum " +- "and will be decreased\n"); +- } +- set_cmm_pages(cfg->cmm_max); +- } + } + + /* check if we are running in an LPAR environment. +diff --git a/cpuplugd/mem.c b/cpuplugd/mem.c +index 2f3d219..6200904 100644 +--- a/cpuplugd/mem.c ++++ b/cpuplugd/mem.c +@@ -138,7 +138,7 @@ int memunplug(int size) + ":%s\n", strerror(errno)); + return -1; + } +- fprintf(filp, "%d", new_size); ++ fprintf(filp, "%d\n", new_size); + if (debug && foreground == 1) + printf("changed number of pages permanently reserved " + "to %d \n", new_size); +@@ -173,7 +173,7 @@ int memplug(int size) + ":%s\n", strerror(errno)); + return -1; + } +- fprintf(filp, "%d", new_size); ++ fprintf(filp, "%d\n", new_size); + if (debug && foreground == 1) + printf("changed number of pages permanently reserved " + "to %d \n", new_size); +@@ -200,7 +200,7 @@ int set_cmm_pages(int size) + ":%s\n", strerror(errno)); + return -1; + } +- fprintf(filp, "%d", size); ++ fprintf(filp, "%d\n", size); + if (debug && foreground == 1) + printf("changed number of pages permanently reserved " + "to %d \n", size); +-- +1.6.3.3 + diff --git a/0025-s390-tools-1.8.1-misc-bugfixes.patch b/0025-s390-tools-1.8.1-misc-bugfixes.patch new file mode 100644 index 0000000..7b80e58 --- /dev/null +++ b/0025-s390-tools-1.8.1-misc-bugfixes.patch @@ -0,0 +1,363 @@ +From 60a3bf1df6d7039f75d889f15d7839f8482c2889 Mon Sep 17 00:00:00 2001 +From: =?utf-8?q?Dan=20Hor=C3=A1k?= +Date: Wed, 30 Sep 2009 18:24:52 +0200 +Subject: [PATCH 25/25] s390-tools-1.8.1-misc-bugfixes + +Miscellaneous minor bufgixes for s390-tools RHEL5.5: +* lsshut: Fix printing of vmcmd shutdown action: Also print CP commands + that have more than one word. +* af_iucv: Doc update for connection-oriented datagram sockets. +--- + ipl_tools/system.c | 13 +++-- + man/af_iucv.7 | 174 +++++++++++++++++++++++++++++++++++++++++++++++----- + 2 files changed, 166 insertions(+), 21 deletions(-) + +diff --git a/ipl_tools/system.c b/ipl_tools/system.c +index 8294db0..fd5b76b 100644 +--- a/ipl_tools/system.c ++++ b/ipl_tools/system.c +@@ -74,7 +74,7 @@ out: + char *substring(size_t start, size_t stop, const char *src, char *dst, + size_t size) + { +- int count; ++ unsigned int count; + + count = stop - start; + if (count >= --size) +@@ -102,7 +102,7 @@ int check_for_root(void) + int ishex(char *cp) + { + +- int i; ++ unsigned int i; + char c; + + for (i = 0; i <= strlen(cp); i++) { +@@ -168,13 +168,13 @@ int strrd(char *string, char *file) + + strncpy(path, file, sizeof(path)); + if (access(path, R_OK) == 0) { +- filp = fopen(path, "r"); ++ filp = fopen(path, "rb"); + if (!filp) { + fprintf(stderr, "%s: Can not open %s: ", name, file); + fprintf(stderr, "%s\n", strerror(errno)); + exit(1); + } +- rc = fscanf(filp, "%s", string); ++ rc = fread(string, 4096, 1, filp); + fclose(filp); + /* + * special handling is required for +@@ -192,8 +192,11 @@ int strrd(char *string, char *file) + file); + fprintf(stderr, "%s\n", strerror(errno)); + return -1; +- } else ++ } else { ++ if (string[strlen(string) - 1] == '\n') ++ string[strlen(string) - 1] = 0; + return 0; ++ } + } else { + fprintf(stderr, "%s: Can not open %s: ", name, file); + fprintf(stderr, "%s\n", strerror(errno)); +diff --git a/man/af_iucv.7 b/man/af_iucv.7 +index cdd2691..9d56640 100644 +--- a/man/af_iucv.7 ++++ b/man/af_iucv.7 +@@ -4,7 +4,7 @@ + .\" Copyright IBM Corp. 2008, 2009. + .\" Author(s): Hendrik Brueckner + .\" ---------------------------------------------------------------------- +-.TH AF_IUCV 7 "March 2009" "s390-tools" "Linux Programmer's Manual" ++.TH AF_IUCV 7 "September 2009" "s390-tools" "Linux Programmer's Manual" + .SH NAME + iucv, AF_IUCV \- Sockets for z/VM IUCV communication + . +@@ -13,15 +13,17 @@ iucv, AF_IUCV \- Sockets for z/VM IUCV communication + .SH SYNOPSIS + .B #include + +-.IB iucv_socket " = socket(AF_IUCV, SOCK_STREAM, 0);" ++.IB iucv_stream_socket " = socket(AF_IUCV, SOCK_STREAM, 0);" ++.br ++.IB iucv_packet_socket " = socket(AF_IUCV, SOCK_SEQPACKET, 0);" + . + . + . + .SH DESCRIPTION + The Inter-User Communication Vehicle (IUCV) is a z/VM communication facility + that enables a program running in one z/VM guest virtual machine to communicate +-with another z/VM guest virtual machine, or with a control program, or even +-with itself. ++with another z/VM guest virtual machine, or with the control program (CP), or ++even with itself. + + The AF_IUCV address family provides communication and addressing in the IUCV + domain. In the IUCV domain, address spaces or virtual machines can use the +@@ -32,7 +34,11 @@ AF_IUCV connects socket applications running on different Linux guest operating + systems, or it connects a Linux application to another socket application + running in another z/VM guest operating system (like z/VM CMS). + +-The AF_IUCV address family supports stream sockets only. ++The AF_IUCV address family supports stream-oriented sockets ++(\f(CWSOCK_STREAM\fP) and connection-oriented datagram sockets ++(\f(CWSOCK_SEQPACKET\fP). Stream-oriented sockets fragment data over several ++native IUCV messages, whereas sockets of type SOCK_SEQPACKET map a particular ++socket write or read operation to a single native IUCV message. + + .SS Features + The AF_IUCV address family provides: +@@ -78,28 +84,106 @@ are reserved for future use. The + .B siucv_port + and + .B siucv_addr +-fields must be zero. The ++fields must be zero. The + .B siucv_nodeid + field must be set to exactly eight blank characters. + . + .TP + .B siucv_userid + is set to the z/VM user ID of the Linux guest virtual machine running the +-application which owns the address. The field must be eight characters long, ++application that owns the address. The field must be eight characters long, + padded with blanks on the right. + + For + .BR bind "(2), " siucv_userid +-must contain blanks only, because AF_IUCV sets the correct z/VM user ID. ++must contain blanks only to allow AF_IUCV to set the z/VM user ID of the Linux ++guest operating system. + . + .TP + .B siucv_name +-is set to the application name by which the socket is known. Servers advertises ++is set to the application name by which the socket is known. Servers advertise + application names and clients use these application names to connect to servers. + This field must be eight characters long, padded with blanks on the right. + . + . + . ++.SH "SOCKET OPTIONS" ++Socket options can be set with ++.BR setsockopt (2) ++and read with ++.BR getsockopt (2) ++by specifying \f(CWSOL_IUCV\fP as the socket level. ++ ++.TP ++.B SO_IPRMDATA_MSG ++Enables the application to send up to seven bytes of socket data in the ++parameter list of an IUCV message. Use this option to increase performance ++when transferring small amounts of data. ++ ++To send data in the parameter list, specify a non-zero integer value. ++ ++.RS ++.TP ++.B Note: ++Use this option with care, older AF_IUCV versions do not support receiving ++socket data in the parameter list and shut down the socket on which ++a parameter list message has been received. ++.RE ++. ++.TP ++.B SO_MSGLIMIT ++Modifies the message limit for new IUCV communication paths. The message ++limit specifies the maximum number of outstanding messages that are allowed ++for established connections. This setting can be lowered by z/VM when an IUCV ++connection is established. ++ ++The message limit is an integer value in range 1 to 65535. ++The default value is 65535. ++ ++The message limit must be set before ++.BR connect "(2) or " listen (2) ++is called for sockets. ++.br ++For sockets that are already connected or listening for connections, ++the message limit cannot be changed. ++.br ++New sockets created by ++.BR accept (2) ++inherit the message limit that has been set for the listening socket. ++ ++.BR getsockopt (2) ++returns the default message limit or the limit that has been set. ++For connected sockets, the current message limit is returned. The current ++message limit is assigned by z/VM for each connection and it depends ++on the IUCV MSGLIMIT statement specified for the z/VM guest virtual machine. ++The current message limit is the lower value of the socket option and the ++value specified for the IUCV MSGLIMIT statement. ++ ++See the SECURITY section below for setting IUCV MSGLIMIT authorizations. ++. ++. ++. ++.SH "ANCILLARY DATA" ++Ancillary data is sent and received using the ++.BR sendmsg (2) ++and ++.BR recvmsg (2)\fR.\fP ++To send ancillary data, set the \fBcmsg_level\fP field of struct \fBcmsghdr\fP ++to \f(CWSOL_IUCV\fP and the \fBcmsg_type\fP field to the type. ++.br ++For more information see ++.BR cmsg (3). ++ ++.TP ++.B SCM_IUCV_TRGCLS ++Send or receive IUCV target class information. The IUCV target class can be used ++to classify and identify an IUCV message at IUCV protocol level. If the target ++class is not specified as ancillary data, it is set to zero. ++ ++The target class is a number of type \fBuint32_t\fP. ++. ++. ++. + . + .SH SECURITY + This section provides an overview of the required IUCV statements for your z/VM +@@ -129,20 +213,20 @@ any other z/VM guest virtual machine. + .TP + .B IUCV \fIuser_ID\fP + allows this z/VM guest virtual machine to establish a communication path to the +-z/VM guest virtual machine with the z/VM user ID \fIuser_ID\fP. ++z/VM guest virtual machine with the z/VM user ID \fIuser_ID\fP. + .PP + You can specify multiple IUCV statements. To any of these IUCV statements you + can append the + .B MSGLIMIT \fIlimit\fP + parameter. + \fIlimit\fP specifies the maximum number of outstanding messages that are +-allowed for each connection authorized by this entry. ++allowed for each connection authorized by this statement. + If no value is specified for \fBMSGLIMIT\fP, AF_IUCV requests 65535, + which is the maximum supported by IUCV. + . + . + .SS "Setting a connection limit" +-Use the \fBOPTION\fP statement to limit the number of concurrent connections. ++Use the \fBOPTION\fP statement to limit the number of concurrent connections. + .TP + .B OPTION MAXCONN \fImaxno\fP + \fImaxno\fP specifies the maximum number of IUCV connections allowed for this +@@ -151,7 +235,7 @@ virtual machine. The default is 64. The maximum is 65535. + . + .SS "Example" + These sample statements allow any z/VM guest virtual machine to connect to your +-z/VM guest virtual machine with a maximum of 10000 outstanding messages for each ++z/VM guest virtual machine with a maximum of 10\^000 outstanding messages for each + incoming connection. Your z/VM guest virtual machine is permitted to connect to + all other z/VM guest virtual machines. The total number of connections for your + z/VM guest virtual machine cannot exceed 100. +@@ -200,6 +284,14 @@ This error can be temporary and the application may try again after some time. + If the error occurs repeatedly, try to increase the maximum number of + connections (for one or both z/VM guest virtual machines). + See the SECURITY section about the required authorization statement. ++ ++.B sendmsg (2) ++called but the maximum number of outstanding IUCV messages for the socket ++connection is reached; i.e. there are data available that has not yet been ++received by the communication partner. ++.br ++If necessary, change the IUCV message limit as explained in section ++"IUCV AUTHORIZATIONS". + . + .TP + .B EACCES +@@ -217,10 +309,22 @@ called but the AF_IUCV setting in the + field of the passed address is missing. + + .BR listen (2) +-called but the AF_IUCV socket has not yet been bound to an address. Always call ++called but the AF_IUCV socket has not yet been bound to an address. ++Always call + .BR bind (2) + before + .BR listen (2). ++ ++.BR setsockopt (2) ++called with option \fBSO_MSGLIMIT\fP for sockets that are already connected. ++. ++.TP ++.B ENOPROTOOPT ++.BR setsockopt (2), ++or ++.BR getsockopt (2) ++called but the socket level has not been set to \f(CWSOL_IUCV\fP, or the ++specified socket option is not supported. + . + .TP + .B EOPNOTSUPP +@@ -232,13 +336,27 @@ might be called with the + flag set. + AF_IUCV does not support sending or receiving \fIout-of-band\fP data on its + sockets. ++ ++For \f(CWSOCK_SEQPACKET\fP sockets, ++.BR sendmsg (2) ++called without the ++.I MSG_EOR ++flag set. ++AF_IUCV does not support segmentation, and thus, the "end-of-record" ++(\fIMSG_EOR\fP) flag must always be set. ++. ++.TP ++.B EPROTONOSUPPORT ++.BR socket (2) ++called with a protocol that is not supported. The socket protocol parameter ++must be either zero or \f(CWPF_IUCV\fP. + . + .TP + .B EAFNOSUPPORT + .BR socket (2) +-called with \fIAF_IUCV\fP but the AF_IUCV protocol / addressing family is not ++called with \f(CWAF_IUCV\fP but the AF_IUCV address family is not + supported by the current Linux kernel. Ensure that your Linux kernel has been +-compiled with support for the AF_IUCV addressing family. ++compiled with support for the AF_IUCV address family. + . + .PP + Other errors can be generated by the generic socket layer. See the respective +@@ -251,6 +369,9 @@ manual pages for more information. + .BR recvmsg (2), + .BR sendmsg (2), + .BR socket (2), ++.BR setsockopt (2), ++.BR getsockopt (2), ++.BR cmsg (3), + .BR socket (7) + + .I "Linux on System z - Device Drivers, Features, and Commands" +@@ -258,3 +379,24 @@ manual pages for more information. + .I "z/VM CP Planning and Administration" + .br + .I "z/VM CP Programming Services" ++. ++. ++. ++.SH "HISTORY" ++.TP ++.B AF_IUCV, version 1.0 ++Initial version. ++.TP ++.B AF_IUCV, version 1.1 ++.RS 4 ++.IP "\(bu" 4 ++Support for sending socket data in the parameter list of an IUCV message ++(\f(CWSO_IPRMDATA_MSG\fP). ++.IP "\(bu" 4 ++Access the target class of an IUCV message as ancillary data using ++.BR sendmsg "(2) and " recvmsg (2). ++.IP "\(bu" 4 ++Support for \f(CWSOCK_SEQPACKET\fP sockets to facilitate development of native ++IUCV applications that interact with AF_IUCV. ++.RE ++ +-- +1.6.3.3 + diff --git a/s390utils.spec b/s390utils.spec index de9335a..7e304e9 100644 --- a/s390utils.spec +++ b/s390utils.spec @@ -8,7 +8,7 @@ Name: s390utils Summary: Utilities and daemons for IBM System/z Group: System Environment/Base Version: 1.8.1 -Release: 6%{?dist} +Release: 7%{?dist} Epoch: 2 License: GPLv2 and GPLv2+ and CPL Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) @@ -46,6 +46,9 @@ Patch19: 0019-s390-tools-1.8.1-lsluns-disk-enc.patch Patch20: 0020-s390-tools-1.8.1-cpuplugd-cmminit.patch Patch21: 0021-s390-tools-1.8.1-lszfcp-perf.patch Patch22: 0022-fix-string-overflow-in-vtoc_volume_label_init.patch +Patch23: 0023-change-default-load-address-for-ramdisk.patch +Patch24: 0024-s390-tools-1.8.1-cpuplugd-limits.patch +Patch25: 0025-s390-tools-1.8.1-misc-bugfixes.patch Patch100: cmsfs-1.1.8-warnings.patch Patch101: cmsfs-1.1.8-kernel26.patch @@ -128,6 +131,15 @@ be used together with the zSeries (s390) Linux kernel and device drivers. # Fix string overflow in vtoc_volume_label_init (#525318) %patch22 -p1 -b .vtoc-label +# Change default load address for ramdisk (#526339) +%patch23 -p1 -b .ramdisk-address + +# Fix cmm_pages allocation outside min and max range (#525495) +%patch24 -p1 -b .ramdisk-address + +# Miscelaneous fixes for 1.8.1 (#525495) +%patch25 -p1 -b .misc + # # cmsfs # @@ -776,6 +788,11 @@ User-space development files for the s390/s390x architecture. %changelog +* 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 diff --git a/zfcpconf.sh b/zfcpconf.sh index b88ff70..a1f474c 100644 --- a/zfcpconf.sh +++ b/zfcpconf.sh @@ -10,15 +10,13 @@ # # manual setup: # modprobe zfcp -# echo WWPN > /sys/bus/ccw/drivers/zfcp/0.0.4000/port_add -# echo LUN > /sys/bus/ccw/drivers/zfcp/0.0.4000/WWPN/unit_add # 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 0x5005076300c213e9 > /sys/bus/ccw/drivers/zfcp/0.0.4000/port_add -# echo 0x5022000000000000 > /sys/bus/ccw/drivers/zfcp/0.0.4000/0x5005076300c213e9/unit_add # 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:/usr/bin:/sbin:/usr/sbin @@ -39,8 +37,7 @@ if [ -f "$CONFIG" ]; then elif [ $numparams == 3 ]; then read DEVICE WWPN FCPLUN < <(echo $line) fi - [ ! -d /sys/bus/ccw/drivers/zfcp/${DEVICE/0x/}/$WWPN ] && echo $WWPN > /sys/bus/ccw/drivers/zfcp/${DEVICE/0x/}/port_add - [ ! -d /sys/bus/ccw/drivers/zfcp/${DEVICE/0x/}/$WWPN/$FCPLUN ] && echo $FCPLUN > /sys/bus/ccw/drivers/zfcp/${DEVICE/0x/}/$WWPN/unit_add echo 1 > /sys/bus/ccw/drivers/zfcp/${DEVICE/0x/}/online + [ ! -d /sys/bus/ccw/drivers/zfcp/${DEVICE/0x/}/$WWPN/$FCPLUN ] && echo $FCPLUN > /sys/bus/ccw/drivers/zfcp/${DEVICE/0x/}/$WWPN/unit_add done fi