In my previous Brocade post, I talked about Brocade zoning, and mentioned at a high level what is required to implement zoning. Prior to jumping in and creating one or more zones in your fabric, you should add aliases to describe the devices that are going to be zoned together. An alias is a descriptive name for a WWN or port number, which makes your zone configuration much easier to read (if you are the kinda person who can spout off the WWNs of all of the devices in your fabric, you can kindly ignore this post). Brocade switches come with a number of commands to manage aliases, and these commands start with the string “ali”:
aliCreate - Creates a new alias
aliDelete - Deletes an alias
aliRemove - Removes an entry from an alias
aliRename - Renames an existing alias
aliShow - Shows the aliases
To create a new alias, you will first need to locate the WWN(s) or port(s) you want to assign to the alias. The easiest way to do this is by running switchshow on the switch (you can also use the Emulex or QLogic host utilities to gather WWN information):
Fabric1Switch1:admin> **switchshow**
switchName: Fabric1Switch1
switchType: 16.2
switchState: Online
switchMode: Native
switchRole: Principal
switchDomain: 1
switchId: fffc01
switchWwn: 10:00:00:60:69:c0:32:a4
switchBeacon: OFF
Zoning: ON (Brocade3200)
port 0: id N2 Online F-Port 10:00:00:00:c9:3e:4c:eb
port 1: id N2 Online F-Port 10:00:00:00:c9:3e:4c:ea
port 2: id N2 No_Light
port 3: id N2 No_Light
port 4: id N2 Online F-Port 21:00:00:e0:8b:1d:f9:03
port 5: id N2 Online F-Port 21:01:00:e0:8b:3d:f9:03
port 6: id N2 No_Light
port 7: id N2 No_Light
Once you know the port numbers or WWNs, you can run the alicreate command, passing it the name of the alias to create, as well as the port or WWN to associate with the alias (if you assign more than one port or WWN to the alias, they need to be separated with a semi-colon):
Fabric1Switch1:admin> **alicreate "CentosNode2Port1",
"21:00:00:e0:8b:1d:f9:03"**
After an alias is created, you can view it with the alishow command:
Fabric1Switch1:admin> **alishow "CentosNode2Port1"**
alias: CentosNode2Port1
21:00:00:e0:8b:1d:f9:03
If you make a typo while adding a WWN or port to an alias, you can run aliadd to add the correct WWN or port to the alias, and then execute aliremove to remove the entry that was incorrectly added. If you make a typo in the alias name, you can run alirename to rename the entry. That is all for today. In my next blog post, I will talk about how to create zones.
The Bourne shell provides here documents to allow block of data to be passed to a process through STDIN. The typical format for a here document is something similar to this:
command <<ARBITRARY_TAG
data to pass 1
data to pass 2
ARBITRARY_TAG
This will send the data between the ARBITRARY_TAG statements to the standard input of the process. In order for this to work, you need to make sure that the data is not indented. If you indent it for readability, you will get a syntax error similar to the following:
./test: line 12: syntax error: unexpected end of file
To allow your here documents to be indented, you can append a “-” to the end of the redirection strings like so:
if [ "${STRING}" = "SOMETHING" ]
then
somecommand <<-EOF
this is a string1
this is a string2
this is a string3
EOF
fi
You will need to use tabs to indent the data, but that is a small price to pay for added readability. Nice!
Storage area networks (SANs) are deployed at most larger organizations, and provide centralized administration for storage devices and management functions. When multiple clients are accessing storage resources through a SAN, you need a way to limit which targets and logical units each initiator can see. Typically LUN masking is used on the storage array to limit which initiators can see which logical units, and zoning is used on the SAN switches to limit which initiators can see which targets. In the next five blog posts, I plan to provide a step-by-step guide to zoning Brocade switches.
Brocade zoning comes in two main flavors. There is hard zoning (port-based zoning), which allows you to create a zone with a collection of switch ports. The second zoning method is soft zoning (WWN-based zoning), which allows you to create a zone with one or more WWNs. There are tons of documents that describe why you would want to use each form of zoning. I typically use the following two rules to determine which zoning method I will use:
I prefer soft zoning, since it provides tons of flexibility when dealing with switch upgrades, faulty SFPs, and defective hardware. But each location has different policies, so it’s best to to take that into account each time you design or implement your zone layout.
To implement zoning on a Brocade switch, the following tasks need to be performed:
Brocade provides awesome zoning documentation, which you can access though the help and zonehelp commands:
Fabric1Switch1:admin> **zonehelp**
aliAdd Add a member to a zone alias
aliCopy Copy a zone alias
aliCreate Create a zone alias
aliDelete Delete a zone alias
aliRemove Remove a member from a zone alias
aliRename Rename a zone alias
aliShow Print zone alias information
cfgAdd Add a member to a configuration
cfgCopy Copy a zone configuration
cfgCreate Create a zone configuration
cfgDelete Delete a zone configuration
cfgRemove Remove a member from a configuration
cfgRename Rename a zone configuration
cfgShow Print zone configuration information
zoneAdd Add a member to a zone
zoneCopy Copy a zone
zoneCreate Create a zone
zoneDelete Delete a zone
zoneRemove Remove a member from a zone
zoneRename Rename a zone
zoneShow Print zone information
cfgClear Clear all zone configurations
cfgDisable Disable a zone configuration
cfgEnable Enable a zone configuration
cfgSave Save zone configurations in flash
cfgSize Print size details of zone database
cfgActvShow Print effective zone configuration
cfgTransAbort Abort zone configuration transaction
Reading through (i.e., running help ) the help sections prior to implementing your zone layout will save you a lot of hassle, especially when you start to ask yourself questions like “Does cfgremove or cfgdelete remove an entry from a configuration?". Well, that is all for today. Tomorrow I will discuss aliases, and how to use the ali* commands to create and manage them.
I was doing some experiments with a number of Ruby gems, and installed several gem versions as part of my testing. The gem utility has a slew of useful built-in options, one being “cleanup”. When gem cleanup runs, it will remove all gems that are older than the the latest gem version. So given a gem that has two versions:
$ gem list httplib
httplib (2.5.1, 2.5)
We can first run gem cleanup in dry-run mode to see what would be removed:
$ gem cleanup -d
Cleaning up installed gems…
Dry Run Mode: Would uninstall httplib-2.5
Clean Up Complete
Once we are happy with the results, we can run gem cleanup to actually remove the old gems:
$ gem cleanup -v
Cleaning up installed gems…
Attempting uninstall on httplib-2.5
Successfully uninstalled httplib version 2.5
Clean Up Complete
Ruby is an amazing language, and the more I read about it the more I like it.
Kickstart is used by numerous organizations to automate Redhat, Fedora and CentOS installations, and has numerous options to control the provisioning process. One thing I really dig about kickstart is the logging that occurs to tty2, tty3 and tty4. This information is useful for debugging build issues, since the last messages usually indicate where a problem resides. But like most admins, I multitask and typically kick off installs and come back at a later time expecting to login and configure the new host. Periodically hosts will fail to build, but will be in a state where the debug messages are no longer available. To ensure that I can easily debug issues similar to this, I like to add the syslog and loglevel directives to the list of kickstart options:
kernel /centos53/vmlinuz ip=dhcp syslog=192.168.1.5 loglevel=debug
ksdevice=eth0 \
load_ramdisk=1 prompt_ramdisk=0 ramdisk_size=32768 network \
ks=http://192.168.1.5/centos/kickstart.cfg
The syslog directives tells the anaconda installer to send its output to the specified syslog server IP, and the loglevel directive controls how much data is logged. Once both directives are enabled, you will get output similar to the following each time a host builds:
May 20 22:36:15 drfeelgood INFO trying to mount sda1 on /
May 20 22:36:15 drfeelgood INFO set SELinux context for mountpoint / to system_u:object_r:root_t:s0
May 20 22:36:17 drfeelgood INFO trying to mount sys on /sys
May 20 22:36:17 drfeelgood INFO set SELinux context for mountpoint /sys to None
May 20 22:36:17 drfeelgood INFO trying to mount proc on /proc
May 20 22:36:17 drfeelgood INFO set SELinux context for mountpoint /proc to None
May 20 22:36:17 drfeelgood INFO moving (1) to step migratefilesystems
May 20 22:36:17 drfeelgood INFO moving (1) to step setuptime
May 20 22:36:17 drfeelgood INFO moving (1) to step preinstallconfig
To locate errors or warnings, you can run egrep passing the strings WARN and ERROR as input:
$ egrep "drfeelgood.(WARN|ERROR)" /var/adm/messages
May 20 22:36:17 drfeelgood WARNING no dev package, going to bind mount /dev
May 20 22:36:38 drfeelgood WARNING Try 1/10 for http://192.168.1.5/centos/5.3/x86_64/os/CentOS/nspr-devel-4.7.3-2.el5.x86_64.rpm failed
May 20 22:38:47 drfeelgood WARNING /usr/lib64/python2.4/site-packages/snack.py:250: DeprecationWarning: integer argument expected, got floatn self.w = _snack.scale(width, total)
Kickstart is pretty sweet, and it is one of those technologies that makes our lives so much easier!