Monthly Archives: March 2017


Just some notes for setting up a new OS to develop projects on GNU/Linux Fedora

If the project is in C++ and uses mysql then install

sudo dnf install mysql++-devel;

If the project is in C/C++ and you are missing talloc.h install

sudo dnf install libtalloc-devel;

Set your name and email for all git projects

git config --global --edit
Then fill-in the configuration file similar to below
# This is Git's per-user configuration file.
[user]
# Please adapt and uncomment the following lines:
#       name = Michael, George
#       email = [email protected]
[user]
        name = Michael, George
        email = [email protected]
[gui]
        editor = gedit

or use these individual commands to set the configuration

[[email protected] ~]$ git config --global user.name "Michael, George"
[[email protected] ~]$ git config --global user.email "[email protected]"

Increase amount of inotify watchers

If you are using CLion or IntelliJ IDEA by jetbrains increase the amount of inotify watchers.
CLion, IntelliJ (and other tools of jetbrains) use inotify on GNU/Linux to monitor directories for changes. It’s common to encounter the system limit on the number of files they monitor.

inotify requires a watch handle to be set for each directory in the project. Unfortunately, the default limit of watch handles will not be enough for sized projects, and reaching the limit will force the jetbrains platform to fall back to recursive scans of directory trees.

Create a file (as root) called /etc/sysctl.d/idea.conf and add the following content to it to increase the number of watchers to 512K

fs.inotify.max_user_watches = 524288

Then call sysctl to reload the settings and apply the new configuration

[[email protected] ~]$ sudo sysctl -p --system;
  •  -p[FILE] or --load[=FILE]: Load in sysctl settings from the file  specified  or /etc/sysctl.conf if none  given.
    Specifying - as filename means reading data from standard input. Using this option will mean arguments to sysctl are files, which are read in the order they are specified.
    The file argument may be specified as regular expression.
  •  --system: Load settings from all system configuration files.
     /run/sysctl.d/*.conf
     /etc/sysctl.d/*.conf
     /usr/local/lib/sysctl.d/*.conf
     /usr/lib/sysctl.d/*.conf
     /lib/sysctl.d/*.conf
     /etc/sysctl.conf

How to “pause” (suspend) an active process

Recently, we were executing the following time-wasting application and we wanted to pause it somehow and release the CPU that was being used temporarily for other tasks.
Unfortunately, the process was not executing on an active console, so we could not press CTRL+Z and suspend it.
Conveniently, the kill command provides us with the suspend functionality as long as we know the PID of the process to be suspended.

Using ps x, we found the PID of the application even though it was not attached to an active console.

Then to suspend the application, we used

kill -TSTP "$PID";

which instructed the process to stop by sending it the SIGTSTP signal.

Fortunately, our application did not block the signal and it was suspended.

Note: In case an application ignores the SIGTSTP signal, you can still force it to suspend by sending it the SIGSTOP signal as follows

kill -STOP "$PID";

After we were done, we resumed the execution of the process by sending the SIGCONT signal to it

kill -CONT "$PID";

 


git: How to move locally committed (but not pushed) changes to a new branch

Recently, we’ve been working on a certain branch, we did some changes and performed a couple of commits that were not pushed on the remote system.

There was a complication and it was decided that the local changes should not be pushed to the branch that we were working on.
Rather, they changes should go to a new branch which eventually will be merged.

As mentioned above, we already had done some changes and we already had performed the commits.

git status would give us the following:

$ git status;
On branch scanner_pdu_parser_master
Your branch is ahead of 'origin/scanner_pdu_parser_master' by 2 commits.
  (use "git push" to publish your local commits)

So, we needed to change the branch for those local commits.

Solution – Move the local commits to a new branch

First we got the name of the current branch using the command:

git branch;

Then, we switched to a new local branch

git checkout -b banana_peeler;

And, we pushed the local branch to the remote system:

git push --set-upstream origin banana_peeler;

Afterwards, we switched back to the previous branch

git checkout apple_peeler;

And reset it back to its original form, removing our local commits from it:

git reset --hard origin/apple_peeler;

Please note that the last command will delete all changes that are not committed as well.
In other words, any file you modified and did not commit or push, they will be reverted back to the original code as well.


Using aliases for SSH

An extremely helpful feature of ssh is the ability to define aliases using its configuration files:

  • ~/.ssh/config
  • /etc/ssh/ssh_config

~/.ssh/config contains configuration that is only available to your user and any user can create one for themselves.
/etc/ssh/ssh_config contains configuration that applies to all users of the system and only administrators can modify it.

Note: ~/.ssh/config should only have read and write access rights by its owner only!
Be sure to execute the following after your create it:

chmod 600 ~/.ssh/config;

Example 1 – Creating an alias for a host name:

Assuming we are too bored to type the full domain of a server, we can define a shorter name as follows:

Host bf
    HostName bytefreaks.net

by having this configuration lines in your ~/.ssh/config file, you can shorten the command ssh bytefreaks.net; to ssh bf;.

Example 2 – Creating an alias for a host name with specific username:

In the next example, we create a new alias that not only will automatically set the host name but also the username

Host bf
    HostName bytefreaks.net
    User george

by having this configuration lines in your ~/.ssh/config file, you shorten the command ssh [email protected]; to ssh bf;.

Example 3 – Creating an alias for a host name with specific username and port:

In the next example, we create a new alias for a specific host name, username and ssh port number

Host bf
    HostName bytefreaks.net
    User george
    Port 22300

The above will shorten ssh [email protected] -p 22300 to ssh bf;.

Example 4 – Creating an alias for a host name with specific username and identity file:

Host bf
    HostName bytefreaks.net
    User george
    IdentityFile /path/to/needed/private/key/id_rsa

The above will shorten ssh [email protected] -i /path/to/needed/private/key/id_rsa; to ssh bf;

For more information on the capabilities of the configuration files, please review the following documentation page as it has a whole lot more of useful information: http://man.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man5/ssh_config.5

Repeated note: ~/.ssh/config should only have read and write access rights by its owner only!
Be sure to execute the following after your create it:

chmod 600 ~/.ssh/config;

C: Code to time execution with accuracy greater than a second

The following application computes the time needed for a process to finish using the method clock().
The result of the application is the time in seconds as a floating number (where 1.0 = 1 second).
It provides greater accuracy than seconds as the estimation is done using processor time used by the program.

#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <limits.h>

int main()
{

    /* clock_t clock(void)
     The clock() function returns an approximation of processor time used by the program.
     The value returned is the CPU time used so far as a clock_t,
     to get the number of seconds used, divide by CLOCKS_PER_SEC.
     On error it returns -1. */
    const clock_t start = clock();

    /* svoid srand(unsigned int __seed)
     The srand() function sets its argument as the seed for a new sequence of pseudo-random
     integers to be returned by rand(). These sequences are repeatable by calling srand() with the
     same seed value.
     If no seed value is provided, the rand() function is automatically seeded with a value of 1. */
    /* time_t time(time_t *__timer)
     time() returns the time since the Epoch (00:00:00 UTC, January 1, 1970), measured in seconds.
     If the __timer variable is not NULL, the return value is also stored there. */
    srand(time(NULL));
    unsigned long i;
    for (i = 0; i < 10000000; i++)
    {
        /* int rand(void)
         The rand() function returns a pseudo-random integer in the range 0 to RAND_MAX inclusive. */
        rand();
    }
    const clock_t end = clock();

    /* ISO/IEC 9899:1999 7.23.1: Components of time
    The macro `CLOCKS_PER_SEC' is an expression with type `clock_t' that is
    the number per second of the value returned by the `clock' function. */
    /* CAE XSH, Issue 4, Version 2: <time.h>
    The value of CLOCKS_PER_SEC is required to be 1 million on all
    XSI-conformant systems. */
    const float seconds = (float) (end - start) / CLOCKS_PER_SEC;

    printf("Seconds elapsed %f\n", seconds);
    return 0;
}

Make building with cmake verbose

Ever wanted to get more information out of a build process controlled by CMake?
We sure did and this is how we did it:

Option 1 – Change your CMakeLists.txt files

As our first option, we present updating your CMakeLists.txt file to include the following configuration line:

set(CMAKE_VERBOSE_MAKEFILE ON)

This option by itself is enough to enable verbosity.
A caveat with this option is that the configuration is not passed on to other CMakeLists.txt files that are included to the build using the command add_subdirectory () from the master CMakeLists.txt file.
Thus, you need to copy the configuration file to each CMakeLists.txt file you want to be verbose.

Option 2 – Add the variable VERBOSE=1 to your make command

Assuming you are using a terminal and you are in the folder where you want to build your project.
After you execute the command

cmake $path_to_project_source;

execute your make command using the VERBOSE=1 variable as follows

make VERBOSE=1;

The caveat of this solution is that EVERYTHING becomes verbose, so you could have too many output data.

Option 3 – Add the variable -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON to your cmake command

Adding the option -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON to the cmake command, it will enable verbosity on all generated Makefiles permanently.
So, assuming you are in the folder where you want to make the build, execute the following to generate the Makefiles:

cmake -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON $path_to_project_source;

and then just issue make to perform the build with verbose output.
Please note, you cannot disable verbose output using make VERBOSE=0 after you enable it through cmake, you need to execute the cmake command again without the -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON option.

Bonus

To remove the ‘building’ and ‘linking’ lines from the output

e.g.

[ 10%] Building C object libs/segmentation/CMakeFiles/segments.dir/list_helpers.c.o
and
[ 30%] Linking C static library libsegments.a

add the option -DCMAKE_RULE_MESSAGES:BOOL=OFF to your cmake command to disable them.
e.g.

cmake -DCMAKE_RULE_MESSAGES:BOOL=OFF $path_to_project_source;

To remove the ‘Entering directory’ and ‘Leaving directory’ lines from the output

e.g.

make[2]: Leaving directory '/home/george/Projects/3rd Party/segments222bit/cmake-build-debug'
and
make[2]: Entering directory '/home/george/Projects/3rd Party/segments222bit/cmake-build-debug'

add the option --no-print-directory to your make command to disable them.
e.g.

make --no-print-directory;

Ubuntu server 16.04+ MySQL port is only accessible from localhost (127.0.0.1)

Recently, we got access to an Ubuntu 16.04 LTS server that had MySQL server installed on it but was not accessible to our external servers.
The service was accessible when testing from localhost but it was not when testing from any other machine.
Executing nmap from another machine would return the value 3306/tcp closed mysql   conn-refused as below.

[[email protected] ~]$ nmap -vv -p 3306 192.168.10.11


 
 Starting Nmap 7.40 ( https://nmap.org ) at 2017-03-06 17:21 EET
 Initiating Ping Scan at 17:21
 Scanning 192.168.10.11 [2 ports]
 Completed Ping Scan at 17:21, 0.06s elapsed (1 total hosts)
 Initiating Parallel DNS resolution of 1 host. at 17:21
 Completed Parallel DNS resolution of 1 host. at 17:21, 0.00s elapsed
 Initiating Connect Scan at 17:21
 Scanning 192.168.10.11 [1 port]
 Completed Connect Scan at 17:21, 0.06s elapsed (1 total ports)
 Nmap scan report for 46.101.137.70
 Host is up, received syn-ack (0.061s latency).
 Scanned at 2017-03-06 17:21:31 EET for 1s
 PORT     STATE  SERVICE REASON
 3306/tcp closed mysql   conn-refused
 
 Read data files from: /usr/bin/../share/nmap
 Nmap done: 1 IP address (1 host up) scanned in 0.16 seconds

The problem was with the default configuration of mysqld that is found in the file /etc/mysql/mysql.conf.d/mysqld.cnf.
At line 41 we got the following snippet:

# Instead of skip-networking the default is now to listen only on
# localhost which is more compatible and is not less secure.
bind-address            = 127.0.0.1

What the line bind-address            = 127.0.0.1 says is that, the service will only listen on localhost.
At this stage there are two solutions that you can apply using your favorite text editor (e.g. sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf):

Solution A:

Completely remove the line bind-address            = 127.0.0.1 or comment it out by adding a # in front of it as follows #bind-address            = 127.0.0.1.

Solution B:

Replace 127.0.0.1 with the IP that you want mysql service to be available to. In our case the line became bind-address            = 192.168.10.11.

After you are done with the change, you need to restart the service for the change to take place:

[email protected]:~$ sudo /etc/init.d/mysql restart
 [ ok ] Restarting mysql (via systemctl): mysql.service.

From an external machine you can verify that the configuration was applied correctly using nmap as below:

[[email protected] ~]$ nmap -vv -p 3306 192.168.10.11
 Starting Nmap 7.40 ( https://nmap.org ) at 2017-03-06 17:24 EET
 Initiating Ping Scan at 17:24
 Scanning 192.168.10.11 [2 ports]
 Completed Ping Scan at 17:24, 0.06s elapsed (1 total hosts)
 Initiating Parallel DNS resolution of 1 host. at 17:24
 Completed Parallel DNS resolution of 1 host. at 17:24, 0.00s elapsed
 Initiating Connect Scan at 17:24
 Scanning 192.168.10.11 [1 port]
 Discovered open port 3306/tcp on 46.101.137.70
 Completed Connect Scan at 17:24, 0.06s elapsed (1 total ports)
 Nmap scan report for 46.101.137.70
 Host is up, received syn-ack (0.061s latency).
 Scanned at 2017-03-06 17:24:30 EET for 0s
 PORT     STATE SERVICE REASON
 3306/tcp open  mysql   syn-ack
 Read data files from: /usr/bin/../share/nmap
 Nmap done: 1 IP address (1 host up) scanned in 0.16 seconds

You should get the value 3306/tcp open  mysql   syn-ack.


CentOS: prevent eth0 from starting at boot time

On a CentOS server we own, we had to disable eth0 from starting at boot time
To do so we needed to modify the file /etc/sysconfig/network-scripts/ifcfg-eth0 and set the value ONBOOT="yes" to ONBOOT="no".

Using you favorite text editor, make this change and restart your machine to verify that the change was successful.

Below is the sample content of /etc/sysconfig/network-scripts/ifcfg-eth0 after the change was applied to prevent eth0 from starting at boot time.

  GNU nano 2.3.1                File: /etc/sysconfig/network-scripts/ifcfg-eth0                             Modified

TYPE="Ethernet"
 BOOTPROTO=dhcp
 DEFROUTE="yes"
 IPV4_FAILURE_FATAL="no"
 IPV6INIT="yes"
 IPV6_AUTOCONF="yes"
 IPV6_DEFROUTE="yes"
 IPV6_FAILURE_FATAL="no"
 NAME="eth0"
 UUID="792d6842-221d-5c99-ba98-cddbba4ff263"
 ONBOOT="no"
 HWADDR="00:AA:5D:01:22:2B"
 DNS1="10.15.10.5"
 DOMAIN="bytefreaks.local"
 IPADDR=10.15.10.249
 PREFIX=24
 GATEWAY=10.15.10.1
 PEERDNS=yes
 PEERROUTES=yes
 IPV6_PEERDNS=yes
 IPV6_PEERROUTES=yes

How to use git features on a local project without a Git server

Like many of you, sometimes we develop code that does not belong to a Git server.
Working as so, one would think that we would miss all the features of a Version Control System (VCS).
Fortunately, this assumption is wrong.
Using the already installed Git tools, we can create a new local repository in any system folder with no additional configuration.

To do so, and create a new repository from an existing project, we need to do the following using a terminal/shell:

  1. Navigate into the directory that contains the project e.g. cd /home/bytefreaks/Projects/Party/banana/
  2. Type git init
    This command will create an empty Git repository in that folder and it will produce a message as follows:
    Initialized empty Git repository in /home/bytefreaks/Projects/Party/banana/.git/
  3. In case you have files that should not be included in your repository, it is better that you create a .gitignore file and add them there.
    This way you will be able to indicate all of the files that you don’t want to the repository to track.
  4. Use git add . (please note that you need the dot . for this command)
    This command will stage all files that are not in .gitignore to be part of your next commit.
  5. Finally, type git commit or git commit -m "Initial Commit with status bla bla", to make your first commit to the repository
  6. Profit!

By now, you should have a fully functional local git repository without the assistance of an external server.


Send ALT+CTRL+Delete to QEMU virtual machine

Recently we wanted to start a Windows virtual machine from a physical hard disk using a Fedora w/ GNOME 3 host machine to change the domain password of a user.
To do so, we used QEMU, QEMU is a generic and open source machine emulator and virtualizer.

To perform the password change, we needed to sent the ALT+CTRL+Delete key combination to the virtual machine to access the system screen and then change the user password.
Pressing ALT+CTRL+Delete on the Fedora/GNOME 3 host machine, it popped up a prompt to shut down the host machine instead of sending the key combination to the active window of the VM. Apparently, we could not sent the key combination directly to the VM and had to find a way around it.

Solution:

We pressed ALT+CTRL+2 while the QEMU window was selected/active to switch to the QEMU terminal/monitor.
In the blank screen that appeared, we typed sendkey alt-ctrl-delete and pressed the Enter key.
This action sent to the virtual machine OS the key combination ALT+CTRL+Delete.
Finally, to switch back  to the guest screen we pressed ALT+CTRL+1.