Mandalika's scratchpad [ Work blog @Oracle | Stock Market Notes | My Music Compositions ]

Old Posts: 09.04  10.04  11.04  12.04  01.05  02.05  03.05  04.05  05.05  06.05  07.05  08.05  09.05  10.05  11.05  12.05  01.06  02.06  03.06  04.06  05.06  06.06  07.06  08.06  09.06  10.06  11.06  12.06  01.07  02.07  03.07  04.07  05.07  06.07  08.07  09.07  10.07  11.07  12.07  01.08  02.08  03.08  04.08  05.08  06.08  07.08  08.08  09.08  10.08  11.08  12.08  01.09  02.09  03.09  04.09  05.09  06.09  07.09  08.09  09.09  10.09  11.09  12.09  01.10  02.10  03.10  04.10  05.10  06.10  07.10  08.10  09.10  10.10  11.10  12.10  01.11  02.11  03.11  04.11  05.11  07.11  08.11  09.11  10.11  11.11  12.11  01.12  02.12  03.12  04.12  05.12  06.12  07.12  08.12  09.12  10.12  11.12  12.12  01.13  02.13  03.13  04.13  05.13  06.13  07.13  08.13  09.13  10.13  11.13  12.13  01.14  02.14  03.14  04.14  05.14  06.14  07.14  09.14  10.14  11.14  12.14  01.15  02.15  03.15  04.15  06.15  09.15  12.15  01.16  03.16  04.16 

Friday, April 22, 2016
Solaris 11: Few Random Commands

Logical Domains
Dependencies & Dependents
Network & Power Consumption Stats
HBA Listing


In the following example, dummy domain depends on two domains -- primary domain for virtual disks and virtual network devices, and dom2 for virtual disks and SR-IOV virtual functions (VF).

# ldm list-dependencies dummy
DOMAIN            DEPENDENCY        TYPE
dummy             primary           VDISK,VNET
                  dom2              VDISK,IOV

-l option displays the actual devices.


-r option in list-dependencies sub-command shows the dependents for the logical domain(s). -l option displays the actual devices in here too.


# ldm list-dependencies -r -l dom2
DOMAIN            DEPENDENT         TYPE           DEVICE
dom2              dummy             VDISK          primary-vds0/vdisk0:vol_dummy_disk0
                                    VDISK          service-vds0/vdisk0:vol_dummy_disk0
                                    IOV            /SYS/IOU1/PCIE14/IOVIB.PF0.VF1
                                    IOV            /SYS/IOU1/EMS4/CARD/NET0/IOVNET.PF0.VF1

Network Statistics

list-netstat sub-command in ldm utility displays the statistics for all the network devices that are configured in the domain(s).


# ldm ls-netstat dom2

NAME               IPACKETS     RBYTES       OPACKETS     OBYTES
----               --------     ------       --------     ------
net4               444.42M      61.27G       444.42M      7.12G
net1               13.20M       4989.22M     0            0
net0               0            0            0            0
ldoms-net0.vf1     37.62M       6.44G        49.15K       3.97M
ldoms-net0.vf0     523.34K      90.15M       62.85K       14.67M
ldoms-net1.vf15    0            0            0            0

List HBAs

list-hba sub-command in ldm utility lists out the physical SCSI HBA initiator ports in the target domain. -t option shows SCSI transport medium type such as FC or SAS.


# ldm ls-hba -t  primary
NAME                                                 VSAN
----                                                 ----
        init-port w5080020000016331
        Transport Protocol SAS
        init-port w5080020000016331
        Transport Protocol SAS

Check the latest man page for ldm(1M) for the complete list of options for those sub-commands.

Power Consumption Statistics

ldmpower command shows the breakdown of power consumed by processors and memory in different domains or in a given domain. Note that ldmpower is an independent command, not part of ldm utility.


# ldmpower -c processors -c memory -l primary
Processor Power Consumption in Watts
DOMAIN          15_SEC_AVG      30_SEC_AVG      60_SEC_AVG
primary         313             315             317

Memory Power Consumption in Watts
DOMAIN          15_SEC_AVG      30_SEC_AVG      60_SEC_AVG
primary         594             595             595

As usual, check the man page ldmpower(1M) for details.

PCI Devices

Scan & List

scanpci utility scans PCI buses and reports configuration settings for each PCI device that it finds.


# scanpci -v

pci bus 0x0002 cardnum 0x06 function 0x00: vendor 0x111d device 0x80ba
 Integrated Device Technology, Inc. [IDT] Device unknown
 CardVendor 0x0000 card 0x0000 (Card unknown)
  STATUS    0x0010  COMMAND 0x0147
  CLASS     0x06 0x04 0x00  REVISION 0x03
  BIST      0x00  HEADER 0x01  LATENCY 0x00  CACHE 0x10
  MAX_LAT   0x00  MIN_GNT 0x03  INT_PIN 0x00  INT_LINE 0x00
  Bus: primary=02, secondary=03, subordinate=72, sec-latency=0
  I/O behind bridge: 00000000-03ffffff
  Memory behind bridge: 00100000-2000ffff
  Prefetchable memory behind bridge: 100000000-777f0ffff

pci bus 0x0003 cardnum 0x00 function 0x00: vendor 0x8086 device 0x1521
 Intel Corporation I350 Gigabit Network Connection
 CardVendor 0x108e card 0x7b18 (Oracle/SUN, Quad Port GbE PCIe 2.0 Low Profile Adapter, UTP)
  STATUS    0x0010  COMMAND 0x0146
  CLASS     0x02 0x00 0x00  REVISION 0x01
  BIST      0x00  HEADER 0x80  LATENCY 0x00  CACHE 0x10
  BASE0     0x00100000 SIZE 1048576  MEM
  BASE3     0x00200000 SIZE 16384  MEM
  BASEROM   0x00280000 SIZE 524288
  MAX_LAT   0x00  MIN_GNT 0x00  INT_PIN 0x01  INT_LINE 0x00



Detect & Show Installed

Identifying Solaris 11 SRU level is one of the popular topics and it was covered in Solaris 11 documentation, My Oracle Support (MOS) and elsewhere by numerous bloggers. After all this, we still have to wonder why there isn't a conscious effort by the development team that owns pkg utility to make this a bit easier for normal human beings. In any case, pkg list entire or pkg info entire commands show a cryptic version string with a bunch of information encoded including the SRU level.

The second numeral in "branch" version represents the Solaris update whereas the third numeral is the SRU.


In the following example, Solaris update is 3 (running Solaris 11 - hence it is a Solaris 11.3 system) and current SRU is 5. (I underlined every alternate field)

# pkg info entire | grep -i branch


IDRs (Interim Diagnostic Reliefs) are in reality package updates whose names usually start with "idr" - therefore, just checking for the string "idr" in the list of installed packages on the system is sufficient to list out what IDRs were installed on the target system.

# pkg list idr*
pkg list: No packages matching 'idr*' installed <-- no IDRs installed

(Ticket Stub CSS Theme Credit: Kia Skretteberg)


Saturday, March 26, 2016
Programming in C: Few Tidbits #6

[1] Case-insensitive String Comparison

strcasecmp() is the case-insensitive version of strcmp(). When building, make sure to include strings.h (note the plural form).

strncasecmp() is the counterpart to strncmp().

#include <string.h>
void main(int argc, char** argv)
        printf("\n\"%s\" and \"%s\" are ", argv[1], argv[2]);
        strcasecmp(argv[1], argv[2]) ? printf(" .. not identical") : printf(" .. identical");

% ./strcompare next NeXT
"next" and "NeXT" are  .. identical

[2] Initializing a Variable Length Array

As of the length of the variable length array is not known to the compiler at compile time, initializing a variable length automatic array with some default value usually results in a compilation error.

% cat -n varlen.c
     1  #include <stdlib.h>
     3  void main(int argc, char** argv) {
     4          int size=atoi(argv[1]);
     5          int array[size] = { 0 };
     6  }
/home/gmandali/C % cc -o varlen varlen.c
"varlen.c", line 5: variable length array can not be initialized: array
cc: acomp failed for varlen.c

One option is to explicitly initialize each element in the array to the desired default value.

% cat -n varlen.c
     1  #include <stdlib.h>
     3  void main(int argc, char** argv) {
     4          int size=atoi(argv[1]);
     5          int array[size];
     6          for (int i = 0; i < size; ++i)
     7                  array[i] = 0;
     8  }

% cc -o varlen varlen.c

Another option is to rely on memset().

% cat -n varlen.c
     1  #include <stdlib.h>
     2  #include <string.h>
     4  void main(int argc, char** argv) {
     5          int size=atoi(argv[1]);
     6          int array[size];
     7          memset(array, 0, sizeof(array));
     8  }

% cc -o varlen varlen.c

In this case, sizeof operator evaluates the operand (variable length array).

[3] Check if a Process is Alive

kill() function can be used to send a null signal (signal 0) to check the validity of a process.

% cat -n chkproc.c
     1  #include <sys/types.h>
     2  #include <signal.h>
     3  #include <stdlib.h>
     4  #include <stdio.h>
     6  void main(int argc, char **argv) {
     7          pid_t pid = atoi( argv[1] );
     8          int rc = kill( pid, 0 );
     9          if ( !rc ) {
    10                  printf("process with pid ( %d ) is alive", pid);
    11          } else {
    12                  printf("process with pid ( %d ) is not found", pid);
    13          }
    14  }

% cc -o chkproc chkproc.c

% ps
  PID TTY         TIME CMD
19846 pts/25      0:00 ps
28978 pts/25      0:00 bash

% ./chkproc 28978
process with pid ( 28978 ) is alive

% ./chkproc 28979
process with pid ( 28979 ) is not found

pid_t is actually int data type.

[4] Evaluating "( integer )" Expression

This is a simple one but probably an important one to remember. When dealing with an expression that yields an integer or when testing an integer, only a value of zero evaluates to false. Everything else including negative numbers, floating point numbers, characters, strings, .. are evaluated to true. In other words, anything non-zero is true.

% cat -n ifexpr.c
     1  #include <stdio.h>
     2  #include <stdlib.h>
     3  #include <ctype.h>
     5  void main(int argc, char **argv) {
     6          printf("\n[ %10d ] : %s",  0, (0) ? "true" : "false" );
     7          printf("\n[ %10d ] : %s",  1, (1) ? "true" : "false" );
     8          printf("\n[ %10d ] : %s",  -2, (-2) ? "true" : "false" );
     9          printf("\n[ %10s ] : %s",  "dummy", ("dummy") ? "true" : "false" );
    10          printf("\n[ %10c ] : %s",  'C', ('C') ? "true" : "false" );
    11          printf("\n[ %10f ] : %s",  2.34, (2.34) ? "true" : "false" );
    12          printf("\n[ %10f ] : %s\n",  0.0000, (0.0000) ? "true" : "false" );
    13  }

% cc -o ifexpr ifexpr.c
% ./ifexpr

[          0 ] : false
[          1 ] : true
[         -2 ] : true
[      dummy ] : true
[          C ] : true
[   2.340000 ] : true
[   0.000000 ] : false

[5] Variable Declaration in a switch { case: } Statement

Let's start with an example that shows compilation failure.

% cat -n varincase.c
     1  #include 
     3  void main() {
     4          switch ( 1 ) {
     5                  case 2:
     6                          int i = 15;
     7                          break;
     8                  default:
     9                          printf("default\n");
    10          }
    11  }

% cc -o varincase varincase.c
"varincase.c", line 6: syntax error before or at: int
"varincase.c", line 7: undefined symbol: i
cc: acomp failed for varincase.c

In this example, identifier i is being declared and initialized in the case label of switch statement. Since no linkage or no static scope was specified, identifier i will have automatic storage duration that is local to the block containing the invocation (switch() { .. }, that is).

However the problem with this code is that case <expression> and default are labels and the controlling expression in switch statement causes the control to jump to appropriate label. In the example, when the control is transferred to default label, it enters the scope of identifier i without initializing it [as it bypasses the case where the identifier is being declared and initialized], which is not permitted. Therefore the fix is to declare the identifier (if at all needed) in its own compound statement so the scope is limited to that compound statement. (A compond statement is a block of code.)

Adding curly braces around case 2: statements will make the code compile and run as shown below.

% cat -n varincase.c
     1  #include <stdio.h>
     3  void main() {
     4          switch ( 1 ) {
     5                  case 2:
     6                  {
     7                          int i = 15;
     8                          break;
     9                  }
    10                  default:
    11                          printf("default\n");
    12          }
    13  }

% cc -o varincase varincase.c

% ./varincase

(Stacked Paper CSS Theme Credit: Chris McLeod)


Friday, January 29, 2016
Solaris: Clock Synchronization, Max Username Length, Removable Media

Synchronize System Time with a Remote Host

One option is to rely on Network Time Protocol. If NTP is not available, rdate is an alternative to set the local system time to the time and date returned by the remote host (server).

  1. NTP

    # date
    Thu Jan 28 13:47:54 PST 2016
    # ntpdate <-- is the NTP server within the network
    29 Jan 15:28:38 ntpdate[21143]: step time server offset 92435.318367 sec
    # date
    Fri Jan 29 15:28:42 PST 2016
  2. rdate


    • On server, ensure that time:stream service is online. If not, bring it online. server is the host that provides date/time.

      # ( svcs -H svc:/network/time:stream | grep online ) || \
       ( svcadm -v enable time:stream && svcadm -v enable time:dgram )
      svc:/network/time:stream enabled.
      svc:/network/time:dgram enabled.
    • On client, run: rdate <server>

      # date
      Thu Jan 28 13:54:37 PST 2016
      # rdate <-- is just another host with the time service enabled.
      Fri Jan 29 15:41:47 2016
      # date
      Fri Jan 29 15:41:49 PST 2016

Listing Removable Media

.. such as CD-ROM, DVD-ROM and PCMCIA cards.

Related command: rmformat

# rmformat
Looking for devices...
     1. Logical Node: /dev/rdsk/c1t0d0s2
        Physical Node: /pci@304/pci@1/pci@0/pci@2/usb@0/storage@2/disk@0,0
        Connected Device: SUN      Remote ISO CDROM 1.01
        Device Type: CD Reader
        Bus: USB
        Size: 103.3 MB
        Access permissions: Medium is not write protected.
     2. Logical Node: /dev/rdsk/c2t0d0s2
        Physical Node: /pci@304/pci@2/usb@0/storage@1/disk@0,0
        Connected Device: VT       eUSB DISK        5206
        Device Type: Removable
        Bus: USB
        Size: 2.0 GB
        Access permissions: Medium is not write protected.

In addition to listing, the same command can also be used to format, label, partition removable & rewritable media.

rmmount and rmumount utilities can be used to mount and unmount removable or hot-pluggable volumes.


List the mountable device along with path(s)

# rmmount -l
/dev/dsk/c1t0d0s2    cdrom,cdrom0,cd,cd0,sr,sr0,CDROM,/media/CDROM

Man pages of rmformat(1) and rmmount(1).

Solaris Username Length

useradd command accepts usernames up to 32 characters. OS may warn beyond 8 characters - simply ignore if more than 8 characters is a requirement.

# useradd guyfawkes
UX: useradd: guyfawkes name too long.

# su guyfawkes

# id guyfawkes
uid=110(guyfawkes) gid=10(staff)

Directory Listing as a Tree

Check and install file/tree package if doesn't exist.

# ( pkg list -q file/tree ) || ( pkg install pkg:/file/tree )

List the directory using tree(1) command.

# tree -d /opt/SUNWldm
|-- bin
|   `-- schemas
|-- lib
|   |-- contrib
|   |-- ds
|   `-- templates
|-- man
|   |-- ja_JP.UTF-8
|   |   `-- man1m
|   `-- man1m
`-- platform
    `-- ORCL,SPARC64-X
        `-- lib
            `-- ds

14 directories


Wednesday, December 30, 2015
[Solaris] Memory Blacklisting, Duplicate IP Address & Recovery, Group Package Installations, ..


Memory blacklist operation

To check if memory blacklist operation by LDoms Manager (ldm) is in progress, run:

echo "zeus ::print -a zeus_t mem_blacklist_inprog" | mdb -p `pgrep ldmd`

If no blacklist operation is in progress, the above may return output that is similar to:

<hex-address> mem_blacklist_inprog = 0 (false)

When a memory blacklist operation is in progress, the above may return output that is similar to:

<hex-address> mem_blacklist_inprog = 0x1 (true)

In such a situation, any attempt to run ldm commands related to memory management may fail with error:

A memory blacklist operation is being processed. Other memory operations are disabled until it completes

Sometimes a power cycle may clear the blacklist operation. In not-so-lucky situations, the affected DIMM(s) may have to be serviced.

(Credit: Eunice M.)


Duplicate IP Address & Recovery

If two nodes [running Solaris] on a network share the same IP address, Solaris kernel detects the duplicate address, marks it as duplicate and eventually disables and turns off the IP interface if the problem persists. These actions are typically recorded in the system log with warnings such as the following.

Dec 23 16:46:18 some-host ip: [ID 759807 kern.warning] WARNING: net0 has duplicate address xx.xx.xx.xx (in use by 00:10:e0:5d:9c:83); disabled
Dec 23 16:46:18 some-host in.routed[737]: [ID 238047 daemon.warning] interface net0 to xx.xx.xx.xx turned off

When the IP interface was disabled/turned off, ipadm show-if shows down state for that interface.

Once the problem was discovered and fixed [by the administrator or user] to avoid duplication of IP address, Solaris kernel enables and brings up the IP interface that it turned off earlier upon detecting a duplicate IP address. This action too is recorded in the system log.

Dec 23 16:51:18 some-host ip: [ID 636139 kern.notice] NOTICE: recovered address ::ffff:xx.xx.xx.xx on net0

Once the system marks an interface down due to the conflicting IP address in a remote system, the local system checks periodically to see if the conflict persists. In Solaris 11.3, the time between the checks is 300,000 milliseconds (300 seconds or 5 minutes). However in some cases waiting for 5 minutes might not be desirable. In such cases, the time between the duplicate IP address checks can be tuned by modifying the IP tunable parameter, _dup_recovery, to appropriate value.


Reduce the _dup_recovery value to 90 seconds.

Notice the slight difference in parameter names when ndd and ipadm were used to tune the same value.


Solaris OS: What Group Package was Installed?

pkg list on target system shows this information.

# pkg list | grep "group/system/solaris" | grep server
group/system/solaris-minimal-server               0.5.11-     i--

List all packages that are part of the group package that was installed by running:

pkg list -as `pkg contents -r -H -o fmri -t depend -a type=group <group-package>`

List available group packages to install Solaris server:

# pkg search solaris-*-server | awk '{ print $3 "\t" $4}'
solaris/group/system/solaris-large-server       pkg:/group/system/solaris-large-server@0.5.11-
solaris/group/system/solaris-minimal-server     pkg:/group/system/solaris-minimal-server@0.5.11-
solaris/group/system/solaris-small-server       pkg:/group/system/solaris-small-server@0.5.11-

In addition to the above, solaris/group/system/solaris-desktop group package provides Solaris desktop environment. This package contains the GNOME desktop environment that includes GUI applications such as web browsers and mail clients, and drivers for graphics and audio devices.

Keep in mind that solaris-desktop group package has a lot more packages compared to the other three group packages outlined above.


Solaris OS: What AI Manifest was Used?

On target system, locate the AI manifest file that was used to perform the Solaris installation at:

Installation log can also be found in the same directory.


Package History

pkg history shows command history related to a specific package or all packages installed on the system. This includes information such as who initiated the package operation, the complete command, how long it took to complete the operation, whether a new boot environment (BE) was created and the errors encountered, if any.

Refer to pkg(1) man page for the options and description.

Fancy Separator Credit: jkneb


Tuesday, September 29, 2015
Solaris: Identifying EFI disks

EFI label supports physical disks and logical volumes that are > 2 TB in size. SMI support is limited to 2 TB.

Listed below are some of the characteristics and patterns that can help identify and differentiate an EFI labeled disk from a SMI labeled disk.

Credit: various internal sources



This page is powered by Blogger. Isn't yours?