Linux: Burning an ISO to a DVD disc

Brasero is not working for me in RHEL7 Desktop. I downloaded the latest Kali Linux ISO image and I want to burn the ISO to a DVD. When I put a blank DVD into the drive, Gnome shows the blank DVD on the desktop. But for some reason Brasero cannot see the disc. After trying some troubleshooting hacks, I realized that I’d much rather have a method for working with DVD burning from the command line rather than messing around with Brasero, or having to install k3b. It is Linux after all, there ought to be a simple way to do this from the command line.

DVD Hardware Check

First things first, I wanted to check up on my DVD burner hardware and see if it is recognized. My burner is an SATA device from an older HP desktop from which I recovered it.

# dmesg | less

[ 1.305351] ata1.00: ATAPI: hp DVD-RAM GHA3N, RH07, max UDMA/100
[ 1.305611] ata2.00: configured for UDMA/133

[ 8.861738] scsi 2:0:0:0: CD-ROM hp DVD-RAM GHA3N RH07 PQ: 0 ANSI: 5

I also wanted to see if RHEL7 does anything with creating device files for the burner. Various Linux distributions create a /dev/dvd, /dev/cdwriter, etc.  I know that /dev/sr# is the way Linux handles CD/DVD drives. I only have one device, so it should be /dev/sr0.

# ls -l /dev/sr0
brw-rw—-+ 1 root cdrom 11, 0 Feb 4 09:58 /dev/sr0
# ls -l /dev/cdrom
lrwxrwxrwx. 1 root root 3 Feb 4 09:58 /dev/cdrom -> sr0

RHEL7 creates a symlink /dev/cdrom which points to /dev/sr0.

Media Verification

My next question was whether the blank DVD media could be recognized. It turns out that the dvd+rw-tools package has a tool to help with that. If it is not on your system, for CentOS/RHEL, run “yum install dvd+rw-tools”.

# dvd+rw-mediainfo /dev/cdrom
INQUIRY: [hp ][DVD-RAM GHA3N ][RH07]
GET [CURRENT] CONFIGURATION:
Mounted Media: 1Bh, DVD+R
Media ID: CMC MAG/M01
Current Write Speed: 16.0×1385=22160KB/s
Write Speed #0: 16.0×1385=22160KB/s
Write Speed #1: 8.0×1385=11080KB/s
Write Speed #2: 6.0×1385=8310KB/s
GET [CURRENT] PERFORMANCE:
Write Performance: 6.8×1385=9420KB/s@0 -> 16.0×1385=22160KB/s@2295103
Speed Descriptor#0: 02/2295103 R@16.0×1385=22166KB/s W@16.0×1385=22160KB/s
Speed Descriptor#1: 02/2295103 R@16.0×1385=22166KB/s W@8.0×1385=11080KB/s
Speed Descriptor#2: 02/2295103 R@16.0×1385=22166KB/s W@6.0×1385=8310KB/s
READ DVD STRUCTURE[#0h]:
Media Book Type: 00h, DVD-ROM book [revision 0]
Legacy lead-out at: 2295104*2KB=4700372992
READ DISC INFORMATION:
Disc status: blank
Number of Sessions: 1
State of Last Session: empty
“Next” Track: 1
Number of Tracks: 1
READ TRACK INFORMATION[#1]:
Track State: blank
Track Start Address: 0*2KB
Next Writable Address: 0*2KB
Free Blocks: 2295104*2KB
Track Size: 2295104*2KB
ROM Compatibility LBA: 266544
READ CAPACITY: 0*2048=0

There is lots of output, but the main point is the “Disc status: blank” and “State of Last Session: empty” which verify the disc is readable and empty.

Wodim – Going down the wrong path…maybe?

When searching for command-line tools to burn ISO images, cdrecord came up frequently. In RHEL7, cdrecord is available and is a symlink to /usr/bin/wodim. Before messing with wodim and disc burning, I thought I’d use to tool to make sure it sees my hardware. After all, Brasero did not see the DVD-RAM drive with an empty disc, and perhaps this will be the same.

# /usr/bin/wodim –devices
/usr/bin/wodim: No such file or directory.
Cannot open SCSI driver!
For possible targets try ‘wodim –devices’ or ‘wodim -scanbus’.
For possible transport specifiers try ‘wodim dev=help’.
For IDE/ATAPI devices configuration, see the file README.ATAPI.setup from
the wodim documentation.

Well, that did not look good. Back to google for more help. On some Ubuntu forums it was recommended to manually instruct wodim to use /dev/sr0.

# wodim dev=/dev/cdrom -checkdrive
Device type : Removable CD-ROM
Version : 5
Response Format: 2
Capabilities :
Vendor_info : ‘hp ‘
Identification : ‘DVD-RAM GHA3N ‘
Revision : ‘RH07’
Device seems to be: Generic mmc2 DVD-R/DVD-RW.
Using generic SCSI-3/mmc DVD-R(W) driver (mmc_mdvd).
Driver flags : SWABAUDIO BURNFREE
Supported modes: PACKET SAO

Much better. But as I was searching further, I came across some information about another utility, growisofs. The name does not sound like a disc burner software, but it turns out that the capability was added over the years.

growisofs – the tool I was looking for

So growisofs does not only burn ISO disc images, it can also be used to create DVD data discs (DVD+R discs) that allow for multiple sessions. At the end of the post I will include some samples for doing so. The focus now is burning an ISO image.

To burn an ISO image, first I added the -dry-run flag so that it only simulates writing to disc. Test first! The next flag is the -dvd-compat flag which makes the disc unappendable. This is what we want for an ISO disc image. Next, the -Z option is used to indicate that this should be the initial session on the disc.  Finally, the ISO disc image is specified and is to be written to /dev/cdrom, which is the symlink to /dev/sr0 on my RHEL7 workstation.

# growisofs -dry-run -dvd-compat -Z /dev/cdrom=/root/kali-linux-2017.3-amd64.iso
😦 growisofs is being executed under sudo, aborting!
    See NOTES paragraph in growisofs manual page for further details.

No bueno. Reading the man page has a long explanation for while performing this operation as root is not necessary. Check the man page if you are interested. Trying again with a regular user account. I made the sure the ISO disc image was readable

$ growisofs -dry-run -dvd-compat -Z /dev/cdrom=/root/kali-linux-2017.3-amd64.iso
😦 unable to open64(“/dev/cdrom”,O_RDONLY): Permission denied

Again, no bueno. Well that is just dandy. The tool does not want to be run via sudo or from the root user account, but my regular user account cannot access the DVD-RAM drive. I bet there is a specific user group for that…checking /etc/group yields a “cdrom” group.

$ ls -al /dev/cdrom
lrwxrwxrwx. 1 root root 3 Feb  4 09:58 /dev/cdrom -> sr0
$ ls -al /dev/sr0
brw-rw—-+ 1 root cdrom 11, 0 Feb  4 09:58 /dev/sr0

Yes, cdrom group owns the DVD-RAM drive, so I need to add my user to that group.

$ sudo usermod -aG cdrom bryan
$ groups
bryan wheel cdrom docker

That’s better. Trying again…

$ growisofs -dry-run -dvd-compat -Z /dev/cdrom=/root/kali-linux-2017.3-amd64.iso
Executing ‘builtin_dd if=/root/kali-linux-2017.3-amd64.iso of=/dev/cdrom obs=32k seek=0’

That output looks promising. After taking away the -dry-run option, I hear the drive spin up and start getting to work:

$ growisofs -dvd-compat -Z /dev/cdrom=/root/kali-linux-2017.3-amd64.iso
Executing ‘builtin_dd if=/root/kali-linux-2017.3-amd64.iso of=/dev/cdrom obs=32k seek=0’

/dev/cdrom: “Current Write Speed” is 16.4x1352KBps.
          0/2886402048 ( 0.0%) @0x, remaining ??:?? RBU 100.0% UBU   0.0%
          0/2886402048 ( 0.0%) @0x, remaining ??:?? RBU 100.0% UBU   0.0%
          0/2886402048 ( 0.0%) @0x, remaining ??:?? RBU 100.0% UBU   0.0%
          0/2886402048 ( 0.0%) @0x, remaining ??:?? RBU 100.0% UBU   0.0%
          0/2886402048 ( 0.0%) @0x, remaining ??:?? RBU 100.0% UBU   0.0%
          0/2886402048 ( 0.0%) @0x, remaining ??:?? RBU 100.0% UBU   0.0%
          0/2886402048 ( 0.0%) @0x, remaining ??:?? RBU 100.0% UBU   0.0%
    1114112/2886402048 ( 0.0%) @0.2x, remaining 1294:52 RBU 100.0% UBU   2.9%
   23396352/2886402048 ( 0.8%) @4.8x, remaining 67:18 RBU 100.0% UBU 100.0%
   56688640/2886402048 ( 2.0%) @7.2x, remaining 30:46 RBU 100.0% UBU 100.0%
   90505216/2886402048 ( 3.1%) @7.3x, remaining 20:35 RBU 100.0% UBU 100.0%
  124846080/2886402048 ( 4.3%) @7.4x, remaining 15:51 RBU 100.0% UBU 100.0%
  159744000/2886402048 ( 5.5%) @7.6x, remaining 13:22 RBU 100.0% UBU 100.0%
  195198976/2886402048 ( 6.8%) @7.7x, remaining 11:29 RBU 100.0% UBU 100.0%
  231178240/2886402048 ( 8.0%) @7.8x, remaining 10:08 RBU 100.0% UBU 100.0%
  267714560/2886402048 ( 9.3%) @7.9x, remaining 9:17 RBU 100.0% UBU 100.0%
  304775168/2886402048 (10.6%) @8.0x, remaining 8:28 RBU 100.0% UBU 100.0%
  342360064/2886402048 (11.9%) @8.1x, remaining 7:48 RBU 100.0% UBU 100.0%
  379125760/2886402048 (13.1%) @8.0x, remaining 7:23 RBU 100.0% UBU 100.0%
  415105024/2886402048 (14.4%) @7.8x, remaining 6:56 RBU 100.0% UBU 100.0%
  454262784/2886402048 (15.7%) @8.5x, remaining 6:30 RBU 100.0% UBU 100.0%
  493977600/2886402048 (17.1%) @8.6x, remaining 6:12 RBU 100.0% UBU 100.0%
  534249472/2886402048 (18.5%) @8.7x, remaining 5:52 RBU 100.0% UBU 100.0%
  575045632/2886402048 (19.9%) @8.8x, remaining 5:33 RBU 100.0% UBU 100.0%
  616398848/2886402048 (21.4%) @9.0x, remaining 5:20 RBU  99.8% UBU 100.0%
  658243584/2886402048 (22.8%) @9.1x, remaining 5:04 RBU 100.0% UBU 100.0%
  700678144/2886402048 (24.3%) @9.2x, remaining 4:50 RBU 100.0% UBU 100.0%
  743604224/2886402048 (25.8%) @9.3x, remaining 4:39 RBU 100.0% UBU 100.0%
  787087360/2886402048 (27.3%) @9.4x, remaining 4:26 RBU 100.0% UBU 100.0%
  831094784/2886402048 (28.8%) @9.5x, remaining 4:14 RBU 100.0% UBU 100.0%
  875659264/2886402048 (30.3%) @9.7x, remaining 4:05 RBU  99.8% UBU 100.0%
  920715264/2886402048 (31.9%) @9.8x, remaining 3:54 RBU 100.0% UBU 100.0%
  966361088/2886402048 (33.5%) @9.9x, remaining 3:44 RBU 100.0% UBU 100.0%
1012531200/2886402048 (35.1%) @10.0x, remaining 3:36 RBU 100.0% UBU 100.0%
1059225600/2886402048 (36.7%) @10.1x, remaining 3:27 RBU 100.0% UBU 100.0%
1106444288/2886402048 (38.3%) @10.2x, remaining 3:17 RBU 100.0% UBU 100.0%
1150877696/2886402048 (39.9%) @9.6x, remaining 3:11 RBU 100.0% UBU 100.0%
1197539328/2886402048 (41.5%) @10.1x, remaining 3:03 RBU 100.0% UBU 100.0%
1246363648/2886402048 (43.2%) @10.6x, remaining 2:55 RBU  99.8% UBU 100.0%
1295712256/2886402048 (44.9%) @10.7x, remaining 2:48 RBU 100.0% UBU 100.0%
1345585152/2886402048 (46.6%) @10.8x, remaining 2:40 RBU 100.0% UBU 100.0%
1396015104/2886402048 (48.4%) @10.9x, remaining 2:32 RBU  99.8% UBU 100.0%
1446969344/2886402048 (50.1%) @11.0x, remaining 2:26 RBU 100.0% UBU 100.0%
1498447872/2886402048 (51.9%) @11.2x, remaining 2:18 RBU 100.0% UBU 100.0%
1550516224/2886402048 (53.7%) @11.3x, remaining 2:11 RBU 100.0% UBU 100.0%
1603108864/2886402048 (55.5%) @11.4x, remaining 2:05 RBU 100.0% UBU 100.0%
1656258560/2886402048 (57.4%) @11.5x, remaining 1:58 RBU 100.0% UBU 100.0%
1709932544/2886402048 (59.2%) @11.6x, remaining 1:52 RBU 100.0% UBU 100.0%
1764196352/2886402048 (61.1%) @11.7x, remaining 1:46 RBU 100.0% UBU 100.0%
1818951680/2886402048 (63.0%) @11.9x, remaining 1:39 RBU 100.0% UBU 100.0%
1874231296/2886402048 (64.9%) @12.0x, remaining 1:33 RBU 100.0% UBU 100.0%
1930100736/2886402048 (66.9%) @12.1x, remaining 1:27 RBU 100.0% UBU 100.0%
1986461696/2886402048 (68.8%) @12.2x, remaining 1:21 RBU 100.0% UBU 100.0%
2043412480/2886402048 (70.8%) @12.3x, remaining 1:15 RBU  99.8% UBU 100.0%
2094792704/2886402048 (72.6%) @11.1x, remaining 1:10 RBU 100.0% UBU 100.0%
2152726528/2886402048 (74.6%) @12.5x, remaining 1:04 RBU 100.0% UBU 100.0%
2211217408/2886402048 (76.6%) @12.7x, remaining 0:59 RBU 100.0% UBU  97.1%
2270265344/2886402048 (78.7%) @12.8x, remaining 0:53 RBU  99.8% UBU 100.0%
2329804800/2886402048 (80.7%) @12.9x, remaining 0:47 RBU 100.0% UBU 100.0%
2389901312/2886402048 (82.8%) @13.0x, remaining 0:42 RBU 100.0% UBU 100.0%
2450554880/2886402048 (84.9%) @13.1x, remaining 0:36 RBU 100.0% UBU  97.1%
2511732736/2886402048 (87.0%) @13.2x, remaining 0:31 RBU 100.0% UBU  97.1%
2573467648/2886402048 (89.2%) @13.4x, remaining 0:26 RBU 100.0% UBU  97.1%
2635726848/2886402048 (91.3%) @13.5x, remaining 0:20 RBU 100.0% UBU  97.1%
2698543104/2886402048 (93.5%) @13.6x, remaining 0:15 RBU 100.0% UBU  97.1%
2761883648/2886402048 (95.7%) @13.7x, remaining 0:10 RBU 100.0% UBU  97.1%
2825781248/2886402048 (97.9%) @13.8x, remaining 0:04 RBU 100.0% UBU  97.1%
builtin_dd: 1409376*2KB out @ average 9.1x1352KBps
/dev/cdrom: flushing cache
/dev/cdrom: closing track
/dev/cdrom: closing disc
/dev/cdrom: reloading tray

To verify the disc…

$ dvd+rw-mediainfo /dev/cdrom
INQUIRY:                [hp      ][DVD-RAM GHA3N   ][RH07]
GET [CURRENT] CONFIGURATION:
Mounted Media:         1Bh, DVD+R
Media ID:              CMC MAG/M01
Current Write Speed:   16.0×1385=22160KB/s
Write Speed #0:        16.0×1385=22160KB/s
Write Speed #1:        8.0×1385=11080KB/s
Write Speed #2:        6.0×1385=8310KB/s
Speed Descriptor#0:    02/1409375 R@13.2×1385=18280KB/s W@16.0×1385=22160KB/s
Speed Descriptor#1:    02/1409375 R@13.2×1385=18280KB/s W@8.0×1385=11080KB/s
Speed Descriptor#2:    02/1409375 R@13.2×1385=18280KB/s W@6.0×1385=8310KB/s
READ DVD STRUCTURE[#0h]:
Media Book Type:       00h, DVD-ROM book [revision 0]
Legacy lead-out at:    1409376*2KB=2886402048
READ DISC INFORMATION:
Disc status:           complete
Number of Sessions:    1
State of Last Session: complete
Number of Tracks:      1
READ TRACK INFORMATION[#1]:
Track State:           partial/complete
Track Start Address:   0*2KB
Free Blocks:           0*2KB
Track Size:            1409376*2KB
FABRICATED TOC:
Track#1  :             14@0
Track#AA :             14@1409376
Multi-session Info:    #1@0
READ CAPACITY:          1409376*2048=2886402048

Note “Disc status: complete” and “State of Last Session: complete”.

Mission accomplished! Also, don’t forget to run “yum remove brasero“.

Working with data discs

To create an appendable data disc, for the first time use the below command, which has flags for the Rock-Ridge / Joilet extensions (CD/DVD standards):

# growisofs -Z /dev/cdrom -R -J /data_files

Then, to append more data to the disc:

# growisofs -M /dev/cdrom -R -J /data_files2

And of course when you’re finished and need to give the disc to your coworker:

# eject /dev/sr0

I will have to try this in the future.

 

Advertisements

Configuration of DB2 CLI/ODBC Driver

IBM provides a CLI/ODBC driver for DB2 which is a light-weight shared library providing a basic ODBC API for accessing DB2. The driver is delivered in its binary form with shared libraries and header files, and it is available from IBM’s website. I recently downloaded the following version: ibm_data_server_driver_for_odbc_cli_linuxx64_v11.1.tar.gz. This post will cover setting up the driver for use with C++ programs. The SAMPLE database provided with DB2 will be used for testing out the connectivity.

DB2 installs in /opt/ibm on Linux, so I will install the driver to the same location and give ownership to the db2inst1 user which owns the instance of DB2 that is running on my system.

$   gzip -d ibm_data_server_driver_for_odbc_cli_linuxx64_v11.1.tar.gz
$   tar -xf ibm_data_server_driver_for_odbc_cli_linuxx64_v11.1.tar
$   sudo mv clidriver /opt/ibm/
$   sudo chown -R db2inst1 /opt/ibm/clidriver
$   sudo chgrp -R db2iadm1 /opt/ibm/clidriver

For each database that will be accessed via the CLI/ODBC library, a configuration for the libraries is required in the db2cli.ini file in the /opt/ibm/clidriver/cfg directory. Use the sample provided by IBM in the cfg directory to create the configuration.

$   cd /opt/ibm/clidriver/cfg
$   cp db2cli.ini.sample db2cli.ini
$   vim db2cli.ini

For example, to access the SAMPLE database provided with DB2, add the following configuration to db2cli.ini:

[SAMPLE]
Database=SAMPLE
Protocol=TCPIP
Port=50000
uid=db2inst1
pwd=db2inst1

If this is not done, there will be errors when calling SQLConnect() in C++ code later. Also make sure to copy db2cli.cfg to the instance user’s cfg directory.

$   su db2inst1
$   cp /opt/ibm/clidriver/cfg/db2cli.ini ~/sqllib/cfg/db2cli.ini

DB2 also provides a utility to validate the configuration file: db2cli with the validate option. Use this to make sure that db2cli is using the right configuration file, and that the tool can read the configuration for the SAMPLE database.

$   cd ~/sqllib/bin
$   ./db2cli validate -dsn SAMPLE

===============================================================================
Client information for the current copy:
===============================================================================

Client Package Type : IBM DB2 Express-C
Client Version (level/bit): DB2 v11.1.1.1 (s1612051900/64-bit)
Client Platform : Linux/X8664
Install/Instance Path : /opt/ibm/db2/V11.1_01
DB2DSDRIVER_CFG_PATH value: <not-set>
db2dsdriver.cfg Path : /home/db2inst1/sqllib/cfg/db2dsdriver.cfg
DB2CLIINIPATH value : <not-set>
db2cli.ini Path : /home/db2inst1/sqllib/cfg/db2cli.ini
db2diag.log Path : /home/db2inst1/sqllib/db2dump/db2diag.log

===============================================================================
db2dsdriver.cfg schema validation for the entire file:
===============================================================================

Note: The validation utility could not find the configuration file
db2dsdriver.cfg. The file is searched at
“/home/db2inst1/sqllib/cfg/db2dsdriver.cfg”.

===============================================================================
db2cli.ini validation for data source name “SAMPLE”:
===============================================================================

[ Keywords used for the connection ]

Keyword Value
—————————————————————————
DATABASE SAMPLE
PROTOCOL TCPIP
PORT 50000
UID db2inst1
PWD ********

===============================================================================
db2dsdriver.cfg validation for data source name “SAMPLE”:
===============================================================================

Note: The validation utility could not find the configuration file
db2dsdriver.cfg. The file is searched at
“/home/db2inst1/sqllib/cfg/db2dsdriver.cfg”.

===============================================================================
The validation is completed.
===============================================================================

Now it is possible to test out connection to the SAMPLE database via CLI/ODBC using the same tool. [Kudos to Easysoft for this tip!]

$   cd ~/sqllib/bin
$   db2 activate SAMPLE                  # set the active DB in the DB2 instance
$   echo “SELECT * from staff” | ./db2cli execsql -dsn SAMPLE
IBM DATABASE 2 Interactive CLI Sample Program
(C) COPYRIGHT International Business Machines Corp. 1993,1996
All Rights Reserved
Licensed Materials – Property of IBM
US Government Users Restricted Rights – Use, duplication or
disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
> SELECT * from staff
FetchAll: Columns: 7
ID NAME DEPT JOB YEARS SALARY COMM
10, Sanders, 20, Mgr , 7, 98357.50, –
20, Pernal, 20, Sales, 8, 78171.25, 612.45
30, Marenghi, 38, Mgr , 5, 77506.75, –
40, O’Brien, 38, Sales, 6, 78006.00, 846.55
50, Hanes, 15, Mgr , 10, 80659.80, –
60, Quigley, 38, Sales, -, 66808.30, 650.25
70, Rothman, 15, Sales, 7, 76502.83, 1152.00
80, James, 20, Clerk, -, 43504.60, 128.20
90, Koonitz, 42, Sales, 6, 38001.75, 1386.70
100, Plotz, 42, Mgr , 7, 78352.80, –
110, Ngan, 15, Clerk, 5, 42508.20, 206.60
120, Naughton, 38, Clerk, -, 42954.75, 180.00
130, Yamaguchi, 42, Clerk, 6, 40505.90, 75.60
140, Fraye, 51, Mgr , 6, 91150.00, –
150, Williams, 51, Sales, 6, 79456.50, 637.65
160, Molinare, 10, Mgr , 7, 82959.20, –
170, Kermisch, 15, Clerk, 4, 42258.50, 110.10
180, Abrahams, 38, Clerk, 3, 37009.75, 236.50
190, Sneider, 20, Clerk, 8, 34252.75, 126.50
200, Scoutten, 42, Clerk, -, 41508.60, 84.20
210, Lu, 10, Mgr , 10, 90010.00, –
220, Smith, 51, Sales, 7, 87654.50, 992.80
230, Lundquist, 51, Clerk, 3, 83369.80, 189.65
240, Daniels, 10, Mgr , 5, 79260.25, –
250, Wheeler, 51, Clerk, 6, 74460.00, 513.30
260, Jones, 10, Mgr , 12, 81234.00, –
270, Lea, 66, Mgr , 9, 88555.50, –
280, Wilson, 66, Sales, 9, 78674.50, 811.50
290, Quill, 84, Mgr , 10, 89818.00, –
300, Davis, 84, Sales, 5, 65454.50, 806.10
310, Graham, 66, Sales, 13, 71000.00, 200.30
320, Gonzales, 66, Sales, 4, 76858.20, 844.00
330, Burke, 66, Clerk, 1, 49988.00, 55.50
340, Edwards, 84, Sales, 7, 67844.00, 1285.00
350, Gafney, 84, Clerk, 5, 43030.50, 188.00
FetchAll: 35 rows fetched.
>

The connection is looking good!  Finally, when building C++ software that uses the driver, be sure to link to add the following compile and link options to g++ or clang++:

-I/opt/ibm/clidriver/include
-L/opt/ibm/clidriver/lib
-ldb2

The relevant include file is “sqlcli1.h” and the primary library of interest is libdb2.so.1.

 

 

Installing DB2 on Debian/Ubuntu

IBM’s DB2 product is delivered as a binary installer for the Linux platform in a tarball format. It would be nice if IBM produced rpm or deb packages for distributing DB2, but I will complain no further. The installer has gotten *much better* since when I first battled with installing DB2 on Linux back in 2006. After downloading the binary, unpack it and kick it off!

root#   mkdir -p /opt/ibm/db2expc_installer
root#   cp v11.1_linuxx64_expc.tar.gz /opt/ibm/db2expc_installer
root#   cd /opt/ibm/db2expc_installer
root#   tar -xfz v11.1_linuxx64_expc.tar.gz
root#   cd expc
root#   ./db2_installer

This failed of course, no binary delivered in this form ever works out of the box. This was good though, as I really wanted to run db2_setup instead of the installer. The setup program is a Java GUI that makes it very simple to go through the configuration, including creating user accounts required by the DB2 RDBMS.

 Requirement not matched for DB2 database “Server” . Version: “11.1.1.1”.

Summary of prerequisites that are not met on the current system:

DBT3514W The db2prereqcheck utility failed to find the following 32-bit library file: “/lib/i386-linux-gnu/libpam.so*”.
DBT3520E The db2prereqcheck utility could not find the library file libaio.so.1.
DBT3514W The db2prereqcheck utility failed to find the following 32-bit library file: “libstdc++.so.6”.

Ugh…32-bit binaries required.

root#   dpkg –add-architecture i386
root#   apt-get update
root#   apt-get install libaio1 libstdc++6:i386 libpam0g:i386

Now it is possible to run the installer, this time with the GUI to make the job easy.

root#  ./db2setup

DBI1190I  db2setup is preparing the DB2 Setup wizard which will guide
you through th6:ie program setup process. Please wait.

The GUI setup program holds one’s hand the whole way, allowing one to setup db2inst1 and db2fenc1 users. After the installation is complete, I ran visudo to add my user account to the sudoers file for DB2 management:

bryan ALL=(db2inst1) /opt/ibm/db2/V11.1_01/bin/*
bryan ALL=(db2fenc1) /opt/ibn/db2/V11.1_01/bin/*

Finally, I usually like to create the SAMPLE database so that I can test out SQL commands and other IBM tools on a test database that actually has a good amount of data and tables.

db2inst1$   ./db2sampl

Creating database “SAMPLE”…
Connecting to database “SAMPLE”…
Creating tables and data in schema “DB2INST1″…
Creating tables with XML columns and XML data in schema “DB2INST1″…

‘db2sampl’ processing complete.

Now to install the CLI/ODBC library for C++ programs, and maybe IBM Data Studio…

 

 

GNU C++ and Gold Linker

The Gold linker (ld.gold) is a ELF linker developed at Google and added to the binutils toolset that can be used in place of standard linker (ld) from binutils.  The Gold linker offers faster object linking times for C++ programs, which is particularly attractive to large C++ code bases. Please follow this link (Linux Foundation) for an interesting read on how it works.

Most Linux platforms will default to using the standard linker, so below are a few options for overriding and using the ld.gold linker:

  1.  Use the -fuse flag on gcc/g++:  g++ -fuse-ld=gold test.cpp
  2. Setting “export LD=ld.gold” so that the $LD environment variable uses ld.gold rather than ld (this is useful for projects using makefiles)
  3. As the super user, running binutils-config –linker ld.gold to change the default

USB Endpoints in Linux

USB endpoints are the logical entities that make up one-way communication channels in a USB system.  Endpoints are unidirectional and the direction is always with respect to the host.  IN endpoints are for transfers to the host from the device (host<-device), and OUT endpoints are for transfers from the host to the device (host->device).  Refer to the USB specification for more information about endpoints, or try this reference from BeyondLogic on endpoint types.

In the Linux kernel the struct usb_host_endpoint, defined in <linux/usb.h>, is used to describe a USB endpoint.

struct usb_host_endpoint {
   struct usb_endpoint_descriptor    desc;
   struct usb_ss_ep_comp_descriptor  ss_ep_comp;
   struct list_head    urb_list;
   void        *hcpriv;
   struct ep_device    *ep_dev;  /* For sysfs info */
   unsigned char *extra;   /* Extra descriptors */
   int extralen;
   int enabled;
};

Among other things, it contains the head of a linked list of URBs (to be discussed later) and a struct usb_endpoint_descriptorwhich is used to describe the endpoint in terms of the USB spec.  In <linux/usb/ch9.h>, the definition of the endpoint descriptor can be seen:

struct usb_endpoint_descriptor {
   __u8  bLength;
   __u8  bDescriptorType;
   __u8  bEndpointAddress;
   __u8  bmAttributes;
   __le16 wMaxPacketSize;
   __u8  bInterval;
   /* NOTE:  these two are _only_ in audio endpoints. */
   /* use USB_DT_ENDPOINT*_SIZE in bLength, not sizeof. */
   __u8  bRefresh;
   __u8  bSynchAddress;
} __attribute__ ((packed));

In order to determine the direction of the endpoint, a few helper functions are available:

#define USB_ENDPOINT_DIR_MASK   0x80
...
static inline int usb_endpoint_dir_in(const struct usb_endpoint_descriptor *epd)
{
  return ((epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN);
}
...
static inline int usb_endpoint_dir_out(
        const struct usb_endpoint_descriptor *epd)
{
  return ((epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT);
}

This could all be done manually with the USB_ENDPOINT_DIR_MASK mask itself, but in order to guard against futures changes, it is best to use the abstractions and helper functions defined in the kernel.  The endpoint transfer type can also be retrieved with helper functions.

#define USB_ENDPOINT_XFERTYPE_MASK  0x03
...
static inline int usb_endpoint_type(const struct usb_endpoint_descriptor *epd)
{
  return epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
}
...
static inline int usb_endpoint_xfer_bulk(const struct usb_endpoint_descriptor *epd)
{
  return ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
    USB_ENDPOINT_XFER_BULK);
}
...
static inline int usb_endpoint_xfer_control(const struct usb_endpoint_descriptor *epd)
{
  return ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
    USB_ENDPOINT_XFER_CONTROL);
}
...
static inline int usb_endpoint_xfer_int(const struct usb_endpoint_descriptor *epd)
{
  return ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
    USB_ENDPOINT_XFER_INT);
}
...
static inline int usb_endpoint_xfer_isoc(const struct usb_endpoint_descriptor *epd)
{
  return ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
    USB_ENDPOINT_XFER_ISOC);
}

Next the Linux kernel representations of USB Interfaces and USB Configurations will be examined.