Manual merge.

This commit is contained in:
kaf24@firebug.cl.cam.ac.uk committed 2005-08-03 09:22:03 +00:00
commit 00244f3e7b
31 files changed
+306 -127

No files matched your search

+1 -1
View File
@@ -115,7 +115,7 @@ config-update-pae:
ifeq ($(XEN_TARGET_X86_PAE),y)
sed -e 's!^CONFIG_HIGHMEM4G=y$$!\# CONFIG_HIGHMEM4G is not set!;s!^\# CONFIG_HIGHMEM64G is not set$$!CONFIG_HIGHMEM64G=y!' $(CONFIG_FILE) > $(CONFIG_FILE)- && mv $(CONFIG_FILE)- $(CONFIG_FILE)
else
@: # do nothing yet
grep '^CONFIG_HIGHMEM64G=y' $(CONFIG_FILE) >/dev/null && ( sed -e 's!^CONFIG_HIGHMEM64G=y$$!\# CONFIG_HIGHMEM64G is not set!;s!^\# CONFIG_HIGHMEM4G is not set$$!CONFIG_HIGHMEM4G=y!' $(CONFIG_FILE) > $(CONFIG_FILE)- && mv $(CONFIG_FILE)- $(CONFIG_FILE) ) || true
endif
# never delete any intermediate files.
-2
View File
@@ -61,7 +61,6 @@ SUBDIRS += arch/xen/drivers/console
SUBDIRS += arch/xen/drivers/evtchn
SUBDIRS += arch/xen/drivers/blkif
SUBDIRS += arch/xen/drivers/netif
#SUBDIRS += arch/xen/drivers/usbif
SUBDIRS += arch/xen/drivers/balloon
ifdef CONFIG_XEN_PRIVILEGED_GUEST
SUBDIRS += arch/xen/drivers/dom0
@@ -72,7 +71,6 @@ CORE_FILES += arch/xen/drivers/evtchn/drv.o
CORE_FILES += arch/xen/drivers/console/drv.o
DRIVERS += arch/xen/drivers/blkif/drv.o
DRIVERS += arch/xen/drivers/netif/drv.o
DRIVERS += arch/xen/drivers/usbif/drv.o
ifdef CONFIG_XEN_PRIVILEGED_GUEST
CORE_FILES += arch/xen/drivers/dom0/drv.o
endif
+2 -12
View File
@@ -16,14 +16,10 @@ mainmenu_option next_comment
comment 'Xen'
bool 'Support for privileged operations (domain 0)' CONFIG_XEN_PRIVILEGED_GUEST
bool 'Device-driver domain (physical device access)' CONFIG_XEN_PHYSDEV_ACCESS
if [ "$CONFIG_XEN_PHYSDEV_ACCESS" = "y" ]; then
bool 'USB-device backend driver' CONFIG_XEN_USB_BACKEND
fi
bool 'Scrub memory before freeing it to Xen' CONFIG_XEN_SCRUB_PAGES
bool 'Network-device frontend driver' CONFIG_XEN_NETDEV_FRONTEND
bool 'Block-device frontend driver' CONFIG_XEN_BLKDEV_FRONTEND
bool 'Block-device uses grant tables' CONFIG_XEN_BLKDEV_GRANT
bool 'USB-device frontend driver' CONFIG_XEN_USB_FRONTEND
endmenu
# The IBM S/390 patch needs this.
define_bool CONFIG_NO_IDLE_HZ y
@@ -267,7 +263,7 @@ fi
source drivers/char/Config.in
if [ "$CONFIG_XEN_PHYSDEV_ACCESS" = "y" -o "$CONFIG_XEN_USB_FRONTEND" = "y" ]; then
if [ "$CONFIG_XEN_PHYSDEV_ACCESS" = "y" ]; then
source drivers/media/Config.in
fi
@@ -302,14 +298,8 @@ if [ "$CONFIG_XEN_PHYSDEV_ACCESS" = "y" ]; then
endmenu
fi
if [ "$CONFIG_XEN_PHYSDEV_ACCESS" = "y" -o "$CONFIG_XEN_USB_FRONTEND" = "y" ]; then
if [ "$CONFIG_XEN_USB_FRONTEND" = "y" -o "$CONFIG_XEN_USB_BACKEND" = "y" ]; then
define_bool CONFIG_USB y
fi
source drivers/usb/Config.in
fi
if [ "$CONFIG_XEN_PHYSDEV_ACCESS" = "y" ]; then
source drivers/usb/Config.in
source net/bluetooth/Config.in
fi
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.12-xen0
# Mon Jul 25 09:48:34 2005
# Wed Aug 3 09:54:56 2005
#
CONFIG_XEN=y
CONFIG_ARCH_XEN=y
@@ -18,8 +18,8 @@ CONFIG_XEN_BLKDEV_GRANT=y
CONFIG_XEN_NETDEV_BACKEND=y
CONFIG_XEN_BLKDEV_FRONTEND=y
CONFIG_XEN_NETDEV_FRONTEND=y
#CONFIG_XEN_NETDEV_GRANT_TX=y
#CONFIG_XEN_NETDEV_GRANT_RX=y
# CONFIG_XEN_NETDEV_GRANT_TX is not set
# CONFIG_XEN_NETDEV_GRANT_RX is not set
# CONFIG_XEN_NETDEV_FRONTEND_PIPELINED_TRANSMITTER is not set
# CONFIG_XEN_BLKDEV_TAP is not set
# CONFIG_XEN_SHADOW_MODE is not set
@@ -93,11 +93,11 @@ CONFIG_GENERIC_IOMAP=y
# CONFIG_M586 is not set
# CONFIG_M586TSC is not set
# CONFIG_M586MMX is not set
# CONFIG_M686 is not set
CONFIG_M686=y
# CONFIG_MPENTIUMII is not set
# CONFIG_MPENTIUMIII is not set
# CONFIG_MPENTIUMM is not set
CONFIG_MPENTIUM4=y
# CONFIG_MPENTIUM4 is not set
# CONFIG_MK6 is not set
# CONFIG_MK7 is not set
# CONFIG_MK8 is not set
@@ -112,15 +112,15 @@ CONFIG_MPENTIUM4=y
# CONFIG_X86_GENERIC is not set
CONFIG_X86_CMPXCHG=y
CONFIG_X86_XADD=y
CONFIG_X86_L1_CACHE_SHIFT=7
CONFIG_X86_L1_CACHE_SHIFT=5
CONFIG_RWSEM_XCHGADD_ALGORITHM=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
CONFIG_X86_PPRO_FENCE=y
CONFIG_X86_WP_WORKS_OK=y
CONFIG_X86_INVLPG=y
CONFIG_X86_BSWAP=y
CONFIG_X86_POPAD_OK=y
CONFIG_X86_GOOD_APIC=y
CONFIG_X86_INTEL_USERCOPY=y
CONFIG_X86_USE_PPRO_CHECKSUM=y
# CONFIG_HPET_TIMER is not set
# CONFIG_HPET_EMULATE_RTC is not set
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.12-xen0
# Wed Jun 29 10:01:20 2005
# Tue Aug 2 23:55:35 2005
#
CONFIG_XEN=y
CONFIG_ARCH_XEN=y
@@ -18,6 +18,8 @@ CONFIG_XEN_BLKDEV_GRANT=y
CONFIG_XEN_NETDEV_BACKEND=y
CONFIG_XEN_BLKDEV_FRONTEND=y
CONFIG_XEN_NETDEV_FRONTEND=y
# CONFIG_XEN_NETDEV_GRANT_TX is not set
# CONFIG_XEN_NETDEV_GRANT_RX is not set
# CONFIG_XEN_NETDEV_FRONTEND_PIPELINED_TRANSMITTER is not set
# CONFIG_XEN_BLKDEV_TAP is not set
# CONFIG_XEN_SHADOW_MODE is not set
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.12-xenU
# Mon Jul 25 10:06:06 2005
# Wed Aug 3 09:57:44 2005
#
CONFIG_XEN=y
CONFIG_ARCH_XEN=y
@@ -15,8 +15,8 @@ CONFIG_NO_IDLE_HZ=y
CONFIG_XEN_BLKDEV_GRANT=y
CONFIG_XEN_BLKDEV_FRONTEND=y
CONFIG_XEN_NETDEV_FRONTEND=y
#CONFIG_XEN_NETDEV_GRANT_TX=y
#CONFIG_XEN_NETDEV_GRANT_RX=y
# CONFIG_XEN_NETDEV_GRANT_TX is not set
# CONFIG_XEN_NETDEV_GRANT_RX is not set
# CONFIG_XEN_NETDEV_FRONTEND_PIPELINED_TRANSMITTER is not set
# CONFIG_XEN_BLKDEV_TAP is not set
# CONFIG_XEN_SHADOW_MODE is not set
@@ -90,11 +90,11 @@ CONFIG_GENERIC_IOMAP=y
# CONFIG_M586 is not set
# CONFIG_M586TSC is not set
# CONFIG_M586MMX is not set
# CONFIG_M686 is not set
CONFIG_M686=y
# CONFIG_MPENTIUMII is not set
# CONFIG_MPENTIUMIII is not set
# CONFIG_MPENTIUMM is not set
CONFIG_MPENTIUM4=y
# CONFIG_MPENTIUM4 is not set
# CONFIG_MK6 is not set
# CONFIG_MK7 is not set
# CONFIG_MK8 is not set
@@ -109,15 +109,15 @@ CONFIG_MPENTIUM4=y
# CONFIG_X86_GENERIC is not set
CONFIG_X86_CMPXCHG=y
CONFIG_X86_XADD=y
CONFIG_X86_L1_CACHE_SHIFT=7
CONFIG_X86_L1_CACHE_SHIFT=5
CONFIG_RWSEM_XCHGADD_ALGORITHM=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
CONFIG_X86_PPRO_FENCE=y
CONFIG_X86_WP_WORKS_OK=y
CONFIG_X86_INVLPG=y
CONFIG_X86_BSWAP=y
CONFIG_X86_POPAD_OK=y
CONFIG_X86_GOOD_APIC=y
CONFIG_X86_INTEL_USERCOPY=y
CONFIG_X86_USE_PPRO_CHECKSUM=y
# CONFIG_HPET_TIMER is not set
# CONFIG_HPET_EMULATE_RTC is not set
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.12-xenU
# Thu Jul 7 11:43:14 2005
# Tue Aug 2 23:56:13 2005
#
CONFIG_XEN=y
CONFIG_ARCH_XEN=y
@@ -15,6 +15,8 @@ CONFIG_NO_IDLE_HZ=y
CONFIG_XEN_BLKDEV_GRANT=y
CONFIG_XEN_BLKDEV_FRONTEND=y
CONFIG_XEN_NETDEV_FRONTEND=y
# CONFIG_XEN_NETDEV_GRANT_TX is not set
# CONFIG_XEN_NETDEV_GRANT_RX is not set
# CONFIG_XEN_NETDEV_FRONTEND_PIPELINED_TRANSMITTER is not set
# CONFIG_XEN_BLKDEV_TAP is not set
# CONFIG_XEN_SHADOW_MODE is not set
@@ -1529,7 +1529,7 @@ void __init smp_cpus_done(unsigned int max_cpus)
extern irqreturn_t smp_reschedule_interrupt(int, void *, struct pt_regs *);
extern irqreturn_t smp_call_function_interrupt(int, void *, struct pt_regs *);
void __init smp_intr_init(void)
void smp_intr_init(void)
{
int cpu = smp_processor_id();
@@ -1546,3 +1546,28 @@ void __init smp_intr_init(void)
smp_call_function_interrupt,
SA_INTERRUPT, callfunc_name[cpu], NULL));
}
static void smp_intr_exit(void)
{
int cpu = smp_processor_id();
free_irq(per_cpu(resched_irq, cpu), NULL);
unbind_ipi_from_irq(RESCHEDULE_VECTOR);
free_irq(per_cpu(callfunc_irq, cpu), NULL);
unbind_ipi_from_irq(CALL_FUNCTION_VECTOR);
}
void smp_suspend(void)
{
/* XXX todo: take down time and ipi's on all cpus */
local_teardown_timer_irq();
smp_intr_exit();
}
void smp_resume(void)
{
/* XXX todo: restore time and ipi's on all cpus */
smp_intr_init();
local_setup_timer_irq();
}
@@ -860,6 +860,8 @@ void start_hz_timer(void)
void time_suspend(void)
{
/* nothing */
teardown_irq(per_cpu(timer_irq, 0), &irq_timer);
unbind_virq_from_irq(VIRQ_TIMER);
}
/* No locking required. We are only CPU running, and interrupts are off. */
@@ -874,10 +876,25 @@ void time_resume(void)
processed_system_time =
per_cpu(shadow_time, smp_processor_id()).system_timestamp;
per_cpu(processed_system_time, 0) = processed_system_time;
per_cpu(timer_irq, 0) = bind_virq_to_irq(VIRQ_TIMER);
(void)setup_irq(per_cpu(timer_irq, 0), &irq_timer);
}
#ifdef CONFIG_SMP
static char timer_name[NR_CPUS][15];
void local_setup_timer_irq(void)
{
int cpu = smp_processor_id();
if (cpu == 0)
return;
per_cpu(timer_irq, cpu) = bind_virq_to_irq(VIRQ_TIMER);
sprintf(timer_name[cpu], "timer%d", cpu);
BUG_ON(request_irq(per_cpu(timer_irq, cpu), timer_interrupt,
SA_INTERRUPT, timer_name[cpu], NULL));
}
void local_setup_timer(void)
{
int seq, cpu = smp_processor_id();
@@ -888,10 +905,17 @@ void local_setup_timer(void)
per_cpu(shadow_time, cpu).system_timestamp;
} while (read_seqretry(&xtime_lock, seq));
per_cpu(timer_irq, cpu) = bind_virq_to_irq(VIRQ_TIMER);
sprintf(timer_name[cpu], "timer%d", cpu);
BUG_ON(request_irq(per_cpu(timer_irq, cpu), timer_interrupt,
SA_INTERRUPT, timer_name[cpu], NULL));
local_setup_timer_irq();
}
void local_teardown_timer_irq(void)
{
int cpu = smp_processor_id();
if (cpu == 0)
return;
free_irq(per_cpu(timer_irq, cpu), NULL);
unbind_virq_from_irq(VIRQ_TIMER);
}
#endif
@@ -284,7 +284,7 @@ void unbind_ipi_from_irq(int ipi)
evtchn_op_t op;
int cpu = smp_processor_id();
int evtchn = per_cpu(ipi_to_evtchn, cpu)[ipi];
int irq = irq_to_evtchn[evtchn];
int irq = evtchn_to_irq[evtchn];
spin_lock(&irq_mapping_update_lock);
@@ -16,6 +16,7 @@ static int errno;
#include <asm-xen/xen-public/dom0_ops.h>
#include <asm-xen/linux-public/suspend.h>
#include <asm-xen/queues.h>
#include <asm-xen/xenbus.h>
void machine_restart(char * __unused)
{
@@ -90,6 +91,10 @@ static void __do_suspend(void)
#define gnttab_resume() do{}while(0)
#endif
#ifdef CONFIG_SMP
extern void smp_suspend(void);
extern void smp_resume(void);
#endif
extern void time_suspend(void);
extern void time_resume(void);
extern unsigned long max_pfn;
@@ -114,6 +119,12 @@ static void __do_suspend(void)
time_suspend();
#ifdef CONFIG_SMP
smp_suspend();
#endif
xenbus_suspend();
ctrl_if_suspend();
irq_suspend();
@@ -153,6 +164,12 @@ static void __do_suspend(void)
ctrl_if_resume();
xenbus_resume();
#ifdef CONFIG_SMP
smp_resume();
#endif
time_resume();
blkdev_resume();
@@ -84,9 +84,6 @@ static struct timer_list balloon_timer;
/* Flag for dom0 xenstore workaround */
static int balloon_xenbus_init=0;
/* Init Function */
void balloon_init_watcher(void);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
/* Use the private and mapping fields of struct page as a list. */
#define PAGE_TO_LIST(p) ( (struct list_head *)&p->private )
@@ -354,27 +351,21 @@ static void watch_target(struct xenbus_watch *watch, const char *node)
}
/*
Try to set up our watcher, if not already set
*/
void balloon_init_watcher(void)
/* Init Function - Try to set up our watcher, if not already set. */
void balloon_init_watcher(void)
{
int err;
if(!xen_start_info.store_evtchn)
{
if (!xen_start_info.store_evtchn) {
IPRINTK("Delaying watcher init until xenstore is available\n");
return;
}
down(&xenbus_lock);
if(! balloon_xenbus_init)
{
if (!balloon_xenbus_init) {
err = register_xenbus_watch(&xb_watch);
if(err)
{
if (err) {
/* BIG FAT FIXME: dom0 sequencing workaround
* dom0 can't set a watch on memory/target until
* after the tools create it. So, we have to watch
@@ -384,16 +375,13 @@ void balloon_init_watcher(void)
* non-existant keys
*/
register_xenbus_watch(&root_watch);
}
else
{
} else {
IPRINTK("Balloon xenbus watcher initialized\n");
balloon_xenbus_init = 1;
}
}
up(&xenbus_lock);
}
EXPORT_SYMBOL(balloon_init_watcher);
@@ -36,6 +36,8 @@
#include <linux/err.h>
#include "xenbus_comms.h"
static unsigned int xb_irq;
#define RINGBUF_DATASIZE ((PAGE_SIZE / 2) - sizeof(struct ringbuf_head))
struct ringbuf_head
{
@@ -202,14 +204,17 @@ int xb_read(void *data, unsigned len)
return 0;
}
/* Set up interrpt handler off store event channel. */
/* Set up interrupt handler off store event channel. */
int xb_init_comms(void)
{
int err, irq;
int err;
irq = bind_evtchn_to_irq(xen_start_info.store_evtchn);
if (!xen_start_info.store_evtchn)
return 0;
err = request_irq(irq, wake_waiting, SA_SHIRQ, "xenbus", &xb_waitq);
xb_irq = bind_evtchn_to_irq(xen_start_info.store_evtchn);
err = request_irq(xb_irq, wake_waiting, 0, "xenbus", &xb_waitq);
if (err) {
printk(KERN_ERR "XENBUS request irq failed %i\n", err);
unbind_evtchn_from_irq(xen_start_info.store_evtchn);
@@ -222,3 +227,13 @@ int xb_init_comms(void)
return 0;
}
void xb_suspend_comms(void)
{
if (!xen_start_info.store_evtchn)
return;
free_irq(xb_irq, &xb_waitq);
unbind_evtchn_from_irq(xen_start_info.store_evtchn);
}
@@ -3,6 +3,7 @@
#define _XENBUS_COMMS_H
int xs_init(void);
int xb_init_comms(void);
void xb_suspend_comms(void);
/* Low level routines. */
int xb_write(const void *data, unsigned len);
@@ -29,6 +29,7 @@
#include <asm-xen/hypervisor.h>
#include <asm-xen/xenbus.h>
#include <asm-xen/balloon.h>
#include <linux/kernel.h>
#include <linux/err.h>
#include <linux/string.h>
@@ -295,6 +296,19 @@ static struct xenbus_watch dev_watch = {
.callback = dev_changed,
};
void xenbus_suspend(void)
{
/* We keep lock, so no comms can happen as page moves. */
down(&xenbus_lock);
xb_suspend_comms();
}
void xenbus_resume(void)
{
xb_init_comms();
up(&xenbus_lock);
}
/* called from a thread in privcmd/privcmd.c */
int do_xenbus_probe(void *unused)
{
@@ -37,7 +37,7 @@ do { \
*/
#define ptep_set_access_flags(__vma, __address, __ptep, __entry, __dirty) \
do { \
set_pte_at((__vma)>vm_mm, (__address), __ptep, __entry); \
set_pte_at((__vma)->vm_mm, (__address), __ptep, __entry); \
flush_tlb_page(__vma, __address); \
} while (0)
#endif
@@ -129,6 +129,7 @@
extern int bind_virq_to_irq(int virq);
extern void unbind_virq_from_irq(int virq);
extern int bind_ipi_to_irq(int ipi);
extern int bind_ipi_on_cpu_to_irq(int ipi);
extern void unbind_ipi_from_irq(int ipi);
extern int bind_evtchn_to_irq(int evtchn);
extern void unbind_evtchn_from_irq(int evtchn);
@@ -127,6 +127,7 @@
extern int bind_virq_to_irq(int virq);
extern void unbind_virq_from_irq(int virq);
extern int bind_ipi_to_irq(int ipi);
extern int bind_ipi_on_cpu_to_irq(int ipi);
extern void unbind_ipi_from_irq(int ipi);
extern int bind_evtchn_to_irq(int evtchn);
extern void unbind_evtchn_from_irq(int evtchn);
@@ -48,4 +48,7 @@ extern spinlock_t balloon_lock;
#define balloon_lock(__flags) spin_lock_irqsave(&balloon_lock, __flags)
#define balloon_unlock(__flags) spin_unlock_irqrestore(&balloon_lock, __flags)
/* Init Function - Try to set up our watcher, if not already set. */
void balloon_init_watcher(void);
#endif /* __ASM_BALLOON_H__ */
@@ -115,4 +115,8 @@ struct xenbus_watch
int register_xenbus_watch(struct xenbus_watch *watch);
void unregister_xenbus_watch(struct xenbus_watch *watch);
/* Called from xen core code. */
void xenbus_suspend(void);
void xenbus_resume(void);
#endif /* _ASM_XEN_XENBUS_H */
+4 -1
View File
@@ -279,9 +279,12 @@ int xc_linux_save(int xc_handle, int fd, u32 dom);
* @parm fd the file descriptor to restore a domain from
* @parm dom the id of the domain
* @parm nr_pfns the number of pages
* @parm store_evtchn the store event channel for this domain to use
* @parm store_mfn returned with the mfn of the store page
* @return 0 on success, -1 on failure
*/
int xc_linux_restore(int xc_handle, int io_fd, u32 dom, unsigned long nr_pfns);
int xc_linux_restore(int xc_handle, int io_fd, u32 dom, unsigned long nr_pfns,
unsigned int store_evtchn, unsigned long *store_mfn);
int xc_linux_build(int xc_handle,
u32 domid,
+6 -2
View File
@@ -48,7 +48,8 @@ read_exact(int fd, void *buf, size_t count)
return r;
}
int xc_linux_restore(int xc_handle, int io_fd, u32 dom, unsigned long nr_pfns)
int xc_linux_restore(int xc_handle, int io_fd, u32 dom, unsigned long nr_pfns,
unsigned int store_evtchn, unsigned long *store_mfn)
{
dom0_op_t op;
int rc = 1, i, n, k;
@@ -464,10 +465,13 @@ int xc_linux_restore(int xc_handle, int io_fd, u32 dom, unsigned long nr_pfns)
}
ctxt.user_regs.esi = mfn = pfn_to_mfn_table[pfn];
p_srec = xc_map_foreign_range(
xc_handle, dom, PAGE_SIZE, PROT_WRITE, mfn);
xc_handle, dom, PAGE_SIZE, PROT_READ | PROT_WRITE, mfn);
p_srec->resume_info.nr_pages = nr_pfns;
p_srec->resume_info.shared_info = shared_info_frame << PAGE_SHIFT;
p_srec->resume_info.flags = 0;
*store_mfn = p_srec->resume_info.store_mfn =
pfn_to_mfn_table[p_srec->resume_info.store_mfn];
p_srec->resume_info.store_evtchn = store_evtchn;
munmap(p_srec, PAGE_SIZE);
/* Uncanonicalise each GDT frame number. */
+17 -11
View File
@@ -20,7 +20,7 @@
#define DEBUG 0
#if 1
#define ERR(_f, _a...) fprintf ( stderr, _f , ## _a )
#define ERR(_f, _a...) do { fprintf(stderr, _f , ## _a); fflush(stderr); } while (0)
#else
#define ERR(_f, _a...) ((void)0)
#endif
@@ -643,6 +643,22 @@ int xc_linux_save(int xc_handle, int io_fd, u32 dom)
goto out;
}
/* Map the suspend-record MFN to pin it. The page must be owned by
dom for this to succeed. */
p_srec = xc_map_foreign_range(xc_handle, dom,
sizeof(*p_srec), PROT_READ | PROT_WRITE,
ctxt.user_regs.esi);
if (!p_srec){
ERR("Couldn't map suspend record");
goto out;
}
/* Canonicalize store mfn. */
if ( !translate_mfn_to_pfn(&p_srec->resume_info.store_mfn) ) {
ERR("Store frame is not in range of pseudophys map");
goto out;
}
print_stats( xc_handle, dom, 0, &stats, 0 );
/* Now write out each data page, canonicalising page tables as we go... */
@@ -983,16 +999,6 @@ int xc_linux_save(int xc_handle, int io_fd, u32 dom)
}
}
/* Map the suspend-record MFN to pin it. The page must be owned by
dom for this to succeed. */
p_srec = xc_map_foreign_range(xc_handle, dom,
sizeof(*p_srec), PROT_READ,
ctxt.user_regs.esi);
if (!p_srec){
ERR("Couldn't map suspend record");
goto out;
}
if (nr_pfns != p_srec->nr_pfns )
{
ERR("Suspend record nr_pfns unexpected (%ld != %ld)",
+5 -5
View File
@@ -254,11 +254,11 @@ static PyObject *xspy_get_permissions(PyObject *self, PyObject *args,
val = PyList_New(perms_n);
for (i = 0; i < perms_n; i++, perms++) {
PyObject *p = Py_BuildValue("{s:i,s:i,s:i,s:i,s:i}",
"dom", perms->id,
"read", (perms->perms & XS_PERM_READ),
"write", (perms->perms & XS_PERM_WRITE),
"create", (perms->perms & XS_PERM_CREATE),
"owner", (perms->perms & XS_PERM_OWNER));
"dom", perms->id,
"read", (perms->perms & XS_PERM_READ),
"write", (perms->perms & XS_PERM_WRITE),
"exist", (perms->perms & XS_PERM_ENOENT_OK),
"owner", (perms->perms & XS_PERM_OWNER));
PyList_SetItem(val, i, p);
}
exit:
+34 -2
View File
@@ -6,6 +6,7 @@
import errno
import os
import re
import select
import sxp
from string import join
@@ -64,6 +65,13 @@ def save(xd, fd, dominfo):
if l.rstrip() == "suspend":
log.info("suspending %d" % dominfo.id)
xd.domain_shutdown(dominfo.id, reason='suspend')
if dominfo.store_channel:
try:
dominfo.db.releaseDomain(dominfo.id)
except Exception, ex:
log.warning("error in domain release on xenstore: %s",
ex)
pass
dominfo.state_wait("suspended")
log.info("suspend %d done" % dominfo.id)
child.tochild.write("done\n")
@@ -76,6 +84,11 @@ def save(xd, fd, dominfo):
if child.wait() != 0:
raise XendError("xc_save failed: %s" % lasterr)
if dominfo.store_channel:
dominfo.store_channel.close()
dominfo.db['store_channel'].delete()
dominfo.db.saveDB(save=True)
dominfo.store_channel = None
xd.domain_destroy(dominfo.id)
return None
@@ -107,8 +120,13 @@ def restore(xd, fd):
raise XendError(
"not a valid guest state file: pfn count out of range")
if dominfo.store_channel:
evtchn = dominfo.store_channel.port2
else:
evtchn = 0
cmd = [PATH_XC_RESTORE, str(xc.handle()), str(fd),
str(dominfo.id), str(nr_pfns)]
str(dominfo.id), str(nr_pfns), str(evtchn)]
log.info("[xc_restore] " + join(cmd))
child = xPopen3(cmd, True, -1, [fd, xc.handle()])
child.tochild.close()
@@ -128,7 +146,21 @@ def restore(xd, fd):
lasterr = l.rstrip()
if fd == child.fromchild.fileno():
l = child.fromchild.readline()
log.info(l.rstrip())
while l:
m = re.match(r"^(store-mfn) (\d+)\n$", l)
if m:
if dominfo.store_channel:
dominfo.store_mfn = int(m.group(2))
if dominfo.store_mfn >= 0:
dominfo.db.introduceDomain(dominfo.id,
dominfo.store_mfn,
dominfo.store_channel)
dominfo.exportToDB(save=True, sync=True)
log.info(l.rstrip())
try:
l = child.fromchild.readline()
except:
l = None
if filter(lambda (fd, event): event & select.POLLHUP, r):
break
+12 -4
View File
@@ -16,15 +16,23 @@
int
main(int argc, char **argv)
{
unsigned int xc_fd, io_fd, domid, nr_pfns;
unsigned int xc_fd, io_fd, domid, nr_pfns, evtchn;
int ret;
unsigned long mfn;
if (argc != 5)
errx(1, "usage: %s xcfd iofd domid nr_pfns", argv[0]);
if (argc != 6)
errx(1, "usage: %s xcfd iofd domid nr_pfns evtchn", argv[0]);
xc_fd = atoi(argv[1]);
io_fd = atoi(argv[2]);
domid = atoi(argv[3]);
nr_pfns = atoi(argv[4]);
evtchn = atoi(argv[5]);
return xc_linux_restore(xc_fd, io_fd, domid, nr_pfns);
ret = xc_linux_restore(xc_fd, io_fd, domid, nr_pfns, evtchn, &mfn);
if (ret == 0) {
printf("store-mfn %li\n", mfn);
fflush(stdout);
}
return ret;
}
+19
View File
@@ -160,3 +160,22 @@ async 2 write /test3 create contents
1 waitwatch' | ./xs_test 2>&1`" = "1:/test2/foo:token
1:contents2
1:waitwatch timeout" ]
# We can watch something which doesn't exist.
[ "`echo '1 watch /dir/subdir token
2 mkdir /dir/subdir
1 waitwatch' | ./xs_test 2>&1`" = "1:/dir/subdir:token" ]
# If we don't have permission, we won't see event (rm).
[ "`echo '1 setid 1
1 watch /dir/subdir token
setperm /dir 0 NONE
rm /dir/subdir
1 waitwatch' | ./xs_test 2>&1`" = "1:waitwatch timeout" ]
# If we don't have permission, we won't see event (create).
[ "`echo '1 setid 1
1 watch /dir/subdir token
mkdir /dir/subdir
write /dir/subdir/entry create contents
1 waitwatch' | ./xs_test 2>&1`" = "1:waitwatch timeout" ]
+4 -1
View File
@@ -14,7 +14,10 @@ run_test()
PID=`cat /tmp/pid`
rm /tmp/pid
else
PID=`./xenstored_test --output-pid`
./xenstored_test --output-pid --trace-file=testsuite/tmp/trace --no-fork > /tmp/pid 2> testsuite/tmp/xenstored_errors &
while [ ! -s /tmp/pid ]; do sleep 0; done
PID=`cat /tmp/pid`
rm /tmp/pid
fi
if sh -e $2 $1; then
if [ -s testsuite/tmp/vgout ]; then
+46 -36
View File
@@ -504,11 +504,13 @@ void send_error(struct connection *conn, int error)
{
unsigned int i;
for (i = 0; error != xsd_errors[i].errnum; i++)
if (i == ARRAY_SIZE(xsd_errors) - 1)
corrupt(conn, "Unknown error %i (%s)", error,
strerror(error));
for (i = 0; error != xsd_errors[i].errnum; i++) {
if (i == ARRAY_SIZE(xsd_errors) - 1) {
eprintf("xenstored: error %i untranslatable", error);
i = 0; /* EINVAL */
break;
}
}
send_reply(conn, XS_ERROR, xsd_errors[i].errstring,
strlen(xsd_errors[i].errstring) + 1);
}
@@ -705,7 +707,7 @@ static enum xs_perm_type perm_for_id(domid_t id,
/* Owners and tools get it all... */
if (!id || perms[0].id == id)
return XS_PERM_READ|XS_PERM_WRITE|XS_PERM_CREATE|XS_PERM_OWNER;
return XS_PERM_READ|XS_PERM_WRITE|XS_PERM_OWNER;
for (i = 1; i < num; i++)
if (perms[i].id == id)
@@ -714,20 +716,13 @@ static enum xs_perm_type perm_for_id(domid_t id,
return perms[0].perms;
}
/* We have a weird permissions system. You can allow someone into a
* specific node without allowing it in the parents. If it's going to
* fail, however, we don't want the errno to indicate any information
* about the node. */
static int check_with_parents(struct connection *conn, const char *node,
int errnum)
/* What do parents say? */
static enum xs_perm_type ask_parents(struct connection *conn,
const char *node)
{
struct xs_permissions *perms;
unsigned int num;
/* We always tell them about memory failures. */
if (errnum == ENOMEM)
return errnum;
do {
node = get_parent(node);
perms = get_perms(conn->transaction, node, &num);
@@ -739,10 +734,23 @@ static int check_with_parents(struct connection *conn, const char *node,
if (!perms)
corrupt(conn, "No permissions file at root");
if (!(perm_for_id(conn->id, perms, num) & XS_PERM_READ))
return EACCES;
return perm_for_id(conn->id, perms, num);
}
return errnum;
/* We have a weird permissions system. You can allow someone into a
* specific node without allowing it in the parents. If it's going to
* fail, however, we don't want the errno to indicate any information
* about the node. */
static int errno_from_parents(struct connection *conn, const char *node,
int errnum)
{
/* We always tell them about memory failures. */
if (errnum == ENOMEM)
return errnum;
if (ask_parents(conn, node) & XS_PERM_READ)
return errnum;
return EACCES;
}
char *canonicalize(struct connection *conn, const char *node)
@@ -774,24 +782,26 @@ bool check_node_perms(struct connection *conn, const char *node,
}
perms = get_perms(conn->transaction, node, &num);
/* No permissions. If we want to create it and
* it doesn't exist, check parent directory. */
if (!perms && errno == ENOENT && (perm & XS_PERM_CREATE)) {
char *parent = get_parent(node);
if (!parent)
return false;
perms = get_perms(conn->transaction, parent, &num);
}
if (!perms) {
errno = check_with_parents(conn, node, errno);
if (perms) {
if (perm_for_id(conn->id, perms, num) & perm)
return true;
errno = EACCES;
return false;
}
if (perm_for_id(conn->id, perms, num) & perm)
return true;
/* If it's OK not to exist, we consult parents. */
if (errno == ENOENT && (perm & XS_PERM_ENOENT_OK)) {
if (ask_parents(conn, node) & perm)
return true;
/* Parents say they should not know. */
errno = EACCES;
return false;
}
errno = check_with_parents(conn, node, EACCES);
/* They might not have permission to even *see* this node, in
* which case we return EACCES even if it's ENOENT or EIO. */
errno = errno_from_parents(conn, node, errno);
return false;
}
@@ -928,9 +938,9 @@ static void do_write(struct connection *conn, struct buffered_data *in)
if (streq(vec[1], XS_WRITE_NONE))
mode = XS_PERM_WRITE;
else if (streq(vec[1], XS_WRITE_CREATE))
mode = XS_PERM_WRITE|XS_PERM_CREATE;
mode = XS_PERM_WRITE|XS_PERM_ENOENT_OK;
else if (streq(vec[1], XS_WRITE_CREATE_EXCL))
mode = XS_PERM_WRITE|XS_PERM_CREATE;
mode = XS_PERM_WRITE|XS_PERM_ENOENT_OK;
else {
send_error(conn, EINVAL);
return;
@@ -949,7 +959,7 @@ static void do_write(struct connection *conn, struct buffered_data *in)
}
/* Not going to create it? */
if (!(mode & XS_PERM_CREATE)) {
if (streq(vec[1], XS_WRITE_NONE)) {
send_error(conn, ENOENT);
return;
}
@@ -983,7 +993,7 @@ static void do_write(struct connection *conn, struct buffered_data *in)
static void do_mkdir(struct connection *conn, const char *node)
{
node = canonicalize(conn, node);
if (!check_node_perms(conn, node, XS_PERM_WRITE|XS_PERM_CREATE)) {
if (!check_node_perms(conn, node, XS_PERM_WRITE|XS_PERM_ENOENT_OK)) {
send_error(conn, errno);
return;
}
+13 -4
View File
@@ -95,10 +95,19 @@ static int destroy_watch_event(void *_event)
return 0;
}
static void add_event(struct watch *watch, const char *node)
static void add_event(struct connection *conn,
struct watch *watch, const char *node)
{
struct watch_event *event;
/* Check read permission: no permission, no watch event.
* If it doesn't exist, we need permission to read parent.
*/
if (!check_node_perms(conn, node, XS_PERM_READ|XS_PERM_ENOENT_OK)) {
fprintf(stderr, "No permission for %s\n", node);
return;
}
if (watch->relative_path) {
node += strlen(watch->relative_path);
if (*node == '/') /* Could be "" */
@@ -132,9 +141,9 @@ void fire_watches(struct connection *conn, const char *node, bool recurse)
list_for_each_entry(watch, &i->watches, list) {
if (is_child(node, watch->node))
add_event(watch, node);
add_event(i, watch, node);
else if (recurse && is_child(watch->node, node))
add_event(watch, watch->node);
add_event(i, watch, watch->node);
else
continue;
/* If connection not doing anything, queue this. */
@@ -206,7 +215,7 @@ void do_watch(struct connection *conn, struct buffered_data *in)
relative = !strstarts(vec[0], "/");
vec[0] = canonicalize(conn, vec[0]);
if (!check_node_perms(conn, vec[0], XS_PERM_READ)) {
if (!is_valid_nodename(vec[0])) {
send_error(conn, errno);
return;
}
+1 -1
View File
@@ -30,7 +30,7 @@ enum xs_perm_type {
XS_PERM_READ = 1,
XS_PERM_WRITE = 2,
/* Internal use. */
XS_PERM_CREATE = 4,
XS_PERM_ENOENT_OK = 4,
XS_PERM_OWNER = 8,
};
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.