Linux Distros That Suck at Multiple Hard Drives

Some Linux distros really suck at dealing with multiple hard drives. Too many “maintainers” only have a laptop.


You need a wee bit of background before we jump in. Hopefully you can see the featured image. Recently picked up this Lenovo M93p ThinkCentre from eBay. I specifically bought an M93p instead of M83 because I wanted two hard drives. I had a 480 GB SSD I wanted to transfer the Windows 10 over to and I had a 6TB Western Digital Black I wanted to use for the other operating systems.

Why did I buy this particular M93p?

Lenovo M93p Ports

I actually added the PS/2 ports today. The little cable showed up to do that. It already had both serial ports, wifi, and the NVIDIA add-on video card. If your eyes are real good you will notice that on the other side of that Wifi antenna is a parallel port.

Software engineers need a lot of ports. If book sales start picking up I may even have to break down and buy another dot matrix printer to print shipping labels with. Yes, parallel port dot matrix printers are still made. You can buy them from today. There are lots of legal requirements to print with impact printers on multi-part forms in various shipping and transport industries. They also do a more economic and reliable job on mailing labels . . . if you buy the right one . . . and you have the proper printer stand.

Printer stand back

The best ones from days of old have both a center feed slot and a rear feed slot to accommodate either type of printer. Long time readers of this blog will remember I started work on a Qt and USB series and then life got in the way. That was all USB serial ports talking to real serial ports. My Raspberry Qt series also involved quite a bit of serial port work. My How Far We’ve Come series also involved quite a bit of serial port stuff as well.

Putting it mildly, I still do a fair bit of serial port work from time to time. If I get done with RedDiamond and RedBug without life getting in the way I’m going to start a new post series using CopperSpice and serial ports. The makers of Qt have honked off their installed base with the new “subscription licensing” for Qt 6.x and beyond. Even more honkable, if that is possible, is the chatter that they are trying to license the OpenSource QtCreator as well. Yeah, people are making a hasty exit from the Qt world and many are headed to CopperSpice.

Sadly Needed Windows

Unlike every other machine in this office, I needed to have Windows on this machine. There is some stuff coming up that will require it. There is no way in Hell I was going to try writing my serial port code using Linux in a VM. I may edit it there, but testing is a completely different story.

You’ve never spent days trying to track down why some characters don’t get through. Worse yet, the serial port just “stops working.” After you do a bunch of digging you find that someone baked in some super secret control strings to do special things in the interface driver of the VM. Nothing nefarious. Usually to support “remoting in” via cable connection.

Boot Managers

In the days of DOS and GUI DOS that Microsoft insisted on calling Windows, this was no big deal. BootMagic and about a dozen other competitors existed to help Noobies and seasoned pros alike install multiple operating systems onto the same computer. Honestly, I can’t even remember all of the different products that had a brief life helping with this very task.

OS/2 had Boot Manager backed in. Those of us needing to develop for multiple operating systems usually ran OS/2 as our primary. It just made life so much easier.

Early floppy based Linux distributions came with Lilo. It was generally pretty good at realizing Linux wasn’t going to be on the primary disk. SCSI controllers could support six drives and distributions were different enough you had to boot and build on each.


Later many distros went with Grub. To this day Grub has issues. The biggest issue is that each Linux distro adopts new versions of Grub at their own pace and Grub has a bit of history when it comes to releasing incompatible versions.

Adding insult to injury is the fact many Linux distros like to hide files Grub needs in different places. When you run your distros version of “update-grub” (as it is called in Ubuntu) it has to be a real good guesser when it wants to add a Grub menu line for a different distro.

Your second fatal injury happens during updates. Say you have an RPM based distro but have Ubuntu as the primary Grub OS. When your RPM based distro updates and changes the boot options for its own Grub menu entry in its own little world it has no way of informing the Grub that is actually going to attempt booting. Sometimes an “update-grub” will fix it and sometimes it won’t. A bit heavier on won’t that will.

Drives got too big

That’s the real problem. During the SCSI days when 80MEG was a whopper we put each OS on its own disk and just changed the boot device. That was our “boot manager.” Every OS existed in its own little universe.

As drives got bigger various “boot manager” type products could play games with MBR based partitions. Only one partition could be “active” so a tiny little boot manager got stuff into the MBR and it changed the active partition to match the requested OS.

Cheap but effective trick as long as you didn’t need more than four partitions. Only a primary partition could be flagged for active booting. Lilo and the other Linux boot managers started allowing Linux distros to boot from Extended partitions.

Today we have GPT and UEFI

I’m not intimate with how these work. The Unified Extensible Firmware Interface (UEFI) created the spec for GUID Partition Table (GPT). {A GUID is a Globally Unique Identifier for those who don’t know. That’s really more than you need to know.}

Theoretically we can have an unlimited number of partitions but Microsoft and Windows have capped support at 128. The UEFI should be replacing Grub, Lilo, and all of these other “boot manager” type techniques.

We shouldn’t have all of these problems

As you install each OS it should obtain its partition GUID then find the boot device and locate the UEFI partition on it. Then it should look for a matching GUID to update and if not found, create an entry. There is a spec so every entry should be following the same rules.

(If you read up on the OS/2 boot manager you will see that from the 10,000 foot level UEFI and the OS/2 boot manager conceptually have a lot in common.)

When any computer boots from UEFI and there are multiple operating systems in the UEFI partition, UEFI should show the menu and let the user select. This should all be in hardware and firmware now. We shouldn’t have Microsoft trying to lock us into their buggy insecure OS and Linux distros shouldn’t be trying to ham-fist Grub into UEFI.

The Split

I wanted all Linux distros to boot from the 6TB drive. I wanted Windows and UEFI to stay on the tiny SSD. This isn’t unreasonable. As all of the background should tell you, I’ve been doing things like this for decades. I did not want to try and stuff everything on the 6TB.

Each Linux distro would get 500 GB – 800 GB depending on how much I thought I would be doing in them. This means I should be able to put up to 12 different distros on the drive.

That may sound like a lot, but it’s not. You’ve never written code that worked perfectly on a Ubuntu LTS and failed rather bad on some of the YABUs supposedly using that LTS as their base . . . I have. The only way to know things for certain is to have a bunch of test systems. When you are testing serial port (or other device stuff) you need to be running on hardware, not in a VM.

Manjaro was the first failure

Manjaro kernel 5.9.16-1 was actually a double failure. I have this distro running on a pair of machines, but it is the only OS on them. Rather like what they’ve done with the KDE desktop. I rather hate the fact PostgreSQL cannot access the /tmp directory bulk import to restore a database doesn’t work on that platform. There are a few other odd Manjaro bugs as well.

I wanted to do some pacman packaging and some testing of the future serial port code in CopperSpice on Manjaro so it was first on the list. It booted fast and seemed to install clean. Rebooted the computer and boom, Windows came up. Navigated to the Advanced Settings under Settings in Control panel and tried to switch the boot OS. Boom! Windows is the only entry.


Let’s Install Ubuntu!

I had real dread when I reached for Ubuntu. That installer has had a lot of assumptions baked into it over the years. I was pleasantly surprised and slightly disturbed.

Installation went smooth and when I rebooted I was greeted with a Grub menu. Both Windows and Manjaro were on the Grub menu, but, should we really be seeing Grub on a UEFI system with multiple operating systems? Shouldn’t there be a UEFI menu that just has an entry for Ubuntu and when you select Ubuntu shouldn’t that be when you see a Ubuntu Grub menu?

Let’s See if Manjaro Boots Now!

Once I verified Ubuntu could boot and apply updates I rebooted and selected Manjaro. That’s as far as you get. The Lenovo logo stays on the screen and nothing else happens. HP owners have the same problem according to Reddit.

Fedora 33 Was Next

The Fedora installer was the worst of the lot. If you chose the second drive via one of the manual methods, it looked for a UEFI partition on that drive. It wasn’t smart enough to determine what the boot device was and go look there. You couldn’t get out of the screen either. There was no back or cancel, you had to power down.


Manjaro at least tried to install. It failed to create anything in the UEFI partition of the boot disk and it failed to show any error with respect to UEFI creation failure. It refuses to boot from the entry Ubuntu created for it in Grub. Double failure. I suspect this is due to a combination of super secret stuff needed on the menu entry, Manjaro using a different version of Grub, and Manjaro potentially hiding the files in a place Ubuntu doesn’t know to look.

Fedora failed to get out of the starting blocks. That graphical installer needs a whole lot of work!

Ubuntu worked despite my expectations of abject failure.

Just because Ubuntu worked doesn’t mean every YABU will. Most tend to write their own installers. If the developer working on the installer only has a laptop, they are going to take unreasonable shortcuts.

Related posts:

Fedora 33 Black Screen Again

How to Install PostgreSQL on Fedora 33

Fedora 32 – Black Screen After Login

OS/2 Back From the Grave!


There were too many banks and too many ATMs still running OS/2. Honest to God I thought IBM officially dumped it in the late 1990s. Then I read this 2007 article on OS/2. They didn’t publicly kill it until 2001 and really really really kill it by ending support in 2007 according to that article.

ATM running OS/2

OS/2 was more secure. It also did a better job of memory handling and networking, so it was the OS of choice for the ATM and quite a few other embedded system worlds. The fact it was and really still is 32-bit really doesn’t matter there.

A company called Arca Noae is actually producing new OS/2 releases with updated drivers and hardware support. It appears they have USB 3.0 support now. Still has to use MBR partitioning though, but I imagine they can fix that with enough customers.

What we really have to hope is that they got the the code for Lotus SmartSuite as well.

Lotus SmartSuite

I clung to OS/2 because of SmartSuite. Still, to this date, the best office package ever. For a personal database Lotus Approach was fantastic. I kept track of my expenses with it for many years. Wrote quite a few books using WordPro. Honestly the integrated Calendar/Address Book/TO-DO list package was to die for.

For the UI, I really liked the whole concept of desk drawers you opened up. Even had a little wood drawer open/close sound.

Every copy of OS/2 I ever owned came bundled with this. The DevCon subscription made certain you could keep current on all of the compilers/products/documentation.

What is dead may never die!

How Far We’ve Come – Pt. 2

We need to establish a time frame before I start showing any code. Yes, you can go visit Source Forge to pull down what is there if you are well and truly desperate to view it. This portion is more about the journey than the code.


The xpnsqt program was originally written around the time IBM sunset OS/2 which, according to this article, spanned the time frame between March 12, 2003 and December 31, 2004. Foundations of Qt Development came out in 2007 and C++ GUI Programming with Qt 4 came out in 2006. Both of them discussed QSqlDatabase. Ordinarily I would just hit the help key in QtCreator for QSqlDatabase. It would then take me to a help page which would say something like “feature/class was added in version blah.ha. Funny thing happened when I tried that today.

qtCreator image

Couldn’t find it on that page. Searched on-line in the 4.8 documentation and didn’t find any mention of when QSqlDatabase class was added. I don’t remember it being in Qt3 but I didn’t do that much with Qt3 because the message boards said Qt4 was going to be a night and day difference.

Point and Laugh

At any rate, now that most of you have some idea just how long ago this was and the fact it was my first “real” Qt program, it is time to let everyone point and laugh.


 * Originally created by Roland Hughes at Logikal Solutions.
 * Project is being released under GPL2 license.
 * At some point in the future either Logikal Solutions or Roland Hughes
 * may elect to publish a book with this original source code in it.  If
 * the book is written it will be part of "The Minimum You Need to Know"
 * book series.

#include "XpnsLogonDialog.h"

int main(int argc, char *argv[])
    int i_x;
    QString qtDbName;
    QTime theTime = QTime::currentTime();

    QApplication app(argc, argv);

        QString driverName = "QPSQL";

        //  Set up information for driver and see if driver is available
        qtDbName = "xpns" + theTime.toString("hhmmsszzz");
        QSqlDatabase db = QSqlDatabase::addDatabase(driverName, qtDbName);
        if (!QSqlDatabase::isDriverAvailable( driverName)) {
            QMessageBox::critical( 0, "Missing PostgreSQL Driver",
                                   "The Qt driver for PostgreSQL "
                                   + driverName
                                   + " is not installed.  You must install it before running this program",
            db = QSqlDatabase();        //  reset to avoid warning
            return 0;

        XpnsLogonDialog *xpnsLogonDialog = new XpnsLogonDialog( 0, qtDbName);
        i_x = app.exec();

        qDebug() << "About to delete dialog";
        delete xpnsLogonDialog;
        qDebug() << "Dialog deleted, now clearing database";

        db = QSqlDatabase::database();  // clear connection to avoid error
    }  // end scope of logon dialog


    return i_x;

Looking at some of the comments in here brought back memories which were a long way from good. I’m sure many of you are freaked seeing the {} block enclosing the bulk of the program and the call to removeDatabase() outside of the block. When I saw the whole “clear connection to avoid error” comment it kind of all came back to me.

One thing I really hate about writing stuff like this for my blog, besides never getting paid for it,  is not being able to highlight code. There is probably some HTML markup tags which would let me set the background color, but the WordPress editor should make it a whole lot easier. Due to the way blog themes change the display of preformatted text I cannot even be sure line numbers will display.

The Logon Dialog

While I’m certainly not going to post all of the code in this series, we need to look at a couple more source files (kind of the worst) before we go too far in the discussion.


 * Originally created by Roland Hughes at Logikal Solutions.
 * Project is being released under GPL2 license.
 * At some point in the future either Logikal Solutions or Roland Hughes
 * may elect to publish a book with this original source code in it.  If
 * the book is written it will be part of "The Minimum You Need to Know"
 * book series.

#include "ui_XpnsLogonDialog.h"
#include "Xpnsform.h"

class XpnsLogonDialog : public QDialog, public Ui::XpnsLogonDialog

    XpnsLogonDialog( QWidget *parent, const QString &qtDbName);

    bool getConnectionStatus() { return m_connectionStatus;}
    int getTaxYear() { return m_tax_year;}
    bool useCalendarYear() { return m_calendarYear;}
    QString getActualDbName() {return m_actualDbName;}

private slots:
    void attempt_postgresql_logon();
    void on_userNameLineEdit_textChanged();

    bool m_connectionStatus;
    void create_database( bool dbCreated);
    void ask_copy();
    void prompt_prior_year();
    void copy_prior_year( int year);
    bool  test_exists( int year);
    int m_tax_year;
    QString m_qtDbName;
    QString m_actualDbName;
    bool m_calendarYear;
    Xpnsform *xpnsForm;


Multiple Inheritance

Take a good look at that class definition. How many of you remember every class based on Qt and a UI file having to perform multiple inheritance? Come on, be honest! That all changed when the infamous “they” tried to make Qt usable by Java developers so they could finally abandon Swing. I and most others railed against that, but we lost. No, I won’t empty my colon on it again. You can buy a copy of this book if you want to read that rant. Let’s just say Java banned multiple inheritance and then had to bring it back with “interfaces.” They also banned the goto statement but the labeled break statement and a few other such things. The really bad parts in C and C++ existed for reasons. You can’t successfully remove the bad parts until you remove the reason for them.

Yes, if I don’t run out of time with this series I will rewrite the application from scratch using the more current approach to all things Qt. I believe you need to know where we came from because at some point you are going to encounter heritage code someone wants you to change without rewriting. If you don’t believe that you are either too young or haven’t been coding long enough. Every 1-2 years I get phone calls for a contract at a medical device company where they are looking for Qt 3 only. They have some device they want to make one small change in. If you rewrite they have to go through a very lengthy FDA approval process if the consultant just tweaks they can go through a much shorter and cheaper approval process. A rewrite means it is a “new device” while a change means it is an “updated/changed device.” No those aren’t the correct terms. I don’t remember the correct terms, but those work for the general audience.

Design due to QSqlDatabase “feature”

The convoluted design came about due to a “feature” with that version of Qt and Postgresql. In order to run like a mainframe/midrange application a database login dialog needed to pop up. Since I was going to release this as OpenSource I needed to have the information splash dialog pop up first so people too lazy to read a README.TXT would actually know something. First time users would be somewhat screwed. There was no way around having to manually enter categories. I didn’t want to ship with a predetermined set of categories. N year users would have it great because the login dialog would create the database for the tax year and offer to copy category information forward.

Our first “feature” reared its head during the first cut where I called the dialog exec() method. Even though QSqlDatabase was supposed to globally keep track of connections, when the dialog which created the database went away, so did the connection. In order to keep an entry you had to keep one reference alive. This left me with some really unenviable design choices.

  1. Pass a pointer to the db variable into the constructor of the dialog
  2. Pass string references for username and password and database year duplicating the connection code
  3. Derive from QApplication splitting all of the login functionality into methods within that class which would be executed when the event loop started.
  4. Doing something similar with a QObject class.

Our second and third “feature” reared its head when I didn’t have {} around the life of the db variable.  If one didn’t clear the database connection a runtime error would spit up in the terminal/debug window about object destroyed with active connection or something like that. Simply clearing the connection wasn’t enough, or at least it wasn’t instant enough. Calling removeDatabase() immediately after the clear with the db variable still in scope would cause more errors to be thrown about removing a database with an active connection.

Growing Pains Leave Warts

Yes, they were growing pains. Yes, most of these oddities have long since been cleaned up. Yes, this code still compiles and runs, I use it every time tax season approaches. Yes, you are going to encounter decade plus old code because it serves its purpose and rewriting isn’t free.

Many years ago I worked on a trading floor system for a stock exchange. The original “temporary” system was written in BASIC on a PDP 11 computer. Years later it was “temporarily” ported to the VAX hardware, then the Alpha, all the while the “permanent” trading floor system was being designed and a platform being chosen. This temporary system got pretty much rewritten when the U.S. stock market switched from trading in fractions to dollars and cents. That stock exchange got rid of its trading floor a few years ago. I’m told that “temporary” system went away with the trading floor but I would not be surprised to learn the automated portions of that system are what is running the exchange today.

Short Term “solutions” = Long Term Problems

Keep in mind that Y2K happened because “short term” solutions which made sense in the 1970s and early 1980s which were supposed to be replaced once storage and software became cheap enough were still in use near the year 2000. Read this page to learn what other Y2K like events are in your future.

Cast no stone at decade plus old code. We can always insult the ability of the developer but sometimes it is the ability of others which forced an ugly choice.

<Previous-part Next-Part>

Related posts:

Where Did My QDebug Output Go?

MOC Parse Error at “std”

KDE Neon – Distcc and Qt

CopperSpice Experiments

QtCreator – No qmlScene installed

So You Can’t Get Your Models to Work with QML?

QT Database book

IBM and Chrysler – Keystone Cops Separated At Birth

As one gets older, if one keeps their memory in tact, they can identify family lines and parenting traits for even illegitimate children. For those of you whose brain cannot focus on anything longer than a tweet, let me put it another way, Arnold admitted the affair because the kid started to look like him.

 IBM and Chrysler have to be illegitimate children from the same father, at least everyone in management must be. Just take a look at how “the twins” behave.

 IBM acquires Lotus which had recently acquired AMI Pro word processor. Soon after they put out the “Lotus SmartSuite” on both Windows and OS/2. Not only is it light years ahead of both Word and Word Perfect, the set of desk drawers was an amazingly intuitive concept. IBM does absolutely nothing to market the product. Does not port to MAC, and does not port to LINUX. Product disappears.

 Chrysler acquires AMC after getting into trouble with several government agencies. Soon after the purchase, not only do all of the government problems go away, but, Chrysler introduces the Eagle Premier ES Limited. This car is designed to go head to head with Mercedes and sell for half the price. Not only did it have style without equal, it had an engine which demanded you use at least 10% alcohol fuel and it got 24MPG on the highway back then! Not only does Chrysler fail to market this car, it floods the rest of the Eagle line with bare minimum econo-box cars to boost its fleet mileage average without having to change the rest of its brands. The finest car Chrysler ever made drifts into history.

 IBM decides to wade into the PC operating system market. They contract Microsoft, the company they will be competing with, to develop much of the new operating system. (Yes, it is OK if your idiot meters are pegged at this point.) The first release of OS/2 stumbles out the door like a senior citizen with a walker. Years and countless dollars pass. The bulk of Microsoft’s code gets removed. When Warp 4.5 is finally released it is stable, has support for all current devices, and has better memory management than its competitor will ever achieve. Rather than market the successful version of the OS, IBM sunsets it.

 Chrysler introduces the trend setting PT Cruiser. Despite the dozens of different six cylinder engines they have in their stable, they stuff in a four cylinder engine making most of the automotive buyers view it as a Neon taking growth hormone tablets. This vehicle launched the Retro craze. Chrysler promised a six cylinder version soon to follow. No significant improvements ever happened to the vehicle. The six cylinder option never appeared. PT Cruiser went from a car selling well above list price to a vehicle, like the Neon, dealers were forced to sell X of before they could get one good car. Like the Neon, the PT Cruiser is no more.

 IBM, once again needs a word processor and other office type software to integrate with Lotus Notes, Mail, and other products. They grab a version of OpenOffice and integrate it with their Eclipse IDE. The initial product is Lotus Symphony and after a few bug fix releases is both stable and elegant. It works on Windows, Linux, and MAC. IBM only moves forward with the Windows OS versions. They stick with outdated and mostly unavailable versions of Linux as the Linux world continues to move forward. While the product has not been officially sunset, it might as well be. Almost nobody has a platform which can install the current version.

 Chrysler introduces the Town & Country mini-van and launches the mini-van market. The rest of the automotive world goes into scramble mode. The Town & Country continues without getting any significant improvements. By the end of 2012 it is an also-ran in a category which it created.

 The list goes on and on.

The parentage of these two children seems obvious.