Investigate the RENAME MI instruction by experimentation.
In the Machine Interface Architecture Introduction documentation in the IBM i
Access is prohibited if another thread is holding any lock on the system object. In general, this rule applies to instructions that destroy or rename a system object.
You might be familiar with the "Destroy" MI instructions, such as Destroy Space (DESS), Destroy Independent Index (DESINX), and so on. However, is there an MI instruction that can be used to rename an MI object? Yes. It's the Rename (RENAME) MI instruction. This article will reveal the details of the RENAME instruction via a set of experiments.
Investigating the RENAME Instruction
A LIC trace of type MI instruction supervisor (*SVL) upon a successful Rename Object (RNMOBJ) command reveals that the QLIRNOBJ (which is the Command Processing Program (CPP) of the RNMOBJ command) issues the RENAME instruction. So let's start our investigation by tracing the RNMOBJ command. Say we have a program object named PGMA. Trace the RNMOBJ command with the Trace Internal (TRCINT) command like so:
4 > trcint *on trctype(*svl) job(name-of-the-current-job) 4 > rnmobj pgma *pgm pgmb Object PGMA in MYLIB type *PGM renamed PGMB. 4 > trcint *off |
From the trace data collected for our previous RNMOBJ operation at V5R4M0, you might find the following MI instructions issued sequentially by program QLIRNOBJ:
MI SVL IDENTIFIER : SV#00001 TIME 14/02/21 18:02:21.374400 TDE# 000000087563 MATTHIF INSTRUCTION #: 6300 RETURN ADDRESS: 39BD3B308B MI SVL IDENTIFIER : SV#00001 TIME 14/02/21 18:02:21.374416 TDE# 000000087563 RSLVSP INSTRUCTION #: 6300 RETURN ADDRESS: 39BD3B308B 003504 PROGRAM NAME: QLIRNOBJ MI SVL IDENTIFIER : SV#00001 TIME 14/02/21 18:02:21.374432 TDE# 000000087563 MATPTR INSTRUCTION #: 6300 RETURN ADDRESS: 39BD3B308B 003634 PROGRAM NAME: QLIRNOBJ MI SVL IDENTIFIER : SV#00001 TIME 14/02/21 18:02:21.374448 TDE# 000000087563 TESTAU INSTRUCTION #: 6300 RETURN ADDRESS: 39BD3B308B 004498 PROGRAM NAME: QLIRNOBJ MI SVL IDENTIFIER : SV#00001 TIME 14/02/21 18:02:21.374448 TDE# 000000087563 TESTAU INSTRUCTION #: 6300 RETURN ADDRESS: 39BD3B308B 004690 PROGRAM NAME: QLIRNOBJ MI SVL IDENTIFIER : SV#00001 TIME 14/02/21 18:02:21.374464 TDE# 000000087563 LOCK INSTRUCTION #: 6300 RETURN ADDRESS: 39BD3B308B MI SVL IDENTIFIER : SV#00001 TIME 14/02/21 18:02:21.374464 TDE# 000000087563 MATPTR INSTRUCTION #: 6300 RETURN ADDRESS: 39BD3B308B 0061B0 PROGRAM NAME: QLIRNOBJ MI SVL IDENTIFIER : SV#00001 TIME 14/02/21 18:02:21.374480 TDE# 000000087563 RESERVED INSTRUCTION #: 6300 RETURN ADDRESS: 24DAA86047 153CD0 PROGRAM NAME: QP0FEPFS MI SVL IDENTIFIER : SV#00001 TIME 14/02/21 18:02:21.374496 TDE# 000000087563 RENAME INSTRUCTION #: 6300 RETURN ADDRESS: 39BD3B308B 006AF8 PROGRAM NAME: QLIRNOBJ ... ... MI SVL IDENTIFIER : SV#00001 TIME 14/02/21 18:02:21.379488 TDE# 000000087563 UNLOCK INSTRUCTION #: 6300 RETURN ADDRESS: 39BD3B308B 00EF34 PROGRAM NAME: QLIRNOBJ |
Determine the PowerPC instructions generated for the RENAME MI instruction in the RISC instruction stream of program QLIRNOBJ by following the RETURN ADDRESS field (39BD3B308B 006AF
ADDRESS LOCATION OBJECT TEXT SOURCE STATEMENT MI INSTRUCTION NUMBERS 39BD3B308B 006AE8 005568 39BD3B308B 006AEC 39BD3B308B 006AF0 005570 39400066 ADDI 10,0,102 39BD3B308B 006AF4 005574 44000141 SCV 10 39BD3B308B 006AF8 005578 |
From the RISC instructions shown above, we know that the RENAME MI instruction is implemented via a SCV 10 (Supervisor Call Vectored (SCV) with dispatch code 10) instruction with the SCV 10 function number set to 102. We also know that two operands are passed (via General Purpose Register (GPR) 3 and GPR 4) when the RENAME instruction is issued. (In the remaining part of this article, GPR N will be simply referred to as rN.) Debugging the QLIRNOBJ program shows that the operand 1 (the address of which is stored in r3) is a system pointer addressing the target MI object. For example, the 16 bytes at the address stored in r3 might look like the following (a 16-byte system pointer addressing program PGMA):
Address . . . . . . . EC9E501719
|
And operand 2 (the address of which is stored in r4) of RENAME might look like the following (at V5R4M0):
Address . . . . . . . EC9E501719 020831
0830 00400000 D 0840 40404040 40404040 40404040 40404040 * * 0850 40400000 00000000 00000000 00000000 * .............. * |
Simulate the RENAME Instruction
In order to discover the detailed format of operand 2 of the RENAME instruction, we need to issue the RENAME instruction from a user program with different content in the operand 2. Given that the RENAME instruction is a blocked MI instruction, you might prefer to simulate the RENAME instruction with a non-blocked MI instruction that has similar operands to get your program complied and then modify the generated RISC instruction stream. The following tiny OMI source program, ren01.emi, accepts the symbolic ID of an MI object (object type/subtype code and object name), resolves a system pointer to it, and then simulates the RENAME instruction with the Modify Space Attributes (MODS) instruction. (The operands of the MODS instruction are of the same types as those of the RENAME instruction; operand1 is a system pointer, and operand 2 is a character scalar.)
dcl spcptr obj-type@ parm ; dcl spcptr obj-name@ parm ; dcl spcptr new-name@ parm ; dcl ol pl-main(obj-type@, obj-name@, new-name@) parm ext ;
entry *(pl-main) ext ;
dcl dd rt char(34) auto ; dcl dd obj-type char(2) bas(obj-type@) ; dcl dd obj-name char(30) bas(obj-name@) ; dcl dd new-name char(30) bas(new-name@) ;
dcl sysptr obj@ auto ; dcl dd tmpl char(33) auto ; dcl dd opt char(1) def(tmpl) pos(1) init(x'40') ; dcl dd opt-2 char(1) def(tmpl) pos(2) init(x'00') ; dcl dd opt-3 char(1) def(tmpl) pos(3) init(x'00') ; dcl dd name char(30) def(tmpl) pos(4) ;
cpybrep rt, x'00' ; cpybla rt(1:2), obj-type ; cpybla rt(3:30), obj-name ; rslvsp obj@, rt, *, * ;
cpybla name, new-name ; mods obj@, tmpl ; brk 'LOOK' ; rtx * ; pend ; |
The PowerPC instructions generated for the MODS instruction in the compiled REN01 program are the following (at V5R4M0):
RISC INSTRUCTIONS (REN01) LOCATION OBJECT TEXT SOURCE STATEMENT MI INSTRUCTION NUMBERS 000180 63630000 ORI 3,27,0 000184 39400138 ADDI 10,0,312 000188 44000141 SCV 10 |
Make the following changes to program REN01:
- Change the program state field in the program header of REN01 from user state (hex 0001) to system state (hex 0080). At V5R4M0, the program state field is at offset hex 50 from the start of the program header. Since RENAME is a blocked instruction, it is necessary for the issuing program to run in the system state at security level 40 or above.
- In the ADDI 10,0,312 instruction, change the immediate value copied into r10 from the SCV 10 function number of MODS2 (312) to that of the RENAME instruction (102). The changed ADDI instruction is ADDI 10,0,102 (hex 39400066).
Here's a quick test of our newly developed rename program:
4 > CRTDTAQ DTAQ(Q020) MAXLEN(5) Object Q020 type *DTAQ created in library MYLIB. 4 > call ren01 (x' 4 > rnmobj q021 *dtaq q020 /* Rename the queue obj to its original name */ Object Q 4 > dltdtaq q020 Object Q |
The Exact Format of Operand 2 of RENAME
To discover the format of operand 2 of the RENAME instruction, you can utilize the above-shown rename program REN01 to issue the RENAME instruction and pass different values for operand 2. Experiments show that operand 2 of RENAME is a 33-byte character scalar containing the following fields:
Format of Operand 2 |
||
Offset (Hex) |
Field Name |
Data Type and Length |
0 |
Option |
Char(1) |
|
Reserved (binary 0) |
Bit 0 |
|
Change object name 0=Do not change object name 1=Change object name |
Bit 1 |
|
Reserved (binary 0) |
Bits 2-7 |
1 |
Reserved (binary 0) |
Char(2) |
3 |
Object name |
Char(30) |
If the Change object name bit is set to zero, no change is made to the MI object specified by operand 1. If one of the reserved fields is not zero, the scalar value invalid (hex 3203) exception will be signaled.
Also note that the object name field can be of length up to 30 bytes, which can be proven via the following little experiment:
4 > CRTDTAQ DTAQ(Q020) MAXLEN(5) Object Q020 type *DTAQ created in library MYLIB. 4 > call ren01 (x' 4 > call ren01 (x' 4 > dltdtaq q020 Object Q |
Document the RENAME MI Instruction Based on the Experiment Results
A few other features of the RENAME instruction can be proven by some trivial experiments. For example, ren03.emi proves that RENAME can also be issued on a temporary object. Using the Edit Object Authority (EDTOBJAUT) command in combination with our previously developed rename program REN01 (or the RNMOBJ command), you can prove that the minimum authority to the object to rename is the object management authority. The fact that if any other thread holds any type of lock on an object, the rename program REN01 will fail with an invalid lock state (hex 1A01) exception proves that the lock enforcement rule applied to RENAME is enforcement of object control; in other words, a LENR (locked exclusive no read) lock state is to be enforced during the execution of the RENAME instruction. Additionally, if the new symbolic ID (object type code, subtype code, and name) is the same as an existing object in the context, a Duplicate Object Identification (hex 0E01) exception is signaled.
Now we are able to offer our own version of documentation (although not complete) for the RENAME instruction, which is an elementary member of the object-based high-level machine interface of IBM i and its ancestors.
Rename Object (RENAME)
Operand 1: System pointer
Operand 2: Char(33) scalar
Description: The name portion of the symbolic ID (object type code, subtype code, and name) of the system object addressed by operand 1 is optionally modified as specified by operand 2. Either permanent or temporary objects can be renamed. The object address remains unchanged after a rename operation.
The format of the character scalar for operand 2 is the following:
Format of Operand 2 |
||
Offset (Hex) |
Field Name |
Data Type and Length |
0 |
Option |
Char(1) |
|
Reserved (binary 0) |
Bit 0 |
|
Change object name 0=Do not change object name 1=Change object name |
Bit 1 |
|
Reserved (binary 0) |
Bits 2-7 |
1 |
Reserved (binary 0) |
Char(2) |
3 |
Object name |
Char(30) |
Authorization Required
Execute
Contexts referenced for address resolution
Object management
Operand 1
Update
Context addressing operand 1
Lock Enforcement
Materialize
Contexts referenced for address resolution
Modify
Context addressing operand 1
Object Control
Operand 1
Exceptions
0E Context Operation
0E01 Duplicate Object Identification
32 Scalar Specification
3203 Scalar Value Invalid
... and more
Final Thoughts
As you might have noticed, the *SVL trace of the RNMOBJ operation shows that the RNMOBJ command locks the object to rename before issuing the RENAME instruction upon it (and unlocks it after the rename operation). In my opinion, this is a reasonable design. Many operating system–level operations allocate locks on the target object. For example, a thread that opens a file (say MYFILE) for read will allocate a LSRD (locked share read) lock on the *FILE object (with MI object type/subtype code hex 1901). Therefore, an attempt to issue the RENAME instruction upon MYFILE in another thread will signal the invalid lock state (hex
CALL PGM(QLIRNMO) PARM( 'MYQUEUE MYLIB' /* From qualified object name */ '*DTAQ' /* Object type */ 'YOURQUEUE MYLIB' /* Target qualified object name */ '0' /* Do not replace target object */ X'0000000000000000' /* Error code */ ) |
So the Work with Object Locks display shown for a WRKOBJLCK MYLIB/MYQUEUE *DTAQ command might look like the following:
Opt Job User Lock Status Scope Thread A LJL *SHRRD HELD *JOB B LJL *EXCL WAIT *THREAD 00000030 |
Also note that not all object operations allocate object locks on the target object (consider program calls or queue operations).
LATEST COMMENTS
MC Press Online