Resizing virtual disks

You have have:

  • installed virtualization software e.g. VirtualBox on your native, host machine e.g. OSX
  • created a virtual machine on your host machine
  • installed an OS (guest e.g. Windows) on the virtual machine
  • proceeded to use the virtual machine, and filled up it’s disk !!!!

Don’t make this mistake: scrimp on virtual disks

When you create a virtual machine you choose a maximum size for its virtual disk.  Don’t scrimp. You are choosing a limit, and it doesn’t immediately use that space on your host machine (if the virtual disk is dynamically allocated.)  But it does fix the size that the guest machine will use.  Then when you install the guest OS, it creates a partition and file system on that size of disk.  (But it only uses, i.e. dynamically allocates, blocks on the host that have been written to by the guest.)  The dynamic allocation refers to the host.(The guest dynamically fills the disk, and that must also involve ‘allocation’ but that’s another thing.)

(If you make a virtual disk very large (as large as the real disk on the host), then when a guest fills up the disk, any ‘disk full’ problems will manifest themselves in the host first.)

If you make a virtual disk too small, when the guest fills it up, ‘disk full’ problems manifest themselves on the guest (even though the host may have plenty of disk space left.)

An Example

I created a Windows virtual machine with only a 25G virtual disk.  My purpose for the machine is software development.  By the time I installed Windows, Dropbox, Cygwin, and Qt, the disk was already full.

Solutions

Possible solutions:

  • struggle by careful managment of what you install and delete (tedious and fraught with error)
  • discard the virtual machine and start over (not pleasant if you have installed much software on the guest.)
  • resize the virtual disk (enlarging it.)

Instructions for resizing a virtual disk

Here are nice instructions for resizing a virtual disk, for the case where:

  • host is Windows
  • guest is Windows
  • virtualization software is VirtualBox OR VMWare
  • GParted is used as a LiveCD for repartioning

You can adapt the instructions for other cases.

One interesting aspect is: you temporarily boot the guest machine (usually running Windows) with a LiveCD (running Linux? and including GParted) so that you can repartition the disk that the guest Windows will see.  (As discussed, you can’t repartition the Windows C: disk while Windows is running.)

It can get confusing very fast.

Print to PDF

Why can you print to PDF but not to SVG?

Because PDF has the notion of pages, while SVG does not.

PDF and SVG are competing formats.  Both are scalable without loss of resolution.

PDF was invented at Adobe.  It displays documents portably, that is, the same on all platforms.  It originally was mostly about text documents, which are paginated.  Thus the notion of pages is built into PDF.

SVG displays a drawing portably (again, the same on all platforms.)  But a drawing that can be scaled does not need pagination, when displayed on a computer screen.  You can just pan, and zoom in and out on the one drawing.

It is only when you want to print an SVG to paper that you need worry about pagination.   But  whatever choice of pagination you make at printing time cannot be saved in a  SVG file.  (There exists a proposal to add pagination to the SVG standard.)

(PDF stands for Portable Document Format.  A Document object often supports pagination.)

X11 XCB xpyb xev -> pyxev, for XI2 touch events and gestures

This is about my effort to write a Python version of xev, to snoop on XInput2 events from a touchpad.

Context

You have:

  • a user input device (e.g. mouse, trackpad, touchscreen. Specifically a Wacom Bamboo Pen and Touch.)
  • Linux (or OSX)
  • X11 (not Wayland)
  • Qt
  • PyQt
  • a Python app

You want to debug why your input device is not working with your app as you expect (specifically, not yielding QGestureEvent to my app.)

Architecture of the software stack

The above list is a stack, or pipe, of software.

The user input device has a microprocessor and firmware inside it, converting your physical actions to a stream of data, here to a USB connector.  Here, the standard for the input stream is ‘HID’.

The Linux kernel has ‘kernel drivers’ that understand physical devices and interface them to ‘logical devices.’  A ‘device’ looks like a file, e.g. /dev/input/mouse0.  Here ‘evdev’ is one name of the ‘kernel driver’ that understands input devices that follow the HID standard.

X11 has ‘input drivers’ that read a ‘logical device’ and interface to a queue of events, internal to the X Server.  Here xf86-input-wacom is one name of the ‘input driver.’

Part of the X Server reads  from the internal queue and interfaces to X Clients.  That part of the XServer dispatches events to windows on your screen.  Here we are mainly concerned with events of the XInput2 protocol.

Qt on Linux is an X Client.

And so forth, more later as I update this post.

A debugging strategy

Any part of the stack could be failing to transmit events as you expect.

One strategy is to read about and understand the code for the whole stack.  Few people have the time to do that.

A common debugging strategy for such a pipeline is to snoop on the pipeline.  You use tools that tap (tee off) the interfaces between parts of the pipe.  The tools typically display the events on the console.

You can use a binary strategy, starting in the middle and continuing on the half that seems to be failing, and recurse until you locate the problem.

Or you can start at the beginning of the pipe, snooping towards the other end until you find the problem.

Snooping the kernel driver

>ls /dev/input

Will show you what input logical devices you have.

Plug in your input device.  Here it is a hot-pluggable USB interface device.  So the kernel should recognize it and create a ‘device’ file for it.
‘>ls /dev/input’ again will show a new entry: ‘wacom-touch’.

>cat /dev/input/wacom-touch

will display that file on your console.  SInce the file is a stream without end (EOF) the above command will not return until you hit Ctl-C.  If you now physically manipulate your input device (move the mouse or touch it), you will see the output from the device.  It will be gobbledy-gook since the data is binary and the console wants printable characters (ASCII.)  Anyway, you know the kernel driver is working with the input device, more or less.

Snooping the X input driver

There are two tools for snooping X events:

  • xev – displays events from a window of an XServer
  • xscope – displays all events from an XServer

These read events from the XServer and display them.

Unfortunately, these tools are not commonly distributed in binary form with most Linux distributions, so these commands may not be on your machine.  You might need to download source and build the tools.

Worse, these tools seem to be outdated: they don’t display touch events from XInput2.2, which was released only in the last few years.

Also, the source for these tools is in the C language, so it will be hard for most people to update the tools themselves.  (That explains why they are not updated already: C programmers are rare, and don’t have time to update tools that few people use, and for a system that many people consider ancient, X11.)

Rewriting xev in Python

So I thought I would rewrite xev in Python, at least enough to display touch events.  If rewritten in Python, maybe it will be kept up to date, since more programmers can read and fix it.

Tools for rewriting xev in Python

xcb is a simplified interface to the X Protocol

xpyb is a Python binding to xcb

pyxev is a Python app (which I am writing) that does the same thing as xev: draws a window and snoops on X11 protocol events from the window, writing them to the console.

Basics of xpyb

Your Python app must do something like:

import xcb
from xcb.xproto import *

You must also import optional modules for the X extensions you will use:

import xcb.render
import xcb.xinput

(I had to look in the configure and Makefile to figure this out.)

Installing xpyb

xpyb is the colloquial name for the  package.  It is known as  python-xpyb package in Ubuntu Software Center.  It is known as ‘xcb’ when you import it in Python.

Unfortunately, it does not include a submodule for interfacing the to XInput extension (only for the XCore (core) protocol and the XRender extension.  Thus we must download the source for xpyb and build it.

>./autogen.sh
>.configure --enable-xinput
>make
>sudo make install

Note the option to build the module ‘xinput’.

Understanding a xpyb binding to extension protocol

In a Python app using xpyb, importing a module of the xpyb package lets you call methods on the module, which in effect are message/replies to the extension e.g.  the AllowDeviceEvents() of the XInputExtension.

Such methods control the extension, or query attributes of the extension.

But that’s secondary to my purpose: to snoop the XInput2 (touch) events coming from an input device.

Documentation of XInput2

There it says that my app (an X client) needs to subscribe to touch events by calling QueryVersion.

(So I am stuck here, not sure whether to call xcb.xinput.GetExtensionVersion() or xcb.core.QueryVersion.)

(Also, explain the need to call methods on an object the binding module returns versus calling methods on the binding module.)

Generic Events from an X Extension

I assumed that something like ‘TouchEvent’ and ‘TouchEventMask’ would be defined by xpyb.  Not so.  Apparently, such events are ‘Generic Events’, i.e. events wrapped inside a core event?

X11 Generic Events

But ‘Generic Event’ doesn’t seem to be defined in xpyb.  Stuck here also.

More later…at this point I am reading about the X11 protocol and trying to understand how to translate from its documentation into xpyb calls to XCB.

The XCB documentation is very abstract: basically it says: “we don’t document every call, the translation from X11 calls to XCB calls is canonical, and you should be able to translate yourself.’

If you want to help, I will put the pyxev code on github and we can work on it together.