Category Archives: Linux

gipc 1.0.0 release

More than three years after the 0.6.0 release I have published gipc version 1.0.0 today.

Quick links

Release highlights

This release focuses on reliability and platform compatibility. It brings along a number of changes relevant for running it on Windows and macOS, as well as for running it under PyPy.

Both, gevent 1.2 and 1.3 are now officially supported. On Linux, gipc now officially supports CPython 2.7, 3.4, 3.5, 3.6, PyPy2.7, and PyPy3. On Windows, gipc officially supports gevent 1.3 on CPython 2.7, 3.4, 3.5, 3.6, and 3.7. Support for gevent 1.1 and CPython 3.3 has been dropped.

The API did not change. In view of the stability of the API over the recent years I thought it is time to officially declare it as such, and to follow the semantic versioning spec‘s point 5: “Version 1.0.0 defines the public API” :-).

For this release most of the work went into

  • fixing a small number of platform-dependent bugs (this one was interesting, and this one was pretty insightful and ugly).
  • setting up a continuous integration (CI) pipeline for Linux and macOS (on Travis CI) as well as for Windows (via AppVeyor).
  • Re-writing and re-styling significant parts of the documentation: the new docs are online and can be found at (for comparison: old docs).
  • moving the repository from Bitbucket to GitHub (I also migrated issues using this well-engineered helper).
  • making tests more stable.
  • running the example programs as part of CI, on all supported platforms (required a number of consolidations).


I would like to thank the following people who have helped with this release, be it by submitting bug reports, by asking great questions, with testing, or with a bit of code: Heungsub Lee, James Addison, Akhil Acharya, Oliver Margetts.

Changelog for this release

For the record, the complete changelog for this release copied from CHANGELOG.rst:

New platform support:

  • Add support for PyPy on Linux. Thanks to Oliver Margetts and to Heungsub Lee for patches.


  • Fix a bug as of which gipc crashed when passing “raw” pipe handles between processes on Windows (see issue #63).
  • Fix can't pickle gevent._semaphore.Semaphore error on Windows.
  • Fix ModuleNotFoundError in test_wsgi_scenario.
  • Fix signal handling in example
  • Work around segmentation fault after fork on Mac OS X (affected test_wsgi_scenario and example program

Test / continuous integration changes:

  • Fix a rare instability in test_exitcode_previous_to_join.
  • Make test_time_sync more stable.
  • Run the example programs as part of CI (run all on Linux and Mac, run most on Windows).
  • Linux main test matrix (all combinations are covered):
    • gevent dimension: gevent 1.2.x, gevent 1.3.x.
    • Python implementation dimension: CPython 2.7, 3.4, 3.5, 3.6, PyPy2.7, PyPy3.
  • Also test on Linux: CPython 3.7, pyenv-based PyPy3 and PyPy2.7 (all with gevent 1.3.x only).
  • Mac OS X tests (all with gevent 1.3.x):
    • pyenv Python builds: CPython 2.7, 3.6, PyPy3
    • system CPython
  • On Windows, test with gevent 1.3.x and CPython 2.7, 3.4, 3.5, 3.6, 3.7.

Potentially breaking changes:

  • gevent 1.1 is not tested anymore.
  • CPython 3.3 is not tested anymore.

Atomically switch a directory tree served by nginx

This post briefly demonstrates how to atomically switch a directory tree of static files served by nginx.

Consider the following minimal nginx config file:

$ cat conf/nginx.conf 
events {
    use epoll;
http {
    server {
        location / {
            root /static/current ;

The goal is to replace the directory /static/current atomically while nginx is running.

This snippet shows the directory layout that I started out with:

$ tree
├── conf
│   └── nginx.conf
└── static
    ├── version-1
    │   └── hello.html
    └── version-2
        └── hello.html

conf/nginx.conf is shown above. The static directory contains two sub trees, and the goal is to switch from version-1 to version-2.

For this demonstration I have started a containerized nginx from its official Docker image:

$ docker run -v $(realpath static):/static:ro -v $(realpath conf):/etc/nginx:ro -p nginx nginx -g 'daemon off;'

This mounts the ./static directory as well as the nginx configuration file into the container, and exposes nginx listening on port 8088 on the local network interface of the host machine.

Then, in the ./static directory one can choose the directory tree served by nginx by setting a symbolic link, and one can subsequently switch the directory tree atomically, as follows:

1) No symbolic link is set yet — leading to a 404 HTTP response (the path /static/current does not exist in the container from nginx’ point of view):

$ curl http://localhost:8088/hello.html
<head><title>404 Not Found</title></head>
<center><h1>404 Not Found</h1></center>

2) Set the current symlink to serve version-1:

$ cd static
$ ln -s version-1 current && curl http://localhost:8088/hello.html
hello 1

3) Prepare a new symlink for version-2 (but don’t switch yet):

$ ln -s version-2 newcurrent

4) Atomically switch to serving version-2:

$ mv -fT newcurrent current && curl http://localhost:8088/hello.html
hello 2

In step (4) It is essential to use mv -fT which changes the symlink with a rename() system call. ln -sfn would also appear to work, but it uses two system calls under the hood and therefore leaves a brief time window during which opening files can fail because the path is invalid.

Final directory layout including the symlink current (currently pointing to version-2):

$ tree
├── conf
│   └── nginx.conf
└── static
    ├── current -> version-2
    ├── version-1
    │   └── hello.html
    └── version-2
        └── hello.html

Kudos to for being a great reference.

Download article as PDF file from Elsevier’s ScienceDirect via command line (curl)

When not in the office, we often times cannot directly access scientific literature, because access control is usually based on IP addresses. However, we usually have SSH access to the university network. Being logged in to a machine in the university network we should — in theory — be able to access a certain article. Most of the times it is the PDF file that we are interested in and not the “web page” corresponding to an article. So, can’t we just $ curl to get that file? Most of the times, this does not work, because access to journal articles usually happens through rather complex web sites, such as Elsevier’s ScienceDirect:

ScienceDirect is a leading full-text scientific database offering journal articles and book chapters from nearly 2,500 journals and 26,000 books.

Such web sites add a considerable amount of complexity to the technical task of downloading a file. The problem usually starts with obtaining the direct URL to the PDF file. Also, HTTP redirection and cookies are usually involved. Often times, the only solution people see to solve these issues is to set up a VPN and then to use a fully fledged browser through that VPN, and let the browser deal with the complexity.

However, I prefer to get back to the basics and always strive to somehow find a direct URL to the PDF file to then download it via curl or wget.

This is my solution for Elsevier’s ScienceDirect:

Say, for instance, you wish to download the PDF version of this article:

Then all you need is that URL and the following commands executed on a common Linux system:

export SDURL=""
curl -Lc cookiejar "${SDURL}" | grep pdfurl | perl -pe 's|.* pdfurl=\"(.*?)\".*|\1|' > pdfurl
curl -Lc cookiejar "$(cat pdfurl)" > article.pdf

The method first parses the HTML source code of the main page corresponding to the article and extracts a URL to the PDF file. At the same time, it also stores the HTTP cookie(s) set by the web server when accessing named web page. These cookies are then re-used when accessing the PDF file directly. This has reproducibly worked for me.

If it does not work for you, I recommend having a look into the file pdfurl and see if that part of the process has lead to a meaningful result or not. Obviously, the second step can only succeed aver having obtained a proper URL to the PDF file.

This snippet should not be treated as a black box. Please execute it in an empty directory. Also note that this snippet only works subject to the condition that ScienceDirect keeps functioning the way it does right now (which most likely is the case for the next couple of months or years).

Don’t hesitate to get back to me if you have any questions! download with wget

Downloading from with premium credentials through the command line is possible using standard tools such as wget or curl. However, there is no official API and the exact method required depends on the mechanism implemented by the website. Finding these implementation details requires a little amount reverse engineering.

Here I share a small shell script that should work on all POSIX-compliant platforms (e.g. Mac or Linux). The method is based on current behavior of the website. There are no special tools involved, just wget, grep, sed, mktemp.

(The solutions I found on the web did not work (anymore) and/or were suspiciously wrong.)


Copy the script content below, define username and password, and save the script as, for instance, Then, invoke the script like so:

$ /bin/sh urls.txt

The file urls.txt should contain one URL per line, such as in this example:


This paragraph is just for the curious ones. The script first POSTs your credentials to and stores the resulting authentication cookie in a file. This authentication cookie is then used for retrieving the website corresponding to an file. That website contains a temporarily valid download URL corresponding to the file. Using grep and sed, the HTML code is filtered for this URL. The payload data transfer is triggered by firing a POST request with empty body against this URL (cookie not needed). Files are downloaded to the current working directory. All intermediate data is stored in a temporary directory. That directory is automatically deleted upon script exit (no data is leaked, unless the script is terminated with SIGKILL).

The script

# Copyright 2015 Jan-Philip Gehrcke,
# See
if [ "$#" -ne 1 ]; then
    echo "Missing argument: URLs file (containing one URL per line)." >&2
    exit 1
if [ ! -r "${URLSFILE}" ]; then
    echo "Cannot read URLs file ${URLSFILE}. Exit." >&2
    exit 1
if [ ! -s "${URLSFILE}" ]; then
    echo "URLs file is empty. Exit." >&2
    exit 1
TMPDIR="$(mktemp -d)"
# Install trap that removes the temporary directory recursively
# upon exit (except for when this program retrieves SIGKILL).
trap 'rm -rf "$TMPDIR"' EXIT
echo "Temporary directory: ${TMPDIR}"
echo "Log in via POST request to ${LOGINURL}, save cookies."
wget --save-cookies=${COOKIESFILE} --server-response \
    --output-document ${LOGINRESPFILE} \
    --post-data="id=${USERNAME}&pw=${PASSWORD}" \
# Status code is 200 even if login failed.
# Uploaded sends a '{"err":"User and password do not match!"}'-like response
# body in case of error.
echo "Verify that login response is empty."
# Response is more than 0 bytes in case of login error.
if [ -s "${LOGINRESPFILE}" ]; then
    echo "Login response larger than 0 bytes. Print response and exit." >&2
    cat "${LOGINRESPFILE}"
    exit 1
# Zero response size does not necessarily imply successful login.
# Wget adds three commented lines to the cookies file by default, so
# set cookies should result in more than three lines in this file.
echo "${COOKIESFILELINES} lines in cookies file found."
if [ "${COOKIESFILELINES}" -lt "4" ]; then
    echo "Expected >3 lines in cookies file. Exit.". >&2
    exit 1
echo "Process URLs."
# Assume that login worked. Iterate through URLs.
while read CURRENTURL; do
    if [ "x$CURRENTURL" = "x" ]; then
        # Skip empty lines.
    echo -e "\n\n"
    TMPFILE="$(mktemp --tmpdir=${TMPDIR} response.html.XXXX)"
    echo "GET ${CURRENTURL} (use auth cookie), store response."
    wget --no-verbose --load-cookies=${COOKIESFILE} \
        --output-document ${TMPFILE} ${CURRENTURL}
    if [ ! -s "${TMPFILE}" ]; then
        echo "No HTML response: ${TMPFILE} is zero size. Skip processing."
    # Extract (temporarily valid) download URL from HTML.
    LINEOFINTEREST="$(grep post ${TMPFILE} | grep action | grep uploaded)"
    # Match entire line, include space after action="bla" , replace
    # entire line with first group, which is bla.
    DLURL=$(echo $LINEOFINTEREST | sed 's/.*action="\(.\+\)" .*/\1/')
    echo "Extracted download URL: ${DLURL}"
    # This file contains account details, so delete as soon as not required
    # anymore.
    rm -f "${TMPFILE}"
    echo "POST to URL w/o data. Response is file. Get filename from header."
    # --content-disposition should extract the proper filename.
    wget --content-disposition --post-data='' "${DLURL}"
done < "${URLSFILE}"

Systemdatenträger wechseln ohne “Augen zu und durch”-Mentalität


In diesem Artikel beschreibe ich wie man Windows in wenigen Schritten von einem Speichermedium zum Anderen überträgt — mit professionellen Werkzeugen. Das ist ein kritischer Prozess. Aber ein simpler Prozess, den man verstehen kann und sollte, bevor man ihn einleitet. Wie immer gibt es zahlreiche schändliche Anleitungen da draußen, bei denen dieser Prozess nicht hinreichend erklärt und irgendwelchen bunten Klick-Tools überlassen wird. Das Problem dabei: der Vorgang wird dem Nutzer übersimplifiziert präsentiert. Wichtige Entscheidungen trifft die angepriesene Software selbst, essentielle Details werden vom Nutzer ferngehalten. Aber im Bereich von Datenträgerstrukturen gibt es zu viele potentielle Komplikationen, deren Behandlung man keiner Pseudointelligenz oder auch der “Holzhammermethode” überlassen darf:

Holzhammermethode, zweckentfremdet von

Holzhammermethode, zweckentfremdet von

In professionellen Umgebungen wird ein solcher Migrationsprozess normalerweise akribisch geplant und jeder Schritt mit dem einen dafür etablierten Werkzeug ausgeführt. Ergebnis: die Migration gelingt schnell und zuverlässig.

In privaten Umgebungen herrscht Unsicherheit, man kennt die technischen Details nicht und folgt gerne einer simplen Abstraktion des Problems. Es herrscht Augen zu und durch-Mentalität. Grafisch hübsch aufgemachte Software-Assistenten suggerieren schließlich eine gewisse Sicherheit. Doch Hoffnung ist keine Strategie. Das etwas andere Ergebnis: mit einiger Wahrscheinlichkeit geht etwas schief und man verbringt Stunden oder Tage mit einer chaotischen Phase der Problemlösung, bei der vielleicht Dritte mit einbezogen werden müssen.

Eine grundsätzliche Ursache dieses Gefälles zwischen professioneller und privater Umgebung ist sicherlich der Mangel an Detailwissen in Letzterer. Damit einher geht aber — und das ist das eigentliche Übel — fehlende Anerkennung, dass ein solcher Prozess akribisch geplant werden muss. Ich schreibe das hier auf Deutsch und mit dieser kleinen Einleitung, um in meinem direkten Umfeld ein besseres Bewusstsein für diese Thematik und Problematik zu schaffen.

Es wird unten stehend demonstriert, wie ein solcher Prozess zuverlässig umgesetzt werden kann. Als Beispiel dient ein Spezialfall, den die meisten Windows-Nutzer zu Hause haben. Die Grundidee — Detailplanung und die verwendeten Ansätze und Werkzeuge — sind jedoch auch auf andere Situationen und Betriebssysteme anwendbar. Ihr werdet merken, wenn Eure Situation von der hier beschriebenen abweicht. Dann könnt Ihr mich gerne fragen. Dementsprechend erhebt die folgende Anleitung keinen Anspruch auf Vollständigkeit.


1) Live-Linux präparieren (5 Minuten)

Ihr braucht einen USB-Stick mit einem modernen Live-Linux-System, welches die notwendigen Werkzeuge bereithält, um zuverlässig Daten auf Datenträgern zu analysieren und zu manipulieren. Ich empfehle die Linux-Distribution SystemRescueCD. Gibt es hier zum Herunterladen. Wie bekommt Ihr das auf einen USB-Stick, von dem der Rechner starten kann? Mit dem quelloffenen Rufus. Dort wählt Ihr “create a bootable disk” und bei “select ISO file” wird das SystemRescueCD-Abbild ausgewählt, was gerade heruntergeladen wurde.

2) Transfersystem vorbereiten (5 Minuten)

Der Quell-Datenträger (mit der bisherigen Windows-Installation) wird aus dem Produktivsystem herausgenommen. Der Ziel-Datenträger wird bereitgelegt.

Es wird ein Rechner gebraucht, in dem diese beiden Datenträger gleichzeitig angeschlossen werden. Dieser Rechner wird vom zuvor präparierten USB-Stick gestartet. Beim Start von SystemRescueCD wird der default Start-Modus gewählt, das Tastaturlayout (z. B. DE) definiert und die Desktop-Umgebung mittels startx gestartet.

In diesem Zustand ist der Zugriff auf alle Datenträger möglich. SystemRescueCD wagt jedoch keine autonomen Zugriffe. Ohne Anweisung wird kein einziges Dateisystem eingehängt. Insbesondere wird ohne konkreten Befehl auf keinen Datenträger schreibend zugegriffen. Das ist ein konzeptioneller Schutz vor ungeplanten Ereignissen.

3) Quelle und Ziel eindeutig identifizieren (2 Minuten)

Jedes Linux-Betriebssystem nummeriert die Datenträger intern durch. Jeder Datenträger und jede Partition ist per /dev/sd* lesend und schreibend erreichbar. Jetzt muss die Bezeichnung des bisherigen Windows-Datenträgers ausfindig gemacht werden. Es hilft eine Auflistung der verfügbaren Datenträger samt Partitionen. Ein praktischer Befehl ist fsarchiver probe simple, welcher in ein Terminal eingegeben wird. Das ist die Ausgabe in meinem Fall:

[======DISK======] [=============NAME==============] [====SIZE====] [MAJ] [MIN]
[sda             ] [KINGSTON SVP200S               ] [   111.79 GB] [  8] [  0]
[sdb             ] [WDC WD10EAVS-00D               ] [   931.51 GB] [  8] [ 16]
[sdc             ] [Samsung SSD 850                ] [   476.94 GB] [  8] [ 32]
[sdd             ] [RALLY2                         ] [     3.74 GB] [  8] [ 48]
[sde             ] [USB DISK                       ] [     7.55 GB] [  8] [ 64]
[=====DEVICE=====] [==FILESYS==] [======LABEL======] [====SIZE====] [MAJ] [MIN] 
[loop0           ] [squashfs   ] [<unknown>        ] [   278.66 MB] [  7] [  0] 
[sda1            ] [ntfs       ] [System Reserved  ] [   100.00 MB] [  8] [  1] 
[sda2            ] [ntfs       ] [<unknown>        ] [   111.69 GB] [  8] [  2] 
[sdb1            ] [ntfs       ] [Software         ] [   196.16 GB] [  8] [ 17] 
[sdb2            ] [ntfs       ] [Daten            ] [   735.35 GB] [  8] [ 18] 
[sdd1            ] [vfat       ] [SYSRCD-4_4_      ] [     3.74 GB] [  8] [ 49] 
[sde1            ] [vfat       ] [<unknown>        ] [     7.55 GB] [  8] [ 65]

Beim Lesen der Ausgabe braucht man ein bisschen Kenntnis über die eigene Hardware: in der oberen Liste sollten Gerätebezeichnung und Datenträgerkapazität genügend Aufschluss geben. Der bisherige Windows-Datenträger von Kingston heißt in diesem Fall sda. Er ist per Dateisystempfad /dev/sda erreichbar.

In der unteren Liste sind die automatisch erkannten Partitionen aufgeführt. Die Partition sda1 ist eine 100 MB große Partition mit dem Namen “System Reserved …”. Diese wird für gewöhnlich von Windows 7 & 8 bei der Installation angelegt und übernimmt essentielle Aufgaben (sie wird im Betrieb von Windows nicht als normaler Datenträger angezeigt aber muss bei der Migration mitgenommen werden). Die Partition sda2 ist das, was man aus Windows-Sicht als Systemlaufwerk bezeichnen würde (meist Laufwerk “C:”). Bei beiden Partitionen hat fsarchiver wie erwartet erkannt, dass sie ein NTFS-Dateisystem enthalten. Es ist keine weitere Partition auf /dev/sda vorhanden. Die Bestandsaufnahme der Quelle ist somit abgeschlossen.

/dev/sdc ist der Datenträger, der zukünftig Windows tragen soll. Bisher ist keine Partition auf diesem Datenträger eingerichtet.

4) Die Transferstrategie festlegen

Die Strategie im Groben: Die Inhalte beider Quell-Partitionen (/dev/sda1 und /dev/sda2) sollen auf Block-Ebene auf den neuen Datenträger kopiert werden. Vorher bekommt der neue Datenträger eine frische Partitionstabelle. Der Bootloader wird vom alten Datenträger auf den Neuen kopiert.

Die Strategie im Detail:

  • Per GNU fdisk wird eine neue Partitionstabelle vom Typ msdos auf /dev/sdc erstellt, sodass die Situation vom alten Datenträger in den wesentlichen Punkten repliziert wird:
    • /dev/sdc1 erhält die selbe Startposition und Größe wie /dev/sda1.
    • In diesem Fall ist der neue Datenträger größer als der alte: /dev/sdc2 soll den Rest des Datenträgers füllen.
    • Beide Partitionen erhalten eine Markierung vom Typ 7 (HPFS/NTFS/exFAT).
    • /dev/sdc1 wird als aktiv markiert.
  • Der Master Boot Record wird per dd nur teilweise vom alten Datenträger auf den neuen kopiert (nur der Bootloader und die Datenträgersignatur, nicht jedoch die Partitionstabelle).
  • /dev/sda1 wird blockweise per dd nach /dev/sdc1 kopiert.
  • /dev/sda2 wird blockweise per dd nach /dev/sdc2 kopiert.
  • Das NTFS-Dateisystem welches auf /dev/sda2 befindet hat nun mehr Platz auf /dev/sdc2. Es wird per ntfsresize entsprechend darauf aufmerksam gemacht, sodass es den verbleibenden Platz innerhalb der Partition nutzen kann. Zur Vereinfachung dieses Schritts wird als Wrapper GParted benutzt. Beide Tools sind quelloffen und Industriestandard.

Alle hier genannten Werkzeuge sind Teil der SystemRescueCD-Distribution.

5) Realisierung (5 Minuten Arbeit, X Minuten Warten)

  • Details der Partitionstabelle vom bisherigen Windows-Datenträger per fdisk -l auslesen:
    Device    Boot     Start       End    Blocks  Id System
    /dev/sda1 *         2048    206847    102400   7 HPFS/NTFS/exFAT
    /dev/sda2         206848 234438655 117115904   7 HPFS/NTFS/exFAT

    Beide Partitionen sind von Typ 7. /dev/sda1 ist Boot-markiert (“active”). Start und Ende sind präzise angegeben. Diese Parameter wollen wir exakt replizieren. Die einzige Änderung der neuen Tabelle gegenüber der Alten wird die Endmarkierung der Partition /dev/sda2 sein, da der neue Datenträger größer ist als der Alte.

  • Neue Partitionstabelle auf neuem Datenträger per fdisk /dev/sdc erstellen. fdisk wird schrittweise per Tastatur bedient:
    • o create a new empty DOS partition table
    • n add a new partition
    • p primary (0 primary, 0 extended, 4 free)
    • Partition number 1, first sector: 2048 (default), last sector: 206847
    • n add a new partition
    • p primary (0 primary, 0 extended, 4 free)
    • Partition number 2, first sector: default, last sector: default (bis zum Ende des Datenträgers)
    • mit Befehl t change a partition type wird Typ 7 für beide Partitionen gewählt.
    • mit Befehl a toggle a bootable flag wird Partition 1 aktiv markiert.
    • mit Befehl w write table to disk and exit werden die Änderungen geschrieben.
  • Bootloader und Datenträgersignatur blockweise kopieren (die ersten 446 Bytes des Datenträgers):
    # dd if=/dev/sda of=/dev/sdc bs=446 count=1
    1+0 records in
    1+0 records out
    446 bytes (446 B) copied, 0.00403888 s, 110 kB/s
  • kleine “System Reserved”-Partition blockweise kopieren:
    # dd if=/dev/sda1 of=/dev/sdc1
    204800+0 records in
    204800+0 records out
    104857600 bytes (105 MB) copied, 2.02602 s, 51.8 MB/s
  • Windows-Partition (“C:”) blockweise kopieren:
    # dd if=/dev/sda2 of=/dev/sdc2
    234231808+0 records in
    234231808+0 records out
    119926685696 bytes (120 GB) copied, 2271.83 s, 52.8 MB/s
  • NTFS-Dateisystem auf /dev/sdc2 vergrößern:
    • GParted starten.
    • /dev/sdc2 rechtsklicken und Check wählen.
    • In der Ausgabe kann man verfolgen, dass ntfsresize --force --force /dev/sdc2 aufgerufen wird. Es wird der Größenunterschied zwischen Dateisystem und Partition aufgeführt: Current volume size: 119926682112 bytes (119927 MB) vs. Current device size: 512004284416 bytes (512005 MB). Am Ende steht ein Successfully resized NTFS on device '/dev/sdc2'. Da keine Daten verschoben werden müssen, dauert dieser Vorgang nur wenige Sekunden.

Bei den obig angegebenen Schritten ist zu beachten, dass ein Vertauschen/Verschreiben bei den Gerätepfaden (/dev/sd*) unverzeihlich ist. Bitte drei mal denken und kontrollieren, bevor Ihr auf Enter drückt. Ansonsten habt Ihr ja sicherlich eine Sicherung Eurer persönlichen Daten.

6) Rückbau des Datenträgers in das Produktivsystem (5 Minuten)

Der neue Datenträger mit der Windows-Installation wird in das Produktivsystem zurückgebaut. Per BIOS-Einstellung wird das Produktivsystem vom neuen Datenträger gestartet. Es sind keine weiteren Schritte erforderlich.


Etwa 25 Minuten Arbeit für eine Betriebssystemmigration (+ Zeit für Datentransfer). Das ist schnell. Warum gewährleistet obige Strategie Zuverlässigkeit? Der durchgeführte Prozess stellt sicher, dass sich zwischen der alten und der neuen Situation nur zwei Kleinigkeiten geändert haben: die Bezeichnung des Datenträgers und die Größe des NTFS-Dateisystems in dem Windows (mehrheitlich) installiert ist. Aus Sicht des BIOS und aus Sicht des Betriebssystems ist der Rest des Gesamtsystems äquivalent zum vorherigen Zustand. Mit dieser Betrachtungsweise ist es leicht zu verstehen, dass die Migration mit hoher Wahrscheinlichkeit gelingt. Die präzise Kontrolle der Geschehnisse erleichtert auch eine etwaige Fehlersuche: gibt es nach Schritt 6 ein Problem, so muss es an einem der beiden geänderten Parameter liegen (in der Tat: UEFI Systeme mögen bedingt durch den Wechsel des Geräte-Namens bzw. der Geräte-ID einen weiteren kleinen Schritt erfordern).

Bei Eurem nächsten Wechsel des Systemdatenträgers solltet Ihr die Migration systematisch durchführen. Wenn Ihr den Prozess unter Kontrolle habt, dann gelingt er mit hoher Wahrscheinlichkeit. Traut lieber den quelloffenen Standard-Werkzeugen welche in professionellen Umgebungen eingesetzt werden als den großen Versprechungen von (kommerziell erhältlichen) Software-Assistenten für Privantanwender.