We had some issues with iSCSI LUN IDs and multi pathing on Linux / OVM mixing up LUN IDs so clients could not load their devices anymore from a ZFS Storage Appliance with two storage pools… putting all LUNs in a pool into own target groups per ZS controller seems to work. We think the problem was based on LUN 0 which has to be seen by the initiators when scanning or connecting to the iSCSI targets.
Based on this issue I want to see if the LUN is in a group and which LUN ID was generated. Clicking around in the BUI or selecting every LUN on CLI takes ages and is quite uncomfortable. So I wrote this little script to get these values… The script language of the Oracle ZFS Storage Appliance is based on JavaScript (ECMAScript version 3) with a few extensions.
# ssh root@zfssa < lun-map.aksh | sort --version-sort Pseudo-terminal will not be allocated because stdin is not a terminal. 0 OVM clusterpool PERFpool zfssa01_tgt_grp 1 OVM store_zfs02 CAPpool zfssa02_tgt_grp 2 OVM store_zfs01 PERFpool zfssa01_tgt_grp 4 CLUSTER01 dg_cluster01 PERFpool zfssa01_tgt_grp 6 CLUSTER01 dg_cluster02 PERFpool zfssa01_tgt_grp 8 CLUSTER01 dg_cluster03 PERFpool zfssa01_tgt_grp 10 CLUSTER01 dg_data01 PERFpool zfssa01_tgt_grp 12 CLUSTER01 dg_data02 PERFpool zfssa01_tgt_grp 14 CLUSTER01 dg_data03 PERFpool zfssa01_tgt_grp 16 CLUSTER01 dg_data04 PERFpool zfssa01_tgt_grp 18 CLUSTER01 dg_fra01 PERFpool zfssa01_tgt_grp 20 CLUSTER01 dg_fra02 PERFpool zfssa01_tgt_grp 22 FRA DG_DATA01 PERFpool zfssa01_tgt_grp 24 FRA DG_DATA02 PERFpool zfssa01_tgt_grp 26 CLUSTER02 dg_cluster01 PERFpool zfssa01_tgt_grp 28 CLUSTER02 dg_cluster02 PERFpool zfssa01_tgt_grp 30 CLUSTER02 dg_cluster03 PERFpool zfssa01_tgt_grp 32 CLUSTER02 dg_data01 PERFpool zfssa01_tgt_grp 34 CLUSTER02 dg_data02 PERFpool zfssa01_tgt_grp 36 CLUSTER02 dg_data03 PERFpool zfssa01_tgt_grp 38 CLUSTER02 dg_data04 PERFpool zfssa01_tgt_grp 40 CLUSTER02 dg_fra01 PERFpool zfssa01_tgt_grp 42 CLUSTER02 dg_fra02 PERFpool zfssa01_tgt_grp 44 FRA DG_DATA03 PERFpool zfssa01_tgt_grp 46 FRA DG_DATA04 PERFpool zfssa01_tgt_grp 48 FRA DG_FRA01 PERFpool zfssa01_tgt_grp 50 FRA DG_FRA02 PERFpool zfssa01_tgt_grp 56 CLUSTER03 dg_cluster01 PERFpool zfssa01_tgt_grp 58 CLUSTER03 dg_cluster02 PERFpool zfssa01_tgt_grp 60 CLUSTER03 dg_cluster03 PERFpool zfssa01_tgt_grp 62 CLUSTER03 dg_data01 PERFpool zfssa01_tgt_grp 64 CLUSTER03 dg_data02 PERFpool zfssa01_tgt_grp 66 CLUSTER03 dg_data03 PERFpool zfssa01_tgt_grp 68 CLUSTER03 dg_data04 PERFpool zfssa01_tgt_grp 70 CLUSTER03 dg_fra01 PERFpool zfssa01_tgt_grp 72 CLUSTER03 dg_fra02 PERFpool zfssa01_tgt_grp
As you can see deleting LUNs and creating new does not use free numbers again. There is also a known bug that OVM cannot see more than 44 LUNs (MOS DocID 1932633.1)
My CODE:
script /* small script to get LUN IDs for ZFSSA iSCSI volumes */ /* let's get some VARs to work with... we need to know how many pools are configured */ function getPools() { var poolChoices, p, poolList = new Array(), singlePool, err; run('cd /'); run('configuration storage'); try { poolChoices = choices('pool'); if (poolChoices.length > 0) { singlePool = false; } else { singlePool = true; } } catch (err) { singlePool = true; } if (singlePool) { poolList[0] = new Object(); poolList[0].pool = get('pool'); poolList[0].status = get('status'); try { poolList[0].owner = get('owner'); } catch (err) { /* poolList[0].owner = 'current'; */ poolList[0].owner = get('pool'); } } else { for (p = 0; p < poolChoices.length; p += 1) { try { run('set pool=' + poolChoices[p]); poolList[p] = new Object(); poolList[p].pool = get('pool'); poolList[p].status = get('status'); try { poolList[p].owner = get('owner'); } catch (err) { poolList[p].owner = 'current'; } } catch (err) { continue; } } } return (poolList); } /* Now we can use the pool(s) and look for LUNs */ allPools = getPools(); run('cd /'); run('shares'); for (p = 0; p < allPools.length; p += 1) { try { run('set pool=' + allPools[p].pool); } catch (err) { continue; } projects = list(); /* in multiple projects could be LUNs */ for (i = 0; i < projects.length; i++) { try { run('select ' + projects[i]); } catch(err) { continue; } luns = list(); for (j = 0; j < luns.length; j++) { run('select ' + luns[j]); /* but it could also be a share, so ignore the error if no ID could be found */ try { printf("%-5s %-15s %-15s %-15s %-15s\n", get('assignednumber'), projects[i], luns[j], allPools[p].pool, get('targetgroup')); } catch(err) { run('cd ..'); continue; } run('cd ..'); } run('cd ..'); } }
If you want to store this code on the appliance you just have to replace “script” by
var workflow = { name: 'LUN ID discovery', description: 'Displays the current LUN IDs', execute: function () { CODE COMES HERE } };
Then you upload the file as a workflor and you will find it in the BUI and on CLI. Workflows are used to store scripts in the Oracle ZFS Storage Appliance and they also offer user access management for scripts and argument validation functionality.
zfssa:> maintenance workflows show Properties: showhidden = false Workflows: WORKFLOW NAME OWNER SETID ORIGIN VERSION workflow-000 LUN ID discovery root false <local> undefined workflow-001 Clear locks root false Oracle Corporation 1.0.0 workflow-002 Configure for Oracle Solaris Cluster NFS root false Oracle Corporation 1.0.0 workflow-003 Unconfigure Oracle Solaris Cluster NFS root false Oracle Corporation 1.0.0 workflow-004 Configure for Oracle Enterprise Manager Monitoring root false Sun Microsystems, Inc. 1.1 workflow-005 Unconfigure Oracle Enterprise Manager Monitoring root false Sun Microsystems, Inc. 1.0 zfssa:> zfssa:> maintenance workflows select workflow-000 run zfssa:> maintenance workflow-000 run (uncommitted)> commit Workflow output: 1 OVM store_zfs02 CAPpool zfssa02_tgt_grp 4 CLUSTER01 dg_cluster01 PERFpool zfssa01_tgt_grp 6 CLUSTER01 dg_cluster02 PERFpool zfssa01_tgt_grp 8 CLUSTER01 dg_cluster03 PERFpool zfssa01_tgt_grp 10 CLUSTER01 dg_data01 PERFpool zfssa01_tgt_grp 12 CLUSTER01 dg_data02 PERFpool zfssa01_tgt_grp 14 CLUSTER01 dg_data03 PERFpool zfssa01_tgt_grp 16 CLUSTER01 dg_data04 PERFpool zfssa01_tgt_grp 18 CLUSTER01 dg_fra01 PERFpool zfssa01_tgt_grp 20 CLUSTER01 dg_fra02 PERFpool zfssa01_tgt_grp 26 CLUSTER02 dg_cluster01 PERFpool zfssa01_tgt_grp 28 CLUSTER02 dg_cluster02 PERFpool zfssa01_tgt_grp 30 CLUSTER02 dg_cluster03 PERFpool zfssa01_tgt_grp 32 CLUSTER02 dg_data01 PERFpool zfssa01_tgt_grp 34 CLUSTER02 dg_data02 PERFpool zfssa01_tgt_grp 36 CLUSTER02 dg_data03 PERFpool zfssa01_tgt_grp 38 CLUSTER02 dg_data04 PERFpool zfssa01_tgt_grp 40 CLUSTER02 dg_fra01 PERFpool zfssa01_tgt_grp 42 CLUSTER02 dg_fra02 PERFpool zfssa01_tgt_grp 56 CLUSTER03 dg_cluster01 PERFpool zfssa01_tgt_grp 58 CLUSTER03 dg_cluster02 PERFpool zfssa01_tgt_grp 60 CLUSTER03 dg_cluster03 PERFpool zfssa01_tgt_grp 62 CLUSTER03 dg_data01 PERFpool zfssa01_tgt_grp 64 CLUSTER03 dg_data02 PERFpool zfssa01_tgt_grp 66 CLUSTER03 dg_data03 PERFpool zfssa01_tgt_grp 68 CLUSTER03 dg_data04 PERFpool zfssa01_tgt_grp 70 CLUSTER03 dg_fra01 PERFpool zfssa01_tgt_grp 72 CLUSTER03 dg_fra02 PERFpool zfssa01_tgt_grp 22 FRA DG_DATA01 PERFpool zfssa01_tgt_grp 24 FRA DG_DATA02 PERFpool zfssa01_tgt_grp 44 FRA DG_DATA03 PERFpool zfssa01_tgt_grp 46 FRA DG_DATA04 PERFpool zfssa01_tgt_grp 48 FRA DG_FRA01 PERFpool zfssa01_tgt_grp 50 FRA DG_FRA02 PERFpool zfssa01_tgt_grp 0 OVM clusterpool PERFpool zfssa01_tgt_grp 2 OVM store_zfs01 PERFpool zfssa01_tgt_grp zfssa:>
many thanks Martin, saves time and brain force 🙂
Rudi