mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
The xenstore header xs.h is producing conflicts with other software[1]. xs is a too short identifier and does not matche the library. Renaming the headers to xenstore.h and xenstore_lib.h is the easiest way to make them easy recognizable and prevent furthe problems. [1]: http://bugs.debian.org/668550 [ Also update QEMU_TAG, to bring in corresponding change to qemu-xen-traditional. -iwj ] Signed-off-by: Bastian Blank <waldi@debian.org> Signed-off-by: Ian Campbell <ian.campbell@citrix.com> Acked-by: Ian Jackson <ian.jackson@eu.citrix.com> Committed-by: Ian Jackson <ian.jackson@eu.citrix.com> --HG-- rename : tools/xenstore/xs.h => tools/xenstore/xenstore.h rename : tools/xenstore/xs_lib.h => tools/xenstore/xenstore_lib.h
149 lines
3.4 KiB
C
149 lines
3.4 KiB
C
/*
|
|
* xen-lowmemd: demo VIRQ_ENOMEM
|
|
* Andres Lagar-Cavilla (GridCentric Inc.)
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <xenctrl.h>
|
|
#include <xenstore.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
static evtchn_port_t virq_port = -1;
|
|
static xc_evtchn *xce_handle = NULL;
|
|
static xc_interface *xch = NULL;
|
|
static struct xs_handle *xs_handle = NULL;
|
|
|
|
void cleanup(void)
|
|
{
|
|
if (virq_port > -1)
|
|
xc_evtchn_unbind(xce_handle, virq_port);
|
|
if (xce_handle)
|
|
xc_evtchn_close(xce_handle);
|
|
if (xch)
|
|
xc_interface_close(xch);
|
|
if (xs_handle)
|
|
xs_daemon_close(xs_handle);
|
|
}
|
|
|
|
/* Never shrink dom0 below 1 GiB */
|
|
#define DOM0_FLOOR (1 << 30)
|
|
#define DOM0_FLOOR_PG ((DOM0_FLOOR) >> 12)
|
|
|
|
/* Act if free memory is less than 92 MiB */
|
|
#define THRESHOLD (92 << 20)
|
|
#define THRESHOLD_PG ((THRESHOLD) >> 12)
|
|
|
|
#define BUFSZ 512
|
|
void handle_low_mem(void)
|
|
{
|
|
xc_dominfo_t dom0_info;
|
|
xc_physinfo_t info;
|
|
unsigned long long free_pages, dom0_pages, diff, dom0_target;
|
|
char data[BUFSZ], error[BUFSZ];
|
|
|
|
if (xc_physinfo(xch, &info) < 0)
|
|
{
|
|
perror("Getting physinfo failed");
|
|
return;
|
|
}
|
|
|
|
free_pages = (unsigned long long) info.free_pages;
|
|
printf("Available free pages: 0x%llx:%llux\n",
|
|
free_pages, free_pages);
|
|
|
|
/* Don't do anything if we have more than the threshold free */
|
|
if ( free_pages >= THRESHOLD_PG )
|
|
return;
|
|
diff = THRESHOLD_PG - free_pages;
|
|
|
|
if (xc_domain_getinfo(xch, 0, 1, &dom0_info) < 1)
|
|
{
|
|
perror("Failed to get dom0 info");
|
|
return;
|
|
}
|
|
|
|
dom0_pages = (unsigned long long) dom0_info.nr_pages;
|
|
printf("Dom0 pages: 0x%llx:%llu\n", dom0_pages, dom0_pages);
|
|
dom0_target = dom0_pages - diff;
|
|
if (dom0_target <= DOM0_FLOOR_PG)
|
|
return;
|
|
|
|
printf("Shooting for dom0 target 0x%llx:%llu\n",
|
|
dom0_target, dom0_target);
|
|
|
|
snprintf(data, BUFSZ, "%llu", dom0_target);
|
|
if (!xs_write(xs_handle, XBT_NULL,
|
|
"/local/domain/0/memory/target", data, strlen(data)))
|
|
{
|
|
snprintf(error, BUFSZ,"Failed to write target %s to xenstore", data);
|
|
perror(error);
|
|
}
|
|
}
|
|
|
|
int main(int argc, char *argv[])
|
|
{
|
|
int rc;
|
|
|
|
atexit(cleanup);
|
|
|
|
xch = xc_interface_open(NULL, NULL, 0);
|
|
if (xch == NULL)
|
|
{
|
|
perror("Failed to open xc interface");
|
|
return 1;
|
|
}
|
|
|
|
xce_handle = xc_evtchn_open(NULL, 0);
|
|
if (xce_handle == NULL)
|
|
{
|
|
perror("Failed to open evtchn device");
|
|
return 2;
|
|
}
|
|
|
|
xs_handle = xs_daemon_open();
|
|
if (xs_handle == NULL)
|
|
{
|
|
perror("Failed to open xenstore connection");
|
|
return 3;
|
|
}
|
|
|
|
if ((rc = xc_evtchn_bind_virq(xce_handle, VIRQ_ENOMEM)) == -1)
|
|
{
|
|
perror("Failed to bind to domain exception virq port");
|
|
return 4;
|
|
}
|
|
|
|
virq_port = rc;
|
|
|
|
while(1)
|
|
{
|
|
evtchn_port_t port;
|
|
|
|
if ((port = xc_evtchn_pending(xce_handle)) == -1)
|
|
{
|
|
perror("Failed to listen for pending event channel");
|
|
return 5;
|
|
}
|
|
|
|
if (port != virq_port)
|
|
{
|
|
char data[BUFSZ];
|
|
snprintf(data, BUFSZ, "Wrong port, got %d expected %d", port, virq_port);
|
|
perror(data);
|
|
return 6;
|
|
}
|
|
|
|
if (xc_evtchn_unmask(xce_handle, port) == -1)
|
|
{
|
|
perror("Failed to unmask port");
|
|
return 7;
|
|
}
|
|
|
|
printf("Got a virq kick, time to get work\n");
|
|
handle_low_mem();
|
|
}
|
|
|
|
return 0;
|
|
}
|