ZFSSA LUN ID mapping

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:>

 

 

 

Leave a Reply

Your email address will not be published. Required fields are marked *