SAN redundant paths

Hello,
When reading ESXi Boot from SAN instructions for UCS, I came across the following sentence:
"Configure a LUN or RAID volume on your SAN, then  connect to the SAN and verify that one (and only one) path exists from  the SAN HBA to the LUN".
I don't understand this sentence, as the design best practices in SAN, correct me if I'm wrong, make each path from HBA to LUN split in 2 (one for each Storage Processor).
What am I missing here?
Thanks a lot,

An easy way is to disable the fc path to a vHBA path by going into the Service Profile, vHBA config and setting its VSAN to another VSAN that it is not zoned in. By default VSAN 1 is always available. But, if VSAN 1 is in use, create a new VSAN, say VSAN 42 (pick something that doesn't exist anywhere in your SAN fabric) and assign the vHBA to VSAN 42 during the installation. After the installation is complete and you are ready to configure MP, put the vHBA back into it's correctly configured VSAN.
Or, If you have access to the SAN configuration, you can remove the vHBA/StorageTarget configuration during the install. After installation, put the configuration back in place and activate it.
The single path install is a requirement of Windows Server 2003 and 2008, not UCS.
http://download.microsoft.com/download/f/9/7/f9775acc-baa6-45cc-9dec-b82983705620/Boot%20from%20SAN%20in%20Windows.doc
"Allow a single path to storage when installing the operating system (OS).  For multiple HBA port configurations, only one HBA port should be connected to the SAN during installation.  The same restriction applies to the storage controller ports"
For ESX and RHEL, both paths can be enabled during install. For RHEL, if you don't have both paths enabled during install, it's extra work to bring the second path in after installation.

Similar Messages

  • BGP - How to create redundant path by bgp (as path prepend alternative)

    I am having issues with BGP seeing the advertised routes. I am trying to find an alternate to AS-Path prepend and trying to use bgp instead for a redundant path.
    Setup:-
    We have 3 mpls sites. (in reality its more than 20 but for simplicity we will call that 3).  The 3 sites are SiteA , SiteB and siteC.  I have simplified the issue below.
    SiteA - Has MPLS link running eBGP with AS 300.
    SiteB - Has MPLS link running eBGP with AS 200
    SiteC- Has MPLS link running eBGP with AS 100
    Site B and C has a local LAN connection between each other.  Site A and B and C are on BGP network. Site A can see B and C and so on.

    Thanks for responding. i have added a prefix list for filtering outbound. I was hoping that it will learn that route through the bgp network statement.
    ie.. I have added network B at C and network C at B. They both are neighbors and when i see advertised routes and received routes i can see the routes. 
    How should i proceed or any guidance would help..
    From site C i want to see below when i do show ip bgp for 20.20.20.20.
    20.20.20.20  - is reachable as As200 -i
    20.20.20.20  - As100 - 200 - i  (i don't see this)

  • Fibre Channel failed not seeing redundant path

    Hi I recently started noticing the following issue in my messages file
    Mar 17 16:23:00 pine genunix: [ID 408114 kern.info] /scsi_vhci/ssd@g290000602200
    443c6257455730303138 (ssd12) online
    Mar 17 16:23:00 pine scsi: [ID 243001 kern.warning] WARNING: /pci@bd,600000/SUNW
    ,qlc@1/fp@0,0 (fcp1):
    Mar 17 16:23:00 pine Failed to create nodes for pwwn=2b00006022004433; error=5
    Mar 17 16:23:00 pine luxadm[88]: [ID 434025 user.error] ID[luxadm.create_fabric_device.2316] configuration failed for line (/devices/pci@bd,600000/SUNW,qlc@1/fp@0,0:fc::2b00006022004433) in file: /etc/cfg/fp/fabric_WWN_map. I/O error
    I notice that my Port B is now missing when I do luxadm display seems I only have 1 path to my SAN I would like some assitances on how to debug this problem ?? I'm not sure if its software or hardware related this system is attached to a T3+ 6960 using mpxio
    -RB

    It would be worth doing a physical check of the 69x0 VE engines and server side switches diagnostic LEDs.
    You should also check StorADE and/or /var/adm/messages on the MSP for failure messages.
    Cabling should be checked if these check out ok.
    Check the output of cfgadm -al and make sure you have at least 2 fc-fabric controllers.
    You can then run 'luxadm -e dump_map /dev/cfg/c<num>' to see if you can actually see the storage devices.
    For a 69x0 you should see two active paths under luxadm display.
    --A.

  • Redundant Paths

    Hi,
    I have a Centro Office Router with Redunant links. If I want that Remote Offices have logical redundancy, should I ask my service provider to give two VLANs, so I can configure subinterfaces and route through EIGRP or OSPF?
    any comment will be highly aprreciate
    regards.....

    If the redundancy is for the attachment VC then you need to have physical redundancy of the links.
    Logical redundancy wont help or is not required as you service providers core is anyway redundant to take care of the Circuit through the core. Only vulnerable area is the
    UPE-CPE link, where you need redundant physical connections.
    Hope I understood your query right, and replied accordingly.
    HTH-Cheers,
    Swaroop

  • Connect SAN LUN to Server

    I am very new to linux (coming from HP-UX) and am tasked with setting up a linux/oracle/rac environment. I have installed OEL 5.1 on three HP DL360 servers. I am pretty much 'running blindly' and am looking for a source of information to help me keep going.
    We have a cx3-40c Clariion and am connected to it through dual HBA ports. I am using Navishpere agent and PowerPath. The server sees the Clariion SP's (LUNZ), in the /proc/scsi/scsi file.
    The storage admin has presented a 100gb lun to the server. It is here I have run into several obstacles.
    I want to use lvm to create one volume group of this 100gb lun, create 2 logical volumes (10gb and 90gb) and put an ext3 filesystem on them. I have worked several paths, the lvm gui and command line. I was able to create the vg and lv's but the mke2fs failed with a superblock warning.
    I think my issue may be at the beginning...so I want to start from scratch and a freshly presented lun. The storage admin has 'un-presented' the lun. So at this point PowerPath shows no logical devices, fdisk -l shows only my internal system drives...but /proc/partitions is still showing the sd* devices. I did a partprobe but no change. And the confusion begins....
    Any, configuration documents or checklists out there?
    Thanks.

    1. once the slices are given out from the SAN, look what you've got on your linux server:
    fdisk -l
    2. If you've got redundant path's, use multipathd to make a meta device for each slice. if that's the case, please post a reply, I can help you further
    at this point you should have devices on linux representing the SAN slices.
    next:
    -make a pv of the devices (pvcreate /path/to/device)
    -make a volume group and add the pv
    -make logical volumes
    (the linux LVM commands are very much alike the HPUX lvm commands)
    after the lv's are made, put a filesystem onto the lv's (mkfs.ext3 /dev/<vgname>/<lvname>

  • Redundant Interconnect Usage

    Hello everyone,
    This is regarding configuring Redundant Interconnect Usage on 11gr2 RAC on linux.
    The RAC is already installed and so I think that I've to use "oifcfg" to configure the same. However, I've few questions regarding the same.
    oifcfg iflist -p -n
    eth0 10.1.1.0 PRIVATE 255.255.255.0
    eth0  169.254.0.0  UNKNOWN  255.255.0.0*
    eth2 172.16.2.0 PRIVATE 255.255.254.0
    My questions are:
    - The eth3 is the new interface provided by system admins. So I think below command will work for me
    - oifcfg setif -global eth3/169.254.0.0:clusster_interconnect
    - 169.254.0.0 is chosen as the same is current subnet used by cluster interconnect as mentioned above.
    - Also, just like eth0 does have a IP statically assigned and there is another IP given again to it by oracle for "redundant interconnect usage", I guess eth3 too needs a IP on each node statically assigned and there will be another IP assigned and managed by CRS for RIU. Am I correct ?
    thanks

    jjk wrote:
    This is regarding configuring Redundant Interconnect Usage on 11gr2 RAC on linux.Why not use bonding? 2 interfaces. Each cabled to a separate private switch. Switches connected to one another. Bond the 2 interface as a single interface. Use the bonded interface as private Interconnect interface.
    With this config you can loose a cable or an entire switch - but the Interconnect will still function.
    This is a much more robust method than using 2 separate interfaces individually. A network socket on a bonded interface survives an underlying infrastructure failure as the logical bonded interface does not fail.
    Using 2 interfaces means that a network socket on the failed interface, also fails. And the s/w needs to be intelligent enough to perform a (potentially complex) failover to the 2nd interface, re-establish communication, handshake and then resume the conversation from where it failed. This is a lot more moving parts than using a bonded interface running on top of redundant paths and hardware.

  • Metro Ethernet Design With Redundant Head Ends

    We're getting ready to turn up some metro ethernet circuits that were just installed by AT&T. AT&T has provided a VLAN for each remote site (so each site has its own VLAN), and those VLANs are trunked to our head end switches (Cisco 3750 Metro Switches).
    I'm struggling with the best design for IP routing. We currently use OSPF on our internal network, and I was going to extend OSPF to our metro solution as well, but I'm not so sure now.
    I don't want routing to occur directly between head end #1 and head end #2, we already have redundant paths within our corporate network, and allowing our two head ends to route between each other via our metro ethernet solution is not what we want. However, running OSPF on each of the VLANs which have been provisioned for us would permit routing between the head ends.
    We simply need to allow redundanny for our remote locations in the event that one head end were to fail, all of the traffic to/from the remote site would be routed through the head end which is still online.
    Anyone suggestions on the best routing design for this situation would be greatly appreciated. I've attached a network diagram to make things clear. I believe I can also go back to AT&T and request one VLAN that includes all sites if that would simply things. I just need to make sure I can still do our traffic shaping because the remote sites are only 10mbps and the head ends are 1gbps.
    Thanks,
    -Steve

    just at a glance it looks as if you should be able to have stp on and setup 1 site as primary and other as secondary

  • MPLS issues with redundant PE routers

    Hello,
    i'd like to set up an mpls lab. the layout of the gear is attached (mpls.jpg) At site A i have to PE router R4 and R6 which should have knowledge of the network 10.0.129.0/24 from site B. Router R1 is configured as a route reflector. the configuration of R1, R4, R5 and R6 are attached as well.
    with the configuration
    Routing Table R6
    O E2     10.0.129.0 [110/1] via 172.16.128.9, 00:04:37, FastEthernet0/1.200
    Routing table R4
    B        10.0.129.0 [200/11] via 150.1.5.5, 00:05:00
    a traceroute shows the path goes through R4 instead direkt through R1
    Tracing the route to 10.0.129.1
    VRF info: (vrf in name/id, vrf out name/id)
      1 172.16.128.9 4 msec 0 msec 4 msec
      2 172.16.128.1 [MPLS: Labels 19/29 Exp 0] 96 msec 100 msec 96 msec
      3 150.1.0.2 [MPLS: Labels 19/29 Exp 0] 68 msec 64 msec 68 msec
      4 172.16.129.9 [MPLS: Label 29 Exp 0] 64 msec 64 msec 64 msec
      5 172.16.129.10 40 msec *  36 msec
    show bgp vpnv4 unicast all 10.0.129.0 indicates an error
    Rack1R6# show bgp vpnv4 unicast all 10.0.129.0
    BGP routing table entry for 200:1:10.0.129.0/24, version 63
    Paths: (1 available, best #1, table CENTRAL, RIB-failure(17) - next-hop mismatch)
      Not advertised to any peer
      Local
        150.1.5.5 (metric 67) from 150.1.1.1 (150.1.1.1)
          Origin incomplete, metric 11, localpref 100, valid, internal, best
          Extended Community: RT:200:1 OSPF DOMAIN ID:0x0005:0x000000C80200
            OSPF RT:0.0.0.0:3:0 OSPF ROUTER ID:172.16.129.242:0
          Originator: 150.1.5.5, Cluster list: 150.1.1.1
          mpls labels in/out nolabel/29
    Rack1R4#show bgp vpnv4 unicast all 10.0.129.0
    BGP routing table entry for 200:1:10.0.129.0/24, version 146
    Paths: (1 available, best #1, table CENTRAL)
      Not advertised to any peer
      Local
        150.1.5.5 (metric 67) from 150.1.1.1 (150.1.1.1)
          Origin incomplete, metric 11, localpref 100, valid, internal, best
          Extended Community: RT:200:1 OSPF DOMAIN ID:0x0005:0x000000C80200
            OSPF RT:0.0.0.0:3:0 OSPF ROUTER ID:172.16.129.242:0
          Originator: 150.1.5.5, Cluster list: 150.1.1.1
          mpls labels in/out nolabel/29
    any ideas what i have to do in order to have a redundant path towards site B?
    thanks in advanced
    Alex

    Hi Alex,
    I think you still have redundancy via R6, but BGP route on R6 is not getting installed in routing table because it is having OSPF route with lesser AD value. If R4 goes down, R6 will loose OSPF route for 10.0.129.0/24 coming from R4, install BGP route ,redistribute this to OSPF and will advertise it to SW4.
    Routing Table R6
    O E2     10.0.129.0 [110/1] via 172.16.128.9, 00:04:37, FastEthernet0/1.200
    Rack1R6# show bgp vpnv4 unicast all 10.0.129.0
    BGP routing table entry for 200:1:10.0.129.0/24, version 63
    Paths: (1 available, best #1, table CENTRAL, RIB-failure(17) - next-hop mismatch)
      Not advertised to any peer
      Local
        150.1.5.5 (metric 67) from 150.1.1.1 (150.1.1.1)
          Origin incomplete, metric 11, localpref 100, valid, internal, best
          Extended Community: RT:200:1 OSPF DOMAIN ID:0x0005:0x000000C80200
            OSPF RT:0.0.0.0:3:0 OSPF ROUTER ID:172.16.129.242:0
          Originator: 150.1.5.5, Cluster list: 150.1.1.1
          mpls labels in/out nolabel/29

  • Adding something to my $PATH permanently

    Hi folks. I want to add /usr/local/bin to my $PATH, permanently. After reading the threads in here, I still am confused about how to do it.
    This is what I am trying:
    PATH=/usr/local/bin:$PATH
    export $PATH
    So when I do this:
    echo $PATH
    ...it comes back fine. Then I close the window, she goes back to the normal value without /usr/local/bin.
    Any ideas? I'm running the bash shell.
    Cheers

    Hi BioRich,
       If you read the invocation section of the bash man page you will find the following:
    When bash is invoked as an interactive login shell, or as a non-inter- active shell with the --login option, it first reads and executes com- mands from the file /etc/profile, if that file exists. After read- ing that file, it looks for ~/.bash_profile, ~/.bash_login, and ~/.pro- file, in that order, and reads and executes commands from the first one that exists and is readable. ... When an interactive shell that is not a login shell is started, bash reads and executes commands from ~/.bashrc, if that file exists.
    What the man page doesn't tell you is what a login shell is. It is generally the first shell you open and it usually suffices to set the PATH in that shell because subsequent shells opened in the same terminal application will inherit the environment of the login shell. However, shells opened in other terminal applications will not inherit the environment. The bash shell fails to consider this now common situation.
       To get around this shortcoming, it is common to put all of your configuration commands in a file sourced by a login shell, such as the ~/.bash_profile as suggested by Asher, and then to source that file from the ~/.bashrc.
       That gives rise to a new problem: redundant path elements. If a non-login shell does inherit the environment of the login shell then the sourcing the ~/.bash_profile will add path elements a second time. A solution to this problem is to test the environment before sourcing the ~/.bash_profile to see if the environment has already been "fixed." A slightly more elegant solution is to check the path before adding to it. This can be done with functions like "append_path" or "prepend_path" functions like those defined in FInk's init.sh file.
    Edit: They stopped respecting the <BLOCKQUOTE> tag in the stupid forum software! This just gets worse and worse.
    Gary
    ~~~~
       When Marriage is Outlawed, Only Outlaws will have Inlaws.

  • Convert old cs4 script to illustrator cc

    This is a big ask, but I found this script to remove redundant points at github.com/mekkablue/Glyphs-Scripts
    Each time I run, it seems to work, it shows how many points it has removed, but then illustrator crashes, with no kind of error notice.
    If I run it via extendscript toolkit it jumps to the following bit of code
    var docRef=app.activeDocument;
    I would really love to get this to work, if anyone is willing to help me.
      RemovetRedundantPoints.jsx
      A Javascript for Adobe Illustrator
      Author:
      Jim Heck
      [email protected]
      Purpose:
      Remove anchorpoints on selected path that are coincident in location.
      Finds and optionally removes redundant points from each selected PathItem.
      Useful for cleaning up after Offset Path and Outline Stroke commands in CS3.
      To Use:
      Select the paths, including compound paths to be affected. If no path is
      selected, the script will run for all paths in the document that are not
      locked. Run the script.
      Rights:
      This work is licensed under the Creative Commons Attribution 3.0 United States
      License. To view a copy of this license, visit
      http://creativecommons.org/licenses/by/3.0/us/
      or send a letter to Creative Commons, 171 Second Street, Suite 300,
      San Francisco, California, 94105, USA.
      Version History:
      1.8 120108 More fixes to the logic for keeping only a single point.
      The direction handles for the remaining point are now correctly calculated
      based on relative angle and distance to the original anchor to which a
      handle related. Also if a SMOOTH point is remaining, the angle of the
      two direction handles has been tweaked to be exactly 180 degrees for
      consistency with the definition of a SMOOTH point.
      1.7 120106 Change the way direction handles and PointType are handled
      when keeping only one point. Retract handles less than 0.5 points to keep
      consistent angles for SMOOTH point types. If keepLeadingPoint or
      keepTrailingPoint is specified, try to keep the PointType of that point.
      In the absence of other indicators, base PointType on the point (leading
      or trailing) that has an extended handle.
      1.6.1 090914 Tweak defaults to make sense for my work style
      1.6 090411 Fix a bug in creating a temporary path. Fix a bug in
      findRedundantPoints(), when searching backwards, the tolerance was always
      applied against the first point on the path instead of the adjacent point
      along the path. Change selection options so that there is more control over
      which points are processed on a given path. The new options allow for ignoring
      selection of points, restricting processing to only selected points, or
      processing redundant points if at least one of them is selected. Correct count
      of redundant points removed when both leading and trailing points retained.
      1.5 090404 Change default action to remove. Fix a major performance issue
      in the docGetSelectedPaths() routine. Searching through all the paths in very
      complex files takes a LONG time. Instead, search the document groups array.
      BETA: Lots of hacking on the removeRedundantPoints() routine to improve the
      look of the resulting curve when applied to the oxbow problem.
      1.4.1 090331 Fix a bug in removeRedundantPoints(), needed to compare absolute
      error to a tolerance. Also, loosen up the error criteria so less smooth
      points are mischaracterized as corners. Tolerance is now 0.02 radians,
      which is about 1.15 degrees. For some reason, the redundant points on
      arbitrary (non-geometric) outlined paths have lots of slop in the
      direction handles.
      1.4 090331 Add options to control which points are left on removal, leading,
      trailing or both. If neither is retained, the redundant point positions
      are averaged. If both are retained, intermediate points are removed, and
      inward facing control handles are synthesized (see comments below).
      Switched to using the atan2 function instead of atan for calculating theta.
      Fixed bugs in docGetSelectedPaths(). CompoundPathItem objects don't seem
      to have properly formed pathItems arrays when they contain what appear to
      be groups of paths. Also, layer objects can contain layers.
      1.3.1 090327 Limit user entered tolerance value to something sane.
      1.3 090327 Add user controls to specify a tolerance in points for identifying
      redundant points.
      1.2.3 090327 Improve results dialog verbiage.
      1.2.2 090326 Bug fix. Observe proper unlocking and locking order for
      handling of locked objects.
      1.2.1 090326 Minor bug fixes including, restricting selection only option
      to not be allowed with selection function.
      1.2 090326 Add option to remove only redundant points sets with at least one
      selected point. Fix broken option to remove locked redundant points.
      Add results dialog OK button.
      1.1 090325 Improve select action to work across selection or entire document.
      Handle nested layers in docGetSelectedPaths(). Clean whitespace.
      1.0.1 090325 Minor bug fix.
      1.0 090311 Initial release.
    * Function: getPairTheta
    * Description:
    * Return the angle relative to the X axis from the line formed between
    * two points, which are passed in as arguments. The angle is measured
    * relative to point A (as if A were relocated to the origin, and the angle
    * is measured to the X axis itself). The arguments are expected to be
    * arrays of two numbers (X, Y) defining the point. The return value is in
    * radians (PI to -PI)
    function getPairTheta(pairA,pairB){
      var deltaX=pairB[0]-pairA[0];
      var deltaY=pairB[1]-pairA[1];
      /*alert("deltaX="+deltaX+" deltaY="+deltaY);*/
      return(Math.atan2(deltaY, deltaX));
    * Function: getPairDistance
    * Description:
    * Return the distance between two points. The arguments are expected to be
    * arrays of two numbers (X, Y) defining the point. The return value is the
    * distance in units relative to the inputs.
    function getPairDistance(pairA,pairB){
      var deltaX=pairB[0]-pairA[0];
      var deltaY=pairB[1]-pairA[1];
      return(Math.sqrt((deltaX*deltaX)+(deltaY*deltaY)));
    * Function: findRedundantPoints
    * Description:
    * Find all sets of redundant points for the input path. A redundant point
    * is defined as one that has the same anchor location as a neighboring point.
    * The arguments are a path to work on, the tolerance in points to apply to
    * determine a point is redundant, and a boolean to indicate that only
    * groups of redundant points where at least one point is selected should
    * be considered. The return value is an Array of Arrays containing the
    * indicies of the redundant pathPoint objects found in the path.
    function findRedundantPoints(path, tolerance, anySelected, allSelected){
      var anchorDistance = 0;
      var redundantPointSets = new Array();
      var redundantPoint = new Array();
      var selectedRedundantPointSets = new Array();
      var selectedRedundantPoint = new Array();
      var i = 0;
      var j = 0;
      var k = 0;
      var index;
      var selected = false;
      if(path.pathPoints.length > 1) {
      * The first path point may be coincident with some at the end of the path
      * so we check going backwards first. Redundant points pushed on the
      * front of the array so they stay in order leftmost to rightmost.
      redundantPoint.push(0);
      index = 0;
      for (i=path.pathPoints.length-1; i>0; i--) {
      * Get distance and round to nearest hundredth of a point.
      * If points are closer than the tolerance, consider them
      * coincident.
      anchorDistance = getPairDistance(path.pathPoints[index].anchor, path.pathPoints[i].anchor);
      anchorDistance = roundToPrecision(anchorDistance, 0.01);
      if (anchorDistance < tolerance) {
      redundantPoint.unshift(i);
      else {
      break;
      index = i;
      * If we haven't used up all the points, start searching forwards
      * up to the point we stopped searching backwards. Test the
      * current point against the next point. If the next point matches push
      * its index onto the redundantPoint array. When the first one doesn't match,
      * check if the redundantPoint array has more than one index. If so add it
      * to the redundantPointSets array. Then clean the redundantPoint array
      * and push on the next point index.
      if(i > 0) {
      for (j=0; j<i; j++) {
      anchorDistance = getPairDistance(path.pathPoints[j].anchor, path.pathPoints[j+1].anchor);
      anchorDistance = roundToPrecision(anchorDistance, 0.01);
      if (anchorDistance < tolerance) {
      redundantPoint.push(j+1);
      else {
      if (redundantPoint.length > 1) {
      redundantPointSets.push(redundantPoint);
      redundantPoint = [];
      redundantPoint.push(j+1);
      * Push the last redundantPoint array onto the redundantPointSets array if
      * its length is greater than one.
      if (redundantPoint.length > 1) {
      redundantPointSets.push(redundantPoint);
      if (anySelected) {
      for (i=0; i<redundantPointSets.length; i++) {
      var currentPointSet = redundantPointSets[i];
      selected = false;
      for (j=0; j<currentPointSet.length; j++) {
      if (path.pathPoints[currentPointSet[j]].selected ==
      PathPointSelection.ANCHORPOINT) {
      selected = true;
      if (selected) {
      selectedRedundantPointSets.push(currentPointSet);
      else if (allSelected) {
      for (i=0; i<redundantPointSets.length; i++) {
      var currentPointSet = redundantPointSets[i];
      for (j=currentPointSet.length-1; j>=0; j--) {
      var currentPoint = path.pathPoints[currentPointSet[j]];
      if (currentPoint.selected == PathPointSelection.ANCHORPOINT) {
      selectedRedundantPoint.unshift(currentPointSet[j]);
      else {
      break;
      if (j > 0) {
      for (k=0; k<j; k++) {
      var currentPoint = path.pathPoints[currentPointSet[k]];
      if (currentPoint.selected == PathPointSelection.ANCHORPOINT) {
      selectedRedundantPoint.push(currentPointSet[k]);
      else {
      if (selectedRedundantPoint.length > 1) {
      selectedRedundantPointSets.push(selectedRedundantPoint);
      selectedRedundantPoint = [];
      if (selectedRedundantPoint.length > 1) {
      selectedRedundantPointSets.push(selectedRedundantPoint);
      selectedRedundantPoint = [];
      else {
      selectedRedundantPointSets = redundantPointSets;
      return(selectedRedundantPointSets);
    * Function: countRedundantPoints
    * Description:
    * Count the number of redundant points given a redundantPointSets array as
    * the first parameter.
    function countRedundantPoints(redundantPointSets, doKeepLeadingPoint, doKeepTrailingPoint) {
      var i = 0;
      var redundantPoints = 0;
      var pointsKept = 1;
      if (doKeepLeadingPoint && doKeepTrailingPoint) {
      pointsKept = 2;
      for (i=0; i<redundantPointSets.length; i++) {
      redundantPoints += redundantPointSets[i].length - pointsKept;
      return (redundantPoints);
    * Function: countSelectedPoints
    * Description:
    * Count the number of selected anchor points given a path as the first parameter.
    function countSelectedPoints(path) {
      var i = 0;
      var selectedPoints = 0;
      for (i=0; i<path.pathPoints.length; i++) {
      if (path.pathPoints[i].selected == PathPointSelection.ANCHORPOINT) {
      selectedPoints++;
      return (selectedPoints);
    * Function: removeRedundantPoints
    * Description:
    * Remove redundant points from a path input as the first parameter. The
    * second input parameter should be an array of arrays containing the
    * indicies of redundant points, as returned from function
    * findRedundantPoints(). From each set of indicies, the first point is
    * retained, and the subsequent points are removed from the path. Care is
    * taken to preserve the proper leftDirection and rightDirection handles,
    * as well as the proper PointType for the remaining point. Returns
    * the number of points removed.
    function removeRedundantPoints(path, redundantPointSets, keepLeadingPoint, keepTrailingPoint, keepAveragedPoint){
      var i = 0;
      var j = 0;
      var pointsToRemove = new Array();
      var tempLayer;
      var tempPath;
      * For each array of redundant point indicies in array redundantPointSets,
      * modify the leadingPoint to have all the properties needed to properly
      * describe the set of coincident points.
      for (i=0; i<redundantPointSets.length; i++) {
      var x = 0;
      var y = 0;
      var currentPointSet = redundantPointSets[i];
      var leadingPoint = path.pathPoints[currentPointSet[0]];
      var trailingPoint = path.pathPoints[currentPointSet[currentPointSet.length-1]];
      if (keepLeadingPoint && keepTrailingPoint) {
      * JAH 090401 REVISIT COMMENT WHEN DONE
      * If we are keeping two points, the leftDirection of the leading point
      * and rightDirection of the trailing point are already fixed. We have to
      * synthesize the inward facing handles, and choose pointType of the two points.
      * To allow easy manipultion of the inner handles without disturbing the fixed
      * handles, make the points PointType.CORNER. For the direction handles, make
      * them parallel to their respective paired handle, and extend them half the
      * distance between the two remaining points.
      var averagedPoint;
      var theta;
      var deltaX;
      var deltaY;
      var pairDistance;
      var leftDistance;
      var rightDistance;
      var firstRemovedIndex = 1;
      if (currentPointSet.length > 2) {
      averagedPoint = path.pathPoints[currentPointSet[1]];
      else {
      tempLayer = app.activeDocument.layers.add();
      tempLayer.name = "Temp";
      tempPath = tempLayer.pathItems.add();
      averagedPoint = tempPath.pathPoints.add();
      if( currentPointSet.length <= 2 || !keepAveragedPoint ) {
      * Use just the leading and trailing points. Create inward facing
      * direction handles for the two endpoints based on the relationship
      * of the angles between each endpoint and the average point.
      * For each endpoint, calcualte the angle of the endpoint to the
      * average point, and the endpoint to the other endpoint. Combine
      * the angles. The base angle for the inward facing direction handle
      * is the angle that points it towards the average point. Add to this
      * angle, a multiple of the difference between the angle just mentioned,
      * and the angle to the other endpoint. Adding this difference angle
      * will bias the curve towards the average point. Finally, set the
      * length of the direction handle as the distance from the endpoint
      * to the average point multiplied by a factor.
      var thetaAverage;
      var thetaPair;
      var tweakThetaToOppositeEndpoint = 1.0;
      var tweakPairDistance = 0.5;
      * Since the leading and trailing points will have direction handles pointing
      * in different directions, these points must be corner points by necessity.
      leadingPoint.pointType = PointType.CORNER;
      trailingPoint.pointType = PointType.CORNER;
      * Create new average point.
      for (j=0; j<currentPointSet.length; j++) {
      x += path.pathPoints[currentPointSet[j]].anchor[0];
      y += path.pathPoints[currentPointSet[j]].anchor[1];
      x /= currentPointSet.length;
      y /= currentPointSet.length;
      averagedPoint.anchor = Array(x, y);
      averagedPoint.leftDirection = Array( averagedPoint.anchor[0], averagedPoint.anchor[1]);
      averagedPoint.rightDirection = Array( averagedPoint.anchor[0], averagedPoint.anchor[1]);
      averagedPoint.pointType = PointType.CORNER;
      /* Calcualte new leading point rightDirection */
      pairDistance = getPairDistance(leadingPoint.anchor, averagedPoint.anchor);
      thetaAverage = getPairTheta(leadingPoint.anchor, averagedPoint.anchor);
      thetaPair = getPairTheta(leadingPoint.anchor, trailingPoint.anchor);
      theta = thetaAverage + tweakThetaToOppositeEndpoint * (thetaAverage - thetaPair);
      /*alert("thetaAverage="+thetaAverage+" thetaPair="+thetaPair" theta="+theta);*/
      deltaX = Math.cos(theta) * tweakPairDistance * pairDistance;
      deltaY = Math.sin(theta) * tweakPairDistance * pairDistance;
      leadingPoint.rightDirection = Array(leadingPoint.anchor[0]+deltaX, leadingPoint.anchor[1]+deltaY);
      /* Calcualte new trailing point leftDirection */
      pairDistance = getPairDistance(trailingPoint.anchor, averagedPoint.anchor);
      thetaAverage = getPairTheta(trailingPoint.anchor, averagedPoint.anchor);
      thetaPair = getPairTheta(trailingPoint.anchor, leadingPoint.anchor);
      theta = thetaAverage + tweakThetaToOppositeEndpoint * (thetaAverage - thetaPair);
      /*alert("thetaAverage="+thetaAverage+" thetaPair="+thetaPair" theta="+theta);*/
      deltaX = Math.cos(theta) * tweakPairDistance * pairDistance;
      deltaY = Math.sin(theta) * tweakPairDistance * pairDistance;
      trailingPoint.leftDirection = Array(trailingPoint.anchor[0]+deltaX, trailingPoint.anchor[1]+deltaY);
      else {
      * Use just the leading and trailing points, along with a third point added
      * at the average of all the removed points. This point will act to anchor
      * the curve at the average point. It will also allow the leading and
      * trailing points to be smooth points, allowing for a continuous
      * curve through them.
      * The inward facing direction handles for the two endpoints will be
      * shortened extensions of the outward facing direction handles for these
      * points. The length of the handles will be a multiple of the
      * distance from the direction handle to the average point.
      * For the average point, the direction handles will be parallel to the
      * angle formed by the angle between the two endpoints. The length
      * of the direction handles for this point will be a different multiple
      * of the length from each endpoint to the average point.
      var thetaAverage;
      var thetaPair;
      var tweakPairDistanceForAveraged = 0.5;
      var tweakPairDistanceForEndpoint = 0.25;
      * Since the leading and trailing points will have direction handles that
      * are parallel, make them smooth points.
      leadingPoint.pointType = PointType.SMOOTH;
      trailingPoint.pointType = PointType.SMOOTH;
      /* We will be keeping one more point, the averaged point. */
      firstRemovedIndex = 2;
      * Create new average point.
      for (j=0; j<currentPointSet.length; j++) {
      x += path.pathPoints[currentPointSet[j]].anchor[0];
      y += path.pathPoints[currentPointSet[j]].anchor[1];
      x /= currentPointSet.length;
      y /= currentPointSet.length;
      averagedPoint.anchor = Array(x, y);
      averagedPoint.leftDirection = Array( averagedPoint.anchor[0], averagedPoint.anchor[1]);
      averagedPoint.rightDirection = Array( averagedPoint.anchor[0], averagedPoint.anchor[1]);
      averagedPoint.pointType = PointType.SMOOTH;
      /* Calcualte new averaged point leftDirection */
      pairDistance = getPairDistance(leadingPoint.anchor, averagedPoint.anchor);
      theta = getPairTheta(leadingPoint.anchor, trailingPoint.anchor);
      /*alert("theta="+theta);*/
      if (theta > 0) {
      theta += Math.PI;
      else {
      theta += -Math.PI;
      deltaX = Math.cos(theta) * tweakPairDistanceForAveraged * pairDistance;
      deltaY = Math.sin(theta) * tweakPairDistanceForAveraged * pairDistance;
      averagedPoint.leftDirection = Array(averagedPoint.anchor[0]+deltaX, averagedPoint.anchor[1]+deltaY);
      /* Calcualte new averaged point rightDirection */
      pairDistance = getPairDistance(trailingPoint.anchor, averagedPoint.anchor);
      theta = getPairTheta(trailingPoint.anchor, averagedPoint.anchor);
      /*alert("theta="+theta);*/
      if (theta > 0) {
      theta += Math.PI;
      else {
      theta += -Math.PI;
      deltaX = Math.cos(theta) * tweakPairDistanceForAveraged * pairDistance;
      deltaY = Math.sin(theta) * tweakPairDistanceForAveraged * pairDistance;
      averagedPoint.rightDirection = Array(averagedPoint.anchor[0]+deltaX, averagedPoint.anchor[1]+deltaY);
      /* Calculate direction handles for leading and trailing points */
      pairDistance = getPairDistance(leadingPoint.anchor, trailingPoint.anchor);
      leftDistance = getPairDistance(leadingPoint.anchor, leadingPoint.leftDirection);
      if (leftDistance > 0) {
      theta = getPairTheta(leadingPoint.anchor, leadingPoint.leftDirection);
      /*alert("theta="+theta);*/
      if (theta > 0) {
      theta += Math.PI;
      else {
      theta += -Math.PI;
      pairDistance = getPairDistance(leadingPoint.anchor, averagedPoint.anchor);
      deltaX = Math.cos(theta) * tweakPairDistanceForEndpoint * pairDistance;
      deltaY = Math.sin(theta) * tweakPairDistanceForEndpoint * pairDistance;
      leadingPoint.rightDirection = Array(leadingPoint.anchor[0]+deltaX, leadingPoint.anchor[1]+deltaY);
      else {
      leadingPoint.rightDirection = leadingPoint.anchor;
      rightDistance = getPairDistance(trailingPoint.anchor, trailingPoint.rightDirection);
      if (rightDistance > 0) {
      theta = getPairTheta(trailingPoint.anchor, trailingPoint.rightDirection);
      if (theta > 0) {
      theta += Math.PI;
      else {
      theta += -Math.PI;
      pairDistance = getPairDistance(trailingPoint.anchor, averagedPoint.anchor);
      deltaX = Math.cos(theta) * tweakPairDistanceForEndpoint * pairDistance;
      deltaY = Math.sin(theta) * tweakPairDistanceForEndpoint * pairDistance;
      trailingPoint.leftDirection = Array(trailingPoint.anchor[0]+deltaX, trailingPoint.anchor[1]+deltaY);
      else {
      trailingPoint.leftDirection = trailingPoint.anchor;
      * Push all points other than the leading and trailing onto the pointsToRemove array
      * for later removal. We can't remove them while we are working with later sets.
      for (j=firstRemovedIndex; j<currentPointSet.length-1; j++) {
      pointsToRemove.push(currentPointSet[j]);
      else {
      * If we are only keeping one point, we will work with the leading point.
      * First, calculate the relative distances and angles of the direction handle for
      * the leadingPoint leftDirection handle and the trailingPoint rightDirection
      * handle. These values will be used to help properly construct the remaining
      * point.
      var leftDistance = getPairDistance(leadingPoint.anchor, leadingPoint.leftDirection);
      var rightDistance = getPairDistance(trailingPoint.anchor, trailingPoint.rightDirection);
      var leftTheta = getPairTheta(leadingPoint.anchor, leadingPoint.leftDirection);
      var rightTheta = getPairTheta(trailingPoint.anchor, trailingPoint.rightDirection);
      * If we are keeping the leadingPoint, calculate a relative rightDirection handle
      * based on the trailingPoint rightDistance and rightTheta. If we are keeping the
      * trailingPoint, copy its anchor and rightDirection handle to the leadingPoint,
      * and calculate a relative leftDirection handle based on the leadingPoint
      * leftDistance and leftTheta. If we are to keep neither leading or trailing point,
      * average the position of all the redundant points and calcuate direction handles
      * based on the appropriate values.
      if (keepLeadingPoint) {
      x = leadingPoint.anchor[0] + (Math.cos(rightTheta) * rightDistance);
      y = leadingPoint.anchor[1] + (Math.sin(rightTheta) * rightDistance);
      leadingPoint.rightDirection = Array(x, y);
      else if (keepTrailingPoint) {
      leadingPoint.anchor = trailingPoint.anchor;
      leadingPoint.rightDirection = trailingPoint.rightDirection;
      x = leadingPoint.anchor[0] + (Math.cos(leftTheta) * leftDistance);
      y = leadingPoint.anchor[1] + (Math.sin(leftTheta) * leftDistance);
      leadingPoint.leftDirection = Array(x, y);
      else {
      for (j=0; j<currentPointSet.length; j++) {
      x += path.pathPoints[currentPointSet[j]].anchor[0];
      y += path.pathPoints[currentPointSet[j]].anchor[1];
      x /= currentPointSet.length;
      y /= currentPointSet.length;
      leadingPoint.anchor = Array(x, y);
      x = leadingPoint.anchor[0] + (Math.cos(leftTheta) * leftDistance);
      y = leadingPoint.anchor[1] + (Math.sin(leftTheta) * leftDistance);
      leadingPoint.leftDirection = Array(x, y);
      x = leadingPoint.anchor[0] + (Math.cos(rightTheta) * rightDistance);
      y = leadingPoint.anchor[1] + (Math.sin(rightTheta) * rightDistance);
      leadingPoint.rightDirection = Array(x, y);
      * If the distance for a handle is less than half a point and rounds to zero,
      * retract that handle fully by setting that direction handle equal to the anchor
      * point. This will keep angles consistent for smooth points.
      if (Math.round(leftDistance) == 0) {
      leadingPoint.leftDirection = leadingPoint.anchor;
      if (Math.round(rightDistance) == 0) {
      leadingPoint.rightDirection = leadingPoint.anchor;
      * Handle the PointType in a minimal manner. If keeping the leadingPoint or keeping
      * the trailingPoint, keep the PointType of that point if possible. If both handles
      * are extended, measure the angles of the two direction handles. If both handles
      * have the same angle relative to the X axis within a tolerance, the PointType
      * can be SMOOTH, otherwise it must be CORNER. If the point type is SMOOTH, ensure
      * the direction handles are corrected to be exactly 180 degrees apart.
      * If not specifically keeping the leading or trailing point and only one handle is
      * extended, base the pointType on the the leadingPoint if only the left handle is
      * extended and the trailingPoint if only the right handle is extended. 
      if (Math.round(leftDistance) > 0 && Math.round(rightDistance) > 0) {
      var absdiff = Math.abs(leftTheta-rightTheta);
      var error = Math.PI - absdiff;
      /*alert("leftTheta="+leftTheta+" rightTheta="+rightTheta+" absdiff="+absdiff+" error="+error);*/
      if (Math.abs(error) < 0.02) {
      if (keepTrailingPoint) {
      leadingPoint.pointType = trailingPoint.pointType;
      else if (!keepLeadingPoint) {
      leadingPoint.pointType = PointType.SMOOTH;
      if (leadingPoint.pointType == PointType.SMOOTH) {
      if (keepTrailingPoint) {
      x = leadingPoint.anchor[0] + (Math.cos(Math.PI + rightTheta) * leftDistance);
      y = leadingPoint.anchor[1] + (Math.sin(Math.PI + rightTheta) * leftDistance);
      leadingPoint.leftDirection = Array(x, y);
      else {
      x = leadingPoint.anchor[0] + (Math.cos(Math.PI + leftTheta) * rightDistance);
      y = leadingPoint.anchor[1] + (Math.sin(Math.PI + leftTheta) * rightDistance);
      leadingPoint.rightDirection = Array(x, y);
      else {
      leadingPoint.pointType = PointType.CORNER;
      else if (keepTrailingPoint) {
      leadingPoint.pointType = trailingPoint.pointType;
      else if (!keepLeadingPoint && rightDistance > 0) {
      leadingPoint.pointType = trailingPoint.pointType;
      * Push all other points onto the pointsToRemove array for later removal. We can't
      * remove them while we are working with later sets.
      for (j=1; j<currentPointSet.length; j++) {
      pointsToRemove.push(currentPointSet[j]);
      * Sort the pointsToRemove array and then remove the points in reverse order, so the indicies
      * remain coherent during the removal.
      pointsToRemove.sort(function (a,b) { return a-b });
      for (i=pointsToRemove.length-1; i>=0; i--) {
      var pointToRemove = path.pathPoints[pointsToRemove[i]];
      pointToRemove.remove();
      if (tempPath) {
      tempPath.remove();
      if (tempLayer) {
      tempLayer.remove();
      return (pointsToRemove.length);
    * Function: selectRedundantPoints
    * Description:
    * Select redundant points on a path input as the first parameter. The
    * second input parameter should be an array of arrays containing the
    * indicies of redundant points, as returned from function
    * findRedundantPoints(). If there are redundant points, deselect all points
    * on the path and select the ANCHORPOINT of each redundant point. If there
    * are no redundant points on the path, do nothing.
    function selectRedundantPoints(path, redundantPointSets){
      var i = 0;
      var j = 0;
      if (redundantPointSets.length > 0) {
      for (i=0; i<path.pathPoints.length; i++) {
      path.pathPoints[i].selected = PathPointSelection.NOSELECTION;
      for (i=0; i<redundantPointSets.length; i++) {
      var currentPointSet = redundantPointSets[i];
      for (j=0; j<currentPointSet.length; j++) {
      path.pathPoints[currentPointSet[j]].selected = PathPointSelection.ANCHORPOINT;
    * Function: unlockPath
    * Description:
    * For a path input as the first parameter, unlock the path and any locked
    * parent object. Return an array of objects that have been unlocked.
    function unlockPath(path){
      var unlockedObjects = new Array();
      var parentObjects = new Array();
      var currentObject = path;
      var i = 0;
      while (currentObject.typename != "Document") {
      parentObjects.unshift(currentObject);
      currentObject = currentObject.parent;
      for (i=0; i<parentObjects.length; i++) {
      if (parentObjects[i].locked) {
      parentObjects[i].locked = false;
      unlockedObjects.unshift(parentObjects[i]);
      return unlockedObjects;
    * Function: lockObjects
    * Description:
    * For a set of objects as the first parameter, lock each object.
    function lockObjects(objects){
      var i = 0;
      for (i=0; i<objects.length; i++) {
      objects[i].locked = true;
    * Function: docGetSelectedPaths
    * Description:
    * Get all the selected paths for the docRef argument passed in as
    * a parameter. The second parameter is a boolean that controls if compound
    * path items are included (default true), and the third parameter is a
    * boolean that controls if locked objects are included (default false).
    * Returns an array of paths.
    function docGetSelectedPaths(docRef, includeCompound, includeLocked){
      var qualifiedPaths = new Array();
      var i = 0;
      var j = 0;
      var nextPath = null;
      var currentSelection = new Array();
      var nextSelection = docRef.selection;
      if (includeCompound == null) {
      includeCompound = true;
      if (includeLocked == null) {
      includeLocked = false;
      do {
      currentSelection = nextSelection;
      nextSelection = [];
      for(i=0; i<currentSelection.length; i++){
      var currentObject=currentSelection[i];
      if (currentObject.typename == "PathItem") {
      if (includeLocked || !(currentObject.locked ||
      currentObject.layer.locked)) {
      qualifiedPaths.push(currentObject);
      else if (currentObject.typename == "CompoundPathItem") {
      if (includeCompound &&
      (includeLocked || !(currentObject.locked ||
      currentObject.layer.locked))) {
      * For more complex compound paths (e.g. concentric circular bands),
      * in CS3 the CompoundPathItem object's pathItems array is empty.
      * Inspection of the paths in a document shows the paths contained
      * in the CompoundPathItem have groups as parents. To get around
      * this seeming bug, in addition to using the pathItems array,
      * which still contains individual paths, we also search through
      * all the groups in the document adding paths whose parent
      * is the CompoundPathItem object.
      * WARNING this takes non-negligible time in large documents.
      for (j=0; j<currentObject.pathItems.length; j++) {
      qualifiedPaths.push(currentObject.pathItems[j]);
      for (j=0; j<docRef.groupItems.length; j++) {
      if (docRef.groupItems[j].parent == currentObject) {
      nextSelection.push(docRef.groupItems[j]);
      else if (currentObject.typename == "GroupItem") {
      for (j=0; j<currentObject.pathItems.length; j++){
      nextSelection.push(currentObject.pathItems[j]);
      for (j=0; j<currentObject.compoundPathItems.length; j++){
      nextSelection.push(currentObject.compoundPathItems[j]);
      for (j=0; j<currentObject.groupItems.length; j++){
      nextSelection.push(currentObject.groupItems[j]);
      else if (currentObject.typename == "Layer") {
      for (j=0; j<currentObject.pathItems.length; j++){
      nextSelection.push(currentObject.pathItems[j]);
      for (j=0; j<currentObject.compoundPathItems.length; j++){
      nextSelection.push(currentObject.compoundPathItems[j]);
      for (j=0; j<currentObject.groupItems.length; j++){
      nextSelection.push(currentObject.groupItems[j]);
      for (j=0; j<currentObject.layers.length; j++){
      nextSelection.push(currentObject.layers[j]);
      } while (nextSelection.length > 0);
      return qualifiedPaths;
    * Function: docGetAllPaths
    * Description:
    * Get all the paths for the docRef argument passed in as a parameter.
    * The second parameter is a boolean that controls if compound path items are
    * included (default true), and the third parameter is a boolean that controls
    * if locked objects are included (default false). Returns an array of paths.
    function docGetAllPaths(docRef, includeCompound, includeLocked) {
      var qualifiedPaths = new Array();
      var i = 0;
      var nextPath = null;
      if (includeCompound == null) {
      includeCompound = true;
      if (includeLocked == null) {
      includeLocked = false;
      for (i=0; i<docRef.pathItems.length; i++) {
      nextPath = docRef.pathItems[i];
      if (!includeCompound && nextPath.parent.typename == "CompoundPathItem") {
      continue;
      if (!includeLocked && (nextPath.layer.locked == true || nextPath.locked == true)) {
      continue;
      qualifiedPaths.push(nextPath);
      return qualifiedPaths;
    * Function: roundToPrecision
    * Description:
    * Round a number input as the first parameter to a given precision. The
    * second input parameter is the precision to round to (typically a power of
    * 10, like 0.1). Returns the rounded value.
    function roundToPrecision(value, precision) {
      var result;
      result = value / precision;
      result = Math.round(result);
      result = result * precision;
      return (result);
    * Main code
    var dlgInit = new Window('dialog', 'Redundant Path Points');
    doInitDialog(dlgInit);
    var exitError;
    var tolerance = 1 * (dlgInit.tolerancePnl.editText.text);
    var doAnalyze = dlgInit.functionPnl.doAnalyze.value;
    var doRemove = dlgInit.functionPnl.doRemove.value;
    var doSelect = dlgInit.functionPnl.doSelect.value;
    var doKeepLeadingPoint = dlgInit.removalPnl.doKeepLeadingPoint.value;
    var doKeepTrailingPoint = dlgInit.removalPnl.doKeepTrailingPoint.value;
    var doKeepAveragedPoint = dlgInit.removalPnl.doKeepAveragedPoint.value;
    var includeCompound = dlgInit.optionPnl.includeCompound.value;
    var includeLocked = dlgInit.optionPnl.includeLocked.value;
    var ignoreSelected = dlgInit.selectionPnl.ignoreSelected.value;
    var anySelected = dlgInit.selectionPnl.anySelected.value;
    var allSelected = dlgInit.selectionPnl.allSelected.value;
    var docRef=app.activeDocument;
    var pathsToProcess = new Array();
    var i = 0;
    var j = 0;
    var totalPaths = 0;
    var totalPointsWithRedundancy = 0;
    var totalPointsToRemove = 0;
    var totalPointsRemoved = 0;
    var totalPointsStarting = 0;
    var totalPointsRemaining = 0;
    var totalPointsSelected = 0;
    var redundantPointSets = new Array();
    var unlockedObjects = new Array();
    try {
      if (exitError != 0) {
      throw("exit");
      exitError = 99;
      if (docRef.selection.length > 0) {
      pathsToProcess = docGetSelectedPaths(docRef, includeCompound, includeLocked);
      else {
      var doAll = confirm("Run script for all paths in document?");
      if (doAll) {
      pathsToProcess = docGetAllPaths(docRef, includeCompound, includeLocked);
      if (doSelect) {
      if (includeLocked) {
      exitError = 2;
      throw("exit");
      if (!ignoreSelected) {
      exitError = 3;
      throw("exit");
      docRef.selection = null;
      for (i=0; i<pathsToProcess.length; i++) {
      redundantPointSets = findRedundantPoints(pathsToProcess[i], tolerance, anySelected, allSelected);
      totalPaths++;
      totalPointsWithRedundancy += redundantPointSets.length;
      totalPointsToRemove += countRedundantPoints(redundantPointSets, doKeepLeadingPoint, doKeepTrailingPoint);
      totalPointsStarting += pathsToProcess[i].pathPoints.length;
      totalPointsSelected += countSelectedPoints(pathsToProcess[i]);
      if (doRemove) {
      if (includeLocked) {
      unlockedObjects = unlockPath(pathsToProcess[i]);
      else {
      unlockedObjects = [];
      totalPointsRemoved += removeRedundantPoints(pathsToProcess[i], redundantPointSets, doKeepLeadingPoint, doKeepTrailingPoint, doKeepAveragedPoint);
      if (unlockedObjects.length > 0) {
      lockObjects(unlockedObjects);
      if (doSelect) {
      selectRedundantPoints(pathsToProcess[i], redundantPointSets);
      totalPointsRemaining += pathsToProcess[i].pathPoints.length;
      var dlgResults = new Window('dialog', 'Redundant Path Points');
      doResultsDialog(dlgResults,
      totalPaths,
      totalPointsWithRedundancy,
      totalPointsToRemove,
      totalPointsRemoved,
      totalPointsStarting,
      totalPointsRemaining,
      totalPointsSelected,
      tolerance);
    catch(er)
      if (exitError == 2) {
      alert("Select function not supported in conjunction with 'Include Locked Items' option.");
      if (exitError == 3) {
      alert("Select function supported only with 'Ignore' selection restriction.");
      if (exitError == 99) {
      alert("ACK! Unexplained error\n");
    * Dialog Code
    * Function: doInitDialog
    function doInitDialog(dlgInit) {
      var defaultTolerance = 5.0;
      var maxSliderTolerance = 5;
      /* Add radio buttons to control functionality */
      dlgInit.functionPnl = dlgInit.add('panel', undefined, 'Function:');
      (dlgInit.functionPnl.doAnalyze = dlgInit.functionPnl.add('radiobutton', undefined, 'Analyze' )).helpTip = "Find and count redundant points.";
      (dlgInit.functionPnl.doRemove = dlgInit.functionPnl.add('radiobutton', undefined, 'Remove' )).helpTip = "Find and remove redundant points.";
      (dlgInit.functionPnl.doSelect = dlgInit.functionPnl.add('radiobutton', undefined, 'Select' )).helpTip = "Find and select redundant points.\nWARNING:Manual removal of selected redundant points can change the shape of your curves.\nTips:Hiding bounding box helps to see which points are selected. Modify selection as desired and rerun script to remove specific redundant points.";
      dlgInit.functionPnl.doRemove.value = true;
      dlgInit.functionPnl.orientation='row';
      /* Add radio buttons to control point selection */
      dlgInit.selectionPnl = dlgInit.add('panel', undefined, 'Point Selection State:');
      (dlgInit.selectionPnl.ignoreSelected = dlgInit.selectionPnl.add('radiobutton', undefined, 'Ignore')).helpTip="Process redundant points on a path regardless of their selection state.";
      (dlgInit.selectionPnl.allSelected = dlgInit.selectionPnl.add('radiobutton', undefined, 'All')).helpTip="Process redundant points on a path only if each of them is selected.";
      (dlgInit.selectionPnl.anySelected = dlgInit.selectionPnl.add('radiobutton', undefined, 'Any')).helpTip="Process redundant points on a path if any one of them is selected.";
      dlgInit.selectionPnl.allSelected.value = true;
      dlgInit.selectionPnl.orientation='row';
      /* Add a checkbox to control options */
      dlgInit.optionPnl = dlgInit.add('panel', undefined, 'Other Options:');
      (dlgInit.optionPnl.includeCompound = dlgInit.optionPnl.add('checkbox', undefined, 'Include Compound Path Items?')).helpTip="Work on compound path items.";
      (dlgInit.optionPnl.includeLocked = dlgInit.optionPnl.add('checkbox', undefined, 'Include Locked Items?')).helpTip="Work on locked items or items in locked layers.";
      dlgInit.optionPnl.includeCompound.value = true;
      dlgInit.optionPnl.includeLocked.value = false;
      dlgInit.optionPnl.alignChildren='left';
      dlgInit.optionPnl.orientation='column';
      /* Add a slider and edit box for user entered tolerance */
      dlgInit.tolerancePnl = dlgInit.add('panel', undefined, 'Tolerance (in PostScript points):');
      (dlgInit.tolerancePnl.slide = dlgInit.tolerancePnl.add('slider', undefined, defaultTolerance, 0.01, maxSliderTolerance)).helpTip="Use slider to set a tolerance value in hundredths of a point.";
      (dlgInit.tolerancePnl.editText = dlgInit.tolerancePnl.add('edittext', undefined, defaultTolerance)).helpTip="Enter a tolerance value. Values greater then 5.0 or more precise than 1/100 point can be manually entered here.";
      dlgInit.tolerancePnl.editText.characters = 5;
      dlgInit.tolerancePnl.orientation='row';
      dlgInit.tolerancePnl.slide.onChange = toleranceSliderChanged;
      dlgInit.tolerancePnl.editText.onChange = toleranceEditTextChanged;
      /* Add a panel control removal options */
      dlgInit.removalPnl = dlgInit.add('panel', undefined, 'Removal Options:');
      (dlgInit.removalPnl.doKeepLeadingPoint = dlgInit.removalPnl.add('checkbox', undefined, 'Keep Leading Point' )).helpTip = "Keep the leading point (lowest path index, lowest prior to origin cross for closed path).";
      (dlgInit.removalPnl.doKeepTrailingPoint = dlgInit.removalPnl.add('checkbox', undefined, 'Keep Trailing Point' )).helpTip = "Keep the trailing point (highest path index, highest following origin cross for closed path).";
      (dlgInit.removalPnl.doKeepAveragedPoint = dlgInit.removalPnl.add('checkbox', undefined, 'Keep Averaged Point' )).helpTip = "Keep an averaged point to help smooth transitions.";
      dlgInit.removalPnl.keepTips = dlgInit.removalPnl.add('statictext', undefined, 'Keeping neither will cause position of remaining point to be averaged. Keeping both will anchor two ends of a segment while removing intermediate redundant points. An averaged point helps smooth transitions.', {multiline:'true'} );
      dlgInit.removalPnl.doKeepLeadingPoint.value = false;
      dlgInit.removalPnl.doKeepTrailingPoint.value = false;
      dlgInit.removalPnl.doKeepAveragedPoint.value = false;
      dlgInit.removalPnl.alignChildren='left';
      dlgInit.removalPnl.orientation='column';
      /* Add execution buttons */
      dlgInit.executeGrp = dlgInit.add('group', undefined, 'Execute:');
      dlgInit.executeGrp.orientation='row';
      dlgInit.executeGrp.buildBtn1= dlgInit.executeGrp.add('button',undefined, 'Cancel', {name:'cancel'});
      dlgInit.executeGrp.buildBtn2 = dlgInit.executeGrp.add('button', undefined, 'OK', {name:'ok'});
      dlgInit.executeGrp.buildBtn1.onClick= initActionCanceled;
      dlgInit.executeGrp.buildBtn2.onClick= initActionOk;
      dlgInit.frameLocation = [100, 100];
      dlgInit.alignChildren='fill';
      dlgInit.show();
      return dlgInit;
    function initActionCanceled() {
      exitError = 1;
      dlgInit.hide();
    function initActionOk() {
      var proceed = true;
      exitError = 0;
      if (dlgInit.tolerancePnl.editText.text > 5.0) {
      proceed = confirm("Tolerance entered greater than 5.0 PostScript points. Proceed?");
      if (proceed) {
      dlgInit.hide();
    function toleranceSliderChanged() {
      dlgInit.tolerancePnl.editText.text = roundToPrecision(dlgInit.tolerancePnl.slide.value, 0.01);
    function toleranceEditTextChanged() {
      if (dlgInit.tolerancePnl.editText.text > 5000) {
      dlgInit.tolerancePnl.editText.text = 5000;
      dlgInit.tolerancePnl.slide.value = roundToPrecision(dlgInit.tolerancePnl.editText.text, 0.01);
    * Function: doResultsDialog
    function doResultsDialog(dlgResults,
      totalPaths,
      totalPointsWithRedundancy,
      totalPointsToRemove,
      totalPointsRemoved,
      totalPointsStarting,
      totalPointsRemaining,
      totalPointsSelected,
      tolerance) {
      /* Add static text to display results */
      dlgResults.resultsPnl = dlgResults.add('panel', undefined, 'Results:');
      dlgResults.resultsPnl.totalPaths = dlgResults.resultsPnl.add('group');
      dlgResults.resultsPnl.totalPaths.txt = dlgResults.resultsPnl.totalPaths.add('statictext', undefined, 'Paths processed: ');
      dlgResults.resultsPnl.totalPaths.txt.alignment = 'right';
      dlgResults.resultsPnl.totalPaths.val = dlgResults.resultsPnl.totalPaths.add('statictext', undefined, totalPaths);
      dlgResults.resultsPnl.totalPaths.val.characters = 10;
      dlgResults.resultsPnl.totalPaths.val.helpTip = "The number of paths processed.";
      dlgResults.resultsPnl.totalPointsSelected = dlgResults.resultsPnl.add('group');
      dlgResults.resultsPnl.totalPointsSelected.txt = dlgResults.resultsPnl.totalPointsSelected.add('statictext', undefined, 'Total points selected: ');
      dlgResults.resultsPnl.totalPointsSelected.txt.alignment = 'right';
      dlgResults.resultsPnl.totalPointsSelected.val = dlgResults.resultsPnl.totalPointsSelected.add('statictext', undefined, totalPointsSelected);
      dlgResults.resultsPnl.totalPointsSelected.val.characters = 10;
      dlgResults.resultsPnl.totalPointsSelected.val.helpTip = "The total number of points initially selected.";
      dlgResults.resultsPnl.separator0 = dlgResults.resultsPnl.add('panel');
      dlgResults.resultsPnl.totalPointsWithRedundancy = dlgResults.resultsPnl.add('group');
      dlgResults.resultsPnl.totalPointsWithRedundancy.txt = dlgResults.resultsPnl.totalPointsWithRedundancy.add('statictext', undefined, 'Points with redundancy: ');
      dlgResults.resultsPnl.totalPointsWithRedundancy.txt.alignment = 'right';
      dlgResults.resultsPnl.totalPointsWithRedundancy.val = dlgResults.resultsPnl.totalPointsWithRedundancy.add('statictext', undefined, totalPointsWithRedundancy);
      dlgResults.resultsPnl.totalPointsWithRedundancy.val.characters = 10;
      dlgResults.resultsPnl.totalPointsWithRedundancy.val.helpTip = "The number of points with redundancy.";
      dlgResults.resultsPnl.totalPointsToRemove = dlgResults.resultsPnl.add('group');
      dlgResults.resultsPnl.totalPointsToRemove.txt = dlgResults.resultsPnl.totalPointsToRemove.add('statictext', undefined, 'Redundant points to remove: ');
      dlgResults.resultsPnl.totalPointsToRemove.txt.alignment = 'right';
      dlgResults.resultsPnl.totalPointsToRemove.val = dlgResults.resultsPnl.totalPointsToRemove.add('statictext', undefined, totalPointsToRemove);
      dlgResults.resultsPnl.totalPointsToRemove.val.characters = 10;
      dlgResults.resultsPnl.totalPointsToRemove.val.helpTip = "The number of redundant points that would be removed.";
      dlgResults.resultsPnl.totalPointsRemoved = dlgResults.resultsPnl.add('group');
      dlgResults.resultsPnl.totalPointsRemoved.txt = dlgResults.resultsPnl.totalPointsRemoved.add('statictext', undefined, 'Redundant points removed: ');
      dlgResults.resultsPnl.totalPointsRemoved.txt.alignment = 'right';
      dlgResults.resultsPnl.totalPointsRemoved.val = dlgResults.resultsPnl.totalPointsRemoved.add('statictext', undefined, totalPointsRemoved);
      dlgResults.resultsPnl.totalPointsRemoved.val.characters = 10;
      dlgResults.resultsPnl.totalPointsRemoved.val.helpTip = "The number of redundant points that were removed.";
      dlgResults.resultsPnl.separator1 = dlgResults.resultsPnl.add('panel');
      dlgResults.resultsPnl.totalPointsStarting = dlgResults.resultsPnl.add('group');
      dlgResults.resultsPnl.totalPointsStarting.txt = dlgResults.resultsPnl.totalPointsStarting.add('statictext', undefined, 'Total points starting: ');
      dlgResults.resultsPnl.totalPointsStarting.txt.alignment = 'right';
      dlgResults.resultsPnl.totalPointsStarting.val = dlgResults.resultsPnl.totalPointsStarting.add('statictext', undefined, totalPointsStarting);
      dlgResults.resultsPnl.totalPointsStarting.val.characters = 10;
      dlgResults.resultsPnl.totalPointsStarting.helpTip = "The total number of points before processing.";
      dlgResults.resultsPnl.totalPointsRemaining = dlgResults.resultsPnl.add('group');
      dlgResults.resultsPnl.totalPointsRemaining.txt = dlgResults.resultsPnl.totalPointsRemaining.add('statictext', undefined, 'Total points remaining: ');
      dlgResults.resultsPnl.totalPointsRemaining.txt.alignment = 'right';
      dlgResults.resultsPnl.totalPointsRemaining.val = dlgResults.resultsPnl.totalPointsRemaining.add('statictext', undefined, totalPointsRemaining);
      dlgResults.resultsPnl.totalPointsRemaining.val.characters = 10;
      dlgResults.resultsPnl.totalPointsRemaining.val.helpTip = "The total number of points after processing.";
      dlgResults.resultsPnl.alignChildren='right';
      dlgResults.resultsPnl.orientation='column';
      dlgResults.note = dlgResults.add('group');
      dlgResults.note.txt = dlgResults.note.add('statictext', undefined, 'Combined results across paths qualified based on options');
      dlgResults.tolerance = dlgResults.add('group');
      dlgResults.tolerance.txt = dlgResults.tolerance.add('statictext', undefined, "Tolerance applied (in PostScript points): ");
      dlgResults.tolerance.val = dlgResults.tolerance.add('statictext', undefined, tolerance);
      /* Add execution buttons */
      dlgResults.executeGrp = dlgResults.add('group', undefined, 'Execute:');
      dlgResults.executeGrp.orientation='row';
      dlgResults.executeGrp.buildBtn1= dlgResults.executeGrp.add('button',undefined, 'OK', {name:'ok'});
      dlgResults.executeGrp.buildBtn1.onClick= resultsActionOk;
      dlgResults.frameLocation = [100, 100];
      dlgResults.show();
    function resultsActionOk() {
      exitError = 0;
      dlgResults.hide();

    you have said you are using cc.
    is it fully up to date?
    are you not using cc2014?
    when run from ESTK are you sure it is pointing to the correct illustrator?

  • 2 VSANs and FC Links To Storage

    I have 2 MDS 9148s and would like to create 2 VSANs, no problem.
    All the storage is located on one EMC (2 FC links from the controllers to the MDS).
    The issue I have is can I have a port a member of 2 VSANs, I would think not. The reason is, the current FC links to the MDS from the EMC is in one zone. So how do I allocate another storage pool to the other VSAN if it's already allocated to another? Do I have to run more Fibre Cables to the controllers?
    Thanks

    The layout is above..... I was thinking of 2 VSANs (10 and 15) that would be mapped to different storage pools in the EMC VNX. My confusion (new to MDS from Brocades) is the MDS configuration.mIn the typical SAN layout above with VSANs we have redundant paths to the storage controllers. So the above pic has one VSAN (10 let's say) and the MDS ports are assigned to this VSAN. Would I not have to run another set of Fibre Cables from the Fabric Interconnects to the MDS and from the MDS to the EMX STorage array to assign these ports to another VSAN (15). I think I am missing something.....
    Or can I use FC Port Channels on these MDS ports to share VSAN 10 and 15????
    Thanks

  • FCIP over Wireless (Disaster Recovery | Live Storage)

    We're in the process of suggesting various DR Scenarios for an Existing Data Center Environment with Dual 9216 Series MDSs (Fiber Connected to EMC Arrays). Our customer requires an economically sound alternative to a metro carrier's gigabit MAN Service. Can FCIP Encapsulated over TCP/IP over a Gigabit Level Wireless Medium be considered a viable design opportunity. If not, what would be the primary negative impact on the existing SAN Environment and its applications(26 T of Raw Storage) - approx 40% would be transported at night, and periodically during the day. Multiple Networking Paths would exists between the Production Data Center and the DR Location located in approx. 20-30 Miles away. Thanks.
    Neil Barnett

    This is actually a loaded question with many things to consider. The main question in my mind is what kind of traffic is going over this link. Are you just snapping your luns over this link to a standby array? Are you running live data in a synchronous environment?
    I would be comfortable snapping data over a wireless link, but not comfortable running synchronous data.
    The reality of the fact is that wireless has signal loss, and events due to weather. If you are doing gigabit at 30 miles (though, the fastest I have seen at that range is oc-12 speeds) you are going to be up in the high microwave range, which tends to react to precipitation and moisture in the air. Along with being on a high tower which can get affected by winds.
    If you have redundant paths, and are snapping this will not be a problem, as you will probably just have to re-initialize the snapshot in a worst case scenario.
    If you are doing synchronous writes, you are just asking for a giant headache.
    --Colin
    http://www.2cups.com

  • Various questions on uplink profiles, CoS, native VLAN, downlink trunking

    I will be using vPC End Host Mode with MAC-pinning. I see I can further configure MAC-Pinning. Is this required or will it automatically forward packets by just turning it on? Is it also best not to enable failover for the vnics in this configuration? See this text from the Cisco 1000V deployment Guide:
    Fabric Fail-Over Mode
    Within the Cisco UCS M71KR-E, M71KR-Q and M81KR adapter types, the Cisco Unified Computing System can
    enable a fabric failover capability in which loss of connectivity on a path in use will cause remapping of traffic
    through a redundant path within the Cisco Unified Computing System. It is recommended to allow the Cisco Nexus
    1000V redundancy mechanism to provide the redundancy and not to enable fabric fail-over when creating the
    network interfaces within the UCS Service Profiles. Figure 3 shows the dialog box. Make sure the Enable Failover
    checkbox is not checked."
    What is the 1000V redundancy?? I didn't know it has redundancy. Is it the MAC-Pinning set up in the 1000V? Is it Network State Tracking?
    The 1000V has redundancy and we can even pin VLANs to whatever vNIC we want. See Cisco's Best Practices for Nexus 1000V and UCS.
    Nexus1000V management VLAN. Can I use the same VLAN for this and for ESX-management and for Switch management? E.g VLan 3 for everything.
    According to the below text (1000V Deployment Guide), I can have them all in the same vlan:
    There are no best practices that specify whether the VSM
    and the VMware ESX management interface should be on the same VLAN. If the management VLAN for
    network devices is a different VLAN than that used for server management, the VSM management
    interface should be on the management VLAN used for the network devices. Otherwise, the VSM and the
    VMware ESX management interfaces should share the same VLAN.
    I will also be using CoS and Qos to prioritize the traffic. The CoS can either be set in the 1000V (Host control Full) or per virtual adapter (Host control none) in UCS. Since I don't know how to configure CoS on the 1000V, I wonder if I can just set it in UCS (per adapter) as before when using the 1000V, ie. we have 2 choices.
    Yes, you can still manage CoS using QoS on the vnics when using 1000V:
    The recommended action in the Cisco Nexus 1000V Series is to assign a class of service (CoS) of 6 to the VMware service console and VMkernel flows and to honor these QoS markings on the data center switch to which the Cisco UCS 6100 Series Fabric Interconnect connects. Marking of QoS values can be performed on the Cisco Nexus 1000V Series Switch in all cases, or it can be performed on a per-VIF basis on the Cisco UCS M81KR or P81E within the Cisco Unified Computing System with or without the Cisco Nexus 1000V Series Switch.
    Something else: Native VLANs
    Is it important to have the same native VLAN on the UCS and the Cisco switch? And not to use the default native VLAN 1?   I read somewhere that the native VLAN is used for communication between the switches and CDP amongst others. I know the native VLAN is for all untagged traffic. I see many people set the ESXi management VLAN as native also, and in the above article the native VLAN (default 1) is setup. Why? I have been advised to leave out the native VLAN.
    Example:Will I be able to access a VM set with VLAN 0 (native) if the native VLAN is the same in UCS and the Cisco switch (Eg. VLAN 2)? Can I just configure a access port with the same VLAN ID as the native VLAN, i.e 2 and connect to it with a PC using the same IP network address?
    And is it important to trunk this native VLAN? I see in a Netapp Flexpod config they state this: "This configuration also leverages the native VLAN on the trunk ports to discard untagged packets, by setting the native VLAN on the port channel, but not including this VLAN in the allowed VLANs on the port channel". But I don't understand it...
    What about the downlinks from the FI to the chassis. Do you configure this as a port channel also in UCS? Or is this not possible with the setup described here with 1000V and MAC-pinning.
    No, port channel should not be configured when MAC-pinning is configured.
    [Robert] The VSM doesn't participate in STP so it will never send BPDU's.  However, since VMs can act like bridges & routers these days, we advise to add two commands to your upstream VEM uplinks - PortFast and BPDUFilter.  PortFast so the interface is FWD faster (since there's no STP on the VSM anyway) and BPDUFilter to ignore any received BPDU's from VMs.  I prefer to ignore them then using BPDU Gaurd - which will shutdown the interface if BPDU's are received.
    -Are you thinking of the upstream switch here (Nexus, Catalyst) or the N1kV uplink profile config?
    Edit: 26 July 14:23. Found answers to many of my many questions...

    Answers inline.
    Atle Dale wrote:
    Something else: Native VLANsIs it important to have the same native VLAN on the UCS and the Cisco switch? And not to use the default native VLAN 1?   I read somewhere that the native VLAN is used for communication between the switches and CDP amongst others. I know the native VLAN is for all untagged traffic. I see many people set the ESXi management VLAN as native also, and in the above article the native VLAN (default 1) is setup. Why? I have been advised to leave out the native VLAN.[Robert] The native VLAN is assigned per hop.  This means between the 1000v Uplinks port profile and your UCS vNIC definition, the native VLAN should be the same.  If you're not using a native VLAN, the "default" VLAN will be used for control traffic communication.  The native VLAN and default VLAN are not necessarily the same.  Native refers to VLAN traffic without an 802.1q header and can be assigned or not.  A default VLAN is mandatory.  This happens to start as VLAN 1 in UCS but can be changed. The default VLAN will be used for control traffic communication.  If you look at any switch (including the 1000v or Fabric Interconnects) and do a "show int trunk" from the NXOS CLI, you'll see there's always one VLAN allowed on every interface (by default VLAN 1) - This is your default VLAN.Example:Will I be able to access a VM set with VLAN 0 (native) if the native VLAN is the same in UCS and the Cisco switch (Eg. VLAN 2)? Can I just configure a access port with the same VLAN ID as the native VLAN, i.e 2 and connect to it with a PC using the same IP network address?[Robert] There's no VLAN 0.  An access port doesn't use a native VLAN - as its assigned to only to a single VLAN.  A trunk on the other hand carries multiple VLANs and can have a native vlan assigned.  Remember your native vlan usage must be matched between each hop.  Most network admins setup the native vlan to be the same throughout their network for simplicity.  In your example, you wouldn't set your VM's port profile to be in VLAN 0 (doens't exist), but rather VLAN 2 as an access port.  If VLAN 2 also happens to be your Native VLAN northbound of UCS, then you would configured VLAN 2 as the Native VLAN on your UCS ethernet uplinks.  On switch northbound of the UCS Interconnects you'll want to ensure on the receiving trunk interface VLAN 2 is set as the native vlan also.  Summary:1000v - VM vEthernet port profile set as access port VLAN 21000v - Ethernet Uplink Port profile set as trunk with Native VLAN 2UCS - vNIC in Service Profile allowing all required VLANs, and VLAN 2 set as NativeUCS - Uplink Interface(s) or Port Channel set as trunk with VLAN 2 as Native VLANUpstream Switch from UCS - Set as trunk interface with Native VLAN 2From this example, your VM will be reachable on VLAN 2 from any device - assuming you have L3/routing configured correctly also.And is it important to trunk this native VLAN? I see in a Netapp Flexpod config they state this: "This configuration also leverages the native VLAN on the trunk ports to discard untagged packets, by setting the native VLAN on the port channel, but not including this VLAN in the allowed VLANs on the port channel". But I don't understand it...[Robert] This statement recommends "not" to use a native VLAN.  This is a practice by some people.  Rather than using a native VLAN throughout their network, they tag everything.  This doesn't change the operation or reachability of any VLAN or device - it's simply a design descision.  The reason some people opt not to use a native VLAN is that almost all switches use VLAN 1 as the native by default.  So if you're using the native VLAN 1 for management access to all your devices, and someone connects in (without your knowing) another switch and simply plug into it - they'd land on the same VLAN as your management devices and potentially do harm.What about the downlinks from the FI to the chassis. Do you configure this as a port channel also in UCS? Or is this not possible with the setup descrived here with 1000V and MAC-pinning.[Robert] On the first generation hardware (6100 FI and 2104 IOM) port channeling is not possible.  With the latest HW (6200 and 2200) you can create port channels with all the IOM - FI server links.  This is not configurable.  You either tell the system to use Port Channel or Individual Links.  The major bonus of using a Port Channel is losing a link doesn't impact any pinned interfaces - as it would with individual server interfaces.  To fix a failed link when configured as "Individual" you must re-ack the Chassis to re-pinn the virtual interfaces to the remaining server uplinks.  In regards to 1000v uplinks - the only supported port channeling method is "Mac Pinning".  This is because you can't port channel physical interfaces going to separate Fabrics (one to A and one to B).  Mac Pinning gets around this by using pinning so all uplinks can be utilized at the same time.--[Robert] The VSM doesn't participate in STP so it will never send BPDU's.  However, since VMs can act like bridges & routers these days, we advise to add two commands to your upstream VEM uplinks - PortFast and BPDUFilter.  PortFast so the interface is FWD faster (since there's no STP on the VSM anyway) and BPDUFilter to ignore any received BPDU's from VMs.  I prefer to ignore them then using BPDU Gaurd - which will shutdown the interface if BPDU's are received.-Are you thinking of the upstream switch here (Nexus, Catalyst) or the N1kV uplink profile config?[Robert] The two STP commands would be used only when the VEM (ESX host) is directly connected to an upstream switch.  For UCS these two commands to NOT apply.

  • Command to block a port in Vlan

    I have 3 switches interconnecting to each other. A PC in switch A wishes to ping to PC on Switch C. There are 2 paths leading to it, what command can i use to block one of the port so that there is only one path?
    Is it setting one of the switch as root? Or is it something to do with portfast?
    Note:Pulling out the physical link is not an option.

    Hi,
    By default, you have Spanning tree enabled on the switches and it should automatically block the redundent port. Use the command " show spanning-tree brief " command to check it is enable on the switch.
    Based on the lowest bridge ID( Lowest MAC + Priority ) the switches will automatically calculate the root and once agreed upon that the root switch blocks the redundent path based on some calculation. If you want you can force a particular switch to be root switch by lowering dwon the priority which is by default 32768 for the switches. You can use command " spanning-tree priority in the config mode.
    Portfast puts the port into forwarding state directly from blocking and thus skipping the intermediate states. It is generally used on host ports. Never enable portfast on the ports connecting to switches as it might results in a loop.
    HTH,
    -amit singh

  • ASM like RAID 1 between two storages

    In my production environment instances of Oracle are under the file system JFS2. Soon we will have to relocate space for these file or switch to ASM. Our preference is going to the ASM, but we do need some tests we are conducting.
    Today, in a production environment, data from storage1 are replicated via AIX / HACMP for storage2.
    Our tests with the ASM has to contemplate the use of a set of disks in storage1 and another set in storage2.
    Below the details of the environment:
    In AIX 5.3 TL8+
    root@suorg06_BKP:/&gt; lspv+
    hdisk17 none None
    hdisk18 none None
    hdisk19 none None
    hdisk16 none None
    root@suorg06_BKP:/&gt; fget_config -Av*
    ---dar0---
    User array name = 'STCATORG01'
    dac0 ACTIVE dac1 ACTIVE
    Disk DAC LUN Logical Drive
    hdisk17 dac0 15 ASMTST_02
    hdisk16 dac0 14 ASMTST_01
    ---dar1---
    User array name = 'STCATORG02'
    dac4 ACTIVE dac5 ACTIVE
    Disk DAC LUN Logical Drive
    hdisk18 dac5 16 ASMTST_B01
    hdisk19 dac5 17 ASMTST_B02
    select+
    *  lpad(name,15) as name,*
    *  group_number,*
    *  disk_number,*
    *  mount_status,*
    *  header_status,*
    *  state,*
    *  redundancy,*
    *  lpad(path,15) as path,*
    *  total_mb,*
    *  free_mb,*
    *  to_char(create_date,'dd/mm/yyyy') as create_date,*
    *  to_char(mount_date,'dd/mm/yyyy') as mount_date*
    from+
    *  v$asm_disk*
    order by+
    *  disk_number;*
    NAME GROUP_NUMBER DISK_NUMBER MOUNT_S HEADER_STATU STATE REDUNDA PATH TOTAL_MB FREE_MB
    0 0 CLOSED CANDIDATE NORMAL UNKNOWN /dev/rhdisk16 30720 0
    0 1 CLOSED CANDIDATE NORMAL UNKNOWN /dev/rhdisk17 30720 0
    0 2 CLOSED CANDIDATE NORMAL UNKNOWN /dev/rhdisk18 30720 0
    0 3 CLOSED CANDIDATE NORMAL UNKNOWN /dev/rhdisk19 30720 0
    select+
    *  v$asm_diskgroup.group_number,*
    *  lpad(v$asm_diskgroup.name,20) as name,*
    *  v$asm_diskgroup.sector_size,*
    *  v$asm_diskgroup.block_size,*
    *  v$asm_diskgroup.allocation_unit_size,*
    *  v$asm_diskgroup.state,*
    *  v$asm_diskgroup.type,*
    *  v$asm_diskgroup.total_mb,*
    *  v$asm_diskgroup.free_mb,*
    *  v$asm_diskgroup.offline_disks,*
    *  v$asm_diskgroup.unbalanced,*
    *  v$asm_diskgroup.usable_file_mb*
    from+
    *  v$asm_diskgroup*
    order by+
    *  v$asm_diskgroup.group_number;*
    no rows selected
    SQL&gt; CREATE DISKGROUP 'DB_DG_TESTE' NORMAL REDUNDANCY DISK '/dev/rhdisk16', '/dev/rhdisk18';+
    Diskgroup created.
    select+
    *  lpad(name,15) as name,*
    *  group_number,*
    *  disk_number,*
    *  mount_status,*
    *  header_status,*
    *  state,*
    *  redundancy,*
    *  lpad(path,15) as path,*
    *  total_mb,*
    *  free_mb,*
    *  to_char(create_date,'dd/mm/yyyy') as create_date,*
    *  to_char(mount_date,'dd/mm/yyyy') as mount_date*
    from+
    *  v$asm_disk*
    order by+
    *  disk_number;*
    NAME GROUP_NUMBER DISK_NUMBER MOUNT_S HEADER_STATU STATE REDUNDA PATH TOTAL_MB FREE_MB CREATE_DAT MOUNT_DATE
    DB_DG_TESTE_000 1 0 CACHED MEMBER NORMAL UNKNOWN /dev/rhdisk16 30720 30669 09/12/2008 09/12/2008
    0 1 CLOSED CANDIDATE NORMAL UNKNOWN /dev/rhdisk17 30720 0 09/12/2008 09/12/2008
    DB_DG_TESTE_000 1 1 CACHED MEMBER NORMAL UNKNOWN /dev/rhdisk18 30720 30669 09/12/2008 09/12/2008
    0 3 CLOSED CANDIDATE NORMAL UNKNOWN /dev/rhdisk19 30720 0 09/12/2008 09/12/2008
    select+
    *  v$asm_diskgroup.group_number,*
    *  lpad(v$asm_diskgroup.name,20) as name,*
    *  v$asm_diskgroup.sector_size,*
    *  v$asm_diskgroup.block_size,*
    *  v$asm_diskgroup.allocation_unit_size,*
    *  v$asm_diskgroup.state,*
    *  v$asm_diskgroup.type,*
    *  v$asm_diskgroup.total_mb,*
    *  v$asm_diskgroup.free_mb,*
    *  v$asm_diskgroup.offline_disks,*
    *  v$asm_diskgroup.unbalanced,*
    *  v$asm_diskgroup.usable_file_mb*
    from+
    *  v$asm_diskgroup*
    order by+
    *  v$asm_diskgroup.group_number;*
    GROUP_NUMBER NAME SECTOR_SIZE BLOCK_SIZE ALLOCATION_UNIT_SIZE STATE TYPE TOTAL_MB FREE_MB OFFLINE_DISKS U USABLE_FILE_MB
    1 DB_DG_TESTE 512 4096 1048576 MOUNTED NORMAL 61440 61338 0 N _30669_
    SQL&gt; ALTER DISKGROUP 'DB_DG_TESTE' ADD DISK '/dev/rhdisk17', '/dev/rhdisk19';+
    select+
    *  lpad(name,15) as name,*
    *  group_number,*
    *  disk_number,*
    *  mount_status,*
    *  header_status,*
    *  state,*
    *  redundancy,*
    *  lpad(path,15) as path,*
    *  total_mb,*
    *  free_mb,*
    *  to_char(create_date,'dd/mm/yyyy') as create_date,*
    *  to_char(mount_date,'dd/mm/yyyy') as mount_date*
    from+
    *  v$asm_disk*
    order by+
    *  disk_number;*
    NAME GROUP_NUMBER DISK_NUMBER MOUNT_S HEADER_STATU STATE REDUNDA PATH TOTAL_MB FREE_MB CREATE_DAT MOUNT_DATE
    DB_DG_TESTE_000 1 0 CACHED MEMBER NORMAL UNKNOWN /dev/rhdisk16 30720 30681 09/12/2008 09/12/2008
    DB_DG_TESTE_000 1 1 CACHED MEMBER NORMAL UNKNOWN /dev/rhdisk18 30720 30681 09/12/2008 09/12/2008
    DB_DG_TESTE_000 1 2 CACHED MEMBER NORMAL UNKNOWN /dev/rhdisk17 30720 30682 09/12/2008 09/12/2008
    DB_DG_TESTE_000 1 3 CACHED MEMBER NORMAL UNKNOWN /dev/rhdisk19 30720 30681 09/12/2008 09/12/2008
    select+
    *  v$asm_diskgroup.group_number,*
    *  lpad(v$asm_diskgroup.name,20) as name,*
    *  v$asm_diskgroup.sector_size,*
    *  v$asm_diskgroup.block_size,*
    *  v$asm_diskgroup.allocation_unit_size,*
    *  v$asm_diskgroup.state,*
    *  v$asm_diskgroup.type,*
    *  v$asm_diskgroup.total_mb,*
    *  v$asm_diskgroup.free_mb,*
    *  v$asm_diskgroup.offline_disks,*
    *  v$asm_diskgroup.unbalanced,*
    *  v$asm_diskgroup.usable_file_mb*
    from+
    *  v$asm_diskgroup*
    order by+
    *  v$asm_diskgroup.group_number;*
    GROUP_NUMBER NAME SECTOR_SIZE BLOCK_SIZE ALLOCATION_UNIT_SIZE STATE TYPE TOTAL_MB FREE_MB OFFLINE_DISKS U USABLE_FILE_MB
    1 DB_DG_TESTE 512 4096 1048576 MOUNTED NORMAL 122880 122725 0 N 46002
    At the end of the creation of diskgroup you can see the query that the space available for the diskgroup is 30669 MB, but after the addition of two other discs the size in MB available 46002.
    It was not expected that the space available for use was approximately 50% of total discs?
    How should I proceed with the creation of diskgroup to have it in the
    mirror storage1 with storage2 without this great loss of space
    Edited by: scarlosantos on Dec 9, 2008 4:39 PM

    Maybe my phrasing was bad in the last post.
    You can do the RAID on IDE 3 by creating the array with either SATA 1 or 2. To install the driver, you must bootup with your Windows CD and hit F6 when being prompt to install 3rd party Drivers for RAID/SCSI.
    You should have the SATA driver Floppy disk with you and it is required to install the drivers.
    After installing the drivers, exit Windows installation and reboot, during reboot press Ctrl F to enter the Promise RAID array menu and you are up to do the RAID. Please read through the Serial ATA Raid manual for more info.

Maybe you are looking for

  • Address data changed after invoice is created

    Hi, I've a problem to solve and it's related with data changed after invoice is created. The scenario is the follow: 1º - create a complete and standard sales process - order => delivery => invoice, with the standard partner scheme and without edit t

  • How do you harness URL external application in a JSP?

    I have successfully deployed the Yahoo Finance sample URL External Application. However, I do not understand how to utilize the URL classes (in the pdkjava.jar) to harness the external application information once a user has authenticated. I am build

  • NoClassDefFound error wl9.2

    I am trying to deploy a war archive to a remote server running 9.2. I'm using the admin console to do this. When I start the application, I am getting the NoClassDef found error. I have tested this same war on my local instance running wl 10.0.3 and

  • Message variant is missing in INBOUND IDOC.

    hi, Any one can help on this issue? The sender has confirmed that message variant was filled in outgoing file. However, When we received this Inbound IDOC, the message variant is blank. I still am confused by two questions: 1. The function module whi

  • IMovie HD saved project in older version of iMovie.  Now can't open/find it

    Working on an iMovie HD slideshow. Saved it although had a warning that older versions could not open it. Since I only have iMovie HD, I assumed no problem. Now I cannot open the file. Received WARNING ' The project "___" was saved with an older vers