Monday, 27 January 2014

A Plea for Social Equality

True democratic wealth is time: everybody has 24 hours of it a day.

The significant social inequality of the day is that some peoples time is not exchangeable for much value, while other peoples time is very much in demand and exchangeable at a high rate.

I simplify somewhat, for a person can sometimes exert control over their exchange rate by means of how much effort they put in; but even at maximum effort there is still a large disparity between the exchangeable values of the time of different people, or in different locations.

In the corrupt imperial west there is a notion that 8 hours of effort per day should be exchangeable for necessities of life (and some discretionary comforts) but the opportunity to make this exchange is not granted equally to all people (and nor is the standard of life).

In the name of social conscience and humanity, this inequality is often reasonably addressed by moving a surfeit of value from those who found favourable exchange, to those who who found a poor rate of exchange.

Yet paradoxically, the extreme inequality of those who found no exchange is addressed by an attempt to provide the value of life necessities with no exchange required.

This does not introduce equality but instead introduces further inequality for in transferring the surfeit of value to those who find no exchange, it leaves them with a surfeit of time. It reduces them to the status of beggar and provides no way to contribute.

It would be more equitable to provide opportunity of exchange to those who found no exchange, making all equal contributors to society from the universal and collective wealth of time, and condemning none to the status of beggar.

TLDR: Or in other words, why in the UK when taxes are going up, and public works are going down, why, are we paying people to do nothing?

It is no socialist triumph to lose the working class and gain another idle class (however unwilling).

Let the time of each be valued equally - sufficient for life, and let all contribute.

And here's hoping for a shorter working day for all, enough time for dancing and singing.

Friday, 29 November 2013

Makefile mash

The dumbest thing so far seen in a makefile:

ECHO      = `which echo`

Apart from the apparent fact that the writer assumes that the external command which is on the path but echo might not be (hint: they don't want to use the built-in echo for whatever reason), the main error is that everywhere $(ECHO) is used it will be replaced with `which echo`

The author probably intends

 ECHO      := $(shell which echo)

which will define ECHO to be something like /bin/echo which is what they intended.

Note the := otherwise which echo would be evaluated each time $(ECHO) is used.


Friday, 4 October 2013

TalkTalk moble data configuration

Today I learned that TalkTalk mobile users can txt 40127 with: TALK and get the configuration sent back.

Monday, 16 September 2013

Why are setjmp /volatile hacks STILL needed?

We all know the old gotcha of setjmp (but I'm going to recount it anyway) which is that when longjmp is executed (and setjmp appears to complete again, but this time with a non-zero result) some (or all) of the original register set will be restored.

Any local variables which were (possibly temporarily) stored in the local registers reserved for such use could appear to revert back to their previous values until they are re-freshed from the stack frame.

And so all pre-existing local variables that would be accessed after the longjmp should be declared volatile so that they will not be fetched from the registers.

Well... why is there no special #pragma or other option attached to the setjmp function indicating a register clobber-list to the compiler that all the local registers could have been modified and it should not depend on cached values any more?

Why do we need such a pragma? Why can't we #define setjmp to be something like:

#define setjmp(env) (setjmp(env) + __asm__ volatile ("mov %%eax,0" : : : "memory" "ebx" "ecx" "etc..." ));

I'm sure that example is insufficient, but I also think that some working method could be contrived, so I'll work on it...

and then...


OK, having tried; I realise that first problems are

  • not stopping the extra return from setjmp from using stale values in restored registers
  • that the correct values from the registers will not have been copied back into the stack frame, but will somewhere be pushed on the stack by a called function where we can't retrieve them

But the worst problem is that the optimiser can remove operations that ought to have been noticeable:

#include 
#include 

int getint() {
  static int i=3;

  i+=2;

  return i;
}

int main(void) {
  static jmp_buf j;
  volatile int x;
  int y;
  x = getint();
  y = getint();
  if (setjmp(j) == 1) {
    asm volatile("nop" : : : "memory", "ecx", "edx");
    printf("%d %d\n", x, y);
    return 0;
  }
  y++;
  x++;
//  printf("%d %d\n", x, y); // Second Printf
  longjmp(j, 1);
}

Unless the second printf is uncommented, the line for y++ is not emitted even at optimisation -O1
The reason is that y is not used after that point, even though the longjmp (acting somewhat like a goto) might have the effect of returning to a point where the y is used.

If I replace the longjmp with a goto then y++ is emitted in the code.

The first lesson: Use volatile in the way everyone says you should; all variables to be accessed in the second return of setjmp should be volatile.

The second lession, some contrivance of:
blah: if (setjmp(j) == 1) {
...
  if (never_true()) goto blah; else longjmp(j, 1);

generates the right code too by recognizing the effect of the goto rather than the longjmp however this cannot be sensibly managed as there can easily be multiple setjmp in a function.

So I still search for some means to cause a block of code to commit all temporary registers back to the stack frame before calling another function, and a means to cause all temporary registers to be flushed on second return from setjmp (although this may be covered by the first case).

further reading


I read http://stackoverflow.com/a/7734313 that:
The returns_twice attribute tells the compiler that a function may return more than one time. The compiler will ensure that all registers are dead before calling such a function and will emit a warning about the variables that may be clobbered after the second return from the function. Examples of such functions are setjmp and vfork. The longjmp-like counterpart of such function, if any, might need to be marked with the noreturn attribute.
So in fact gcc at least does evict any registers before calling setjmp but that doesn't prevent local variables being cached later on and not comitted to the stack frame before longjmp is called.

So I really just need a way to mark that functions might call longjmp and that temporary registers should be evicted before calling; but I know deep down that this is rubbish as longjmp might be called even from a signal handler.

Thursday, 12 September 2013

Can all for-loops be transformed to while-loops?

I previously wrote on using for as a brace-less scope using a trick by Jens Gustedt but I wanted to be able to propagate any break clause that might be used within that scope so that it would take effect in an enclosing loop or case statement.

I found a method that worked for gcc but which made use of it's compound statements.

#include 

main() {
  int a;
  for (a=1; a<=2; a++) {
    printf("Main context a=%d\n", a);

    for (int o = 0; o >=0; ({ if (o == 1) { printf("Detected break\n"); break; } }) )
      for (int i=0; !o && (o=1), i==0; o=-1, i=-1 ) { printf("Inner context\n"); break; }
  }
}

produces:
Main context a=1
Inner context
Detected break

which shows that the break statement in the inner-context was propagated to take effect in the top level loop, by means of the break statement in the compound statement of the second loop.

Thats nice, and it is the intended effect, but a for-loop of this form

for ( expression-1 ; expression-2 ; expression-3 ) statement;

is meant to be equivalent to this while loop:

expression-1 ;
while ( expression-2) {
  statement
  expression-3 ;
}

In my case, expression-3 consisted of ({ if (o == 1) { printf("Detected break\n"); break; } }) and the break clause took affect in the containing scope - no doubt because it was not part of the statement of it's associated for-loop.

But it would transform into this while-loop:

expression-1 ;
while ( expression-2) {
  statement
  printf("Detected break\n"); break ;
}

Can there be any doubt that in this while-loop, the break statement would terminate the loop itself and not any containing scope? I don't think so.

Therefore gcc compound statements in for loops open the door to high-class trickery which cannot be achieved the normal way.

using sed to split a stream into 2 streams

An expensive file listing operation needs to invoke an action on the listed files.

xargs is normally the candidate for that, but what when there are multiple file types with varied actions?

Normally I would pipe into a bash scriptlet like this

... | while read "$file" ; do if [ $(expr "$file" :  "$pattern" ) = "0" ] ; then ... ; else ...

but it lacks the bulk appeal of xargs which can reduce the number of command invocations by thousands of times for a large file list.

So here I make use of sed, and bash's >( ... ) construct to open a subshell and substitute a magic filename that refers a file descriptor that writes to the input of the subshell. (The substituted filename is typically something like /dev/fd/63). The newline can be entered on a terminal session with ^V ^J. It is also essential that there are no spaces between the ' and >( and also between the ) and ', otherwise the sed script will be presented to sed as multiple arguments instead of one argument.

... | sed -e '/\.ko$/{w'>( xargs strip --strip-debug )'
;d}' | xargs strip

This allows kernel objects to be stripped of debug only but other objects to be stripped entirely.

An alternative would be to use tee and a separate grep

... | tee >( grep '\.ko$' | xargs strip --strip-debug ) | grep -v '\.ko$' | xargs strip

Thursday, 1 August 2013

Installing ESXi Server with PXE and a serial console

I wanted to install ESXi Server 5.1 on a machine on the other side of the word. I have remote power control, and serial console and access to it's DHCP server and another server on that network, so I thought I could manage it.

I read many half-baked, typo-ridden and downright misleading sets of instructions so I thought I'd write some half-baked, typo-ridden and downright misleading instructions which worked for me.

Generally follow the instructions on the vSphere 5 Doumentation Center with a dash of this but here is what I did:

Unpack the iso into a tftp subdirectory (vmw for me), and so my pxelinux config file is here - and note that I am using the mboot.c32 from the vmware iso but the menu.c32 from my pxelinux installation, otherwise mboot tries to fetch a file called -c.

DEFAULT menu.c32
MENU TITLE ESXi-5.x.x-XXXXXX-full Boot Menu
NOHALT 1
PROMPT 0
TIMEOUT 80
LABEL install
  KERNEL /vmw/mboot.c32
  APPEND -c /vmw/boot.cfg gdbPort=none logPort=none tty2Port=com1
  ipappend 2
  MENU LABEL ESXi-5.x.x-XXXXXX-full ^Installer

LABEL hddboot
 LOCALBOOT 0x80
 MENU LABEL ^Boot from local disk

edit boot.cfg (unpacked from the iso), note that the leading / from all the filenames has been removed, a prefix has been added and some nonsense about comports added to kernelopt

bootstate=0
title=Loading ESXi installer
prefix=vmw
kernel=tboot.b00
kernelopt=runweasel com1_Port=0x3f8 tty2Port=com1 gdbPort=none logPort=none 
modules=b.b00 --- useropts.gz --- k.b00 --- chardevs.b00 --- a.b00 --- user.b00 --- s.v00 --- ata_pata.v00 --- ata_pata.v01 --- ata_pata.v02 --- ata_pata.v03 --- ata_pata.v04 --- ata_pata.v05 --- ata_pata.v06 --- ata_pata.v07 --- block_cc.v00 --- ehci_ehc.v00 --- weaselin.t00 --- esx_dvfi.v00 --- xlibs.v00 --- ima_qla4.v00 --- ipmi_ipm.v00 --- ipmi_ipm.v01 --- ipmi_ipm.v02 --- misc_cni.v00 --- misc_dri.v00 --- net_be2n.v00 --- net_bnx2.v00 --- net_bnx2.v01 --- net_cnic.v00 --- net_e100.v00 --- net_e100.v01 --- net_enic.v00 --- net_forc.v00 --- net_igb.v00 --- net_ixgb.v00 --- net_nx_n.v00 --- net_r816.v00 --- net_r816.v01 --- net_s2io.v00 --- net_sky2.v00 --- net_tg3.v00 --- net_vmxn.v00 --- ohci_usb.v00 --- sata_ahc.v00 --- sata_ata.v00 --- sata_sat.v00 --- sata_sat.v01 --- sata_sat.v02 --- sata_sat.v03 --- sata_sat.v04 --- scsi_aac.v00 --- scsi_adp.v00 --- scsi_aic.v00 --- scsi_bnx.v00 --- scsi_fni.v00 --- scsi_hps.v00 --- scsi_ips.v00 --- scsi_lpf.v00 --- scsi_meg.v00 --- scsi_meg.v01 --- scsi_meg.v02 --- scsi_mpt.v00 --- scsi_mpt.v01 --- scsi_mpt.v02 --- scsi_qla.v00 --- scsi_qla.v01 --- scsi_rst.v00 --- uhci_usb.v00 --- tools.t00 --- xorg.v00 --- imgdb.tgz --- imgpayld.tgz
build=
updated=0

It only remained to de-program F11 as a magic key for gnome-terminal as that key was needed to accept the license.