#!/usr/bin/env perl

use strict;
require "sys/ioctl.ph";

sub SIZEOF_HYPERCALL () { 24; }
sub STRUCT_PRIVCMD_HYPERCALL () {"L P";}
sub IOCTL_PRIVCMD_HYPERCALL ()
        { &_IOC( &_IOC_NONE, ord('P'), 0, SIZEOF_HYPERCALL );}
sub __HYPERVISOR_dom0_op () {7;}
sub DOM0_INTERFACE_VERSION () {0xaaaa0010;}
sub DOM0_SETDOMAINMAXMEM () {28;}
sub STRUCT_DOM0_OP_PREFIX () {"L L";}
sub STRUCT_SETDOMAINMAXMEM () {STRUCT_DOM0_OP_PREFIX."L x4 L";}
sub XEN_PRIVCMD () {"/proc/xen/privcmd";}

sub setdomainmaxmem($$) {
    my ($domain,$bytes) = @_;
    my $msg = pack(STRUCT_SETDOMAINMAXMEM,DOM0_SETDOMAINMAXMEM,
        DOM0_INTERFACE_VERSION,  $domain, $bytes);
    my $cmd = pack(STRUCT_PRIVCMD_HYPERCALL,__HYPERVISOR_dom0_op,$msg);
    open(XEN,XEN_PRIVCMD) or die "$!\n";
    ioctl(XEN, IOCTL_PRIVCMD_HYPERCALL, $cmd) or die "ioctl: $!";
    close XEN;
}

my ($bytes,$suffix) = $ARGV[1] =~ m/(^\d+)([mMkKgG])/;
$bytes<<=10 if $suffix =~ m/[kK]/;
$bytes<<=20 if $suffix =~ m/[mM]/;
$bytes<<=30 if $suffix =~ m/[gG]/;

printf "set domain $ARGV[0] to $bytes\n";
setdomainmaxmem($ARGV[0],$bytes);

