About Me

My photo
I know the last digit of PI

Sunday, November 20, 2016

Convert MBR to GPT and BIOS bootable to UEFI bootable without data loss

Convert MBR to GPT

Instructons for Windows users

  1. Clone the disk in order to have backup data. You can skip this step but if somethings goes wrong the data on the disk may be lost
  2. Identify the disk which will be converted. Open Windows Disk Management and look the number (e.g. Disk 0).
  3. Download gptgen from sourceforge http://sourceforge.net/projects/gptgen This tool will allow you to convert the paritition table without loosing any data
  4. Unzip and start gptgen under elevated CMD (via Run as Administrator)
    gptgen.exe -w \\.\physicaldriveX
    Replace physicaldriveX with the disk number (e.g. physicaldrive0)
Now the disk should be converted to GPT. If you face a problem that the disk doesn't have enough space at the end of the disk, then you can shrink the volume (assuming that you have free space on the volume). This can be done with 3d party tools or with diskpart
  1. Open elevated CMD and run
    diskpart
  2. list volume
  3. select volume
    and choose the number of the corresponding volume (e.g. 0)
  4. shrink
  5. exit
  6. Rerun gptgen

Instructions for Linux

  1. Boot and open terminal. You need parted installed
  2. Make backup of the existing MBR partition table:
    parted /dev/sda unit s print > partition_table.txt
    If you are converting the disk with the operating system you are currently running copy the partition_table.txt file to USB drive or upload it to internet, so you can access it later if something goes wrong.
  3. Create new GPT partition table overriding the existing MBR table
    mktable gpt
    When asked choose to ignore the warnings and to continue (with overwriting). We will recreate the existing partitions on exact sectors they have been before, but with new partition table format.
  4. Recrete partitions by using the information from partition_table.txt file and commands
    unit s
    mkpart
    When asked fill the partition type (e.g. ext4) and partition starting/ending sector (see partition_table.txt)
  5. Optionally set the legacy boot flag to the corresponding partition number.
    set 1 legacy_boot on
  6. Print the partition table and compare it with the partition_table.txt file
    print

Convert BIOS bootable to UEFI bootable for GPT partitioned disk

Since it is difficult to do the conversion while running the operating system I suggest you download a Fedora live CD and create bootable USB drive, so you can boot from it. Make sure that the USB is UEFI bootable - this means when you write it with rufus, choose GPT partition table and FAT32 system. If you plan to convert Windows to UEFI, then you need also a Windows installation DVD or USB. Then change the boot type in BIOS from Legacy BIOS to UEFI - see docs from your commputer manifacturer how to do it.

In order for UEFI to work you need a new partition with type C12A7328-F81F-11D2-BA4B-00A0C93EC93B - EFI System Partition (ESP). The new partition should be formatted with FAT32 system. The partition should be the first one. It will contain the files required to boot the operating system(s).

Windows

In GPT Windows needs additional partition called Microsoft Reserved Partition (MSR). In standard MBR partition scheme Windows used hidden sectors to store system data, but GPT doesn't allow hidden sectors, so MSR partition is used instead. It should not be formatted with any file system, because its sectors will be used directly by the operating system. The partition type should be E3C9E316-0B5C-4DB8-817D-F92DF00215AE.

How to create the ESP and MSR under Windows

This guide is adapted from Technet article
  1. Boot from Windows installation DVD or USB
  2. Choose repair and open command prompt
  3. Start diskpart
  4. Select the disk where the ESR and MSR partitions will be created
    list disk
    select disk X
    Replace X with the disk number (e.g. 0)
  5. Usually you have one small bootable partition used to boot Windows. We are going to delete it and use the space to create a new ESR and MSR
    list partition
    select partition 1
    delete partition
  6. Now create ESR
    create partition EFI size=100 offset=1
    format quick fs=fat32 label="System"
    assign letter=S
  7. Now create MSR
    create partition msr size=128 offset=103424
  8. Find out the windows installation drive letter.
    list volume
    You can also reassign it if needed (Usually it should be C:)
    select volume 3
    assign letter=C
  9. Exit disk part
    exit
  10. Generate boot partiton data
    bcdboot c:\windows /s s: /f UEFI
    Replace C: with your Windows installation letter

Linux

TODO : (draft version) 1. Delete /dev/sda1 2. Shring /boot and move it at the end, so the begining of the disk is free space 3. Create ESR at begining 4./etc/fstab -> mount UUID=xxxxx to /boot/efi 5.copy livecd /boot/efi to /dev/sda1 (UUID=xxxx)

Sunday, October 30, 2016

Keyboard back light under linux.

For some reason my fedora is turning the keyboard back light off. Even if I press the keyboard shorcut to turn the light on, it doesn't work. For a long time I thought that the reason is hardware problem, until I found this post and it turns out to be software issue. Here is the script that I used on my machine to restore the keyboard light. Execute following command line several times until it outputs "100" (percents)
kb-light.py +
or
kb-light.py --up
The python script:
#!/usr/bin/env python3
# coding: utf-8

from sys import argv
import dbus


def kb_light_set(delta):
    bus = dbus.SystemBus()
    kbd_backlight_proxy = bus.get_object('org.freedesktop.UPower', '/org/freedesktop/UPower/KbdBacklight')
    kbd_backlight = dbus.Interface(kbd_backlight_proxy, 'org.freedesktop.UPower.KbdBacklight')

    current = kbd_backlight.GetBrightness()
    maximum = kbd_backlight.GetMaxBrightness()
    new = max(0, current + delta)

    if new >= 0 and new <= maximum:
        current = new
        kbd_backlight.SetBrightness(current)

    # Return current backlight level percentage
    return 100 * current / maximum

if __name__ == '__main__':
    if len(argv[1:]) == 1:
        if argv[1] == "--up" or argv[1] == "+":
            # ./kb-light.py (+|--up) to increment
            print(kb_light_set(1))
        elif argv[1] == "--down" or argv[1] == "-":
            # ./kb-light.py (-|--down) to decrement
            print(kb_light_set(-1))
        else:
            print("Unknown argument:", argv[1])
    else:
        print("Script takes exactly one argument.", len(argv[1:]), "arguments provided.")

Sunday, October 02, 2016

How to monitor progress of linux command dd.

If you start a dd command from the command prompt, there is no progress output. The easiest way to get the current dd progress is by executing following commmand from different terminal
sudo kill -USR1 $(pgrep ^dd)
The progress will be printed in the dd terminal. To print the progress every 5 seconds use
watch -n5 'sudo kill -USR1 $(pgrep ^dd)'
For dd version 8.24 and above the following command line will print the progress
dd status=progress  if=xxx of=yyy

Thursday, June 30, 2016

NGINX Reverse proxy and load balancer for Java servers

This is a simple script for the load balancing and reverse proxy configuration for an application called "myAppName" which runs on two servers "https://xxxxx:8080/myAppName" and "https://yyyyy:8080/myAppName". The script is designed for Java servers (tomcat, glassfish, jboss, etc.)

However please note that since NGINX open source doesn't support sticky it is not suitable for productive environments load balancing, because it uses ip_hash directive, which tells nginx that all request from particular IP to be served by one and the same server. If that IP is the external IP of large internal LAN (via NAT), then it means only one server will be loaded, which may crash that server. If you are not willing to pay $1900/yr then stick to apache httpd.

There are two options - the reverse proxy machine is serving all requests on the root "/" or "/myAppName".

worker_processes  1;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    sendfile        on;
    keepalive_timeout  65;
    
    # Load balancing    
    upstream myAppName {        
        ip_hash;
        server xxxxx:8080;
        server yyyyy:8081;
    }
    
    server {
        listen       1080;
        server_name  localhost;

        location / {
            rewrite ^/myAppName/(.*)$  /myAppName/$1 break;
            rewrite ^(.*)$  /myAppName/$1 break;
            proxy_pass http://myAppName;
            proxy_cookie_path / /myAppName;    
        }
        
        #location /myAppName {            
        #    proxy_pass http://myAppName;
        #    proxy_cookie_path /myAppName/ /myAppName;    
        #    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        #    proxy_set_header Host $http_host;
        #    proxy_set_header X-Real-IP $remote_addr;
        #    proxy_set_header X-Forwarded-Proto https;
        #    proxy_redirect off;
        #    proxy_connect_timeout      240;
        #    proxy_send_timeout         240;
        #    proxy_read_timeout         240;
        #    if ($http_cookie ~* "jsessionid=([^;]+)(?:;|$)") {
        #        set $co "jsessionid=$1";
        #    }
        #    proxy_set_header Cookie "$co";            
        #}
    }    
}

Monday, March 28, 2016

Eclipse is too big under Gnome (Fedora 23)

To make eclipse looks more nicer (similar look as on Windows machines) perform following steps:
  1. Create new eclipse launcher and pass GTK version 2 as parameter
    [Desktop Entry]
    Encoding=UTF-8
    Name=Eclipse IDE
    Exec=/opt/eclipse.4.5.2/eclipse --launcher.GTK_version 2
    Icon=/opt/eclipse.4.5.2/icon.xpm
    Type=Application
    Categories=Development;
    
  2. Create configuration file ~/.gtkrc-2.0 with following content:
    style "gtkcompact" { 
      font_name="Sans 8"
      GtkButton::defaultborder={0,0,0,0} 
      GtkButton::defaultoutsideborder={0,0,0,0} 
      GtkButtonBox::childminwidth=0 
      GtkButtonBox::childminheigth=0 
      GtkButtonBox::childinternalpadx=0 
      GtkButtonBox::childinternalpady=0 
      GtkMenu::vertical-padding=1 
      GtkMenuBar::internalpadding=0 
      GtkMenuItem::horizontalpadding=4
      GtkToolbar::internal-padding=0 
      GtkToolbar::space-size=0 
      GtkOptionMenu::indicatorsize=0 
      GtkOptionMenu::indicatorspacing=2 
      GtkPaned::handlesize=4 
      GtkRange::troughborder=0 
      GtkRange::stepperspacing=0 
      GtkScale::valuespacing=0 
      GtkScrolledWindow::scrollbarspacing=0 
      GtkExpander::expandersize=10 
      GtkExpander::expanderspacing=0 
      GtkTreeView::vertical-separator=0 
      GtkTreeView::horizontal-separator=0 
      GtkTreeView::expander-size=8 
      GtkTreeView::fixed-height-mode=TRUE 
      GtkWidget::focuspadding=1 
    } 
    class "GtkWidget" style "gtkcompact"
    
    style "gtkcompactextra" { 
      xthickness=2 ythickness=2 
    } 
    class "GtkButton" style "gtkcompactextra"
    class "GtkToolbar" style "gtkcompactextra"
    class "GtkPaned" style "gtkcompactextra"
    

Thursday, January 21, 2016

How to check your motherboard model under windows

wmic baseboard get product,Manufacturer,version,serialnumber

Sunday, December 06, 2015

Apache Directory (DS) systemd.service

Place following file into /usr/lib/systemd/system/apacheds.service
# Systemd unit file for ApacheDS instances.

[Unit]
Description=Apache DS LDAP server
After=syslog.target network.target

[Service]
Type=forking
ExecStart=/opt/apacheds-2.0.0_M20/bin/apacheds start default
ExecStop=/opt/apacheds-2.0.0_M20/bin/apacheds stop default
SuccessExitStatus=143
User=apacheds
Group=apacheds

[Install]
WantedBy=multi-user.target
Then execute:
systemctl enable apacheds
systemctl start apacheds

Thursday, October 01, 2015

How reliable is your PC

Thanks to the research done by Bianca Schroeder, Eduardo Pinheiro and Wolf-Dietrich Weber about errors that occur in DRAM memory, now we know that it is possible a single machine to have 48621 errors (correctable errors) per year. Roughly this makes 133.20 (48621 / 365) errors per day or 5.55 errors per hour.
The research is based on DRAM memory equipped with ECC (Error-correcting code). Most home/office PCs don't use ECC, so those errors are not detected and cause software failure (like infamous blue screen of death)

Thursday, September 24, 2015

Windows update error 8024402C

When windows update gives error 8024402C, and the machine is not managed by WSUS and has internet connection, the problem could be solved by executing following command line:
netsh winhttp reset proxy

Friday, August 14, 2015

Updating to Windows 10 when having GRUB 2 bootloader installed in MBR.



Usually when having dualboot of Windows and Linux the GRUB 2 bootloader is installed in MBR. When trying to update to Windows 10 it fails with the following error "We Can't Tell if your PC has enough space to continue".
Well the solution for updating to Windows 10 is simple - restore the hardisk Master Boot Record (MBR) using Windows installation disc (it can be also created via Microsoft's MediaCreationTool - the same tool used for updating to Windows 10. Just on the first screen choose not to update, but "Create installation media for another PC" and write it to DVD/USB).
Boot from the Windows installation DVD/USB and follow instruction until screen that allows you to install windows or "Repair your computer". Choose to "Repair your computer" / "Troubleshoot" / "Advanced options" / "Command prompt"
Execute following command:
bootrec.exe /fixmbr
Reboot and start the update process again. Now the update should be successful.
Now Windows boots successfully but Linux is no longer accessible. One way to make Linux bootable again is to use Windows bootloader to load Linux. I prefer this method because I don't want to face any future problems with windows updates.
We need a copy of the GRUB2 exported as file. For that reason we will install GRUB on Partition Boot Record (PBR) and copy the boot sector to file. First we must access the installed Linux partitions. Create a "Live CD" on DVD/USB and boot from it. The from the shell mount your existing linux installation. Let's assume that /dev/sda3 is the linux boot partition, /dev/sda4 is the root partition. Now mount the volumes:
mount /dev/sda4 /mnt
mount /dev/sda3 /mnt/boot
mount --bind /dev /mnt/dev
mount --bind /proc /mnt/proc
mount --bind /sys /mnt/sys
Optionally you may mount home directory
mount /dev/sdaX /mnt/home

Now do chroot:
chroot /mnt
Reinstall grup 2 on boot partition
grub2-install /dev/sda3
You may receive following error:
"warning: Embedding is not possible. GRUB can only be installed in this setup by using blocklists. However, blocklists are UNRELIABLE and their use is discouraged.
error: will not proceed with blocklists"
Then just use --force
grub2-install --force /dev/sda3
Once the installation complets create a dump of the bootsector:
dd if=/dev/sda3 of=/tmp/linux.bootsector.bin bs=512 count=1
copy the /tmp/linux.bootsector.bin  to some partition accessible by Windows.
mkdir /mnt/c
mount /dev/sda2 /mnt/c
cp /tmp/linux.bootsector.bin /mnt/c
umount /mnt/c
Now reboot and start Windows and we need to create a new BCD entry for Linux
Open administrative command prompt (right click on "command prompt" and choose run as administrator)
bcdedit /create /d “Linux” /application BOOTSECTOR
The command will return GUID e.g. {5474794d-1fe8-4008-a0ae-d10210214f2a}
That GUID will be use in next commands.
Configure new BCD entry's partition and path to the location where linux.bootsector.bin is copied
bcdedit /set {5474794d-1fe8-4008-a0ae-d10210214f2a} device partition=C: 
bcdedit /set {5474794d-1fe8-4008-a0ae-d10210214f2a}  PATH \linux.bootsector.bin
Then configure the new entry to be shown last, and the OS selection menu timeout to be 5 seconds.
bcdedit /displayorder {5474794d-1fe8-4008-a0ae-d10210214f2a}  /addlast
bcdedit /timeout 5
Reboot and now you will be able to boot either Windows or Linux.

Tuesday, August 04, 2015

Windows 10/8/7/Vista administrative shares are not accessible (from linux / windows)

The information is based on Access Denied Trying to Connect to Administrative Shares C$, D$ etc.

Typical error is :

mount -t cifs -o username=superman,password=secret //192.168.22.14/c$ /mnt/c
mount error(13): Permission denied
Refer to the mount.cifs(8) manual page (e.g. man mount.cifs)
The reason is that described in KB951916 Microsoft introduced as part of UAC a little known feature called “UAC remote restrictions”. It filters the access token for connections made with local user accounts or Microsoft accounts (the latter typically have the format MicrosoftAccount\EMailAddress). In other words it removes the SID for “Administrators”. Connections made with domain accounts remain unchanged. From KB951016:
If the user wants to administer the workstation with a Security Account Manager (SAM) account, the user must interactively log on to the computer that is to be administered with Remote Assistance or Remote Desktop, if these services are available.
UAC remote restrictions can be disabled by setting the DWORD registry value LocalAccountTokenFilterPolicy to 1:
Key: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System
Value: LocalAccountTokenFilterPolicy
Data: 1 (to disable, 0 enables filtering)
Type: REG_DWORD (32-bit)
Reboot is not required on Windows 8/10

Thursday, July 23, 2015

OpeneElec Kodi hacking - creating music catalog

Systemd CIFS mount

/storage/.config/system.d/storage-music-rock.mount
[Unit]
 Description=cifs mount script
 Requires=network-online.service
 After=network-online.service
 Before=kodi.service

 [Mount]
 What=//192.168.0.31/MusicRock
 Where=/storage/music/rock
 Options=username=myusername,password=mypassword,rw
 Type=cifs

 [Install]
 WantedBy=multi-user.target
Important: this file must be renamed to mountpoint.mount where mountpoint, is the FULL path where the share will be mounted. Slashes "/" MUST BE REPLACED with dashes "-" with .mount as extension. This means, if we want mount to "/storage/music/rock" (see above "Where=/storage/music/rock") then this file must be renamed to 'storage-music-rock.mount'. This is only for the filename! not for the What= and Where= sections!

Script that maps file by the first two letters

/storage/.config/create_symb_links.sh chmod +s /storage/.config/create_symb_links.sh
#!/bin/bash
displayUsage() { 
  echo "Scans source directory and create symbolic links based on the file first two letters" 
  echo -e "\nUsage:\n$0 [src-dir] [links-dir]\n  src-dir\tsource directory to be scanned\n  links-dir\tfull path to target directory where symbolic links will be created\n\n" 
  echo -e "e.g.:\n $0 /storage/music/rock /storage/music/rock_links/\n\n"
  echo -e "Let's have 3 files:\n    /storage/music/rock/rock1\n    /storage/music/rock/rock2\n    /storage/music/rock/metal\n"
  echo -e "then inside /storage/music/rock_links/ you will have following files:\n"
  echo -e "    /storage/music/rock_links/RO/rock1\n    /storage/music/rock_links/RO/rock2\n    /storage/music/rock_links/ME/metal\n"
} 


if [[ -z $1 ]]; then
  displayUsage
  exit 1 
fi

if [[ -z $2 ]]; then
  displayUsage
  exit 1 
fi

dir=$1
links=$2
currdir=`pwd`

rm -Rf $links

cd $dir

mkdir -p $links
for f in *
do 
  prefix=`echo $f | cut -c 1,2 | tr [:lower:] [:upper:]`
  mkdir -p $links/$prefix
  ln -s "$dir/$f" "$links/$prefix/$f"
done

cd $currdir

Service for creating music catalog

/storage/.config/system.d/catalog-music-rock.service
[Unit]
Description=Create musics catalog
Requires=storage-music-rock.mount
After=storage-music-rock.mount
Before=kodi.service

[Service]
Type=oneshot
ExecStartPre=/bin/bash -c 'echo "Creating music catalog ..."'
ExecStart=/bin/bash -c '/storage/.config/create_symb_links.sh  /storage/music/rock /storage/music/rock_links'
StandardOutput=tty

[Install]
WantedBy=multi-user.target

Enabling mount and services

systemctl enable storage-music.mount
systemctl enable storage-music-rock.mount
systemctl enable catalog-music-rock.service

Friday, May 08, 2015

Glassfish 2.1: Using Local EJB interface in WAR's POJO

Base interface for local and remote interfaces

public interface HelloEjb extends Serializable {
  public String hello(); 
}

Define local interface

@Local
public interface HelloEjbLocal extends HelloEjb {
}

Define remote interface

@Remote
public interface HelloEjbRemote extends HelloEjb {
}

Define EJB implementation

//@Local(HelloEjbLocal.class) // not needed
//@Remote(HelloEjbRemote.class) // not needed
@Stateless
public class HelloEjbImpl extends HelloEjbLocal, HelloEjbRemote {
  public String hello() { return "hello world!"; }
}

Using EJB in POJO

Please note that the POJO must be called from a class that is part of the WAR (either servlet, webservice, etc.)
// Notes: POJO must be called by class from the WAR
@EJB(name="helloEjbJndi", beanInterface=HelloEjbLocal.class)
public class HelloClient {

  public HelloEjb getEjb() throws NamingException {
    final InitialContext ctx = new InitialContext();
    return (HelloEjb)ctx.lookup("java:comp/env/helloEjbJndi");
  }
}

Wednesday, April 22, 2015

Read time and battery status from bluetooth device

Pair with the device

[root@laptop ~]$ bluetoothctl 
[NEW] Controller AA:BB:CC:DD:EE:FF laptop [default]
[bluetooth]# power on
Changing power on succeeded
[bluetooth]# scan on
Discovery started
[CHG] Controller AA:BB:CC:DD:EE:FF Discovering: yes
[NEW] Device F1:F2:F3:F4:F5:F6 CHRONOS ECO XXXX
[bluetooth]# info F1:F2:F3:F4:F5:F6
Device F1:F2:F3:F4:F5:F6
 Name: CHRONOS ECO XXXX
 Alias: CHRONOS ECO XXXX
 Appearance: 0x1234
 Paired: no
 Trusted: no
 Blocked: no
 Connected: no
 LegacyPairing: no
 UUID: Vendor specific           (6e400001-b5a3-f393-e0a9-e50e24dcca9e)
[bluetooth]# trust F1:F2:F3:F4:F5:F6
[CHG] Device F1:F2:F3:F4:F5:F6 Trusted: yes
Changing F1:F2:F3:F4:F5:F6 trust succeeded
[bluetooth]# agent on
Agent registered
[bluetooth]# default-agent
Default agent request successful
[bluetooth]# pair F1:F2:F3:F4:F5:F6
Attempting to pair with F1:F2:F3:F4:F5:F6
[CHG] Device F1:F2:F3:F4:F5:F6 Connected: yes
[CHG] Device F1:F2:F3:F4:F5:F6 UUIDs:
 00001800-0000-1000-8000-00805f9b34fb
 00001801-0000-1000-8000-00805f9b34fb
 00001805-0000-1000-8000-00805f9b34fb
 0000180a-0000-1000-8000-00805f9b34fb
 0000180f-0000-1000-8000-00805f9b34fb
 6e400001-b5a3-f393-e0a9-e50e24dcca9e
[CHG] Device F1:F2:F3:F4:F5:F6 Paired: yes
Pairing successful
[bluetooth]# paired-devices 
Device F1:F2:F3:F4:F5:F6 CHRONOS ECO XXXX
[bluetooth]# info F1:F2:F3:F4:F5:F6
Device F1:F2:F3:F4:F5:F6
 Name: CHRONOS ECO XXXX
 Alias: CHRONOS ECO XXXX
 Appearance: 0x1234
 Paired: yes
 Trusted: yes
 Blocked: no
 Connected: no
 LegacyPairing: no
 UUID: Generic Access Profile    (00001800-0000-1000-8000-00805f9b34fb)
 UUID: Generic Attribute Profile (00001801-0000-1000-8000-00805f9b34fb)
 UUID: Current Time Service      (00001805-0000-1000-8000-00805f9b34fb)
 UUID: Device Information        (0000180a-0000-1000-8000-00805f9b34fb)
 UUID: Battery Service           (0000180f-0000-1000-8000-00805f9b34fb)
 UUID: Vendor specific           (6e400001-b5a3-f393-e0a9-e50e24dcca9e)
[bluetooth]# quit

We will read the information from the "Current Time Service" and "Battery Service"

Connect to the device and list services with handles
[root@laptop ~]$ gatttool -t random -I -b F1:F2:F3:F4:F5:F6
[F1:F2:F3:F4:F5:F6][LE]> connect
Attempting to connect to F1:F2:F3:F4:F5:F6
Connection successful
[F1:F2:F3:F4:F5:F6][LE]> primary
attr handle: 0x0001, end grp handle: 0x0007 uuid: 00001800-0000-1000-8000-00805f9b34fb
attr handle: 0x0008, end grp handle: 0x000b uuid: 00001801-0000-1000-8000-00805f9b34fb
attr handle: 0x000c, end grp handle: 0x0011 uuid: 6e400001-b5a3-f393-e0a9-e50e24dcca9e
attr handle: 0x0012, end grp handle: 0x0015 uuid: 0000180f-0000-1000-8000-00805f9b34fb
attr handle: 0x0016, end grp handle: 0x0020 uuid: 0000180a-0000-1000-8000-00805f9b34fb
attr handle: 0x0021, end grp handle: 0xffff uuid: 00001805-0000-1000-8000-00805f9b34fb
Connect to handle of "Current Time Service" (00001805-0000-1000-8000-00805f9b34fb).

Use the handle and the grp handle values.
[F1:F2:F3:F4:F5:F6][LE]> characteristics 0x0021 0xffff
handle: 0x0022, char properties: 0x12, char value handle: 0x0023, uuid: 00002a2b-0000-1000-8000-00805f9b34fb
Note the "char value handle" and use it for reading characteristics data.
[F1:F2:F3:F4:F5:F6][LE]> char-read-hnd 0x0023
Characteristic value/descriptor: df 07 04 1A 16 0e 00 00 03 00 00 00 
the first two bytes are the year: 07df = 2015
the thrid byte is the month: 04 = April
the fourth byte is the date: 1A = 26
the fifth byte is the hour: 16 = 22
the sixth byte is the minutes: 0e = 14
So the date is: 26.April.2015 22:14
More information about the format could be found here

Now let's read the battery status from Battery Service (0000180f-0000-1000-8000-00805f9b34fb)
[F1:F2:F3:F4:F5:F6][LE]> characteristics 0x0012 0x0015
handle: 0x0013, char properties: 0x12, char value handle: 0x0014, uuid: 00002a19-0000-1000-8000-00805f9b34fb
[F1:F2:F3:F4:F5:F6][LE]> char-read-hnd 0x0014
Characteristic value/descriptor: 5a
This is the battery status (in percentage): 5a = 90
So the battery level is 90%.
More information about the format could be found here

Friday, January 02, 2015

Bluetooth COM port in Linux

Following tools are needed for dealing with bluetooth devices in Linux: bluetoothctl, hcitool, rfcomm, minicom

Pairing

Powering the bluetooth adapter and making it pairable
user@workstation:~$ bluetoothctl
[bluetooth]# power on
Changing power on succeeded

[bluetooth]# pairable on 
Changing pairable on succeeded
Search for new bluetooth devices - note the btaddress of the device (00:06:66:04:9E:4A). It is needed for all bluetooth commands
[bluetooth]# scan on
Discovery started
[CHG] Controller aa:bb:cc:dd:ee:ff Discovering: yes
[NEW] Device 00:06:66:04:9E:4A FireFly-9E4A

[bluetooth]# scan off
Discovery stopped
[CHG] Controller aa:bb:cc:dd:ee:ff Discovering: no
Retrieve some information about the device
[bluetooth]# info 00:06:66:04:9E:4A
Device 00:06:66:04:9E:4A
 Name: FireFly-9E4A
 Alias: FireFly-9E4A
 Class: 0x001f00
 Paired: no
 Trusted: no
 Blocked: no
 Connected: no
 LegacyPairing: yes
Optionally configure the device to be trusted - so if it automatically accepts generated PINs. However for legacy pairing manually entered PIN is required.
[bluetooth]# trust 00:06:66:04:9E:4A
[CHG] Device 00:06:66:04:9E:4A Trusted: yes
Changing 00:06:66:04:9E:4A trust succeeded
Configure the bluetoothctl to be default agent for dealing with PIN code.
[bluetooth]# agent on
Agent registered

[bluetooth]# default-agent 
Default agent request successful
Now pair with the device
[bluetooth]# pair 00:06:66:04:9E:4A
Attempting to pair with 00:06:66:04:9E:4A
[CHG] Device 00:06:66:04:9E:4A Connected: yes
Request PIN code
[agent] Enter PIN code: 1234
[CHG] Device 00:06:66:04:9E:4A UUIDs:
 00001101-0000-1000-8000-00805f9b34fb
[CHG] Device 00:06:66:04:9E:4A Paired: yes
Pairing successful
Double check the pairing and quit
[bluetooth]# paired-devices 
Device 00:06:66:04:9E:4A FireFly-9E4A

[bluetooth]# quit

Discovering services and RFCOMM channels

For devices that support SDP - Service Discovery Protocol (UUID: 00000001-0000-1000-8000-00805F9B34FB) the following command will show available protocols and RFCOMM channels. The XX:XX:XX:XX:XX:XX is the btaddress of the device. Note that in the previos example the device 00:06:66:04:9E:4A do not support SDP protocol, so the sdptool command will produce empty result.
user@workstation:~$ sdptool browse XX:XX:XX:XX:XX:XX
Service Name: Object Push Profile
Service RecHandle: 0x1000f
Service Class ID List:
  "OBEX Object Push" (0x1105)
Protocol Descriptor List:
  "L2CAP" (0x0100)
  "RFCOMM" (0x0003)
    Channel: 2
  "OBEX" (0x0008)
Profile Descriptor List:
  "OBEX Object Push" (0x1105)
    Version: 0x0100

Creating links to the remote COM port

Retrieving the bluetooth adapter name on the local machine.
user@workstation:~$ hcitool dev
Devices
        hci0    aa:bb:cc:dd:ee:ff
The adapter is called hci0 Optionally the connection could be tested with the following command
user@workstation:~$ sudo rfcomm connect hci0 00:06:66:04:9E:4A 1
Creating symlink to bluetooth serial port
user@workstation:~$ sudo rfcomm bind hci0 00:06:66:04:9E:4A 1
Verifying that the connection is established
user@workstation:~$ sudo rfcomm -a
rfcomm0: 00:06:66:04:9E:4A channel 1 connected [tty-attached]
The serial (COM) port is available as /dev/rcomm0 Any terminal program can use it. With following command will configure rootooth bluetooth device to communicate with Roomba 520 at baud rate 115200
user@workstation:~$ sudo minicom -D /dev/rfcomm0
$$$
>CMD
U,115K,N
>AOK
---
>END

Removing the symlink

In order to remove the symbolic link to the serial port the following command must be executed:
user@workstation:~$ sudo rfcomm release hci0

Unpairing the device and removing pairing configuration

user@workstation:~$ bluetoothctl

[bluetooth]# disconnect 00:06:66:04:9E:4A
Attempting to disconnect from 00:06:66:04:9E:4A
Successful disconnected

[bluetooth]# remove 00:06:66:04:9E:4A
[DEL] Device 00:06:66:04:9E:4A FireFly-9E4A
Device has been removed

[bluetooth]# power off
Changing power off succeeded

Tuesday, November 04, 2014

Jenkins deployment script with VPN establishment and SSH port forwarding

Here is a deployment script that can be run from Jenkins.
It establishes VPN connections, creates SSH tunnels and copies the WAR file to remote server. At the end the WAR is verified and a deployment script is executed.

The 192.168.0.2 is the server that gives access to other machines. The target tomcat server is 192.168.0.3, but it can be accessed only from 192.168.0.2.
The deploy.sh is responsible to stop tomcat server, delete the old artifact and start the tomcat server.

#!/bin/bash
now="$(date +'%Y%m%d%H%M')"

yes | cp /opt/hudson/jobs/WAR/lastSuccessful/archive/target/app.war ./app.war

cksumline=`cksum ./app.war`

fileChkSum=$(echo "$cksumline" | awk '{print $1}')
fileSize=$(echo "$cksumline" | awk '{print $2}')

#echo "Local Checksum:$fileChkSum"
#echo "Local FileSize:$fileSize"

sudo pon vpn-conn1
echo VPN connected
sleep 10

echo Creating tunnel
sshpass -p $pass ssh -f -o ExitOnForwardFailure=yes -o StrictHostKeyChecking=no user@192.168.0.2 -L 1234:192.168.0.3:22 'sleep 30' &
sleep 10
echo Tunnel created


echo Copyng WAR file...
sshpass -p $pass scp -oStrictHostKeyChecking=no -P 1234 ./app.war user@localhost:webapps/app.war.$now
echo WAR file copied.

cksumline2=`sshpass -p $pass ssh -oStrictHostKeyChecking=no -p 1234 user@localhost cksum webapps/app.war.$now`
echo "Checksum execution on remote machine: $cksumline2"




fileChkSum2=$(echo "$cksumline2" | awk '{print $1}')
fileSize2=$(echo "$cksumline2" | awk '{print $2}')

if [[ "$fileChkSum" != "$fileChkSum2" ]]; then
  echo "Checksum differs! local: $fileChkSum, remote: $fileChkSum2"
  sudo poff vpn-conn1
  echo VPN disconnected
  exit -1
fi

if [[ "$fileSize" != "$fileSize2" ]]; then
  echo "Size differs! local: $fileSize, remote: $fileSize2"
  sudo poff vpn-conn1
  echo VPN disconnected
  exit -1
fi


sshpass -p $pass ssh -oStrictHostKeyChecking=no -p 1234 user@localhost cp webapps/app.war.$now webapps/app.war
sshpass -p $pass ssh -oStrictHostKeyChecking=no -p 1234 user@localhost ./deploy.sh


sudo poff vpn-conn1
echo VPN disconnected

Resizing VirtualBox HDD

Original post from here https://forums.virtualbox.org/viewtopic.php?f=35&t=50661

Steps:
  1. Resize the Virutalbox HDD VBoxManage modifyhd <absolute path to file> --resize <size in MB>>
  2. Use GParted liveCD to resize the partition http://sourceforge.net/projects/gparted/

Thursday, May 22, 2014

Reverse proxy with apache

Creating reverse proxy with appache is quite easy. The common scenario is that you want to redirect entire domain to internal application server. Steps: 1) install apache 2) Edit APACHE_HOME/conf/httpd.conf with following content:
Listen 80
#Listen 1080

LogLevel debug
#ProxyHTMLLogVerbose On

LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so
LoadModule proxy_ajp_module modules/mod_proxy_ajp.so
LoadModule authz_core_module modules/mod_authz_core.so
LoadModule xml2enc_module modules/mod_xml2enc.so
LoadModule proxy_html_module modules/mod_proxy_html.so
LoadModule deflate_module modules/mod_deflate.so

<VirtualHost *>
 ProxyRequests OFF
 ProxyPreserveHost On
 
 ProxyPass / ajp://127.0.0.1:8009/
 ProxyPassReverse / ajp://127.0.0.1:8009/

 #ProxyPass /app/ ajp://127.0.0.1:8009/app/
 #ProxyPass /app/ ajp://127.0.0.1:8009/app/
 #ProxyHTMLURLMap  / /app/ 

</VirtualHost>
3) On the application server (Tomcat/JBoss) deploy your app in the root context. For JBoss use jboss-web.xml with following content:
<?xml version="1.0" encoding="UTF-8"?>
<jboss-web>
<context-root>/</context-root>
</jboss-web>
Also do not forget to disable the default root application from JBOSS_HOME/standalone/configuration/ set enable-welcome-root to false
<virtual-server name="default-host" enable-welcome-root="false">

Friday, April 11, 2014

UPS under Linux

The following steps are tested on Fedora 20, but generally should work on every other system with few modifications.

Step1. Install NUT


yum install nut*

Step2. Configure UPS

Execute
nut-scanner
It should output something like this:
[nutdev1]
driver = "blazer_usb"
port = "auto"
vendorid = "0001"
productid = "0000"
product = "STD UPS MON V1.0"
bus = "006"

Add the nut-scanner output to the end of /etc/ups/ups.conf file. You can change the [nutdev1] to something more meaningful e.g. [myUps1] or [InformGuardUPS]. In the examples bellow we will use the default name [nutdev1].

Change /etc/ups/upsd.conf and add "LISTEN 127.0.0.1 3493" (without quotes)

Change /etc/ups/upsd.users and add a new admin user

[admin]
password = mypassword
actions = SET
instcmds = ALL

Change /etc/ups/upsmon.conf and add following lines:

RUN_AS_USER root
MONITOR nutdev1@localhost 1 admin mypassword master


Step3. Manually test everything

upsdrvctl start
The command should output something similar to:
Network UPS Tools - Generic HID driver 0.34 (2.4.1)
USB communication driver 0.31
Using subdriver: MGE HID 1.12
Detected EATON - Ellipse MAX 1100 [ADKK22008]
If you face a problem like "libusb couldn't open usb device /dev/usb/XXXXXX: permission denied", then use google to find a way how to solve it nicely. I used very brutal method:
chmod -R 777 /dev/bus/usb/
Then try to start UPS driver again Start the upsd:
upsd
And the result should be similar to:
Network UPS Tools upsd 2.4.1
listening on 127.0.0.1 port 3493
listening on ::1 port 3493
Connected to UPS [eaton]: usbhid-ups-eaton
List your ups names with
upsc -L
Try to query the UPS status with.
upsc nutdev1@localhost
or just
upsc nutdev1
Depending on your UPS capabilities it should return various variables and their values. See http://www.networkupstools.org/docs/user-manual.chunked/apcs01.html for more details. If you want to check if is it working on battery right now execute
upsc nutdev1 ups.status
and the output should be OL (online) or OB (on battery), LB (low battery), etc. You can also play around with some of the UPS commands/settings
upscmd nutdev1 beeper.toggle

After that reboot the system (or stop all daemons)



Step4. Starts UPS daemons automatically

Execute following commands:
systemctl enable nut-server
systemctl start nut-server
systemctl enable nut-monitor.service
systemctl start nut-monitor.service
Restart the system, and if check if everything is ok, by executing the UPS status with upsc command. Now the UPS monitoring system is configured and in case of power loss, the computer will shutdown, when the UPS battery is low. If you don't want to shutdown the computer before the 'battery low' signal follow proceed with the step

Step5. Fine tuning

This step is optional, but gives you more control over the UPS events handling. If you want to trunoff the computer before the low battery signal, then use following steps:
1. Edit /etc/ups/upsmon.conf and add following lines:
NOTIFYCMD /usr/sbin/upssched
NOTIFYFLAG ONLINE     EXEC
NOTIFYFLAG ONBATT     EXEC
NOTIFYFLAG LOWBATT    EXEC
NOTIFYFLAG FSD        EXEC
NOTIFYFLAG COMMOK     EXEC
NOTIFYFLAG COMMBAD    EXEC
NOTIFYFLAG SHUTDOWN   EXEC
NOTIFYFLAG REPLBATT   EXEC
NOTIFYFLAG NOCOMM     EXEC
NOTIFYFLAG NOPARENT   EXEC
2. Edit /etc/ups/upssched.conf and add following lines (it will allow you shutdown the computer after 15 seconds, after working on battery)
PIPEFN /var/run/nut/upssched.pipe
LOCKFN /var/run/nut/upssched.pipe
AT ONBATT * START-TIMER executeShutdown 15
AT ONLINE * CANCEL-TIMER executeShutdown
AT ONBATT * EXECUTE onBattery
AT ONLINE * EXECUTE onLine
AT NOCOMM * EXECUTE noComm
AT COMMBAD * EXECUTE commBad
AT COMMOK * EXECUTE commOk
3. Edit /usr/bin/upssched-cmd (see the exact file name from /usr/bin/upssched-cmd variable CMDSCRIPT) and add executeShutdown section similar to:
case $1 in
        upsgone)
                logger -t upssched-cmd "The UPS has been gone for awhile"
                ;;
        executeShutdown)
                shutdown -h now
                ;;
        onBattery)
                logger -t upssched-cmd "UPS is on battery!"
                ;;
        onLine)
                logger -t upssched-cmd "UPS is back online!"
                ;;
        noComm)
                logger -t upssched-cmd "No communication with the UPS device"
                ;;
        commBad)
                logger -t upssched-cmd "Communication with UPS device lost"
                ;;
        commOk)
                logger -t upssched-cmd "Communication with UPS device restored"
                ;;
        *)
                logger -t upssched-cmd "Unrecognized command: $1"
                ;;
esac

Tuesday, April 08, 2014

PermGen space leaks

The causes of PermGen space leaks:
  1. Thread left running after web-app undeployment - the context class loader of the thread is usually the class loader of the web application, so it contains all webapp classes.
  2. Using ThreadLocal with thread created by the web server - web app class is assigned to web server thread (e.g. HTTP worker thread) - the web app class holds a reference to the classloader, even if the web app is undeployed.
  3. Database driver leak - every database driver should register in  java.sql.DriverManager
    the web-app must deregister it from the there, otherwise it hold a reference to the web-app class loader, if the web app is undeploye