How to trace asmcmd cp command

Hi everyone,

As part of my research to understand all the small details of +ASM, i’ve decided to understand asmcmd cp command implementation. This particular command allows you to copy files from a diskgroup to the operating system, to copy files between diskgroups or just copy files from your operating system to a particular diskgroup.

The first clue here is when you try an invalid operation with the cp command;i will try to copy a control file from my operating system to my +DATA diskgroup using a file number and incarnation notation. +ASM will not allow this operation and returns an error:

[oracle@phoenix ~]$ asmcmd cp /home/oracle/Current.267.796669051 +DATA/FENIX/CONTROLFILE/Current.267.796669052
copying /home/oracle/Current.267.796669051 -> +DATA/FENIX/CONTROLFILE/Current.267.796669052
ASMCMD-8016: copy source'/home/oracle/Current.267.796669051' and target'+DATA/FENIX/CONTROLFILE/Current.267.796669052' failed
ORA-15056: additional error message
ORA-15046: ASM file name '+DATA/FENIX/CONTROLFILE/Current.267.796669052' is not in single-file creation form
ORA-06512: at "SYS.X$DBMS_DISKGROUP", line 413
ORA-06512: at line 3 (DBD ERROR: OCIStmtExecute)

This will allow us to see one important thing here, the package SYS.X$DBMS_DISKGROUP. Since +ASM instance have no dictionary we can’t find it as “object” and we can’t see the contents of the package directly using dictionary tables. No luck here for much debug.

On a successful cp command, strace will only give a bunch of syscalls and shows the communication between +ASM instance and the operating system. This is not a good way (and simple) to understand how cp is implemented.


write(7, "\25\6\3\5 \1[\3", 21) = 21
read(8, "\345\6\6\1\"\226\1[\3"..., 8208) = 229
stat("/home/oracle", {st_mode=S_IFDIR|0770, st_size=4096, ...}) = 0
write(7, "\2z\6\21x!\376\377\377\377\377\377\377\377\1\1"..., 634) = 634
read(8, "\1\4\6\v\1\5s\4\1@H}\233"..., 8208) = 260
write(1, "copying +DATA/FENIX/CONTROLFILE/"..., 92) = 92
write(7, "\2\363\6\21i$\376\377\377\377\377\377\377\377\1\1"..., 755) = 755
read(8, "\354\6\v\1\5R\5\1@H}\233"..., 8208) = 236

Tracing an +ASM instance is not that easy, we will need to translate that bunch of syscalls into something more readable (and i’m not Tanel Poder :-)) and that we can relate to X$DBMS_DISKGROUP package. Since +ASM uses SQL*Net to establish the communication tracing SQL*Net will reveal interesting things. For enable SQL*Net tracing just add the following lines to sqlnet.ora:

# ADR_BASE = /u01/app/oracle
TRACE_LEVEL_CLIENT=16
TRACE_DIRECTORY_CLIENT=/home/oracle/sql_trace
TRACE_FILE_CLIENT=client
TRACE_UNIQUE_CLIENT=ON
DIAG_ADR_ENABLED=off
TRACE_TIMESTAMP_CLIENT=ON

After enabling the trace, we just need to copy one file from a diskgroup to operating system:

[oracle@phoenix ~]$ asmcmd cp +DATA/FENIX/CONTROLFILE/Current.267.796669051 /home/oracle
copying +DATA/FENIX/CONTROLFILE/Current.267.796669051 -> /home/oracle/Current.267.796669051

The trace file shows up with something interesting:

(1466255104) nsbasic_bsd: 20 20 20 20 20 62 65 67  |.....beg|
(1466255104) nsbasic_bsd: 69 6E 0A 20 20 20 20 20  |in......|
(1466255104) nsbasic_bsd: 20 20 20 20 20 64 62 6D  |.....dbm|
(1466255104) nsbasic_bsd: 73 5F 64 69 73 6B 67 72  |s_diskgr|
(1466255104) nsbasic_bsd: 6F 75 70 2E 67 65 74 66  |oup.getf|
(1466255104) nsbasic_bsd: 69 6C 65 61 74 74 72 28  |ileattr(|
(1466255104) nsbasic_bsd: 3A 66 69 6C 65 6E 61 6D  |:filenam|
(1466255104) nsbasic_bsd: 65 2C 20 3A 66 69 6C 65  |e,.:file|
(1466255104) nsbasic_bsd: 74 79 70 65 2C 20 3A 66  |type,.:f|
(1466255104) nsbasic_bsd: 69 6C 65 73 7A 2C 20 3A  |ilesz,.:|
(1466255104) nsbasic_bsd: 62 6C 6B 73 7A 29 3B 0A  |blksz);.|
(1466255104) nsbasic_bsd: 20 20 20 20 20 20 20 20  |........|
(1466255104) nsbasic_bsd: 65 6E 64 3B 0A 20 20 20  |end;....|
...
(1466255104) nsbasic_bsd: 44 41 54 41 2F 46 45 4E  |DATA/FEN|
(1466255104) nsbasic_bsd: 49 58 2F 43 4F 4E 54 52  |IX/CONTR|
(1466255104) nsbasic_bsd: 4F 4C 46 49 4C 45 2F 43  |OLFILE/C|
(1466255104) nsbasic_bsd: 75 72 72 65 6E 74 2E 32  |urrent.2|
(1466255104) nsbasic_bsd: 36 37 2E 37 39 36 36 36  |67.79666|
(1466255104) nsbasic_bsd: 39 30 35 31 01 31 05 31  |9051.1.1|
(1466255104) nsbasic_bsd: 36 33 38 34 03 36 30 34  |6384.604|
(1466255104) nsbasic_bsd: 22 2F 68 6F 6D 65 2F 6F  |"/home/o|
(1466255104) nsbasic_bsd: 72 61 63 6C 65 2F 43 75  |racle/Cu|
(1466255104) nsbasic_bsd: 72 72 65 6E 74 2E 32 36  |rrent.26|
(1466255104) nsbasic_bsd: 37 2E 37 39 36 36 36 39  |7.796669|
(1466255104) nsbasic_bsd: 30 35 31                 |051     |

On a more readable way we have:

BEGIN
 dbms_diskgroup.getfileattr( :filename, :filetype, :filesz, :blksz);
END;

BEGIN
 dbms_diskgroup.copy('', '', '', :src_path, :src_ftyp, :src_blksz, :src_fsize, '', '', '', :dst_path, 1);
END; 

The first procedure will check the file attributes to be copied (filename, size, etc) and on this version of ASM, the package dbms_diskgroup have a procedure to directly copy from the diskgroup to the OS.

Please note that this post is not an exhaustive and boring post to debug and all the aspects of asmcmd cp command, but to provide the Oracle community a way to understand it.

Advertisements

One thought on “How to trace asmcmd cp command

  1. Pingback: ASM spfile operations | Luís Marques

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s