Vergrößern einer virtuellen Festplatte in VirtualBox

Kennen Sie dass? Sie wollen etwas in einer virtuellen Linux/Windows/etc... Umgebung ausprobieren und legen dafür eine virtuelle Maschine mit einer virtuellen Festplatte mit 10GB an. In der Regel reicht das oft. Aber jetzt stellen Sie fest das der Platz eben nicht mehr ausreicht. Das Anlegen einer neuen virtuellen Datei und das Neuaufsetzen des Betriebssystems sowie das kopieren der Daten, alles ist ziemlich Zeitaufwändig. Sie denken sich, ok, mal schauen ob ich mir mit vboxmanage helfen kann. Es gibt da den Parameter: "modifiymedium" und dieser hat die wunderbare Option: --resize. "Toll" denken Sie, und probieren das gleich mal aus. Und dann die herbe Enttäuschung:

0%...
Progress state: VBOX_E_NOT_SUPPORTED
VBoxManage.exe: error: Resize medium operation for this format is not implemented yet!

Hmm... blöd... na gut... aber es gibt noch eine andere Möglichkeit (Voraussetzung das Gastbetriebssystem ist Linux):

Dafür brauchen wir drei Dinge:

  1. Genug Platz für die neue virtuelle Festplatte.
  2. Eine bestehende virtuelle Linux-Box wo wir die neue Festplatte einbinden können.
  3. gparted in dieser Linux-Box



Los gehts:

  1. Erstellen Sie mit vboxmanage createmedium eine neue virtuelle Festplatten-Datei. Wir gehen mal davon aus daß diese eine feste Größe (hier 15GB) haben soll.

    vboxmanage createmedium disk --filename d:\VirtualBox\debian\debian.vdi --size 15001 --format VDI
  2. Jetzt kommt der wichtige Befehl: Wir kopieren die Daten von der alten virtuellen Festplatte auf die neue um. Dafür bemühen wir wieder vboxmanage:

    vboxmanage clonemedium d:\VirtualBox\debian\debian_harddisk.vdi d:\VirtualBox\debian\debian.vdi --existing

    Wichtig ist die Option --existing
  3. Jetzt brauchen wir nur noch mit gparted die der Partition anzupassen und die neue Platte einzubinden und wir sind fertig. Dazu starten wir fix das Linux, starten gparted und passen die Größe an. Danach herunterfahren Medium in die virtuelle Box einbinden und wir sind fertig. Falls sich die Größe der Partition nicht ändern lässt, liegt das an der UUID der Partition. Es sind jetzt zwei Partitionen mit der selben UUID im System und die neue virtuelle Partition braucht eine neue ID. Das geht mit den Tools tune2fs und uuid. Um die UUID der Partition /dev/sdb1 zu ändern, folgenden Befehl verwenden: tune2fs /dev/sdb1 -U `uuid`
  4. Letzter Schritt:

    Durch die neue UUID werden noch folgende Änderungen nötig: die neue UUID in /etc/fstab bekannt machen und update-grub ausführen.
    • die Partition mounten und proc, sys, dev einbinden, danach dahin chrooten: chroot /media/{USER}/{UUID} /bin/bash
    • sudo nano /etc/fstab und bei / die UUID durch die neue erstetzen ( falls die SWAP Partition auch betroffen ist, auch hier änderen)
    • den Bootmanager Grub aktualisieren mit update-grub
Image: 

Binäre Darstellung eines Integers

Wenn man viel mit der hardwarenahen Darstellung von Zahlen zu tun hat, sei es in der Automatisierung oder in der Grafikprogrammierung, dann kommt es häufiger vor dass man eine binäre Darstellung von einer Ganzzahl braucht, um diese auf dem Terminal oder in einer Logdatei auszugeben. Viele Sprachen bieten dafür eigene Funktionen an, wie zum Beispiel Javascripts .toString(2). Diese sind jedoch oft unzureichend. Z.B will man die alle Stellen angezeigt bekommen und nicht nur jene vom höchsten belegten Bit herunter.


Eine einfache Funktion die Abhilfe schaft und mit vielen Sprachen funktioniert, könnte so aussehen:

in C/C++

void printBinarie(int z) {
    for (int i = sizeof(z); i>=0; --i) {
        if ( (z >> 1) & 0x1) {
            print("1");
        } else {
            print("0");
        }
    }
}

 

in Python(3):

def printBinary(zahl, nBits):
 for i in range(0, nBits):
  if (zahl >> (nBits-1-i)) & 0x1:
   print('1', end='')
  else:
   print('0', end='')
 print()

 

in Javascript:

function printBinary(zahl, nBits) {
    var i = nBits-1;
    var binStr = "";
    for (;i>=0; i--) {
        if ( (zahl >> i) & 0x1 )
            binStr = binStr + "1";
        else
            binStr = binStr + "0";
    }
    document.getElementById("ouput").innerHtml = binStr;
}

Probleme mit Windows 10 kumulativem November Update

Neulich hat Microsoft mal wieder ein grösseres Update für Windows 10 herausgebracht. Mein PC bekam dieses am 17. Januar 2016. Nach ein wenig Recherche im Internet handelte es sich wahrscheinlich um das kumulative November Update. Ärgerlich, dass das Update erst Wochen später in meinem PC zur Verfügung steht. Aber es kam schlimmer! Nach dem Update gab es Fehler. Das Update selber dauerte etwa eine Stunde. Nach dem Update, schien alles zu funktionieren. Erst nach dem Login poppte ein Informationsfenster auf: "Sie wurden mit einem temporären Profil angemeldet." Na hoppla, wieso dass denn? Irgendwas schien das Update zerschossen zu haben. Nach ein wenig Recherche im Internet, fand ich einen Hinweis auf eine Registry Eintrag. Unter diesem werden in Windows die Benutzer Profile referenziert. Der besagte Reigstry Pfad lautet:

HKLM\Software\Microsoft\Windows NT\CurrentVersion\ProfileList

Der besagte Hinweis aus dem Internet brachte keinen Erfolg (es war etwas mit Verschobenen Benutzerpfaden). Jedoch sah ich mir die Schlüssel etwas genauer an: Dabei fiel mir auf, dass einige Profile Keys ein .bak am Ende hatten. Das war ungewöhnlich. Bei diesen Einträgen handelte es sich genau um die Einträge der "echten" Benutzer Profile. Das .bak entfernt, neu gestartet, und die Sache lief wieder.

Image: 

Programmier Fehler: void new* = malloc(len)

Neulich bin ich bei der Integration einer Open Source Bibliothek in eine Anwendung auf ein Codefragment gestoßen, wo ich dachte, "das darf doch nicht Wahr sein". Aber seht selbst:


#if !HAVE_STRDUP
#undef strdup
char *strdup(const char *s)
{
	size_t len = strlen(s) + 1;
	void *new = malloc(len);
	if(new == NULL) return NULL;
	return (char *)memcpy(new, s, len);
}
#endif

Na, entdeckt? Kleiner Tipp: versuchen Sie mal den Code mit einem C++ Compiler zu übersetzen.

Sowas dämliches dürfte einem Softwareentwickler eigentlich nicht passieren. Aber es kommt vor wie man sieht. Der Code hat durchaus seine Berechtigung: wenn er in einer reinen C Umgebung verwendet wird! new ist ein reiner C++ Bezeichner. Jedoch findet sich in der Header Datei dann wieder so etwas:

#if defined(__cplusplus)
extern "C" {
#endif

Also kann davon ausgegangen werden, dass dieser Code tatsächlich für die Kompilierung mit einem C++ Compiler vorgesehen war. Wieso diese grandiose Fehlleistung dem Programmierer nicht aufgefallen ist, könnte an folgendem Grund liegen: Der Code hat es nie aus einer (Linux) Umgebung herausgeschaft, wo strdup() zu der Standardbibliothek gehört und der oben angegebene Code ja gerade auf Systemen verwendet werden soll wo strdup() nicht zu der Standardbibliothek dazugehört. Mit ./configure wird dieses ausgetestet und dann die config.h erzeugt worin dann HAVE_STRDUP definiert wird wenn strdup() existiert. Und hier ist auch der Haken: Wenn strdup() nun existiert, wird HAVE_STRDUP definiert. Und dann fliegt der obige Code schon beim Preprozessor raus und der Compiler sieht null davon. Fazit: grandiose Programmierer Fehlleistung mit vorprogrammiertem Selbstschutz.

Subscribe to Front page feed