Jan 082018
 

Apparently shrinking a Windows VM (actually any kind of VM) cannot be done with XenServer and XenCenter. You need to create an image of the original volume to a smaller virtual disk in order to do that.

On top of that, the tool that used to work fine for this, Citrix XenConvert, has been deprecated by Citrix and is no longer available for download.

And just to make matters worse, this answer on ServerFault links to an article that is no longer available (or did, until I edited it). Fortunately it’s still in the WaybackMachine

Now, where do we get XenConvert? It’s available for download here in various versions. I took version 2.5. and followed the instructions in the above mentioned article. You might want to virus check the installer before running it.

  1. Create a new virtual disk with the desired size.
  2. Attach it to your VM.
  3. Start the VM.
  4. Optionally, shrink the source drive (partition) from within the virtual machine (Windows 7+ comes with the tools for that).
  5. Format the newly created virtual disk.
  6. Install XenConvert
  7. Start XenConvert, select From: Volume and To: Volume (That’s not the default.)
  8. Select source and destination volumes.
  9. Run the conversion (which takes forever).
  10. Activate the new partition in the Disk Manager (if you forget this, you won’t be able to boot from it).
  11. Shutdown the VM.
  12. Detach the original virtual disk.
  13. Boot the VM (from the new virtual disk).

If everything works, you can now delete the original virtual disk.

Jan 072018
 

When Mozilla released their last big update, they deprecated quite a few APIs for plugins. One of these plugins was FireGestures which I used to get some of the mouse gestures of Opera in Firefox. There are a few new plugins that try to replace FireGestures but none of them really seemed to work quite the way I wanted them, so I thought “Hey, you are a programmer, just write it yourself. It can’t be that hard.”.

It turned out it isn’t that hard, really. So, here comes dzMouseGestures, a tool, that supports 3 different mouse gestures and converts them to keyboard input for Mozilla Firefox:

  • Down -> Right: Ctrl+w
  • Left -> Right: Alt+Left
  • Right -> Left: Alt+Right

It requires the user to hold down the right mouse button while making these gestures.

It took me a few hours to figure out how to install a system wide mouse hook and use that to interpret the mouse movements, convert them to gestures and send key sequences to Firefox. It works for me.

The source code and version 0.0.2 of the binaries (a dll with the hook and an executable that loads this dll and displays some debug information) is available on SourceForge.

Jan 042018
 

(Disclaimer: I am by no means an expert with XenServer. So please don’t take anything you read here for granted. It’s my own experience and what I found in documentation and online.)

In my previous post, I described how to add a Storage Repository to a XenServer using the xe command line tool.

Now, since I have installed the device driver for the RAID controller, created a RAID 5 and added it as Storage Repository (in the same way as described in the linked article), I want to get rid of the SATA drive which I had added as a temporary measure. Guess what, there seem to be no way of doing that using the XenCenter tool (even though the second link below mentions a “Detach” option I could not find it, see the disclaimer above). So, again, it’s the xe command line to the rescue.

xe help

writes a list of supported commands to the console which only contains one command with an sr- prefix: sr-list. Only if you tell it to give you a complete list, you will see what we need here, the sr-destroy command.

xe help --all
[... very long list of commands ...]
xe help sr-destroy
command name            : sr-destroy
        reqd params     : uuid
        optional params :
        description     : Destroy the SR.

But where do we get that uuid? Simple, by asking for it:

xe sr-list
[...]
uuid ( RO)                : 3f1d80c6-929a-f547-9ab1-63a2ca638cbf
          name-label ( RW): XenServer Tools
    name-description ( RW): XenServer Tools ISOs
                host ( RO): xenserver1
                type ( RO): iso
        content-type ( RO): iso
[...]
uuid ( RO)                : <UUID of SR>
          name-label ( RW): temporary-sata-disk
    name-description ( RW):
                host ( RO): xenserver1
                type ( RO): lvm
        content-type ( RO): user

As you can see, there is one Storage Repository with the label temporary-sata-disk. That’s the one I want to remove (the actual list is longer). So

xe sr-destroy uuid=<UUID of SR>

should delete that Storage Repository, right?

No, of course not, you get the error message

The SR is still connected to a host via a PBD. It cannot be destroyed or forgotten.
sr: <UUID of SR> (temporary-sata-disk)

There is also an sr-forget command but it displays the same error message.

So simple guessing doesn’t get us any further. Maybe we should read the docs? Nah, we don’t do that yet, we google and find this and also this.

One of the answers in the second link gives an extended version of the sr-list command:

xe sr-list uuid=<UUID of SR> params all
uuid ( RO)                    : <UUID of SR>
              name-label ( RW): temporary-sata-disk
[...]
      allowed-operations (SRO): unplug; plug; PBD.create; update; PBD.destroy; VDI.resize; VDI.clone; scan; VDI.snapshot; VDI.mirror; VDI.create; VDI.destroy
[...]
                    VDIs (SRO):
                    PBDs (SRO): <UUID of PBD>
[...]

This shows a lot of stuff, in particular it shows a list of allowed operations and a list of VDIs and PDBs currently connected to the Storage Repository. In the case above, we can see, that there are no VDIs connected to it and one PDB. So we follow the instructions in the first link:

xe sr-list name-label=temporary-sata-disk
uuid ( RO)                : <UUID of SR>
          name-label ( RW): temporary-sata-disk
    name-description ( RW): 
                host ( RO): xenserver1
                type ( RO): lvm
        content-type ( RO): user

which gets us the UUID of the SR (OK, we already had that one)

xe pbd-list sr-uuid=<UUID of SR>
uuid ( RO)                  : <UUID of PBD>
             host-uuid ( RO): 78059c4a-73f2-4975-936a-537529772d67
               sr-uuid ( RO): <UUID of SR>
         device-config (MRO): device: /dev/sdb
    currently-attached ( RO): true

which gets us the UUID of the PDB (we already had that one too)

xe pbd-unplug uuid=<UUID of PBD>

followed by

xe sr-forget uuid=<UUID of SR>

After that last command, the Storage Repository vanishes from XenCenter. Also

xe sr-list

no longer lists it. So I guess, it’s safe now to

  • Shut down the computer
  • Remove the hard disk that was used for that Storage Repository
  • Turn on the computer again

One last question: What is the difference between the xe commands sr-forget and sr-destroy? My google fu nearly left me here, until I found a link to XenServer Administrator’s Guide – Layer 8 Consulting (PDF!). There, on page 45 it says
Destroying or forgetting a SR
You can destroy an SR, which actually deletes the contents of the SR from the physical media. Alternatively you can forget an SR, which allows you to re-attach the SR, for example, to another XenServer host, without removing any of the SR contents.”
So, there you go.

Jan 042018
 

(Disclaimer: I am by no means an expert with XenServer. So please don’t take anything you read here for granted. It’s my own experience and what I found in documentation and online.)

There is at least one reason why installing updates for XenServer via XenCenter may fail (with unhelpful error messages of course): You haven’t got created any Storage Repository yet.

One might think that this is pretty unusual but your’s truly has actually managed to run into this problem. Why? Because I didn’t install the drivers necessary for accessing the hardware RAID controller (in my case the LSI megaraid package). Usually you do that during the XenServer setup but I was at that time not aware that I would actually need a driver. And thus apart from the boot disk there was nowhere to put a Storage Repository. And I didn’t want to put that on the boot ssd. So I ended up with a XenServer installation that didn’t have any Storage Repositories.

So, what can you do?

You can attach a single SATA hard disk to the system and configure it as a storage.

One might think that is easy to do using XenCenter since there is a menu entry Storage -> New SR, but no, there you can only add NVS, iSCSI, Hardware HBA or Software FCoE. Local drives aren’t even mentioned.

So you have to resort to the xe command as described here:

  1. Shut down and turn off the computer
  2. Attach the hard disk and boot
  3. On the console use fdisk to get information about the new hard disk
    fdisk -l
    

    Search for the new hard drive in the list. It will be the last on the list and it is indicated as /dev/sdc. c is the position it is in. Generally, it starts at a, and the list continues. You can verify the device path using the SCSI ID in /dev/disk/by-id directory by listing out the contents.
    Note: I wouldn’t rely on the drive being the last one in the list. Definitely verify the drive parameters that fdisk outputs.

  4. Run the following command from the command line interface (in the console or on the a computer with XenCenter installed):
    xe sr-create name-label=<Name of Storage> shared=false device-config:device=<Path of the Storage device> type=lvm content-type=user
    
    • Name of Storage is the name of the Storage Repository you require
    • Path of the Storage device is the path as noted in the preceding tasks, /dev/sdc)
      Now, the installed hard drive is visible in the XenServer Console.

    Note: This works fine if you run it on the server console. If you run it from a remote computer with XenCenter, you need additional parameters to actually connect to the server. In that case insert the following between xe and sr-create:

    -s <server> -u <username> -pw <password>
    
    • server is the server’s name or IP address
    • username is the user to logon (e.g. root)
    • password is the password of the given user

And yes, it worked. After adding this Storage Repository I could install the updates.

Jan 032018
 

Today, I finally found the time to read up on some rather ancient e-mails. One was from Paolo in the dxgettext mailing list about a bug in gnugettext.pas:

With SVN revision 75 and the following, AddDomainForResourceString() has no effect, additional translations are not used.

Suggested patch:

original code from SVN revision 79:

function TGnuGettextInstance.LoadResString(
  ResStringRec: PResStringRec): UnicodeString;
begin
  Result:=Gettext(GetResString(ResStringRec));
end;

patched code:

function TGnuGettextInstance.LoadResString(
  ResStringRec: PResStringRec): UnicodeString;
begin
  Result:=ResourceStringGettext(GetResString(ResStringRec));
end;

He is right: After the change I made in revision 75 AddDomainForResourceString no longer worked as expected. I had never experienced that problem because I don’t use resource strings but prefer calling _() explicitly.

Having had not much sleep last night (at least that’s a good excuse because it’s even true), I simply took the suggested patch and committed it. This turned out to be a bad idea because it was reverting the change I made in revision 75 back in July 2016. That change fixed a bug that “Der schöne Günther” mentioned in Delphi Praxis. Unfortunately that bugfix introduced the new bug.

Good thing that Obones apparently had slept well 😉 and spotted the problem immediately:

Before changing this back, please consider where it comes from:
https://sourceforge.net/p/dxgettext/code/75
http://www.delphipraxis.net/1333593-post1.html

I’m not sure which one is correct, but going back to the global instance in an method of the instance itself seems a bit counterintuitive.
If one wants to call .LoadResString, I believe one should make sure it works on the expected domain.
But if one wants to have the support for multiple domains, then no specific instance method should be called.

My 2 cents.

That woke me up and I actually went and wrote a test program based on the code which Der schöne Günther posted. Then I fixed the bug, or actually, both:

As of revision 83 TGnuGettextInstance has a method ResourceStringGettext which takes both, the selected language of that instance as well as the domains added with AddDomainForResourceString into account. The fix was even quite simple: Just move the code from the global ResourceStringGettext function to the new method and from the global function call the method of the DefaultInstance like it is done e.g. in the GetText method.

Dec 302017
 

The Unicode issues in GExperts just don’t end. Today I fixed three of them:

procedure bla;
begin
  SomeVar := 3245;
  // german description with some äöüß to SomeVar
  SomeVar := 123;

  SomeQuery.FieldByName('GermanWordWithäöüß').AsString := 'some value';
end;

(Yes, I know, this doesn’t compile.)

  • Move the cursor to the first occurrence of SomeVar and press Ctrl+Alt+Down. The cursor jumps to the middle of the next Occurrence of SomeVar instead of the start of the identifier.
  • Move the cursor to the opening parenthesis after FieldByName and press Ctrl+Alt+Right. The cursor moves to somewhere in AsString rather than the closing parenthesis.
  • Move the cursor to the closing parenthesis and press Ctrl+Alt+Left. You get the error that AsString is not a valid delimiter

They were caused by the two byte UTF-8 characters in the respective lines which threw off the column index.

And if that wasn’t enough I also fixed some bugs in the Grep history list which could cause an Access Violation, infinite loop or wrong check marks in the Open dialog.

All these were reported by Konstantin Tkachenko who also included some patches which fixed them. Unfortunately he could only test them in Delphi 2010 so they worked for Delphi 2007+ but not for Delphi 6 and 7. They were valuable nonetheless. Thanks Konstantin!

Also, Achim Kalwa, who already contributed quite a few patches to GExperts, sent me some more this week:

  • Remove the ugly “(S+C+x)” suffixes in the Project Options dialog and replace them with a hint.
  • Sort the component names by tab order in the Copy Component Names expert.
  • Shortcuts for Add/Remove/Default buttons in the Editor Popup menu configuration dialog as well as sorting the list of experts alphabetically.
Dec 302017
 

Note to self:

If you get an access violation when setting IOTASourceEditor.BlockVisible to true in Delphi 6 or 7 e.g.:

procedure GxOtaSelectBlock(const Editor: IOTASourceEditor; const Start, After: TOTACharPos);
begin
  Assert(Assigned(Editor));
  Editor.BlockVisible := False;
  try
    Editor.BlockType := btNonInclusive;
    Editor.BlockStart := Start;
    Editor.BlockAfter := After;
  finally
    Editor.BlockVisible := True; // <---- BOOM
  end;
end;

Check that your source editor does not contain UTF-8 characters or a BOM. Delphi 6 and 7 allow you to paste those into the editor window (from an editor that supports them, like Notepad++ or Delphi >7) but cannot handle it correctly.

Dec 292017
 

Today I had a rather annoying problem with Delphi XE2. I only wanted to change the caption of a TListView column using the Columns Editor (right click -> Columns Editor). The IDE crashed on me with an Access Violation. So, I thought I had broken it again (things like this happen when you are developing IDE plugins) and uninstalled GExperts. After a restart I tried it again and got the same Access Violation, proving at least that GExperts was not the culprit.

So, which other IDE plugins were installed? To find out, I opened the Help -> About dialog, which immediately crashed on me with an Access Violation. It happened while it was drawing the list of Installed Products.

Next I tried to debug Delphi with itself, loading the GExperts sources. The problem at least was reproducible and the call stack told me the crash was in TCustomListView.CNNotify. That unfortunately wasn’t very helpful apart from telling me that it had something to do with custom drawing (which was deeper in the call stack) of a TListView, which was what both crashes shared: The About Dialog as well as the Columns Editor both use TListView and apparently do custom drawing.

So, I removed all experts that I had installed …

… and tried it again. At first, it seemed to work, I could open the About Dialog and nothing bad happened. Then I opened the project I was trying to change, called the Columns Editor and – boom – got the Access Violation.

I restarted the IDE again and looked into the About Dialog. There were only the Embarcadero Quality Insight and the JEDI Visual Component Library left. No crash occurred. I reloaded the project, opened the About Dialog again and got the now familiar Access Violation. WTF? Could it be the JVCL?

I renamed the JvCore160.bpl package that all jvcl packages load. And tried again. I got lots of error messages when I started the IDE and again when I opened my project, but I could successfully open the About Dialog.

So, if it really is the JVCL, why did the Access Violation only occur when my project was loaded?

I made the JvCore160.bpl package available again, restarted the IDE, but this time created a new VCL project and added a JVCL component to it. I opened the About Dialog and got the AV. I guess that proved the point.

That was when I remembered reading about Delphi 2005 (and later) loading packages on demand instead of on startup. This explains why the AV happens only after a JVCL component was used in a project: Because otherwise the packages simply were not loaded at all.

Unfortunately that didn’t help much, because my project needs the JVCL (in particular the TJvFilenameEdit component), so I could not simply uninstall it. Since I had not heard about this problem, I guess it isn’t wide spread. One possibility is that I have produced it myself by sticking with an older JCL/JVCL source code and simply patching it to make it compile with Delphi XE2 instead of keeping up with the latest version (The reason for that is that I don’t like the hassle with Git, so I stopped following the JEDI projects when the sources were moved from SourceForge to GitHub.)

I went to GitHub, downloaded the latest ZIP files from all three projects, put everything together and installed JCL and JVCL to Delphi XE2 (the JCL installer dialog looks intimidating if you have got 18 versions of Delphi installed). I then had to remove the directories from the library paths again and compile several of my packages that need the JCL or JVCL+JCL, which required me to make some small changes to my code. But it took only about half an hour, which is nothing compared to the several hours I had already wasted trying to find out what made Delphi XE2 crash.

I loaded the dreaded project again, and everything worked fine. I could finally change the List View captions which was all I wanted to do to start with.

Isn’t it great when everything just works?

Dec 292017
 

Seagate has changed their Barracuda desktop 3,5″ 2 and 4 TB drives from using 3 platters to using only 2 while doubling the cache RAM from 128 to 256 MBs.

We have been buying this type of drives for various usages, one of them is the 4 TB drive for the backup of our main file server (using Dirvish). Before the change, an ext3 format under Ubuntu Linux took a few minutes. After the change, it now takes literally(!) hours. The inode tables counter grows very quickly until it has reached about 1000, after which it starts crawling upwards veeeeeerrrrryyyy sloooooowwwwwlyyyyyy. I guess about 1000 is when the cache has been filled and any further writing goes directly to the actual drive.

Once the formatting is done, the initial backup takes several days rather than the usual 8 to 12 hours it took before the change.

Once the initial backup is done, the incremental backups only take the usual 30 minutes unless there have been very many changes, then again you can see that the drive is very slow when writing large amounts of data.

It does not matter whether the drive is connected via USB 3 (which is the way we use it for the backup) or SATA, the slowdown is reproducible every time.

Another use for these drives was the 2 TB variant to store videos in our measurement vehicles. There are 2 of these drives in one PC which are used to write MJPEG streams of 2 HD cameras each. These cameras take a picture every metre, which comes out at about 22 pictures per second when driving at 80 km/h. Before the change that was no problem at all. We could even drive at 100 km/h (27 pictures per second). After the change, the videos suddenly had lots of lost frames because the drive is just too slow to write them.

For now the 1 TB variant seems to be as fast as ever.

So now we are looking for alternative drives to use. Until a few years ago we only bought Hitachi but switched to Seagate when Western Digital acquired HGST and raised the prices. I guess we’ll have to look into WD / HGST again as well as checking out other Seagate product lines.

Dec 232017
 

Es ist jedes Jahr dasselbe, es soll vor der Bescherung gesungen werden und nur wenige kennen den Text. Irgendwie schon peinlich. Deshalb habe ich jetzt endlich eine Maßnahme ergriffen und mir den Text der gebräuchlichsten Lieder zusammengestellt. Sie passen in noch lesbarer Schrift auf eine DIN A4 Seite, wenn man zwei Seiten auf eine druckt (typischerweise erlauben heutige Drucker das).

Enthalten sind:

  • O Tannenbaum
  • O du fröliche
  • Ihr Kinderlein kommet
  • Alle Jahre wieder
  • Stille Nacht, heilige Nacht

Download als PDF.

Alternativ zum Ausdruck kann man sich das PDF auch auf dem Smartphone anzeigen lassen. Das hat den Vorteil, dass man es auch bei schlechter Beleuchtung lesen kann. Ob das der Stimmung zuträglich ist, muss jeder selbst entscheiden.

%d bloggers like this: