I had to update an already unsupported Postgresql instance running on version 9.3 to the latest version 11. Luckily, this process is quite straightforward and all the hard lifting is done by the postgresql update tool.

The only problem there was that the database in question had bloated over the years to such an extent that it was not possible to have two separate data directories for both versions, 9.3 and 11, which is the normal way to go about this – you install the newer version, run pg_upgrade tool against the old data directory and it takes the data, converts them to the new format and saves them in a new directory of the newly installed postgresql version. This is usually more safe as you can go back to the older postgresql version if something went wrong; the old data directory is till intact. If that’s not possible, however, because you don’t have enough space on your system, you can use –link parameter that makes pg_upgrade tool reclaim the old directory as its own.

Here are the steps that I had to take:

  1. enable repository with the new version, as I was on Centos, I followed the instructions from here https://yum.postgresql.org/
  2. install new packages
    yum install postgresql11 postgresql11-contrib postgresql11-devel postgresql11-libs postgresql11-server
  3. stop and disable the older version service
  4. initialize the new data directory, note that you need to do this as postgres user:
    /usr/pgsql-11/bin/initdb -D /var/lib/pgsql/11/data"
  5. check consistency between the two versions (again, as postgres user):
    /usr/pgsql-11/bin/pg_upgrade --old-bindir=/usr/pgsql-9.3/bin/ --new-bindir=/usr/pgsql-11/bin/ --old-datadir=/var/lib/pgsql/9.3/data/ --new-datadir=/var/lib/pgsql/11/data/ --check
  6. and finally run the upgrade itself (again, as postgres user):
    /usr/pgsql-11/bin/pg_upgrade --old-bindir=/usr/pgsql-9.3/bin/ --new-bindir=/usr/pgsql-11/bin/ --old-datadir=/var/lib/pgsql/9.3/data/ --new-datadir=/var/lib/pgsql/11/data/ --link
  7. run analyze and delete scripts

Needless to say, it’s a very good idea to backup your database before the upgrade and and to have an emergency plan in case things go wrong.

Tagged with: , ,

Beta version of Red Hat Enterprise Linux 8.0 was announced recently. It can be downloaded without any registration, or you can go through the Developers Program and get a subscription for development usage for free.

I downloaded the ISO this way and here go a few screenshots from my installation in a KVM environment:

Tagged with: , , ,

Note: I wrote this post during Christmas break 2017, but it took me some time before I managed to give it a better form, verify the steps again and publish it. Hence some Xmas references in a text published during summer time.

Xmas break is, as usually, just about the right time to either play some really old-school RPG, or to finally get on with some “fun” tasks that you’d been postponing for as much as you could. This year, one such task on my plate was to finally get rid of an old Centos 5 machine with OpenLDAP server where I kept an address book and accounts of my mail server.

For some tasks, it’s never the right time. Like this upgrade of old Centos 5 machine with OpenLDAP 2.3 to Centos 7 and newer version of OpenLDAP, which already stores configuration information in separate files in /etc/openldap/slapd.d, instead of /etc/openldap/slapd.conf as it was the case before. So, despite me postponing this “fun” as much as I could, I finally had to upgrade this old machine of mine.

This is how I went about it. I had a brand new installation of Centos 7 where I installed the server and client packages as the first step:

yum install openldap-servers openldap-clients openldap

Next, I used slappasswd to generate a hashed copy of some generated password.


This tool will print the hashed password into standard output. I copy pasted it and used it in this step1.ldif file. Since it’s not recommended to edit OpenLDAP config files directly any more, ldif files are the way to perform config updates now. The below referenced step1.ldif file performs an update of ldap root password.


vim step1.ldif
systemctl start slapd.service
ldapadd -Y EXTERNAL -H ldapi:/// -f step1.ldif

Having added root ldap password, I now created a new database based on a sample config file:

cp /usr/share/openldap-servers/DB_CONFIG.example /var/lib/ldap/DB_CONFIG
chown ldap. /var/lib/ldap/DB_CONFIG
systemctl restart slapd.service

and then added schemas that I was interested in:

ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/cosine.ldif
ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/nis.ldif
ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/inetorgperson.ldif

That done, I could proceed to set up the same structure and data as it was the case on my old Centos 5 LDAP server, starting with creating manager role using this step2.ldif file (example.com used as an example domain here):


vim step2.ldif
ldapmodify -Y EXTERNAL -H ldapi:/// -f step2.ldif

Now, with manager role added, I could add the structure of People organization using this step3.ldif file:


vim step3.ldif
ldapadd -x -D cn=Manager,dc=example,dc=com -W -f step3.ldif

That was it as far as structure was concerned. Now I only had to import the actual data from an ldif dump coming from my old ldap server. The dump of people in database looked a bit like this skeleton file people.ldif (some data like password hashes was removed on purpose, this is just to give you an idea):


When I tried to import it, however, openldap wouldn’t import the data. I had to get rid of some fields that couldn’t be imported as they are generated anew:

cat people.ldif | grep -v "entryCSN\|entryUUID\|structuralObjectClass\|creatorsName\|createTimestamp\|modifiersName\|modifyTimestamp" > people_updated.ldif

With this new file people_updated.ldif, I was able to import my old data into new directory without any further issues:


ldapadd -x -D cn=Manager,dc=example,dc=com -W -f people_updated.ldif

Verified by successfully performing a query against that new directory:

ldapsearch -h server_hostname_or_ip -D "cn=Manager,dc=example,dc=com" -W -b "uid=john,ou=People,dc=example,dc=com"

I home this might come handy to someone who gets stuck on such a “fun” task as I did.


Tagged with: , ,

For quite some time, I used to have a low-end motherboard that didn’t support Wake on LAN. So when I left for work or holiday, I would usually leave my home PC on, because sometimes I just needed to access it. Now, with a second-hand, but still significantly newer motherboard I got from my brother, I could finally set up WOL and wake the PC up remotely from a Raspberry that is also running at my place – but Raspberry doesn’t consume so much electricity. As it’s often the case, Debian documentation works for the current stable, while I have buster/testing on my PC at the moment and I had to search for how to to that for a bit. Luckily, I was able to find information elsewhere.

Having enabled the feature in BIOS (it was called “Power On by PME” instead WOL), I had to enable it on the operating system level as well. To make the change permanent, I added this file:

# cat /etc/systemd/network/50-wired.link 

Then, from my rpi, I could just

wakeonlan MAC_ADDRESS

and it worked.

Tagged with: , ,

This is a PC that belongs to my brother in law. He hasn’t been using it for over a year, ever since he switched to Mac, so he’d like to get rid of it. It has i5 (Sandy bridge) inside – not an high-end machine any more, but it can still serve as a decent workstation. I’m considering using it as my second PC, but maybe it will just go to ebay. Either way, it deserved some proper cleaning after years of service, because whatever you do, some places inside which are not easy to reach tend to collect dust over time. So:

  1. Take everything out, motherboard, chassis fans, all of it.
  2. You can see that places that are normally difficult to reach collect lots of dust.
  3. Clean everything, including careful cleaning of fan blades and such.
  4. Assemble everything back together.

So this is my weekend hobby. As good as new.

Tagged with:

I installed Centos 7 on a brand new machine about a half a year ago, and set up KVM with two data pools – one just a regular directory for old raw images, the second being an LVM volume group. Later, I added one additional physical disk to the machine, for local backups, which turned out to be an important detail later.

Nowadays I wanted to start a new virtual machine but to my surprise, the data pool based on LVM volume group ‘vg2’ wasn’t active:

# virsh pool-list
Name State Autostart 
backups active yes 
vg2 inactive yes

The LVM itself seemed to be working just fine, as well as the one virtual machine which was already residing in a logical volume in this particular data pool. But the data pool would not get activated, no matter if I tried from virsh:

unsupported configuration: cannot find any matching source devices for logical volume group 'vg2'

or from virt-manager:

Error starting pool 'vg2': unsupported configuration: cannot find any
matching source devices for logical volume group 'vg2'

Eventually, it turned out that when I had added the physical disk for backups into the machine back then, this new disk got /dev/sda assigned while the original old disk got /dev/sdb as the device name. LVM was able to cope with the change, but libvirt remembered the original value:

# virsh pool-dumpxml vg2
<pool type='logical'>
 <capacity unit='bytes'>1351803207680</capacity>
 <allocation unit='bytes'>461373440000</allocation>
 <available unit='bytes'>890429767680</available>
 <device path='/dev/sda7'/>
 <format type='lvm2'/>

Luckily for me, I was not the first one to run into this issue, so it was an easy fix:

 <device path='/dev/sdb7'/>

After changing the device path to the correct device name, data pool was able to start again. In the referenced bug ticket, it was stated that removing the device path altogether works just as well and might actually be a better option because device path is only needed when storage pool is being defined for the first time.

Tagged with: , ,

I’ve run across this peculiar problem. I was trying to set up IPv6 on a Centos 6 machine. I thought that it would be a simple task – a couple of minutes at most – as I had done that on other Centos 6 machines before. But I was wrong.

My initial configuration steps were:

# cat /etc/sysconfig/network | grep IPV6
# cat /etc/sysconfig/network-scripts/ifcfg-eth0
NAME="System eth0"

Take note of the two (obfuscated) IP addresses, the machine IP address 2a01:xxxx:xxxx:xxxx::1 is in a different subnet than the IP address 2a01:xxxx:xxxx:yyyy::1 of the default gateway given to me by the ISP.

On other machines I had configured in the past, IPV6_DEFAULTGW was 2a01:xxxx:xxxx::1, in other words – my own machine’s IP address 2a01:xxxx:xxxx:xxxx::1 was in a subnet that was a part of the bigger 2a01:xxxx:xxxx:: subnet in which the ISP’s gateway machine was located. In those cases, IPv6 worked without any problems when I used the above mentioned simple configuration. But here, it didn’t work, I was getting the following warning and wasn’t able to connect/ping anywhere:

WARN : [ipv6_add_route] 'No route to host' adding route '::/0' via gateway '2a01:xxxx:xxxx:yyyy::1'

I tried specifying the interface, like this:


but that didn’t help either.

Eventually, I got an advice from a friend who’s far more IPv6 savvy than I am. I had thought that it was not possible to have default gateway in a completely different subnet and that this was the reason why I was running into this problem, but I was told that IPv6, unlike IPv4, did actually allow for a gateway to be in a different subnet, but in those cases, addtional network script has to be configured like this:

# cat /etc/sysconfig/network-scripts/route6-eth0 
2a01:xxxx:xxxx:yyyy::1 dev eth0
default via 2a01:xxxx:xxxx:yyyy::1

Having set the gateway this way, I had to remove it from the interface configuration file, of course:

# cat /etc/sysconfig/network-scripts/ifcfg-eth0

After restarting network, this machine was finally IPv6 ready.

Tagged with: ,

I got Raspberry Pi 2 as a present from my brother. It’s a nice toy, I was trying out OpenELEC, it makes for a really nice home theater in combination with a NAS on local network. The only drawback was that the analog sound output produced kind of unpleasant noise. I tried to follow a lot of pieces of advice found around on forums, changed the operating system, drivers, nothing helped. It seemed that the noise was a design problem of the analog sound (the digital sound output was all right).

In the end, I installed Raspbian and started using this Pi as a “thin client” to connect to other computers using X2Go remote sessions. It was a nice use case, but I didn’t need it so often as to actually miss sound. Eventually, I was advised to use an external sound card. A small, $10 USB card did the trick. The noise was gone and now, when using Raspberry as a thin client, I’m able to listen to music on it, too.

Tagged with: , , , ,

images-duckduckgo-comSpending a lot of time with mouse and keyboard, I decided I would give it a try with trackball. A friend lent me Logitech Trackman Marble for a week to see if I can get used to it. The one drawback in Linux is that there’s no support for scroll emulation by default. It was relatively easy to set this up on my laptop with help of xinput, but at home, where I’m using Debian 9 (currently ‘testing’ branch) with Mate, this didn’t work. So this had to go to a good old X.Org configuration file:

# cat /usr/share/X11/xorg.conf.d/50-trackball.conf 
Section "InputClass"
    Identifier  "Marble Mouse"
    MatchProduct "Logitech USB Trackball"
    MatchIsPointer "on"
    MatchDevicePath "/dev/input/event*"
    Driver "evdev"
    Option "ButtonMapping" "1 2 3 4 5 6 7 8 9"
    Option "EmulateWheel" "true"
    Option "EmulateWheelButton" "8"
    Option "ZAxisMapping" "4 5"
    Option "XAxisMapping" "6 7"
    Option "Emulate3Buttons" "true"
    Option "EmulateWheelInertia" "10"
# cat /etc/debian_version 

By the way, after two days of using it, I think I’m getting used to it, so I’ll probably buy one for myself.

9 February 2018 update:
As Debian testing keeps rolling on and on, the above mentioned stopped worked for me, and had to be replaced by the following (obviously, there has been a driver change):

#cat /etc/debian_version 
# cat /usr/share/X11/xorg.conf.d/50-trackball.conf 
Section "InputClass"
        Identifier      "Marble Mouse"
        MatchProduct    "Logitech USB Trackball"
        Driver          "libinput"
        Option          "ScrollMethod" "button"
        Option          "ScrollButton" "8"
	Option		"MiddleEmulation" "on"
Tagged with: , , ,

images.duckduckgo.comI’ve had this mail server of mine for some time. I was an early adopter of Gmail back then, but as years went on and it became obvious that messages were data-mined by Gmail, I eventually started running my own Postfix server. Not just for me, but for family and eventually other people. Now, the thing is that some folks insist on having their emails forwarded to another service, like Gmail, Yahoo, etc. I can understand that. The problem is that if such mailbox receives a lot of spam messages, those messages get forwarded to Gmail and Yahoo as well, and as a result, my mail server can get bad reputation because of that – I can’t just explain to the other side that those spams are only forwarded.

I’m using Spamassassin to mark spam, but all it can do is to mark the messages for users’ MUAs, it can’t do anything else, like drop or reject unsolicited bulk email so that it doesn’t get forwarded. I’ve used Amavis somewhere in the past and it could have solved the problém here, too, but here it felt as too large a gun for the task. All I wanted was to prevent the most obvious spam with high score points from being forwarded. So I created a file with a regular expression to catch all messages marked as Spamassassin with help of X-Spam-Level header.

#cat /etc/postfix/header_checks
/^X-Spam-Level: \*\*\*\*\*\*\*.*/ HOLD custom spam rule

and uncommented this line in:

#grep header_checks /etc/postfix/main.cf
header_checks = regexp:/etc/postfix/header_checks

The above mentioned HOLD action will put the messages into the hold queue for further inspection. Other option is to REJECT the messages (more here external_link).

To my dismay, it just didn’t work when I gave it a try with help of Gtube. What I didn’t realize was that header_checks happen while message is being received. Spamassassin, however, works as a milter that adds extra headers later, so it couldn’t work. There is a Postfix feature designed to solve this problem – milter_header_checks – which does the same thing, except it takes headers added by milters into account, too. The only tiny drawback was that this feature was added to Postfix 2.7 and my Centos 6 had Postfix 2.6 running. There was a patch on Postfix page which backported milter_header_checks into version 2.6, but I just didn’t have enough courage to go for it. Instead I used the workaround discussed here external_link (many thanks). The trick is to create another service in master.cf and use it as a content filter for the main smtp service. That way, the Spamassassin headers get applied and on the second run, they get noticed by header_checks.

smtp      inet  n       -       n       -       -       smtpd
  -o content_filter=smtp: inet  n -       n       -       -       smtpd
  -o content_filter=

I also had to add permit_mynetworks in recipient restrictions, but that was probably relevant just to my particular setup.

smtpd_recipient_restrictions = permit_mynetworks, 

After the postfix reload, the spam messages with score higher than defined in /etc/postfix/header_checks finally got caught and stopped.

Update 21. 2. 2017:

There was one unintended side effect with the above mentioned solution – all forwarded emails were duplicated and arrived into the final mailbox twice. When there was forwarding set in the aliases file, the rule got applied on both smtpd service, the external one, as well as the internal one, where the header_checks happened. So this behaviour had to be suppressed using receive_override_options=no_address_mappings option to prevent this unintended duplication:

smtp      inet  n       -       n       -       -       smtpd
  -o content_filter=smtp:
  -o receive_override_options=no_address_mappings inet  n -       n       -       -       smtpd
  -o content_filter=
Tagged with: , ,