direct-io.hg
changeset 7329:74d56b7ff46c
Merged
line diff
1.1 --- a/.hgignore Tue Oct 11 15:50:21 2005 -0600 1.2 +++ b/.hgignore Tue Oct 11 16:57:44 2005 -0600 1.3 @@ -161,6 +161,7 @@ 1.4 ^tools/xenstore/xs_tdb_dump$ 1.5 ^tools/xenstore/xs_test$ 1.6 ^tools/xenstore/xs_watch_stress$ 1.7 +^tools/xenstore/xsls$ 1.8 ^tools/xentrace/xenctx$ 1.9 ^tools/xentrace/xentrace$ 1.10 ^xen/BLOG$
2.1 --- a/Makefile Tue Oct 11 15:50:21 2005 -0600 2.2 +++ b/Makefile Tue Oct 11 16:57:44 2005 -0600 2.3 @@ -66,7 +66,7 @@ install-tools: 2.4 $(MAKE) -C tools install 2.5 2.6 install-kernels: 2.7 - for i in $(XKERNELS) ; do $(MAKE) $$i-build || exit 1; done 2.8 + for i in $(XKERNELS) ; do $(MAKE) $$i-install || exit 1; done 2.9 2.10 install-docs: 2.11 sh ./docs/check_pkgs && $(MAKE) -C docs install || true 2.12 @@ -179,7 +179,7 @@ uninstall: 2.13 rm -rf $(D)/usr/$(LIBDIR)/libxenctrl* $(D)/usr/$(LIBDIR)/libxenguest* 2.14 rm -rf $(D)/usr/$(LIBDIR)/libxenstore* 2.15 rm -rf $(D)/usr/$(LIBDIR)/python/xen $(D)/usr/$(LIBDIR)/xen 2.16 - rm -rf $(D)/usr/libexec/xen 2.17 + rm -rf $(D)/usr/$(LIBDIR)/xen/bin 2.18 rm -rf $(D)/usr/sbin/xen* $(D)/usr/sbin/netfix $(D)/usr/sbin/xm 2.19 rm -rf $(D)/usr/share/doc/xen 2.20 rm -rf $(D)/usr/share/xen
3.1 --- a/buildconfigs/Rules.mk Tue Oct 11 15:50:21 2005 -0600 3.2 +++ b/buildconfigs/Rules.mk Tue Oct 11 16:57:44 2005 -0600 3.3 @@ -87,9 +87,17 @@ ref-%/.valid-ref: pristine-%/.valid-pris 3.4 touch $@ # update timestamp to avoid rebuild 3.5 endif 3.6 3.7 -%-build: 3.8 +%-install: 3.9 $(MAKE) -f buildconfigs/mk.$* build 3.10 3.11 +%-dist: DESTDIR=$(DISTDIR)/install 3.12 +%-dist: %-install 3.13 + @: # do nothing 3.14 + 3.15 +# Legacy dist target 3.16 +%-build: %-dist 3.17 + @: # do nothing 3.18 + 3.19 %-delete: 3.20 $(MAKE) -f buildconfigs/mk.$* delete 3.21
4.1 --- a/linux-2.6-xen-sparse/arch/xen/boot/Makefile Tue Oct 11 15:50:21 2005 -0600 4.2 +++ b/linux-2.6-xen-sparse/arch/xen/boot/Makefile Tue Oct 11 16:57:44 2005 -0600 4.3 @@ -8,4 +8,4 @@ vmlinux-stripped: vmlinux FORCE 4.4 $(call if_changed,objcopy) 4.5 4.6 bzImage: vmlinuz 4.7 - $(Q)$(LN) -sf ../../../vmlinuz $(srctree)/arch/xen/boot/bzImage 4.8 + $(Q)ln -sf ../../../vmlinuz $(srctree)/arch/xen/boot/bzImage
5.1 --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c Tue Oct 11 15:50:21 2005 -0600 5.2 +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c Tue Oct 11 16:57:44 2005 -0600 5.3 @@ -1327,18 +1327,14 @@ static struct xenbus_watch cpu_watch = { 5.4 .callback = handle_vcpu_hotplug_event 5.5 }; 5.6 5.7 -/* NB: Assumes xenbus_lock is held! */ 5.8 static int setup_cpu_watcher(struct notifier_block *notifier, 5.9 unsigned long event, void *data) 5.10 { 5.11 - int err = 0; 5.12 + int err; 5.13 5.14 - BUG_ON(down_trylock(&xenbus_lock) == 0); 5.15 err = register_xenbus_watch(&cpu_watch); 5.16 - 5.17 - if (err) { 5.18 + if (err) 5.19 printk("Failed to register watch on /cpu\n"); 5.20 - } 5.21 5.22 return NOTIFY_DONE; 5.23 } 5.24 @@ -1368,7 +1364,7 @@ static void handle_vcpu_hotplug_event(st 5.25 return; 5.26 5.27 /* get the state value */ 5.28 - err = xenbus_scanf(dir, "availability", "%s", state); 5.29 + err = xenbus_scanf(NULL, dir, "availability", "%s", state); 5.30 5.31 if (err != 1) { 5.32 printk(KERN_ERR 5.33 @@ -1578,7 +1574,7 @@ void smp_suspend(void) 5.34 void smp_resume(void) 5.35 { 5.36 smp_intr_init(); 5.37 - local_setup_timer_irq(); 5.38 + local_setup_timer(); 5.39 } 5.40 5.41 void vcpu_prepare(int vcpu)
6.1 --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/time.c Tue Oct 11 15:50:21 2005 -0600 6.2 +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/time.c Tue Oct 11 16:57:44 2005 -0600 6.3 @@ -122,7 +122,7 @@ static u32 shadow_tv_version; 6.4 static u64 processed_system_time; /* System time (ns) at last processing. */ 6.5 static DEFINE_PER_CPU(u64, processed_system_time); 6.6 6.7 -#define NS_PER_TICK (1000000000L/HZ) 6.8 +#define NS_PER_TICK (1000000000ULL/HZ) 6.9 6.10 static inline void __normalize_time(time_t *sec, s64 *nsec) 6.11 { 6.12 @@ -800,9 +800,9 @@ static inline u64 jiffies_to_st(unsigned 6.13 delta = j - jiffies; 6.14 /* NB. The next check can trigger in some wrap-around cases, 6.15 * but that's ok: we'll just end up with a shorter timeout. */ 6.16 - if (delta < 1) 6.17 + if (delta < 1) 6.18 delta = 1; 6.19 - st = processed_system_time + (delta * NS_PER_TICK); 6.20 + st = processed_system_time + ((u64)delta * NS_PER_TICK); 6.21 } while (read_seqretry(&xtime_lock, seq)); 6.22 6.23 return st; 6.24 @@ -816,7 +816,7 @@ void stop_hz_timer(void) 6.25 { 6.26 unsigned int cpu = smp_processor_id(); 6.27 unsigned long j; 6.28 - 6.29 + 6.30 /* s390 does this /before/ checking rcu_pending(). We copy them. */ 6.31 cpu_set(cpu, nohz_cpu_mask); 6.32
7.1 --- a/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c Tue Oct 11 15:50:21 2005 -0600 7.2 +++ b/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c Tue Oct 11 16:57:44 2005 -0600 7.3 @@ -270,26 +270,28 @@ static void __shutdown_handler(void *unu 7.4 } 7.5 } 7.6 7.7 -static void shutdown_handler(struct xenbus_watch *watch, const char *node) 7.8 +static void shutdown_handler(struct xenbus_watch *watch, 7.9 + const char **vec, unsigned int len) 7.10 { 7.11 static DECLARE_WORK(shutdown_work, __shutdown_handler, NULL); 7.12 char *str; 7.13 + struct xenbus_transaction *xbt; 7.14 int err; 7.15 7.16 again: 7.17 - err = xenbus_transaction_start(); 7.18 - if (err) 7.19 + xbt = xenbus_transaction_start(); 7.20 + if (IS_ERR(xbt)) 7.21 return; 7.22 - str = (char *)xenbus_read("control", "shutdown", NULL); 7.23 + str = (char *)xenbus_read(xbt, "control", "shutdown", NULL); 7.24 /* Ignore read errors and empty reads. */ 7.25 if (XENBUS_IS_ERR_READ(str)) { 7.26 - xenbus_transaction_end(1); 7.27 + xenbus_transaction_end(xbt, 1); 7.28 return; 7.29 } 7.30 7.31 - xenbus_write("control", "shutdown", ""); 7.32 + xenbus_write(xbt, "control", "shutdown", ""); 7.33 7.34 - err = xenbus_transaction_end(0); 7.35 + err = xenbus_transaction_end(xbt, 0); 7.36 if (err == -EAGAIN) { 7.37 kfree(str); 7.38 goto again; 7.39 @@ -315,26 +317,28 @@ static void shutdown_handler(struct xenb 7.40 } 7.41 7.42 #ifdef CONFIG_MAGIC_SYSRQ 7.43 -static void sysrq_handler(struct xenbus_watch *watch, const char *node) 7.44 +static void sysrq_handler(struct xenbus_watch *watch, const char **vec, 7.45 + unsigned int len) 7.46 { 7.47 char sysrq_key = '\0'; 7.48 + struct xenbus_transaction *xbt; 7.49 int err; 7.50 7.51 again: 7.52 - err = xenbus_transaction_start(); 7.53 - if (err) 7.54 + xbt = xenbus_transaction_start(); 7.55 + if (IS_ERR(xbt)) 7.56 return; 7.57 - if (!xenbus_scanf("control", "sysrq", "%c", &sysrq_key)) { 7.58 + if (!xenbus_scanf(xbt, "control", "sysrq", "%c", &sysrq_key)) { 7.59 printk(KERN_ERR "Unable to read sysrq code in " 7.60 "control/sysrq\n"); 7.61 - xenbus_transaction_end(1); 7.62 + xenbus_transaction_end(xbt, 1); 7.63 return; 7.64 } 7.65 7.66 if (sysrq_key != '\0') 7.67 - xenbus_printf("control", "sysrq", "%c", '\0'); 7.68 + xenbus_printf(xbt, "control", "sysrq", "%c", '\0'); 7.69 7.70 - err = xenbus_transaction_end(0); 7.71 + err = xenbus_transaction_end(xbt, 0); 7.72 if (err == -EAGAIN) 7.73 goto again; 7.74 7.75 @@ -358,9 +362,6 @@ static struct xenbus_watch sysrq_watch = 7.76 7.77 static struct notifier_block xenstore_notifier; 7.78 7.79 -/* Setup our watcher 7.80 - NB: Assumes xenbus_lock is held! 7.81 -*/ 7.82 static int setup_shutdown_watcher(struct notifier_block *notifier, 7.83 unsigned long event, 7.84 void *data) 7.85 @@ -370,8 +371,6 @@ static int setup_shutdown_watcher(struct 7.86 int err2 = 0; 7.87 #endif 7.88 7.89 - BUG_ON(down_trylock(&xenbus_lock) == 0); 7.90 - 7.91 err1 = register_xenbus_watch(&shutdown_watch); 7.92 #ifdef CONFIG_MAGIC_SYSRQ 7.93 err2 = register_xenbus_watch(&sysrq_watch); 7.94 @@ -411,4 +410,3 @@ subsys_initcall(setup_shutdown_event); 7.95 * tab-width: 8 7.96 * End: 7.97 */ 7.98 -#
8.1 --- a/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c Tue Oct 11 15:50:21 2005 -0600 8.2 +++ b/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c Tue Oct 11 16:57:44 2005 -0600 8.3 @@ -357,7 +357,7 @@ static void watch_target(struct xenbus_w 8.4 unsigned long long new_target; 8.5 int err; 8.6 8.7 - err = xenbus_scanf("memory", "target", "%llu", &new_target); 8.8 + err = xenbus_scanf(NULL, "memory", "target", "%llu", &new_target); 8.9 if (err != 1) { 8.10 printk(KERN_ERR "Unable to read memory/target\n"); 8.11 return; 8.12 @@ -370,17 +370,12 @@ static void watch_target(struct xenbus_w 8.13 8.14 } 8.15 8.16 -/* Setup our watcher 8.17 - NB: Assumes xenbus_lock is held! 8.18 -*/ 8.19 int balloon_init_watcher(struct notifier_block *notifier, 8.20 unsigned long event, 8.21 void *data) 8.22 { 8.23 int err; 8.24 8.25 - BUG_ON(down_trylock(&xenbus_lock) == 0); 8.26 - 8.27 err = register_xenbus_watch(&target_watch); 8.28 if (err) 8.29 printk(KERN_ERR "Failed to set balloon watcher\n");
9.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c Tue Oct 11 15:50:21 2005 -0600 9.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c Tue Oct 11 16:57:44 2005 -0600 9.3 @@ -61,18 +61,19 @@ static void frontend_changed(struct xenb 9.4 unsigned long ring_ref; 9.5 unsigned int evtchn; 9.6 int err; 9.7 + struct xenbus_transaction *xbt; 9.8 struct backend_info *be 9.9 = container_of(watch, struct backend_info, watch); 9.10 9.11 /* If other end is gone, delete ourself. */ 9.12 - if (vec && !xenbus_exists(be->frontpath, "")) { 9.13 + if (vec && !xenbus_exists(NULL, be->frontpath, "")) { 9.14 device_unregister(&be->dev->dev); 9.15 return; 9.16 } 9.17 if (be->blkif == NULL || be->blkif->status == CONNECTED) 9.18 return; 9.19 9.20 - err = xenbus_gather(be->frontpath, "ring-ref", "%lu", &ring_ref, 9.21 + err = xenbus_gather(NULL, be->frontpath, "ring-ref", "%lu", &ring_ref, 9.22 "event-channel", "%u", &evtchn, NULL); 9.23 if (err) { 9.24 xenbus_dev_error(be->dev, err, 9.25 @@ -84,7 +85,8 @@ static void frontend_changed(struct xenb 9.26 /* Map the shared frame, irq etc. */ 9.27 err = blkif_map(be->blkif, ring_ref, evtchn); 9.28 if (err) { 9.29 - xenbus_dev_error(be->dev, err, "mapping ring-ref %lu port %u", 9.30 + xenbus_dev_error(be->dev, err, 9.31 + "mapping ring-ref %lu port %u", 9.32 ring_ref, evtchn); 9.33 return; 9.34 } 9.35 @@ -92,13 +94,13 @@ static void frontend_changed(struct xenb 9.36 9.37 again: 9.38 /* Supply the information about the device the frontend needs */ 9.39 - err = xenbus_transaction_start(); 9.40 - if (err) { 9.41 + xbt = xenbus_transaction_start(); 9.42 + if (IS_ERR(xbt)) { 9.43 xenbus_dev_error(be->dev, err, "starting transaction"); 9.44 return; 9.45 } 9.46 9.47 - err = xenbus_printf(be->dev->nodename, "sectors", "%lu", 9.48 + err = xenbus_printf(xbt, be->dev->nodename, "sectors", "%lu", 9.49 vbd_size(&be->blkif->vbd)); 9.50 if (err) { 9.51 xenbus_dev_error(be->dev, err, "writing %s/sectors", 9.52 @@ -107,14 +109,14 @@ again: 9.53 } 9.54 9.55 /* FIXME: use a typename instead */ 9.56 - err = xenbus_printf(be->dev->nodename, "info", "%u", 9.57 + err = xenbus_printf(xbt, be->dev->nodename, "info", "%u", 9.58 vbd_info(&be->blkif->vbd)); 9.59 if (err) { 9.60 xenbus_dev_error(be->dev, err, "writing %s/info", 9.61 be->dev->nodename); 9.62 goto abort; 9.63 } 9.64 - err = xenbus_printf(be->dev->nodename, "sector-size", "%lu", 9.65 + err = xenbus_printf(xbt, be->dev->nodename, "sector-size", "%lu", 9.66 vbd_secsize(&be->blkif->vbd)); 9.67 if (err) { 9.68 xenbus_dev_error(be->dev, err, "writing %s/sector-size", 9.69 @@ -122,7 +124,7 @@ again: 9.70 goto abort; 9.71 } 9.72 9.73 - err = xenbus_transaction_end(0); 9.74 + err = xenbus_transaction_end(xbt, 0); 9.75 if (err == -EAGAIN) 9.76 goto again; 9.77 if (err) { 9.78 @@ -136,7 +138,7 @@ again: 9.79 return; 9.80 9.81 abort: 9.82 - xenbus_transaction_end(1); 9.83 + xenbus_transaction_end(xbt, 1); 9.84 } 9.85 9.86 /* 9.87 @@ -154,7 +156,8 @@ static void backend_changed(struct xenbu 9.88 = container_of(watch, struct backend_info, backend_watch); 9.89 struct xenbus_device *dev = be->dev; 9.90 9.91 - err = xenbus_scanf(dev->nodename, "physical-device", "%li", &pdev); 9.92 + err = xenbus_scanf(NULL, dev->nodename, 9.93 + "physical-device", "%li", &pdev); 9.94 if (XENBUS_EXIST_ERR(err)) 9.95 return; 9.96 if (err < 0) { 9.97 @@ -169,7 +172,7 @@ static void backend_changed(struct xenbu 9.98 be->pdev = pdev; 9.99 9.100 /* If there's a read-only node, we're read only. */ 9.101 - p = xenbus_read(dev->nodename, "read-only", NULL); 9.102 + p = xenbus_read(NULL, dev->nodename, "read-only", NULL); 9.103 if (!IS_ERR(p)) { 9.104 be->readonly = 1; 9.105 kfree(p); 9.106 @@ -184,7 +187,8 @@ static void backend_changed(struct xenbu 9.107 if (IS_ERR(be->blkif)) { 9.108 err = PTR_ERR(be->blkif); 9.109 be->blkif = NULL; 9.110 - xenbus_dev_error(dev, err, "creating block interface"); 9.111 + xenbus_dev_error(dev, err, 9.112 + "creating block interface"); 9.113 return; 9.114 } 9.115 9.116 @@ -192,7 +196,8 @@ static void backend_changed(struct xenbu 9.117 if (err) { 9.118 blkif_put(be->blkif); 9.119 be->blkif = NULL; 9.120 - xenbus_dev_error(dev, err, "creating vbd structure"); 9.121 + xenbus_dev_error(dev, err, 9.122 + "creating vbd structure"); 9.123 return; 9.124 } 9.125 9.126 @@ -210,13 +215,14 @@ static int blkback_probe(struct xenbus_d 9.127 9.128 be = kmalloc(sizeof(*be), GFP_KERNEL); 9.129 if (!be) { 9.130 - xenbus_dev_error(dev, -ENOMEM, "allocating backend structure"); 9.131 + xenbus_dev_error(dev, -ENOMEM, 9.132 + "allocating backend structure"); 9.133 return -ENOMEM; 9.134 } 9.135 memset(be, 0, sizeof(*be)); 9.136 9.137 frontend = NULL; 9.138 - err = xenbus_gather(dev->nodename, 9.139 + err = xenbus_gather(NULL, dev->nodename, 9.140 "frontend-id", "%li", &be->frontend_id, 9.141 "frontend", NULL, &frontend, 9.142 NULL); 9.143 @@ -228,7 +234,7 @@ static int blkback_probe(struct xenbus_d 9.144 dev->nodename); 9.145 goto free_be; 9.146 } 9.147 - if (strlen(frontend) == 0 || !xenbus_exists(frontend, "")) { 9.148 + if (strlen(frontend) == 0 || !xenbus_exists(NULL, frontend, "")) { 9.149 /* If we can't get a frontend path and a frontend-id, 9.150 * then our bus-id is no longer valid and we need to 9.151 * destroy the backend device. 9.152 @@ -244,7 +250,8 @@ static int blkback_probe(struct xenbus_d 9.153 err = register_xenbus_watch(&be->backend_watch); 9.154 if (err) { 9.155 be->backend_watch.node = NULL; 9.156 - xenbus_dev_error(dev, err, "adding backend watch on %s", 9.157 + xenbus_dev_error(dev, err, 9.158 + "adding backend watch on %s", 9.159 dev->nodename); 9.160 goto free_be; 9.161 }
10.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c Tue Oct 11 15:50:21 2005 -0600 10.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c Tue Oct 11 16:57:44 2005 -0600 10.3 @@ -460,7 +460,7 @@ static void watch_for_status(struct xenb 10.4 if (info->connected == BLKIF_STATE_CONNECTED) 10.5 return; 10.6 10.7 - err = xenbus_gather(watch->node, 10.8 + err = xenbus_gather(NULL, watch->node, 10.9 "sectors", "%lu", §ors, 10.10 "info", "%u", &binfo, 10.11 "sector-size", "%lu", §or_size, 10.12 @@ -532,10 +532,11 @@ static int talk_to_backend(struct xenbus 10.13 { 10.14 char *backend; 10.15 const char *message; 10.16 + struct xenbus_transaction *xbt; 10.17 int err; 10.18 10.19 backend = NULL; 10.20 - err = xenbus_gather(dev->nodename, 10.21 + err = xenbus_gather(NULL, dev->nodename, 10.22 "backend-id", "%i", &info->backend_id, 10.23 "backend", NULL, &backend, 10.24 NULL); 10.25 @@ -559,25 +560,26 @@ static int talk_to_backend(struct xenbus 10.26 } 10.27 10.28 again: 10.29 - err = xenbus_transaction_start(); 10.30 - if (err) { 10.31 + xbt = xenbus_transaction_start(); 10.32 + if (IS_ERR(xbt)) { 10.33 xenbus_dev_error(dev, err, "starting transaction"); 10.34 goto destroy_blkring; 10.35 } 10.36 10.37 - err = xenbus_printf(dev->nodename, "ring-ref","%u", info->ring_ref); 10.38 + err = xenbus_printf(xbt, dev->nodename, 10.39 + "ring-ref","%u", info->ring_ref); 10.40 if (err) { 10.41 message = "writing ring-ref"; 10.42 goto abort_transaction; 10.43 } 10.44 - err = xenbus_printf(dev->nodename, 10.45 + err = xenbus_printf(xbt, dev->nodename, 10.46 "event-channel", "%u", info->evtchn); 10.47 if (err) { 10.48 message = "writing event-channel"; 10.49 goto abort_transaction; 10.50 } 10.51 10.52 - err = xenbus_transaction_end(0); 10.53 + err = xenbus_transaction_end(xbt, 0); 10.54 if (err) { 10.55 if (err == -EAGAIN) 10.56 goto again; 10.57 @@ -598,8 +600,7 @@ again: 10.58 return 0; 10.59 10.60 abort_transaction: 10.61 - xenbus_transaction_end(1); 10.62 - /* Have to do this *outside* transaction. */ 10.63 + xenbus_transaction_end(xbt, 1); 10.64 xenbus_dev_error(dev, err, "%s", message); 10.65 destroy_blkring: 10.66 blkif_free(info); 10.67 @@ -620,7 +621,8 @@ static int blkfront_probe(struct xenbus_ 10.68 struct blkfront_info *info; 10.69 10.70 /* FIXME: Use dynamic device id if this is not set. */ 10.71 - err = xenbus_scanf(dev->nodename, "virtual-device", "%i", &vdevice); 10.72 + err = xenbus_scanf(NULL, dev->nodename, 10.73 + "virtual-device", "%i", &vdevice); 10.74 if (XENBUS_EXIST_ERR(err)) 10.75 return err; 10.76 if (err < 0) {
11.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkfront/vbd.c Tue Oct 11 15:50:21 2005 -0600 11.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/vbd.c Tue Oct 11 16:57:44 2005 -0600 11.3 @@ -160,7 +160,8 @@ xlbd_get_major_info(int vdevice) 11.4 11.5 mi = ((major_info[index] != NULL) ? major_info[index] : 11.6 xlbd_alloc_major_info(major, minor, index)); 11.7 - mi->usage++; 11.8 + if (mi) 11.9 + mi->usage++; 11.10 return mi; 11.11 } 11.12
12.1 --- a/linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.c Tue Oct 11 15:50:21 2005 -0600 12.2 +++ b/linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.c Tue Oct 11 16:57:44 2005 -0600 12.3 @@ -20,69 +20,48 @@ 12.4 #include <linux/sched.h> 12.5 #include <linux/err.h> 12.6 #include "xencons_ring.h" 12.7 - 12.8 -struct ring_head 12.9 -{ 12.10 - u32 cons; 12.11 - u32 prod; 12.12 - char buf[0]; 12.13 -} __attribute__((packed)); 12.14 +#include <asm-xen/xen-public/io/console.h> 12.15 12.16 static int xencons_irq; 12.17 +static xencons_receiver_func *xencons_receiver; 12.18 12.19 -#define XENCONS_RING_SIZE (PAGE_SIZE/2 - sizeof (struct ring_head)) 12.20 -#define XENCONS_IDX(cnt) ((cnt) % XENCONS_RING_SIZE) 12.21 -#define XENCONS_FULL(ring) (((ring)->prod - (ring)->cons) == XENCONS_RING_SIZE) 12.22 - 12.23 -static inline struct ring_head *outring(void) 12.24 +static inline struct xencons_interface *xencons_interface(void) 12.25 { 12.26 return mfn_to_virt(xen_start_info->console_mfn); 12.27 } 12.28 12.29 -static inline struct ring_head *inring(void) 12.30 -{ 12.31 - return mfn_to_virt(xen_start_info->console_mfn) + PAGE_SIZE/2; 12.32 -} 12.33 - 12.34 - 12.35 -/* don't block - write as much as possible and return */ 12.36 -static int __xencons_ring_send( 12.37 - struct ring_head *ring, const char *data, unsigned len) 12.38 -{ 12.39 - int copied = 0; 12.40 - 12.41 - mb(); 12.42 - while (copied < len && !XENCONS_FULL(ring)) { 12.43 - ring->buf[XENCONS_IDX(ring->prod)] = data[copied]; 12.44 - ring->prod++; 12.45 - copied++; 12.46 - } 12.47 - mb(); 12.48 - 12.49 - return copied; 12.50 -} 12.51 - 12.52 int xencons_ring_send(const char *data, unsigned len) 12.53 { 12.54 - int sent = __xencons_ring_send(outring(), data, len); 12.55 + int sent = 0; 12.56 + struct xencons_interface *intf = xencons_interface(); 12.57 + 12.58 + while ((sent < len) && 12.59 + (intf->out_prod - intf->out_cons) < sizeof(intf->out)) { 12.60 + intf->out[MASK_XENCONS_IDX(intf->out_prod, intf->out)] = 12.61 + data[sent]; 12.62 + intf->out_prod++; 12.63 + sent++; 12.64 + } 12.65 + 12.66 /* Use evtchn: this is called early, before irq is set up. */ 12.67 notify_remote_via_evtchn(xen_start_info->console_evtchn); 12.68 + 12.69 return sent; 12.70 } 12.71 12.72 - 12.73 -static xencons_receiver_func *xencons_receiver; 12.74 - 12.75 static irqreturn_t handle_input(int irq, void *unused, struct pt_regs *regs) 12.76 { 12.77 - struct ring_head *ring = inring(); 12.78 - while (ring->cons < ring->prod) { 12.79 - if (xencons_receiver != NULL) { 12.80 - xencons_receiver(ring->buf + XENCONS_IDX(ring->cons), 12.81 - 1, regs); 12.82 - } 12.83 - ring->cons++; 12.84 + struct xencons_interface *intf = xencons_interface(); 12.85 + 12.86 + while (intf->in_cons != intf->in_prod) { 12.87 + if (xencons_receiver != NULL) 12.88 + xencons_receiver( 12.89 + intf->in + MASK_XENCONS_IDX(intf->in_cons, 12.90 + intf->in), 12.91 + 1, regs); 12.92 + intf->in_cons++; 12.93 } 12.94 + 12.95 return IRQ_HANDLED; 12.96 } 12.97 12.98 @@ -96,7 +75,7 @@ int xencons_ring_init(void) 12.99 int err; 12.100 12.101 if (xencons_irq) 12.102 - unbind_evtchn_from_irqhandler(xencons_irq, inring()); 12.103 + unbind_evtchn_from_irqhandler(xencons_irq, NULL); 12.104 xencons_irq = 0; 12.105 12.106 if (!xen_start_info->console_evtchn) 12.107 @@ -104,7 +83,7 @@ int xencons_ring_init(void) 12.108 12.109 err = bind_evtchn_to_irqhandler( 12.110 xen_start_info->console_evtchn, 12.111 - handle_input, 0, "xencons", inring()); 12.112 + handle_input, 0, "xencons", NULL); 12.113 if (err <= 0) { 12.114 xprintk("XEN console request irq failed %i\n", err); 12.115 return err;
13.1 --- a/linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c Tue Oct 11 15:50:21 2005 -0600 13.2 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c Tue Oct 11 16:57:44 2005 -0600 13.3 @@ -69,15 +69,15 @@ static void frontend_changed(struct xenb 13.4 int i; 13.5 13.6 /* If other end is gone, delete ourself. */ 13.7 - if (vec && !xenbus_exists(be->frontpath, "")) { 13.8 - xenbus_rm(be->dev->nodename, ""); 13.9 + if (vec && !xenbus_exists(NULL, be->frontpath, "")) { 13.10 + xenbus_rm(NULL, be->dev->nodename, ""); 13.11 device_unregister(&be->dev->dev); 13.12 return; 13.13 } 13.14 if (be->netif == NULL || be->netif->status == CONNECTED) 13.15 return; 13.16 13.17 - mac = xenbus_read(be->frontpath, "mac", NULL); 13.18 + mac = xenbus_read(NULL, be->frontpath, "mac", NULL); 13.19 if (IS_ERR(mac)) { 13.20 err = PTR_ERR(mac); 13.21 xenbus_dev_error(be->dev, err, "reading %s/mac", 13.22 @@ -98,7 +98,8 @@ static void frontend_changed(struct xenb 13.23 } 13.24 kfree(mac); 13.25 13.26 - err = xenbus_gather(be->frontpath, "tx-ring-ref", "%lu", &tx_ring_ref, 13.27 + err = xenbus_gather(NULL, be->frontpath, 13.28 + "tx-ring-ref", "%lu", &tx_ring_ref, 13.29 "rx-ring-ref", "%lu", &rx_ring_ref, 13.30 "event-channel", "%u", &evtchn, NULL); 13.31 if (err) { 13.32 @@ -137,7 +138,7 @@ static void backend_changed(struct xenbu 13.33 struct xenbus_device *dev = be->dev; 13.34 u8 be_mac[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 }; 13.35 13.36 - err = xenbus_scanf(dev->nodename, "handle", "%li", &handle); 13.37 + err = xenbus_scanf(NULL, dev->nodename, "handle", "%li", &handle); 13.38 if (XENBUS_EXIST_ERR(err)) 13.39 return; 13.40 if (err < 0) { 13.41 @@ -188,7 +189,7 @@ static int netback_hotplug(struct xenbus 13.42 13.43 key = env_vars; 13.44 while (*key != NULL) { 13.45 - val = xenbus_read(xdev->nodename, *key, NULL); 13.46 + val = xenbus_read(NULL, xdev->nodename, *key, NULL); 13.47 if (!IS_ERR(val)) { 13.48 char buf[strlen(*key) + 4]; 13.49 sprintf(buf, "%s=%%s", *key); 13.50 @@ -220,7 +221,7 @@ static int netback_probe(struct xenbus_d 13.51 memset(be, 0, sizeof(*be)); 13.52 13.53 frontend = NULL; 13.54 - err = xenbus_gather(dev->nodename, 13.55 + err = xenbus_gather(NULL, dev->nodename, 13.56 "frontend-id", "%li", &be->frontend_id, 13.57 "frontend", NULL, &frontend, 13.58 NULL); 13.59 @@ -232,7 +233,7 @@ static int netback_probe(struct xenbus_d 13.60 dev->nodename); 13.61 goto free_be; 13.62 } 13.63 - if (strlen(frontend) == 0 || !xenbus_exists(frontend, "")) { 13.64 + if (strlen(frontend) == 0 || !xenbus_exists(NULL, frontend, "")) { 13.65 /* If we can't get a frontend path and a frontend-id, 13.66 * then our bus-id is no longer valid and we need to 13.67 * destroy the backend device.
14.1 --- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c Tue Oct 11 15:50:21 2005 -0600 14.2 +++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c Tue Oct 11 16:57:44 2005 -0600 14.3 @@ -1083,10 +1083,11 @@ static int talk_to_backend(struct xenbus 14.4 { 14.5 char *backend, *mac, *e, *s; 14.6 const char *message; 14.7 + struct xenbus_transaction *xbt; 14.8 int err, i; 14.9 14.10 backend = NULL; 14.11 - err = xenbus_gather(dev->nodename, 14.12 + err = xenbus_gather(NULL, dev->nodename, 14.13 "backend-id", "%i", &info->backend_id, 14.14 "backend", NULL, &backend, 14.15 NULL); 14.16 @@ -1102,7 +1103,7 @@ static int talk_to_backend(struct xenbus 14.17 goto out; 14.18 } 14.19 14.20 - mac = xenbus_read(dev->nodename, "mac", NULL); 14.21 + mac = xenbus_read(NULL, dev->nodename, "mac", NULL); 14.22 if (IS_ERR(mac)) { 14.23 err = PTR_ERR(mac); 14.24 xenbus_dev_error(dev, err, "reading %s/mac", 14.25 @@ -1131,32 +1132,32 @@ static int talk_to_backend(struct xenbus 14.26 } 14.27 14.28 again: 14.29 - err = xenbus_transaction_start(); 14.30 - if (err) { 14.31 + xbt = xenbus_transaction_start(); 14.32 + if (IS_ERR(xbt)) { 14.33 xenbus_dev_error(dev, err, "starting transaction"); 14.34 goto destroy_ring; 14.35 } 14.36 14.37 - err = xenbus_printf(dev->nodename, "tx-ring-ref","%u", 14.38 + err = xenbus_printf(xbt, dev->nodename, "tx-ring-ref","%u", 14.39 info->tx_ring_ref); 14.40 if (err) { 14.41 message = "writing tx ring-ref"; 14.42 goto abort_transaction; 14.43 } 14.44 - err = xenbus_printf(dev->nodename, "rx-ring-ref","%u", 14.45 + err = xenbus_printf(xbt, dev->nodename, "rx-ring-ref","%u", 14.46 info->rx_ring_ref); 14.47 if (err) { 14.48 message = "writing rx ring-ref"; 14.49 goto abort_transaction; 14.50 } 14.51 - err = xenbus_printf(dev->nodename, 14.52 + err = xenbus_printf(xbt, dev->nodename, 14.53 "event-channel", "%u", info->evtchn); 14.54 if (err) { 14.55 message = "writing event-channel"; 14.56 goto abort_transaction; 14.57 } 14.58 14.59 - err = xenbus_transaction_end(0); 14.60 + err = xenbus_transaction_end(xbt, 0); 14.61 if (err) { 14.62 if (err == -EAGAIN) 14.63 goto again; 14.64 @@ -1177,8 +1178,7 @@ again: 14.65 return 0; 14.66 14.67 abort_transaction: 14.68 - xenbus_transaction_end(1); 14.69 - /* Have to do this *outside* transaction. */ 14.70 + xenbus_transaction_end(xbt, 1); 14.71 xenbus_dev_error(dev, err, "%s", message); 14.72 destroy_ring: 14.73 shutdown_device(info); 14.74 @@ -1201,7 +1201,7 @@ static int netfront_probe(struct xenbus_ 14.75 struct netfront_info *info; 14.76 unsigned int handle; 14.77 14.78 - err = xenbus_scanf(dev->nodename, "handle", "%u", &handle); 14.79 + err = xenbus_scanf(NULL, dev->nodename, "handle", "%u", &handle); 14.80 if (XENBUS_EXIST_ERR(err)) 14.81 return err; 14.82 if (err < 0) {
15.1 --- a/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c Tue Oct 11 15:50:21 2005 -0600 15.2 +++ b/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c Tue Oct 11 16:57:44 2005 -0600 15.3 @@ -246,7 +246,10 @@ static int privcmd_ioctl(struct inode *i 15.4 PAGE_SHIFT); 15.5 ret = xen_start_info->store_mfn; 15.6 15.7 - /* We'll return then this will wait for daemon to answer */ 15.8 + /* 15.9 + ** Complete initialization of xenbus (viz. set up the 15.10 + ** connection to xenstored now that it has started). 15.11 + */ 15.12 kthread_run(do_xenbus_probe, NULL, "xenbus_probe"); 15.13 } 15.14 break;
16.1 --- a/linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c Tue Oct 11 15:50:21 2005 -0600 16.2 +++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c Tue Oct 11 16:57:44 2005 -0600 16.3 @@ -66,12 +66,13 @@ static void frontend_changed(struct xenb 16.4 unsigned int evtchn; 16.5 unsigned long ready = 1; 16.6 int err; 16.7 + struct xenbus_transaction *xbt; 16.8 struct backend_info *be 16.9 = container_of(watch, struct backend_info, watch); 16.10 16.11 /* If other end is gone, delete ourself. */ 16.12 - if (vec && !xenbus_exists(be->frontpath, "")) { 16.13 - xenbus_rm(be->dev->nodename, ""); 16.14 + if (vec && !xenbus_exists(NULL, be->frontpath, "")) { 16.15 + xenbus_rm(NULL, be->dev->nodename, ""); 16.16 device_unregister(&be->dev->dev); 16.17 return; 16.18 } 16.19 @@ -79,7 +80,7 @@ static void frontend_changed(struct xenb 16.20 if (be->tpmif == NULL || be->tpmif->status == CONNECTED) 16.21 return; 16.22 16.23 - err = xenbus_gather(be->frontpath, 16.24 + err = xenbus_gather(NULL, be->frontpath, 16.25 "ring-ref", "%lu", &ringref, 16.26 "event-channel", "%u", &evtchn, NULL); 16.27 if (err) { 16.28 @@ -115,20 +116,20 @@ static void frontend_changed(struct xenb 16.29 * unless something bad happens 16.30 */ 16.31 again: 16.32 - err = xenbus_transaction_start(); 16.33 - if (err) { 16.34 + xbt = xenbus_transaction_start(); 16.35 + if (IS_ERR(xbt)) { 16.36 xenbus_dev_error(be->dev, err, "starting transaction"); 16.37 return; 16.38 } 16.39 16.40 - err = xenbus_printf(be->dev->nodename, 16.41 + err = xenbus_printf(xbt, be->dev->nodename, 16.42 "ready", "%lu", ready); 16.43 if (err) { 16.44 xenbus_dev_error(be->dev, err, "writing 'ready'"); 16.45 goto abort; 16.46 } 16.47 16.48 - err = xenbus_transaction_end(0); 16.49 + err = xenbus_transaction_end(xbt, 0); 16.50 if (err == -EAGAIN) 16.51 goto again; 16.52 if (err) { 16.53 @@ -139,7 +140,7 @@ again: 16.54 xenbus_dev_ok(be->dev); 16.55 return; 16.56 abort: 16.57 - xenbus_transaction_end(1); 16.58 + xenbus_transaction_end(xbt, 1); 16.59 } 16.60 16.61 16.62 @@ -152,7 +153,7 @@ static void backend_changed(struct xenbu 16.63 = container_of(watch, struct backend_info, backend_watch); 16.64 struct xenbus_device *dev = be->dev; 16.65 16.66 - err = xenbus_scanf(dev->nodename, "instance", "%li", &instance); 16.67 + err = xenbus_scanf(NULL, dev->nodename, "instance", "%li", &instance); 16.68 if (XENBUS_EXIST_ERR(err)) 16.69 return; 16.70 if (err < 0) { 16.71 @@ -205,7 +206,7 @@ static int tpmback_probe(struct xenbus_d 16.72 memset(be, 0, sizeof(*be)); 16.73 16.74 frontend = NULL; 16.75 - err = xenbus_gather(dev->nodename, 16.76 + err = xenbus_gather(NULL, dev->nodename, 16.77 "frontend-id", "%li", &be->frontend_id, 16.78 "frontend", NULL, &frontend, 16.79 NULL); 16.80 @@ -217,7 +218,7 @@ static int tpmback_probe(struct xenbus_d 16.81 dev->nodename); 16.82 goto free_be; 16.83 } 16.84 - if (strlen(frontend) == 0 || !xenbus_exists(frontend, "")) { 16.85 + if (strlen(frontend) == 0 || !xenbus_exists(NULL, frontend, "")) { 16.86 /* If we can't get a frontend path and a frontend-id, 16.87 * then our bus-id is no longer valid and we need to 16.88 * destroy the backend device.
17.1 --- a/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c Tue Oct 11 15:50:21 2005 -0600 17.2 +++ b/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c Tue Oct 11 16:57:44 2005 -0600 17.3 @@ -226,7 +226,7 @@ static void watch_for_status(struct xenb 17.4 if (tp->connected) 17.5 return; 17.6 17.7 - err = xenbus_gather(watch->node, 17.8 + err = xenbus_gather(NULL, watch->node, 17.9 "ready", "%lu", &ready, 17.10 NULL); 17.11 if (err) { 17.12 @@ -311,9 +311,10 @@ static int talk_to_backend(struct xenbus 17.13 const char *message; 17.14 int err; 17.15 int backend_id; 17.16 + struct xenbus_transaction *xbt; 17.17 17.18 backend = NULL; 17.19 - err = xenbus_gather(dev->nodename, 17.20 + err = xenbus_gather(NULL, dev->nodename, 17.21 "backend-id", "%i", &backend_id, 17.22 "backend", NULL, &backend, 17.23 NULL); 17.24 @@ -339,27 +340,27 @@ static int talk_to_backend(struct xenbus 17.25 } 17.26 17.27 again: 17.28 - err = xenbus_transaction_start(); 17.29 - if (err) { 17.30 + xbt = xenbus_transaction_start(); 17.31 + if (IS_ERR(xbt)) { 17.32 xenbus_dev_error(dev, err, "starting transaction"); 17.33 goto destroy_tpmring; 17.34 } 17.35 17.36 - err = xenbus_printf(dev->nodename, 17.37 + err = xenbus_printf(xbt, dev->nodename, 17.38 "ring-ref","%u", info->ring_ref); 17.39 if (err) { 17.40 message = "writing ring-ref"; 17.41 goto abort_transaction; 17.42 } 17.43 17.44 - err = xenbus_printf(dev->nodename, 17.45 + err = xenbus_printf(xbt, dev->nodename, 17.46 "event-channel", "%u", my_private.evtchn); 17.47 if (err) { 17.48 message = "writing event-channel"; 17.49 goto abort_transaction; 17.50 } 17.51 17.52 - err = xenbus_transaction_end(0); 17.53 + err = xenbus_transaction_end(xbt, 0); 17.54 if (err == -EAGAIN) 17.55 goto again; 17.56 if (err) { 17.57 @@ -380,8 +381,7 @@ again: 17.58 return 0; 17.59 17.60 abort_transaction: 17.61 - xenbus_transaction_end(1); 17.62 - /* Have to do this *outside* transaction. */ 17.63 + xenbus_transaction_end(xbt, 1); 17.64 xenbus_dev_error(dev, err, "%s", message); 17.65 destroy_tpmring: 17.66 destroy_tpmring(info, &my_private); 17.67 @@ -399,7 +399,7 @@ static int tpmfront_probe(struct xenbus_ 17.68 struct tpmfront_info *info; 17.69 int handle; 17.70 17.71 - err = xenbus_scanf(dev->nodename, 17.72 + err = xenbus_scanf(NULL, dev->nodename, 17.73 "handle", "%i", &handle); 17.74 if (XENBUS_EXIST_ERR(err)) 17.75 return err;
18.1 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c Tue Oct 11 15:50:21 2005 -0600 18.2 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c Tue Oct 11 16:57:44 2005 -0600 18.3 @@ -128,19 +128,16 @@ int xb_write(const void *data, unsigned 18.4 void *dst; 18.5 unsigned int avail; 18.6 18.7 - wait_event(xb_waitq, output_avail(out)); 18.8 + wait_event_interruptible(xb_waitq, output_avail(out)); 18.9 18.10 - /* Read, then check: not that we don't trust store. 18.11 - * Hell, some of my best friends are daemons. But, 18.12 - * in this post-911 world... */ 18.13 + mb(); 18.14 h = *out; 18.15 - mb(); 18.16 - if (!check_buffer(&h)) { 18.17 - set_current_state(TASK_RUNNING); 18.18 - return -EIO; /* ETERRORIST! */ 18.19 - } 18.20 + if (!check_buffer(&h)) 18.21 + return -EIO; 18.22 18.23 dst = get_output_chunk(&h, out->buf, &avail); 18.24 + if (avail == 0) 18.25 + continue; 18.26 if (avail > len) 18.27 avail = len; 18.28 memcpy(dst, data, avail); 18.29 @@ -172,15 +169,16 @@ int xb_read(void *data, unsigned len) 18.30 unsigned int avail; 18.31 const char *src; 18.32 18.33 - wait_event(xb_waitq, xs_input_avail()); 18.34 - h = *in; 18.35 + wait_event_interruptible(xb_waitq, xs_input_avail()); 18.36 + 18.37 mb(); 18.38 - if (!check_buffer(&h)) { 18.39 - set_current_state(TASK_RUNNING); 18.40 + h = *in; 18.41 + if (!check_buffer(&h)) 18.42 return -EIO; 18.43 - } 18.44 18.45 src = get_input_chunk(&h, in->buf, &avail); 18.46 + if (avail == 0) 18.47 + continue; 18.48 if (avail > len) 18.49 avail = len; 18.50 was_full = !output_avail(&h); 18.51 @@ -195,10 +193,6 @@ int xb_read(void *data, unsigned len) 18.52 notify_remote_via_evtchn(xen_start_info->store_evtchn); 18.53 } 18.54 18.55 - /* If we left something, wake watch thread to deal with it. */ 18.56 - if (xs_input_avail()) 18.57 - wake_up(&xb_waitq); 18.58 - 18.59 return 0; 18.60 } 18.61
19.1 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c Tue Oct 11 15:50:21 2005 -0600 19.2 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c Tue Oct 11 16:57:44 2005 -0600 19.3 @@ -45,86 +45,132 @@ 19.4 #include <asm-xen/xen_proc.h> 19.5 #include <asm/hypervisor.h> 19.6 19.7 +struct xenbus_dev_transaction { 19.8 + struct list_head list; 19.9 + struct xenbus_transaction *handle; 19.10 +}; 19.11 + 19.12 struct xenbus_dev_data { 19.13 - /* Are there bytes left to be read in this message? */ 19.14 - int bytes_left; 19.15 - /* Are we still waiting for the reply to a message we wrote? */ 19.16 - int awaiting_reply; 19.17 - /* Buffer for outgoing messages. */ 19.18 + /* In-progress transaction. */ 19.19 + struct list_head transactions; 19.20 + 19.21 + /* Partial request. */ 19.22 unsigned int len; 19.23 union { 19.24 struct xsd_sockmsg msg; 19.25 char buffer[PAGE_SIZE]; 19.26 } u; 19.27 + 19.28 + /* Response queue. */ 19.29 +#define MASK_READ_IDX(idx) ((idx)&(PAGE_SIZE-1)) 19.30 + char read_buffer[PAGE_SIZE]; 19.31 + unsigned int read_cons, read_prod; 19.32 + wait_queue_head_t read_waitq; 19.33 }; 19.34 19.35 static struct proc_dir_entry *xenbus_dev_intf; 19.36 19.37 -/* Reply can be long (dir, getperm): don't buffer, just examine 19.38 - * headers so we can discard rest if they die. */ 19.39 static ssize_t xenbus_dev_read(struct file *filp, 19.40 char __user *ubuf, 19.41 size_t len, loff_t *ppos) 19.42 { 19.43 - struct xenbus_dev_data *data = filp->private_data; 19.44 - struct xsd_sockmsg msg; 19.45 - int err; 19.46 - 19.47 - /* Refill empty buffer? */ 19.48 - if (data->bytes_left == 0) { 19.49 - if (len < sizeof(msg)) 19.50 - return -EINVAL; 19.51 + struct xenbus_dev_data *u = filp->private_data; 19.52 + int i; 19.53 19.54 - err = xb_read(&msg, sizeof(msg)); 19.55 - if (err) 19.56 - return err; 19.57 - data->bytes_left = msg.len; 19.58 - if (ubuf && copy_to_user(ubuf, &msg, sizeof(msg)) != 0) 19.59 - return -EFAULT; 19.60 - /* We can receive spurious XS_WATCH_EVENT messages. */ 19.61 - if (msg.type != XS_WATCH_EVENT) 19.62 - data->awaiting_reply = 0; 19.63 - return sizeof(msg); 19.64 + if (wait_event_interruptible(u->read_waitq, 19.65 + u->read_prod != u->read_cons)) 19.66 + return -EINTR; 19.67 + 19.68 + for (i = 0; i < len; i++) { 19.69 + if (u->read_cons == u->read_prod) 19.70 + break; 19.71 + put_user(u->read_buffer[MASK_READ_IDX(u->read_cons)], ubuf+i); 19.72 + u->read_cons++; 19.73 } 19.74 19.75 - /* Don't read over next header, or over temporary buffer. */ 19.76 - if (len > sizeof(data->u.buffer)) 19.77 - len = sizeof(data->u.buffer); 19.78 - if (len > data->bytes_left) 19.79 - len = data->bytes_left; 19.80 - 19.81 - err = xb_read(data->u.buffer, len); 19.82 - if (err) 19.83 - return err; 19.84 - 19.85 - data->bytes_left -= len; 19.86 - if (ubuf && copy_to_user(ubuf, data->u.buffer, len) != 0) 19.87 - return -EFAULT; 19.88 - return len; 19.89 + return i; 19.90 } 19.91 19.92 -/* We do v. basic sanity checking so they don't screw up kernel later. */ 19.93 +static void queue_reply(struct xenbus_dev_data *u, 19.94 + char *data, unsigned int len) 19.95 +{ 19.96 + int i; 19.97 + 19.98 + for (i = 0; i < len; i++, u->read_prod++) 19.99 + u->read_buffer[MASK_READ_IDX(u->read_prod)] = data[i]; 19.100 + 19.101 + BUG_ON((u->read_prod - u->read_cons) > sizeof(u->read_buffer)); 19.102 + 19.103 + wake_up(&u->read_waitq); 19.104 +} 19.105 + 19.106 static ssize_t xenbus_dev_write(struct file *filp, 19.107 const char __user *ubuf, 19.108 size_t len, loff_t *ppos) 19.109 { 19.110 - struct xenbus_dev_data *data = filp->private_data; 19.111 - int err; 19.112 + struct xenbus_dev_data *u = filp->private_data; 19.113 + struct xenbus_dev_transaction *trans; 19.114 + void *reply; 19.115 + int err = 0; 19.116 19.117 - /* We gather data in buffer until we're ready to send it. */ 19.118 - if (len > data->len + sizeof(data->u)) 19.119 + if ((len + u->len) > sizeof(u->u.buffer)) 19.120 return -EINVAL; 19.121 - if (copy_from_user(data->u.buffer + data->len, ubuf, len) != 0) 19.122 + 19.123 + if (copy_from_user(u->u.buffer + u->len, ubuf, len) != 0) 19.124 return -EFAULT; 19.125 - data->len += len; 19.126 - if (data->len >= sizeof(data->u.msg) + data->u.msg.len) { 19.127 - err = xb_write(data->u.buffer, data->len); 19.128 - if (err) 19.129 - return err; 19.130 - data->len = 0; 19.131 - data->awaiting_reply = 1; 19.132 + 19.133 + u->len += len; 19.134 + if (u->len < (sizeof(u->u.msg) + u->u.msg.len)) 19.135 + return len; 19.136 + 19.137 + switch (u->u.msg.type) { 19.138 + case XS_TRANSACTION_START: 19.139 + case XS_TRANSACTION_END: 19.140 + case XS_DIRECTORY: 19.141 + case XS_READ: 19.142 + case XS_GET_PERMS: 19.143 + case XS_RELEASE: 19.144 + case XS_GET_DOMAIN_PATH: 19.145 + case XS_WRITE: 19.146 + case XS_MKDIR: 19.147 + case XS_RM: 19.148 + case XS_SET_PERMS: 19.149 + reply = xenbus_dev_request_and_reply(&u->u.msg); 19.150 + if (IS_ERR(reply)) { 19.151 + err = PTR_ERR(reply); 19.152 + } else { 19.153 + if (u->u.msg.type == XS_TRANSACTION_START) { 19.154 + trans = kmalloc(sizeof(*trans), GFP_KERNEL); 19.155 + trans->handle = (struct xenbus_transaction *) 19.156 + simple_strtoul(reply, NULL, 0); 19.157 + list_add(&trans->list, &u->transactions); 19.158 + } else if (u->u.msg.type == XS_TRANSACTION_END) { 19.159 + list_for_each_entry(trans, &u->transactions, 19.160 + list) 19.161 + if ((unsigned long)trans->handle == 19.162 + (unsigned long)u->u.msg.tx_id) 19.163 + break; 19.164 + BUG_ON(&trans->list == &u->transactions); 19.165 + list_del(&trans->list); 19.166 + kfree(trans); 19.167 + } 19.168 + queue_reply(u, (char *)&u->u.msg, sizeof(u->u.msg)); 19.169 + queue_reply(u, (char *)reply, u->u.msg.len); 19.170 + kfree(reply); 19.171 + } 19.172 + break; 19.173 + 19.174 + default: 19.175 + err = -EINVAL; 19.176 + break; 19.177 } 19.178 - return len; 19.179 + 19.180 + if (err == 0) { 19.181 + u->len = 0; 19.182 + err = len; 19.183 + } 19.184 + 19.185 + return err; 19.186 } 19.187 19.188 static int xenbus_dev_open(struct inode *inode, struct file *filp) 19.189 @@ -134,7 +180,6 @@ static int xenbus_dev_open(struct inode 19.190 if (xen_start_info->store_evtchn == 0) 19.191 return -ENOENT; 19.192 19.193 - /* Don't try seeking. */ 19.194 nonseekable_open(inode, filp); 19.195 19.196 u = kmalloc(sizeof(*u), GFP_KERNEL); 19.197 @@ -142,28 +187,26 @@ static int xenbus_dev_open(struct inode 19.198 return -ENOMEM; 19.199 19.200 memset(u, 0, sizeof(*u)); 19.201 + INIT_LIST_HEAD(&u->transactions); 19.202 + init_waitqueue_head(&u->read_waitq); 19.203 19.204 filp->private_data = u; 19.205 19.206 - down(&xenbus_lock); 19.207 - 19.208 return 0; 19.209 } 19.210 19.211 static int xenbus_dev_release(struct inode *inode, struct file *filp) 19.212 { 19.213 - struct xenbus_dev_data *data = filp->private_data; 19.214 - 19.215 - /* Discard any unread replies. */ 19.216 - while (data->bytes_left || data->awaiting_reply) 19.217 - xenbus_dev_read(filp, NULL, sizeof(data->u.buffer), NULL); 19.218 + struct xenbus_dev_data *u = filp->private_data; 19.219 + struct xenbus_dev_transaction *trans, *tmp; 19.220 19.221 - /* Harmless if no transaction in progress. */ 19.222 - xenbus_transaction_end(1); 19.223 + list_for_each_entry_safe(trans, tmp, &u->transactions, list) { 19.224 + xenbus_transaction_end(trans->handle, 1); 19.225 + list_del(&trans->list); 19.226 + kfree(trans); 19.227 + } 19.228 19.229 - up(&xenbus_lock); 19.230 - 19.231 - kfree(data); 19.232 + kfree(u); 19.233 19.234 return 0; 19.235 }
20.1 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c Tue Oct 11 15:50:21 2005 -0600 20.2 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c Tue Oct 11 16:57:44 2005 -0600 20.3 @@ -125,7 +125,7 @@ static int backend_bus_id(char bus_id[BU 20.4 20.5 devid = strrchr(nodename, '/') + 1; 20.6 20.7 - err = xenbus_gather(nodename, "frontend-id", "%i", &domid, 20.8 + err = xenbus_gather(NULL, nodename, "frontend-id", "%i", &domid, 20.9 "frontend", NULL, &frontend, 20.10 NULL); 20.11 if (err) 20.12 @@ -133,7 +133,7 @@ static int backend_bus_id(char bus_id[BU 20.13 if (strlen(frontend) == 0) 20.14 err = -ERANGE; 20.15 20.16 - if (!err && !xenbus_exists(frontend, "")) 20.17 + if (!err && !xenbus_exists(NULL, frontend, "")) 20.18 err = -ENOENT; 20.19 20.20 if (err) { 20.21 @@ -229,18 +229,13 @@ static int xenbus_dev_remove(struct devi 20.22 static int xenbus_register_driver_common(struct xenbus_driver *drv, 20.23 struct xen_bus_type *bus) 20.24 { 20.25 - int err; 20.26 - 20.27 drv->driver.name = drv->name; 20.28 drv->driver.bus = &bus->bus; 20.29 drv->driver.owner = drv->owner; 20.30 drv->driver.probe = xenbus_dev_probe; 20.31 drv->driver.remove = xenbus_dev_remove; 20.32 20.33 - down(&xenbus_lock); 20.34 - err = driver_register(&drv->driver); 20.35 - up(&xenbus_lock); 20.36 - return err; 20.37 + return driver_register(&drv->driver); 20.38 } 20.39 20.40 int xenbus_register_driver(struct xenbus_driver *drv) 20.41 @@ -256,9 +251,7 @@ int xenbus_register_backend(struct xenbu 20.42 20.43 void xenbus_unregister_driver(struct xenbus_driver *drv) 20.44 { 20.45 - down(&xenbus_lock); 20.46 driver_unregister(&drv->driver); 20.47 - up(&xenbus_lock); 20.48 } 20.49 EXPORT_SYMBOL(xenbus_unregister_driver); 20.50 20.51 @@ -447,7 +440,7 @@ static int xenbus_probe_backend(const ch 20.52 if (!nodename) 20.53 return -ENOMEM; 20.54 20.55 - dir = xenbus_directory(nodename, "", &dir_n); 20.56 + dir = xenbus_directory(NULL, nodename, "", &dir_n); 20.57 if (IS_ERR(dir)) { 20.58 kfree(nodename); 20.59 return PTR_ERR(dir); 20.60 @@ -470,7 +463,7 @@ static int xenbus_probe_device_type(stru 20.61 unsigned int dir_n = 0; 20.62 int i; 20.63 20.64 - dir = xenbus_directory(bus->root, type, &dir_n); 20.65 + dir = xenbus_directory(NULL, bus->root, type, &dir_n); 20.66 if (IS_ERR(dir)) 20.67 return PTR_ERR(dir); 20.68 20.69 @@ -489,7 +482,7 @@ static int xenbus_probe_devices(struct x 20.70 char **dir; 20.71 unsigned int i, dir_n; 20.72 20.73 - dir = xenbus_directory(bus->root, "", &dir_n); 20.74 + dir = xenbus_directory(NULL, bus->root, "", &dir_n); 20.75 if (IS_ERR(dir)) 20.76 return PTR_ERR(dir); 20.77 20.78 @@ -535,7 +528,7 @@ static void dev_changed(const char *node 20.79 if (char_count(node, '/') < 2) 20.80 return; 20.81 20.82 - exists = xenbus_exists(node, ""); 20.83 + exists = xenbus_exists(NULL, node, ""); 20.84 if (!exists) { 20.85 xenbus_cleanup_devices(node, &bus->bus); 20.86 return; 20.87 @@ -621,53 +614,49 @@ static int resume_dev(struct device *dev 20.88 20.89 void xenbus_suspend(void) 20.90 { 20.91 - /* We keep lock, so no comms can happen as page moves. */ 20.92 - down(&xenbus_lock); 20.93 bus_for_each_dev(&xenbus_frontend.bus, NULL, NULL, suspend_dev); 20.94 bus_for_each_dev(&xenbus_backend.bus, NULL, NULL, suspend_dev); 20.95 + xs_suspend(); 20.96 } 20.97 20.98 void xenbus_resume(void) 20.99 { 20.100 xb_init_comms(); 20.101 - reregister_xenbus_watches(); 20.102 + xs_resume(); 20.103 bus_for_each_dev(&xenbus_frontend.bus, NULL, NULL, resume_dev); 20.104 bus_for_each_dev(&xenbus_backend.bus, NULL, NULL, resume_dev); 20.105 - up(&xenbus_lock); 20.106 } 20.107 20.108 int register_xenstore_notifier(struct notifier_block *nb) 20.109 { 20.110 int ret = 0; 20.111 20.112 - down(&xenbus_lock); 20.113 - 20.114 if (xen_start_info->store_evtchn) { 20.115 ret = nb->notifier_call(nb, 0, NULL); 20.116 } else { 20.117 notifier_chain_register(&xenstore_chain, nb); 20.118 } 20.119 20.120 - up(&xenbus_lock); 20.121 - 20.122 return ret; 20.123 } 20.124 EXPORT_SYMBOL(register_xenstore_notifier); 20.125 20.126 void unregister_xenstore_notifier(struct notifier_block *nb) 20.127 { 20.128 - down(&xenbus_lock); 20.129 notifier_chain_unregister(&xenstore_chain, nb); 20.130 - up(&xenbus_lock); 20.131 } 20.132 EXPORT_SYMBOL(unregister_xenstore_notifier); 20.133 20.134 -/* called from a thread in privcmd/privcmd.c */ 20.135 +/* 20.136 +** Called either from below xenbus_probe_init() initcall (for domUs) 20.137 +** or, for dom0, from a thread created in privcmd/privcmd.c (after 20.138 +** the user-space tools have invoked initDomainStore()) 20.139 +*/ 20.140 int do_xenbus_probe(void *unused) 20.141 { 20.142 int err = 0; 20.143 20.144 - /* Initialize xenstore comms unless already done. */ 20.145 + /* Initialize the interface to xenstore. */ 20.146 err = xs_init(); 20.147 if (err) { 20.148 printk("XENBUS: Error initializing xenstore comms:" 20.149 @@ -675,16 +664,17 @@ int do_xenbus_probe(void *unused) 20.150 return err; 20.151 } 20.152 20.153 - down(&xenbus_lock); 20.154 /* Enumerate devices in xenstore. */ 20.155 xenbus_probe_devices(&xenbus_frontend); 20.156 xenbus_probe_devices(&xenbus_backend); 20.157 + 20.158 /* Watch for changes. */ 20.159 register_xenbus_watch(&fe_watch); 20.160 register_xenbus_watch(&be_watch); 20.161 + 20.162 /* Notify others that xenstore is up */ 20.163 notifier_call_chain(&xenstore_chain, 0, 0); 20.164 - up(&xenbus_lock); 20.165 + 20.166 return 0; 20.167 } 20.168 20.169 @@ -698,6 +688,10 @@ static int __init xenbus_probe_init(void 20.170 device_register(&xenbus_frontend.dev); 20.171 device_register(&xenbus_backend.dev); 20.172 20.173 + /* 20.174 + ** Domain0 doesn't have a store_evtchn yet - this will 20.175 + ** be set up later by xend invoking initDomainStore() 20.176 + */ 20.177 if (!xen_start_info->store_evtchn) 20.178 return 0; 20.179
21.1 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c Tue Oct 11 15:50:21 2005 -0600 21.2 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c Tue Oct 11 16:57:44 2005 -0600 21.3 @@ -42,11 +42,58 @@ 21.4 21.5 #define streq(a, b) (strcmp((a), (b)) == 0) 21.6 21.7 -static char printf_buffer[4096]; 21.8 -static LIST_HEAD(watches); 21.9 +struct xs_stored_msg { 21.10 + struct list_head list; 21.11 + 21.12 + struct xsd_sockmsg hdr; 21.13 + 21.14 + union { 21.15 + /* Queued replies. */ 21.16 + struct { 21.17 + char *body; 21.18 + } reply; 21.19 + 21.20 + /* Queued watch events. */ 21.21 + struct { 21.22 + struct xenbus_watch *handle; 21.23 + char **vec; 21.24 + unsigned int vec_size; 21.25 + } watch; 21.26 + } u; 21.27 +}; 21.28 + 21.29 +struct xs_handle { 21.30 + /* A list of replies. Currently only one will ever be outstanding. */ 21.31 + struct list_head reply_list; 21.32 + spinlock_t reply_lock; 21.33 + wait_queue_head_t reply_waitq; 21.34 21.35 -DECLARE_MUTEX(xenbus_lock); 21.36 -EXPORT_SYMBOL(xenbus_lock); 21.37 + /* One request at a time. */ 21.38 + struct semaphore request_mutex; 21.39 + 21.40 + /* Protect transactions against save/restore. */ 21.41 + struct rw_semaphore suspend_mutex; 21.42 +}; 21.43 + 21.44 +static struct xs_handle xs_state; 21.45 + 21.46 +/* List of registered watches, and a lock to protect it. */ 21.47 +static LIST_HEAD(watches); 21.48 +static DEFINE_SPINLOCK(watches_lock); 21.49 + 21.50 +/* List of pending watch calbback events, and a lock to protect it. */ 21.51 +static LIST_HEAD(watch_events); 21.52 +static DEFINE_SPINLOCK(watch_events_lock); 21.53 + 21.54 +/* 21.55 + * Details of the xenwatch callback kernel thread. The thread waits on the 21.56 + * watch_events_waitq for work to do (queued on watch_events list). When it 21.57 + * wakes up it acquires the xenwatch_mutex before reading the list and 21.58 + * carrying out work. 21.59 + */ 21.60 +static pid_t xenwatch_pid; 21.61 +static DECLARE_MUTEX(xenwatch_mutex); 21.62 +static DECLARE_WAIT_QUEUE_HEAD(watch_events_waitq); 21.63 21.64 static int get_error(const char *errorstring) 21.65 { 21.66 @@ -65,47 +112,82 @@ static int get_error(const char *errorst 21.67 21.68 static void *read_reply(enum xsd_sockmsg_type *type, unsigned int *len) 21.69 { 21.70 - struct xsd_sockmsg msg; 21.71 - void *ret; 21.72 - int err; 21.73 + struct xs_stored_msg *msg; 21.74 + char *body; 21.75 + 21.76 + spin_lock(&xs_state.reply_lock); 21.77 21.78 - err = xb_read(&msg, sizeof(msg)); 21.79 - if (err) 21.80 - return ERR_PTR(err); 21.81 - 21.82 - ret = kmalloc(msg.len + 1, GFP_KERNEL); 21.83 - if (!ret) 21.84 - return ERR_PTR(-ENOMEM); 21.85 + while (list_empty(&xs_state.reply_list)) { 21.86 + spin_unlock(&xs_state.reply_lock); 21.87 + wait_event_interruptible(xs_state.reply_waitq, 21.88 + !list_empty(&xs_state.reply_list)); 21.89 + spin_lock(&xs_state.reply_lock); 21.90 + } 21.91 21.92 - err = xb_read(ret, msg.len); 21.93 - if (err) { 21.94 - kfree(ret); 21.95 - return ERR_PTR(err); 21.96 - } 21.97 - ((char*)ret)[msg.len] = '\0'; 21.98 + msg = list_entry(xs_state.reply_list.next, 21.99 + struct xs_stored_msg, list); 21.100 + list_del(&msg->list); 21.101 + 21.102 + spin_unlock(&xs_state.reply_lock); 21.103 21.104 - *type = msg.type; 21.105 + *type = msg->hdr.type; 21.106 if (len) 21.107 - *len = msg.len; 21.108 - return ret; 21.109 + *len = msg->hdr.len; 21.110 + body = msg->u.reply.body; 21.111 + 21.112 + kfree(msg); 21.113 + 21.114 + return body; 21.115 } 21.116 21.117 /* Emergency write. */ 21.118 void xenbus_debug_write(const char *str, unsigned int count) 21.119 { 21.120 - struct xsd_sockmsg msg; 21.121 + struct xsd_sockmsg msg = { 0 }; 21.122 21.123 msg.type = XS_DEBUG; 21.124 msg.len = sizeof("print") + count + 1; 21.125 21.126 + down(&xs_state.request_mutex); 21.127 xb_write(&msg, sizeof(msg)); 21.128 xb_write("print", sizeof("print")); 21.129 xb_write(str, count); 21.130 xb_write("", 1); 21.131 + up(&xs_state.request_mutex); 21.132 +} 21.133 + 21.134 +void *xenbus_dev_request_and_reply(struct xsd_sockmsg *msg) 21.135 +{ 21.136 + void *ret; 21.137 + struct xsd_sockmsg req_msg = *msg; 21.138 + int err; 21.139 + 21.140 + if (req_msg.type == XS_TRANSACTION_START) 21.141 + down_read(&xs_state.suspend_mutex); 21.142 + 21.143 + down(&xs_state.request_mutex); 21.144 + 21.145 + err = xb_write(msg, sizeof(*msg) + msg->len); 21.146 + if (err) { 21.147 + msg->type = XS_ERROR; 21.148 + ret = ERR_PTR(err); 21.149 + } else { 21.150 + ret = read_reply(&msg->type, &msg->len); 21.151 + } 21.152 + 21.153 + up(&xs_state.request_mutex); 21.154 + 21.155 + if ((msg->type == XS_TRANSACTION_END) || 21.156 + ((req_msg.type == XS_TRANSACTION_START) && 21.157 + (msg->type == XS_ERROR))) 21.158 + up_read(&xs_state.suspend_mutex); 21.159 + 21.160 + return ret; 21.161 } 21.162 21.163 /* Send message to xs, get kmalloc'ed reply. ERR_PTR() on error. */ 21.164 -static void *xs_talkv(enum xsd_sockmsg_type type, 21.165 +static void *xs_talkv(struct xenbus_transaction *t, 21.166 + enum xsd_sockmsg_type type, 21.167 const struct kvec *iovec, 21.168 unsigned int num_vecs, 21.169 unsigned int *len) 21.170 @@ -115,31 +197,34 @@ static void *xs_talkv(enum xsd_sockmsg_t 21.171 unsigned int i; 21.172 int err; 21.173 21.174 - WARN_ON(down_trylock(&xenbus_lock) == 0); 21.175 - 21.176 + msg.tx_id = (u32)(unsigned long)t; 21.177 msg.type = type; 21.178 msg.len = 0; 21.179 for (i = 0; i < num_vecs; i++) 21.180 msg.len += iovec[i].iov_len; 21.181 21.182 + down(&xs_state.request_mutex); 21.183 + 21.184 err = xb_write(&msg, sizeof(msg)); 21.185 - if (err) 21.186 + if (err) { 21.187 + up(&xs_state.request_mutex); 21.188 return ERR_PTR(err); 21.189 + } 21.190 21.191 for (i = 0; i < num_vecs; i++) { 21.192 err = xb_write(iovec[i].iov_base, iovec[i].iov_len);; 21.193 - if (err) 21.194 + if (err) { 21.195 + up(&xs_state.request_mutex); 21.196 return ERR_PTR(err); 21.197 + } 21.198 } 21.199 21.200 - /* Watches can have fired before reply comes: daemon detects 21.201 - * and re-transmits, so we can ignore this. */ 21.202 - do { 21.203 - kfree(ret); 21.204 - ret = read_reply(&msg.type, len); 21.205 - if (IS_ERR(ret)) 21.206 - return ret; 21.207 - } while (msg.type == XS_WATCH_EVENT); 21.208 + ret = read_reply(&msg.type, len); 21.209 + 21.210 + up(&xs_state.request_mutex); 21.211 + 21.212 + if (IS_ERR(ret)) 21.213 + return ret; 21.214 21.215 if (msg.type == XS_ERROR) { 21.216 err = get_error(ret); 21.217 @@ -152,14 +237,16 @@ static void *xs_talkv(enum xsd_sockmsg_t 21.218 } 21.219 21.220 /* Simplified version of xs_talkv: single message. */ 21.221 -static void *xs_single(enum xsd_sockmsg_type type, 21.222 - const char *string, unsigned int *len) 21.223 +static void *xs_single(struct xenbus_transaction *t, 21.224 + enum xsd_sockmsg_type type, 21.225 + const char *string, 21.226 + unsigned int *len) 21.227 { 21.228 struct kvec iovec; 21.229 21.230 iovec.iov_base = (void *)string; 21.231 iovec.iov_len = strlen(string) + 1; 21.232 - return xs_talkv(type, &iovec, 1, len); 21.233 + return xs_talkv(t, type, &iovec, 1, len); 21.234 } 21.235 21.236 /* Many commands only need an ack, don't care what it says. */ 21.237 @@ -182,20 +269,22 @@ static unsigned int count_strings(const 21.238 return num; 21.239 } 21.240 21.241 -/* Return the path to dir with /name appended. */ 21.242 +/* Return the path to dir with /name appended. Buffer must be kfree()'ed. */ 21.243 static char *join(const char *dir, const char *name) 21.244 { 21.245 - static char buffer[4096]; 21.246 + char *buffer; 21.247 21.248 - BUG_ON(down_trylock(&xenbus_lock) == 0); 21.249 - /* XXX FIXME: might not be correct if name == "" */ 21.250 - BUG_ON(strlen(dir) + strlen("/") + strlen(name) + 1 > sizeof(buffer)); 21.251 + buffer = kmalloc(strlen(dir) + strlen("/") + strlen(name) + 1, 21.252 + GFP_KERNEL); 21.253 + if (buffer == NULL) 21.254 + return ERR_PTR(-ENOMEM); 21.255 21.256 strcpy(buffer, dir); 21.257 if (!streq(name, "")) { 21.258 strcat(buffer, "/"); 21.259 strcat(buffer, name); 21.260 } 21.261 + 21.262 return buffer; 21.263 } 21.264 21.265 @@ -207,7 +296,7 @@ static char **split(char *strings, unsig 21.266 *num = count_strings(strings, len); 21.267 21.268 /* Transfer to one big alloc for easy freeing. */ 21.269 - ret = kmalloc(*num * sizeof(char *) + len, GFP_ATOMIC); 21.270 + ret = kmalloc(*num * sizeof(char *) + len, GFP_KERNEL); 21.271 if (!ret) { 21.272 kfree(strings); 21.273 return ERR_PTR(-ENOMEM); 21.274 @@ -222,12 +311,18 @@ static char **split(char *strings, unsig 21.275 return ret; 21.276 } 21.277 21.278 -char **xenbus_directory(const char *dir, const char *node, unsigned int *num) 21.279 +char **xenbus_directory(struct xenbus_transaction *t, 21.280 + const char *dir, const char *node, unsigned int *num) 21.281 { 21.282 - char *strings; 21.283 + char *strings, *path; 21.284 unsigned int len; 21.285 21.286 - strings = xs_single(XS_DIRECTORY, join(dir, node), &len); 21.287 + path = join(dir, node); 21.288 + if (IS_ERR(path)) 21.289 + return (char **)path; 21.290 + 21.291 + strings = xs_single(t, XS_DIRECTORY, path, &len); 21.292 + kfree(path); 21.293 if (IS_ERR(strings)) 21.294 return (char **)strings; 21.295 21.296 @@ -236,12 +331,13 @@ char **xenbus_directory(const char *dir, 21.297 EXPORT_SYMBOL(xenbus_directory); 21.298 21.299 /* Check if a path exists. Return 1 if it does. */ 21.300 -int xenbus_exists(const char *dir, const char *node) 21.301 +int xenbus_exists(struct xenbus_transaction *t, 21.302 + const char *dir, const char *node) 21.303 { 21.304 char **d; 21.305 int dir_n; 21.306 21.307 - d = xenbus_directory(dir, node, &dir_n); 21.308 + d = xenbus_directory(t, dir, node, &dir_n); 21.309 if (IS_ERR(d)) 21.310 return 0; 21.311 kfree(d); 21.312 @@ -253,78 +349,133 @@ EXPORT_SYMBOL(xenbus_exists); 21.313 * Returns a kmalloced value: call free() on it after use. 21.314 * len indicates length in bytes. 21.315 */ 21.316 -void *xenbus_read(const char *dir, const char *node, unsigned int *len) 21.317 +void *xenbus_read(struct xenbus_transaction *t, 21.318 + const char *dir, const char *node, unsigned int *len) 21.319 { 21.320 - return xs_single(XS_READ, join(dir, node), len); 21.321 + char *path; 21.322 + void *ret; 21.323 + 21.324 + path = join(dir, node); 21.325 + if (IS_ERR(path)) 21.326 + return (void *)path; 21.327 + 21.328 + ret = xs_single(t, XS_READ, path, len); 21.329 + kfree(path); 21.330 + return ret; 21.331 } 21.332 EXPORT_SYMBOL(xenbus_read); 21.333 21.334 /* Write the value of a single file. 21.335 * Returns -err on failure. 21.336 */ 21.337 -int xenbus_write(const char *dir, const char *node, const char *string) 21.338 +int xenbus_write(struct xenbus_transaction *t, 21.339 + const char *dir, const char *node, const char *string) 21.340 { 21.341 const char *path; 21.342 struct kvec iovec[2]; 21.343 + int ret; 21.344 21.345 path = join(dir, node); 21.346 + if (IS_ERR(path)) 21.347 + return PTR_ERR(path); 21.348 21.349 iovec[0].iov_base = (void *)path; 21.350 iovec[0].iov_len = strlen(path) + 1; 21.351 iovec[1].iov_base = (void *)string; 21.352 iovec[1].iov_len = strlen(string); 21.353 21.354 - return xs_error(xs_talkv(XS_WRITE, iovec, ARRAY_SIZE(iovec), NULL)); 21.355 + ret = xs_error(xs_talkv(t, XS_WRITE, iovec, ARRAY_SIZE(iovec), NULL)); 21.356 + kfree(path); 21.357 + return ret; 21.358 } 21.359 EXPORT_SYMBOL(xenbus_write); 21.360 21.361 /* Create a new directory. */ 21.362 -int xenbus_mkdir(const char *dir, const char *node) 21.363 +int xenbus_mkdir(struct xenbus_transaction *t, 21.364 + const char *dir, const char *node) 21.365 { 21.366 - return xs_error(xs_single(XS_MKDIR, join(dir, node), NULL)); 21.367 + char *path; 21.368 + int ret; 21.369 + 21.370 + path = join(dir, node); 21.371 + if (IS_ERR(path)) 21.372 + return PTR_ERR(path); 21.373 + 21.374 + ret = xs_error(xs_single(t, XS_MKDIR, path, NULL)); 21.375 + kfree(path); 21.376 + return ret; 21.377 } 21.378 EXPORT_SYMBOL(xenbus_mkdir); 21.379 21.380 /* Destroy a file or directory (directories must be empty). */ 21.381 -int xenbus_rm(const char *dir, const char *node) 21.382 +int xenbus_rm(struct xenbus_transaction *t, const char *dir, const char *node) 21.383 { 21.384 - return xs_error(xs_single(XS_RM, join(dir, node), NULL)); 21.385 + char *path; 21.386 + int ret; 21.387 + 21.388 + path = join(dir, node); 21.389 + if (IS_ERR(path)) 21.390 + return PTR_ERR(path); 21.391 + 21.392 + ret = xs_error(xs_single(t, XS_RM, path, NULL)); 21.393 + kfree(path); 21.394 + return ret; 21.395 } 21.396 EXPORT_SYMBOL(xenbus_rm); 21.397 21.398 /* Start a transaction: changes by others will not be seen during this 21.399 * transaction, and changes will not be visible to others until end. 21.400 - * You can only have one transaction at any time. 21.401 */ 21.402 -int xenbus_transaction_start(void) 21.403 +struct xenbus_transaction *xenbus_transaction_start(void) 21.404 { 21.405 - return xs_error(xs_single(XS_TRANSACTION_START, "", NULL)); 21.406 + char *id_str; 21.407 + unsigned long id; 21.408 + 21.409 + down_read(&xs_state.suspend_mutex); 21.410 + 21.411 + id_str = xs_single(NULL, XS_TRANSACTION_START, "", NULL); 21.412 + if (IS_ERR(id_str)) { 21.413 + up_read(&xs_state.suspend_mutex); 21.414 + return (struct xenbus_transaction *)id_str; 21.415 + } 21.416 + 21.417 + id = simple_strtoul(id_str, NULL, 0); 21.418 + kfree(id_str); 21.419 + 21.420 + return (struct xenbus_transaction *)id; 21.421 } 21.422 EXPORT_SYMBOL(xenbus_transaction_start); 21.423 21.424 /* End a transaction. 21.425 * If abandon is true, transaction is discarded instead of committed. 21.426 */ 21.427 -int xenbus_transaction_end(int abort) 21.428 +int xenbus_transaction_end(struct xenbus_transaction *t, int abort) 21.429 { 21.430 char abortstr[2]; 21.431 + int err; 21.432 21.433 if (abort) 21.434 strcpy(abortstr, "F"); 21.435 else 21.436 strcpy(abortstr, "T"); 21.437 - return xs_error(xs_single(XS_TRANSACTION_END, abortstr, NULL)); 21.438 + 21.439 + err = xs_error(xs_single(t, XS_TRANSACTION_END, abortstr, NULL)); 21.440 + 21.441 + up_read(&xs_state.suspend_mutex); 21.442 + 21.443 + return err; 21.444 } 21.445 EXPORT_SYMBOL(xenbus_transaction_end); 21.446 21.447 /* Single read and scanf: returns -errno or num scanned. */ 21.448 -int xenbus_scanf(const char *dir, const char *node, const char *fmt, ...) 21.449 +int xenbus_scanf(struct xenbus_transaction *t, 21.450 + const char *dir, const char *node, const char *fmt, ...) 21.451 { 21.452 va_list ap; 21.453 int ret; 21.454 char *val; 21.455 21.456 - val = xenbus_read(dir, node, NULL); 21.457 + val = xenbus_read(t, dir, node, NULL); 21.458 if (IS_ERR(val)) 21.459 return PTR_ERR(val); 21.460 21.461 @@ -340,18 +491,28 @@ int xenbus_scanf(const char *dir, const 21.462 EXPORT_SYMBOL(xenbus_scanf); 21.463 21.464 /* Single printf and write: returns -errno or 0. */ 21.465 -int xenbus_printf(const char *dir, const char *node, const char *fmt, ...) 21.466 +int xenbus_printf(struct xenbus_transaction *t, 21.467 + const char *dir, const char *node, const char *fmt, ...) 21.468 { 21.469 va_list ap; 21.470 int ret; 21.471 +#define PRINTF_BUFFER_SIZE 4096 21.472 + char *printf_buffer; 21.473 21.474 - BUG_ON(down_trylock(&xenbus_lock) == 0); 21.475 + printf_buffer = kmalloc(PRINTF_BUFFER_SIZE, GFP_KERNEL); 21.476 + if (printf_buffer == NULL) 21.477 + return -ENOMEM; 21.478 + 21.479 va_start(ap, fmt); 21.480 - ret = vsnprintf(printf_buffer, sizeof(printf_buffer), fmt, ap); 21.481 + ret = vsnprintf(printf_buffer, PRINTF_BUFFER_SIZE, fmt, ap); 21.482 va_end(ap); 21.483 21.484 - BUG_ON(ret > sizeof(printf_buffer)-1); 21.485 - return xenbus_write(dir, node, printf_buffer); 21.486 + BUG_ON(ret > PRINTF_BUFFER_SIZE-1); 21.487 + ret = xenbus_write(t, dir, node, printf_buffer); 21.488 + 21.489 + kfree(printf_buffer); 21.490 + 21.491 + return ret; 21.492 } 21.493 EXPORT_SYMBOL(xenbus_printf); 21.494 21.495 @@ -361,19 +522,28 @@ void xenbus_dev_error(struct xenbus_devi 21.496 va_list ap; 21.497 int ret; 21.498 unsigned int len; 21.499 + char *printf_buffer; 21.500 21.501 - BUG_ON(down_trylock(&xenbus_lock) == 0); 21.502 + printf_buffer = kmalloc(PRINTF_BUFFER_SIZE, GFP_KERNEL); 21.503 + if (printf_buffer == NULL) 21.504 + goto fail; 21.505 21.506 len = sprintf(printf_buffer, "%i ", -err); 21.507 va_start(ap, fmt); 21.508 - ret = vsnprintf(printf_buffer+len, sizeof(printf_buffer)-len, fmt, ap); 21.509 + ret = vsnprintf(printf_buffer+len, PRINTF_BUFFER_SIZE-len, fmt, ap); 21.510 va_end(ap); 21.511 21.512 - BUG_ON(len + ret > sizeof(printf_buffer)-1); 21.513 + BUG_ON(len + ret > PRINTF_BUFFER_SIZE-1); 21.514 dev->has_error = 1; 21.515 - if (xenbus_write(dev->nodename, "error", printf_buffer) != 0) 21.516 - printk("xenbus: failed to write error node for %s (%s)\n", 21.517 - dev->nodename, printf_buffer); 21.518 + if (xenbus_write(NULL, dev->nodename, "error", printf_buffer) != 0) 21.519 + goto fail; 21.520 + 21.521 + kfree(printf_buffer); 21.522 + return; 21.523 + 21.524 + fail: 21.525 + printk("xenbus: failed to write error node for %s (%s)\n", 21.526 + dev->nodename, printf_buffer); 21.527 } 21.528 EXPORT_SYMBOL(xenbus_dev_error); 21.529 21.530 @@ -381,7 +551,7 @@ EXPORT_SYMBOL(xenbus_dev_error); 21.531 void xenbus_dev_ok(struct xenbus_device *dev) 21.532 { 21.533 if (dev->has_error) { 21.534 - if (xenbus_rm(dev->nodename, "error") != 0) 21.535 + if (xenbus_rm(NULL, dev->nodename, "error") != 0) 21.536 printk("xenbus: failed to clear error node for %s\n", 21.537 dev->nodename); 21.538 else 21.539 @@ -391,7 +561,7 @@ void xenbus_dev_ok(struct xenbus_device 21.540 EXPORT_SYMBOL(xenbus_dev_ok); 21.541 21.542 /* Takes tuples of names, scanf-style args, and void **, NULL terminated. */ 21.543 -int xenbus_gather(const char *dir, ...) 21.544 +int xenbus_gather(struct xenbus_transaction *t, const char *dir, ...) 21.545 { 21.546 va_list ap; 21.547 const char *name; 21.548 @@ -403,7 +573,7 @@ int xenbus_gather(const char *dir, ...) 21.549 void *result = va_arg(ap, void *); 21.550 char *p; 21.551 21.552 - p = xenbus_read(dir, name, NULL); 21.553 + p = xenbus_read(t, dir, name, NULL); 21.554 if (IS_ERR(p)) { 21.555 ret = PTR_ERR(p); 21.556 break; 21.557 @@ -429,27 +599,8 @@ static int xs_watch(const char *path, co 21.558 iov[1].iov_base = (void *)token; 21.559 iov[1].iov_len = strlen(token) + 1; 21.560 21.561 - return xs_error(xs_talkv(XS_WATCH, iov, ARRAY_SIZE(iov), NULL)); 21.562 -} 21.563 - 21.564 -static char **xs_read_watch(unsigned int *num) 21.565 -{ 21.566 - enum xsd_sockmsg_type type; 21.567 - char *strings; 21.568 - unsigned int len; 21.569 - 21.570 - strings = read_reply(&type, &len); 21.571 - if (IS_ERR(strings)) 21.572 - return (char **)strings; 21.573 - 21.574 - BUG_ON(type != XS_WATCH_EVENT); 21.575 - 21.576 - return split(strings, len, num); 21.577 -} 21.578 - 21.579 -static int xs_acknowledge_watch(const char *token) 21.580 -{ 21.581 - return xs_error(xs_single(XS_WATCH_ACK, token, NULL)); 21.582 + return xs_error(xs_talkv(NULL, XS_WATCH, iov, 21.583 + ARRAY_SIZE(iov), NULL)); 21.584 } 21.585 21.586 static int xs_unwatch(const char *path, const char *token) 21.587 @@ -461,10 +612,10 @@ static int xs_unwatch(const char *path, 21.588 iov[1].iov_base = (char *)token; 21.589 iov[1].iov_len = strlen(token) + 1; 21.590 21.591 - return xs_error(xs_talkv(XS_UNWATCH, iov, ARRAY_SIZE(iov), NULL)); 21.592 + return xs_error(xs_talkv(NULL, XS_UNWATCH, iov, 21.593 + ARRAY_SIZE(iov), NULL)); 21.594 } 21.595 21.596 -/* A little paranoia: we don't just trust token. */ 21.597 static struct xenbus_watch *find_watch(const char *token) 21.598 { 21.599 struct xenbus_watch *i, *cmp; 21.600 @@ -474,6 +625,7 @@ static struct xenbus_watch *find_watch(c 21.601 list_for_each_entry(i, &watches, list) 21.602 if (i == cmp) 21.603 return i; 21.604 + 21.605 return NULL; 21.606 } 21.607 21.608 @@ -485,92 +637,223 @@ int register_xenbus_watch(struct xenbus_ 21.609 int err; 21.610 21.611 sprintf(token, "%lX", (long)watch); 21.612 + 21.613 + down_read(&xs_state.suspend_mutex); 21.614 + 21.615 + spin_lock(&watches_lock); 21.616 BUG_ON(find_watch(token)); 21.617 + spin_unlock(&watches_lock); 21.618 21.619 err = xs_watch(watch->node, token); 21.620 - if (!err) 21.621 + 21.622 + /* Ignore errors due to multiple registration. */ 21.623 + if ((err == 0) || (err == -EEXIST)) { 21.624 + spin_lock(&watches_lock); 21.625 list_add(&watch->list, &watches); 21.626 + spin_unlock(&watches_lock); 21.627 + } 21.628 + 21.629 + up_read(&xs_state.suspend_mutex); 21.630 + 21.631 return err; 21.632 } 21.633 EXPORT_SYMBOL(register_xenbus_watch); 21.634 21.635 void unregister_xenbus_watch(struct xenbus_watch *watch) 21.636 { 21.637 + struct xs_stored_msg *msg, *tmp; 21.638 char token[sizeof(watch) * 2 + 1]; 21.639 int err; 21.640 21.641 sprintf(token, "%lX", (long)watch); 21.642 + 21.643 + down_read(&xs_state.suspend_mutex); 21.644 + 21.645 + spin_lock(&watches_lock); 21.646 BUG_ON(!find_watch(token)); 21.647 + list_del(&watch->list); 21.648 + spin_unlock(&watches_lock); 21.649 21.650 err = xs_unwatch(watch->node, token); 21.651 - list_del(&watch->list); 21.652 - 21.653 if (err) 21.654 printk(KERN_WARNING 21.655 "XENBUS Failed to release watch %s: %i\n", 21.656 watch->node, err); 21.657 + 21.658 + up_read(&xs_state.suspend_mutex); 21.659 + 21.660 + /* Cancel pending watch events. */ 21.661 + spin_lock(&watch_events_lock); 21.662 + list_for_each_entry_safe(msg, tmp, &watch_events, list) { 21.663 + if (msg->u.watch.handle != watch) 21.664 + continue; 21.665 + list_del(&msg->list); 21.666 + kfree(msg->u.watch.vec); 21.667 + kfree(msg); 21.668 + } 21.669 + spin_unlock(&watch_events_lock); 21.670 + 21.671 + /* Flush any currently-executing callback, unless we are it. :-) */ 21.672 + if (current->pid != xenwatch_pid) { 21.673 + down(&xenwatch_mutex); 21.674 + up(&xenwatch_mutex); 21.675 + } 21.676 } 21.677 EXPORT_SYMBOL(unregister_xenbus_watch); 21.678 21.679 -/* Re-register callbacks to all watches. */ 21.680 -void reregister_xenbus_watches(void) 21.681 +void xs_suspend(void) 21.682 +{ 21.683 + down_write(&xs_state.suspend_mutex); 21.684 + down(&xs_state.request_mutex); 21.685 +} 21.686 + 21.687 +void xs_resume(void) 21.688 { 21.689 struct xenbus_watch *watch; 21.690 char token[sizeof(watch) * 2 + 1]; 21.691 21.692 + up(&xs_state.request_mutex); 21.693 + 21.694 + /* No need for watches_lock: the suspend_mutex is sufficient. */ 21.695 list_for_each_entry(watch, &watches, list) { 21.696 sprintf(token, "%lX", (long)watch); 21.697 xs_watch(watch->node, token); 21.698 } 21.699 + 21.700 + up_write(&xs_state.suspend_mutex); 21.701 +} 21.702 + 21.703 +static int xenwatch_thread(void *unused) 21.704 +{ 21.705 + struct list_head *ent; 21.706 + struct xs_stored_msg *msg; 21.707 + 21.708 + for (;;) { 21.709 + wait_event_interruptible(watch_events_waitq, 21.710 + !list_empty(&watch_events)); 21.711 + 21.712 + down(&xenwatch_mutex); 21.713 + 21.714 + spin_lock(&watch_events_lock); 21.715 + ent = watch_events.next; 21.716 + if (ent != &watch_events) 21.717 + list_del(ent); 21.718 + spin_unlock(&watch_events_lock); 21.719 + 21.720 + if (ent != &watch_events) { 21.721 + msg = list_entry(ent, struct xs_stored_msg, list); 21.722 + msg->u.watch.handle->callback( 21.723 + msg->u.watch.handle, 21.724 + (const char **)msg->u.watch.vec, 21.725 + msg->u.watch.vec_size); 21.726 + kfree(msg->u.watch.vec); 21.727 + kfree(msg); 21.728 + } 21.729 + 21.730 + up(&xenwatch_mutex); 21.731 + } 21.732 } 21.733 21.734 -static int watch_thread(void *unused) 21.735 +static int process_msg(void) 21.736 { 21.737 - for (;;) { 21.738 - char **vec = NULL; 21.739 - unsigned int num; 21.740 + struct xs_stored_msg *msg; 21.741 + char *body; 21.742 + int err; 21.743 21.744 - wait_event(xb_waitq, xs_input_avail()); 21.745 + msg = kmalloc(sizeof(*msg), GFP_KERNEL); 21.746 + if (msg == NULL) 21.747 + return -ENOMEM; 21.748 21.749 - /* If this is a spurious wakeup caused by someone 21.750 - * doing an op, they'll hold the lock and the buffer 21.751 - * will be empty by the time we get there. 21.752 - */ 21.753 - down(&xenbus_lock); 21.754 - if (xs_input_avail()) 21.755 - vec = xs_read_watch(&num); 21.756 + err = xb_read(&msg->hdr, sizeof(msg->hdr)); 21.757 + if (err) { 21.758 + kfree(msg); 21.759 + return err; 21.760 + } 21.761 + 21.762 + body = kmalloc(msg->hdr.len + 1, GFP_KERNEL); 21.763 + if (body == NULL) { 21.764 + kfree(msg); 21.765 + return -ENOMEM; 21.766 + } 21.767 + 21.768 + err = xb_read(body, msg->hdr.len); 21.769 + if (err) { 21.770 + kfree(body); 21.771 + kfree(msg); 21.772 + return err; 21.773 + } 21.774 + body[msg->hdr.len] = '\0'; 21.775 21.776 - if (vec && !IS_ERR(vec)) { 21.777 - struct xenbus_watch *w; 21.778 - int err; 21.779 + if (msg->hdr.type == XS_WATCH_EVENT) { 21.780 + msg->u.watch.vec = split(body, msg->hdr.len, 21.781 + &msg->u.watch.vec_size); 21.782 + if (IS_ERR(msg->u.watch.vec)) { 21.783 + kfree(msg); 21.784 + return PTR_ERR(msg->u.watch.vec); 21.785 + } 21.786 21.787 - err = xs_acknowledge_watch(vec[XS_WATCH_TOKEN]); 21.788 - if (err) 21.789 - printk(KERN_WARNING "XENBUS ack %s fail %i\n", 21.790 - vec[XS_WATCH_TOKEN], err); 21.791 - w = find_watch(vec[XS_WATCH_TOKEN]); 21.792 - BUG_ON(!w); 21.793 - w->callback(w, (const char **)vec, num); 21.794 - kfree(vec); 21.795 - } else if (vec) 21.796 - printk(KERN_WARNING "XENBUS xs_read_watch: %li\n", 21.797 - PTR_ERR(vec)); 21.798 - up(&xenbus_lock); 21.799 + spin_lock(&watches_lock); 21.800 + msg->u.watch.handle = find_watch( 21.801 + msg->u.watch.vec[XS_WATCH_TOKEN]); 21.802 + if (msg->u.watch.handle != NULL) { 21.803 + spin_lock(&watch_events_lock); 21.804 + list_add_tail(&msg->list, &watch_events); 21.805 + wake_up(&watch_events_waitq); 21.806 + spin_unlock(&watch_events_lock); 21.807 + } else { 21.808 + kfree(msg->u.watch.vec); 21.809 + kfree(msg); 21.810 + } 21.811 + spin_unlock(&watches_lock); 21.812 + } else { 21.813 + msg->u.reply.body = body; 21.814 + spin_lock(&xs_state.reply_lock); 21.815 + list_add_tail(&msg->list, &xs_state.reply_list); 21.816 + spin_unlock(&xs_state.reply_lock); 21.817 + wake_up(&xs_state.reply_waitq); 21.818 + } 21.819 + 21.820 + return 0; 21.821 +} 21.822 + 21.823 +static int xenbus_thread(void *unused) 21.824 +{ 21.825 + int err; 21.826 + 21.827 + for (;;) { 21.828 + err = process_msg(); 21.829 + if (err) 21.830 + printk(KERN_WARNING "XENBUS error %d while reading " 21.831 + "message\n", err); 21.832 } 21.833 } 21.834 21.835 int xs_init(void) 21.836 { 21.837 int err; 21.838 - struct task_struct *watcher; 21.839 + struct task_struct *task; 21.840 21.841 + INIT_LIST_HEAD(&xs_state.reply_list); 21.842 + spin_lock_init(&xs_state.reply_lock); 21.843 + init_waitqueue_head(&xs_state.reply_waitq); 21.844 + 21.845 + init_MUTEX(&xs_state.request_mutex); 21.846 + init_rwsem(&xs_state.suspend_mutex); 21.847 + 21.848 + /* Initialize the shared memory rings to talk to xenstored */ 21.849 err = xb_init_comms(); 21.850 if (err) 21.851 return err; 21.852 - 21.853 - watcher = kthread_run(watch_thread, NULL, "kxbwatch"); 21.854 - if (IS_ERR(watcher)) 21.855 - return PTR_ERR(watcher); 21.856 + 21.857 + task = kthread_run(xenwatch_thread, NULL, "xenwatch"); 21.858 + if (IS_ERR(task)) 21.859 + return PTR_ERR(task); 21.860 + xenwatch_pid = task->pid; 21.861 + 21.862 + task = kthread_run(xenbus_thread, NULL, "xenbus"); 21.863 + if (IS_ERR(task)) 21.864 + return PTR_ERR(task); 21.865 + 21.866 return 0; 21.867 } 21.868
22.1 --- a/linux-2.6-xen-sparse/include/asm-xen/xenbus.h Tue Oct 11 15:50:21 2005 -0600 22.2 +++ b/linux-2.6-xen-sparse/include/asm-xen/xenbus.h Tue Oct 11 16:57:44 2005 -0600 22.3 @@ -78,30 +78,35 @@ int xenbus_register_driver(struct xenbus 22.4 int xenbus_register_backend(struct xenbus_driver *drv); 22.5 void xenbus_unregister_driver(struct xenbus_driver *drv); 22.6 22.7 -/* Caller must hold this lock to call these functions: it's also held 22.8 - * across watch callbacks. */ 22.9 -extern struct semaphore xenbus_lock; 22.10 +struct xenbus_transaction; 22.11 22.12 -char **xenbus_directory(const char *dir, const char *node, unsigned int *num); 22.13 -void *xenbus_read(const char *dir, const char *node, unsigned int *len); 22.14 -int xenbus_write(const char *dir, const char *node, const char *string); 22.15 -int xenbus_mkdir(const char *dir, const char *node); 22.16 -int xenbus_exists(const char *dir, const char *node); 22.17 -int xenbus_rm(const char *dir, const char *node); 22.18 -int xenbus_transaction_start(void); 22.19 -int xenbus_transaction_end(int abort); 22.20 +char **xenbus_directory(struct xenbus_transaction *t, 22.21 + const char *dir, const char *node, unsigned int *num); 22.22 +void *xenbus_read(struct xenbus_transaction *t, 22.23 + const char *dir, const char *node, unsigned int *len); 22.24 +int xenbus_write(struct xenbus_transaction *t, 22.25 + const char *dir, const char *node, const char *string); 22.26 +int xenbus_mkdir(struct xenbus_transaction *t, 22.27 + const char *dir, const char *node); 22.28 +int xenbus_exists(struct xenbus_transaction *t, 22.29 + const char *dir, const char *node); 22.30 +int xenbus_rm(struct xenbus_transaction *t, const char *dir, const char *node); 22.31 +struct xenbus_transaction *xenbus_transaction_start(void); 22.32 +int xenbus_transaction_end(struct xenbus_transaction *t, int abort); 22.33 22.34 /* Single read and scanf: returns -errno or num scanned if > 0. */ 22.35 -int xenbus_scanf(const char *dir, const char *node, const char *fmt, ...) 22.36 - __attribute__((format(scanf, 3, 4))); 22.37 +int xenbus_scanf(struct xenbus_transaction *t, 22.38 + const char *dir, const char *node, const char *fmt, ...) 22.39 + __attribute__((format(scanf, 4, 5))); 22.40 22.41 /* Single printf and write: returns -errno or 0. */ 22.42 -int xenbus_printf(const char *dir, const char *node, const char *fmt, ...) 22.43 - __attribute__((format(printf, 3, 4))); 22.44 +int xenbus_printf(struct xenbus_transaction *t, 22.45 + const char *dir, const char *node, const char *fmt, ...) 22.46 + __attribute__((format(printf, 4, 5))); 22.47 22.48 /* Generic read function: NULL-terminated triples of name, 22.49 * sprintf-style type string, and pointer. Returns 0 or errno.*/ 22.50 -int xenbus_gather(const char *dir, ...); 22.51 +int xenbus_gather(struct xenbus_transaction *t, const char *dir, ...); 22.52 22.53 /* Report a (negative) errno into the store, with explanation. */ 22.54 void xenbus_dev_error(struct xenbus_device *dev, int err, const char *fmt,...); 22.55 @@ -113,7 +118,11 @@ void xenbus_dev_ok(struct xenbus_device 22.56 struct xenbus_watch 22.57 { 22.58 struct list_head list; 22.59 + 22.60 + /* Path being watched. */ 22.61 char *node; 22.62 + 22.63 + /* Callback (executed in a process context with no locks held). */ 22.64 void (*callback)(struct xenbus_watch *, 22.65 const char **vec, unsigned int len); 22.66 }; 22.67 @@ -124,7 +133,11 @@ void unregister_xenstore_notifier(struct 22.68 22.69 int register_xenbus_watch(struct xenbus_watch *watch); 22.70 void unregister_xenbus_watch(struct xenbus_watch *watch); 22.71 -void reregister_xenbus_watches(void); 22.72 +void xs_suspend(void); 22.73 +void xs_resume(void); 22.74 + 22.75 +/* Used by xenbus_dev to borrow kernel's store connection. */ 22.76 +void *xenbus_dev_request_and_reply(struct xsd_sockmsg *msg); 22.77 22.78 /* Called from xen core code. */ 22.79 void xenbus_suspend(void);
23.1 --- a/tools/blktap/xenbus.c Tue Oct 11 15:50:21 2005 -0600 23.2 +++ b/tools/blktap/xenbus.c Tue Oct 11 16:57:44 2005 -0600 23.3 @@ -260,10 +260,6 @@ int xs_fire_next_watch(struct xs_handle 23.4 node = res[XS_WATCH_PATH]; 23.5 token = res[XS_WATCH_TOKEN]; 23.6 23.7 - er = xs_acknowledge_watch(h, token); 23.8 - if (er == 0) 23.9 - warn("Couldn't acknowledge watch (%s)", token); 23.10 - 23.11 w = find_watch(token); 23.12 if (!w) 23.13 {
24.1 --- a/tools/console/Makefile Tue Oct 11 15:50:21 2005 -0600 24.2 +++ b/tools/console/Makefile Tue Oct 11 16:57:44 2005 -0600 24.3 @@ -3,7 +3,7 @@ XEN_ROOT=../.. 24.4 include $(XEN_ROOT)/tools/Rules.mk 24.5 24.6 DAEMON_INSTALL_DIR = /usr/sbin 24.7 -CLIENT_INSTALL_DIR = /usr/libexec/xen 24.8 +CLIENT_INSTALL_DIR = /usr/$(LIBDIR)/xen/bin 24.9 24.10 INSTALL = install 24.11 INSTALL_PROG = $(INSTALL) -m0755
25.1 --- a/tools/console/client/main.c Tue Oct 11 15:50:21 2005 -0600 25.2 +++ b/tools/console/client/main.c Tue Oct 11 16:57:44 2005 -0600 25.3 @@ -220,7 +220,7 @@ int main(int argc, char **argv) 25.4 if (path == NULL) 25.5 err(ENOMEM, "realloc"); 25.6 strcat(path, "/console/tty"); 25.7 - str_pty = xs_read(xs, path, &len); 25.8 + str_pty = xs_read(xs, NULL, path, &len); 25.9 25.10 /* FIXME consoled currently does not assume domain-0 doesn't have a 25.11 console which is good when we break domain-0 up. To keep us 25.12 @@ -245,7 +245,7 @@ int main(int argc, char **argv) 25.13 struct timeval tv = { 0, 500 }; 25.14 select(0, NULL, NULL, NULL, &tv); /* pause briefly */ 25.15 25.16 - str_pty = xs_read(xs, path, &len); 25.17 + str_pty = xs_read(xs, NULL, path, &len); 25.18 } 25.19 25.20 if (str_pty == NULL) {
26.1 --- a/tools/console/daemon/io.c Tue Oct 11 15:50:21 2005 -0600 26.2 +++ b/tools/console/daemon/io.c Tue Oct 11 16:57:44 2005 -0600 26.3 @@ -25,6 +25,7 @@ 26.4 #include <xenctrl.h> 26.5 #include <xs.h> 26.6 #include <xen/linux/evtchn.h> 26.7 +#include <xen/io/console.h> 26.8 26.9 #include <malloc.h> 26.10 #include <stdlib.h> 26.11 @@ -62,25 +63,12 @@ struct domain 26.12 char *conspath; 26.13 int ring_ref; 26.14 int local_port; 26.15 - char *page; 26.16 int evtchn_fd; 26.17 + struct xencons_interface *interface; 26.18 }; 26.19 26.20 static struct domain *dom_head; 26.21 26.22 -struct ring_head 26.23 -{ 26.24 - u32 cons; 26.25 - u32 prod; 26.26 - char buf[0]; 26.27 -} __attribute__((packed)); 26.28 - 26.29 -#define PAGE_SIZE (getpagesize()) 26.30 -#define XENCONS_RING_SIZE (PAGE_SIZE/2 - sizeof (struct ring_head)) 26.31 -#define XENCONS_IDX(cnt) ((cnt) % XENCONS_RING_SIZE) 26.32 -#define XENCONS_FULL(ring) (((ring)->prod - (ring)->cons) == XENCONS_RING_SIZE) 26.33 -#define XENCONS_SPACE(ring) (XENCONS_RING_SIZE - ((ring)->prod - (ring)->cons)) 26.34 - 26.35 static void evtchn_notify(struct domain *dom) 26.36 { 26.37 struct ioctl_evtchn_notify notify; 26.38 @@ -91,12 +79,12 @@ static void evtchn_notify(struct domain 26.39 static void buffer_append(struct domain *dom) 26.40 { 26.41 struct buffer *buffer = &dom->buffer; 26.42 - struct ring_head *ring = (struct ring_head *)dom->page; 26.43 size_t size; 26.44 - u32 oldcons; 26.45 + XENCONS_RING_IDX oldcons; 26.46 int notify = 0; 26.47 + struct xencons_interface *intf = dom->interface; 26.48 26.49 - while ((size = ring->prod - ring->cons) != 0) { 26.50 + while ((size = (intf->out_prod - intf->out_cons)) != 0) { 26.51 notify = 1; 26.52 26.53 if ((buffer->capacity - buffer->size) < size) { 26.54 @@ -108,12 +96,12 @@ static void buffer_append(struct domain 26.55 } 26.56 } 26.57 26.58 - oldcons = ring->cons; 26.59 - while (ring->cons < (oldcons + size)) { 26.60 - buffer->data[buffer->size] = 26.61 - ring->buf[XENCONS_IDX(ring->cons)]; 26.62 + oldcons = intf->out_cons; 26.63 + while ((intf->out_cons - oldcons) < size) { 26.64 + buffer->data[buffer->size] = intf->out[ 26.65 + MASK_XENCONS_IDX(intf->out_cons, intf->out)]; 26.66 buffer->size++; 26.67 - ring->cons++; 26.68 + intf->out_cons++; 26.69 } 26.70 26.71 if (buffer->max_capacity && 26.72 @@ -179,7 +167,7 @@ static int domain_create_tty(struct doma 26.73 success = asprintf(&path, "%s/tty", dom->conspath) != -1; 26.74 if (!success) 26.75 goto out; 26.76 - success = xs_write(xs, path, slave, strlen(slave)); 26.77 + success = xs_write(xs, NULL, path, slave, strlen(slave)); 26.78 free(path); 26.79 if (!success) 26.80 goto out; 26.81 @@ -187,7 +175,7 @@ static int domain_create_tty(struct doma 26.82 success = asprintf(&path, "%s/limit", dom->conspath) != -1; 26.83 if (!success) 26.84 goto out; 26.85 - data = xs_read(xs, path, &len); 26.86 + data = xs_read(xs, NULL, path, &len); 26.87 if (data) { 26.88 dom->buffer.max_capacity = strtoul(data, 0, 0); 26.89 free(data); 26.90 @@ -216,7 +204,7 @@ int xs_gather(struct xs_handle *xs, cons 26.91 char *p; 26.92 26.93 asprintf(&path, "%s/%s", dir, name); 26.94 - p = xs_read(xs, path, NULL); 26.95 + p = xs_read(xs, NULL, path, NULL); 26.96 free(path); 26.97 if (p == NULL) { 26.98 ret = ENOENT; 26.99 @@ -246,12 +234,13 @@ static int domain_create_ring(struct dom 26.100 goto out; 26.101 26.102 if (ring_ref != dom->ring_ref) { 26.103 - if (dom->page) 26.104 - munmap(dom->page, getpagesize()); 26.105 - dom->page = xc_map_foreign_range(xc, dom->domid, getpagesize(), 26.106 - PROT_READ|PROT_WRITE, 26.107 - (unsigned long)ring_ref); 26.108 - if (dom->page == NULL) { 26.109 + if (dom->interface != NULL) 26.110 + munmap(dom->interface, getpagesize()); 26.111 + dom->interface = xc_map_foreign_range( 26.112 + xc, dom->domid, getpagesize(), 26.113 + PROT_READ|PROT_WRITE, 26.114 + (unsigned long)ring_ref); 26.115 + if (dom->interface == NULL) { 26.116 err = EINVAL; 26.117 goto out; 26.118 } 26.119 @@ -334,7 +323,7 @@ static struct domain *create_domain(int 26.120 26.121 dom->ring_ref = -1; 26.122 dom->local_port = -1; 26.123 - dom->page = NULL; 26.124 + dom->interface = NULL; 26.125 dom->evtchn_fd = -1; 26.126 26.127 if (!watch_domain(dom, true)) 26.128 @@ -396,9 +385,9 @@ static void shutdown_domain(struct domai 26.129 { 26.130 d->is_dead = true; 26.131 watch_domain(d, false); 26.132 - if (d->page) 26.133 - munmap(d->page, getpagesize()); 26.134 - d->page = NULL; 26.135 + if (d->interface != NULL) 26.136 + munmap(d->interface, getpagesize()); 26.137 + d->interface = NULL; 26.138 if (d->evtchn_fd != -1) 26.139 close(d->evtchn_fd); 26.140 d->evtchn_fd = -1; 26.141 @@ -426,13 +415,21 @@ void enum_domains(void) 26.142 26.143 static void handle_tty_read(struct domain *dom) 26.144 { 26.145 - ssize_t len; 26.146 + ssize_t len = 0; 26.147 char msg[80]; 26.148 - struct ring_head *inring = 26.149 - (struct ring_head *)(dom->page + PAGE_SIZE/2); 26.150 int i; 26.151 + struct xencons_interface *intf = dom->interface; 26.152 + XENCONS_RING_IDX filled = intf->in_prod - intf->in_cons; 26.153 26.154 - len = read(dom->tty_fd, msg, MIN(XENCONS_SPACE(inring), sizeof(msg))); 26.155 + if (sizeof(intf->in) > filled) 26.156 + len = sizeof(intf->in) - filled; 26.157 + if (len > sizeof(msg)) 26.158 + len = sizeof(msg); 26.159 + 26.160 + if (len == 0) 26.161 + return; 26.162 + 26.163 + len = read(dom->tty_fd, msg, len); 26.164 if (len < 1) { 26.165 close(dom->tty_fd); 26.166 dom->tty_fd = -1; 26.167 @@ -444,8 +441,9 @@ static void handle_tty_read(struct domai 26.168 } 26.169 } else if (domain_is_valid(dom->domid)) { 26.170 for (i = 0; i < len; i++) { 26.171 - inring->buf[XENCONS_IDX(inring->prod)] = msg[i]; 26.172 - inring->prod++; 26.173 + intf->in[MASK_XENCONS_IDX(intf->in_prod, intf->in)] = 26.174 + msg[i]; 26.175 + intf->in_prod++; 26.176 } 26.177 evtchn_notify(dom); 26.178 } else { 26.179 @@ -505,7 +503,6 @@ static void handle_xs(int fd) 26.180 domain_create_ring(dom); 26.181 } 26.182 26.183 - xs_acknowledge_watch(xs, vec[1]); 26.184 free(vec); 26.185 } 26.186 26.187 @@ -565,3 +562,13 @@ void handle_io(void) 26.188 } 26.189 } while (ret > -1); 26.190 } 26.191 + 26.192 +/* 26.193 + * Local variables: 26.194 + * c-file-style: "linux" 26.195 + * indent-tabs-mode: t 26.196 + * c-indent-level: 8 26.197 + * c-basic-offset: 8 26.198 + * tab-width: 8 26.199 + * End: 26.200 + */
27.1 --- a/tools/examples/Makefile Tue Oct 11 15:50:21 2005 -0600 27.2 +++ b/tools/examples/Makefile Tue Oct 11 16:57:44 2005 -0600 27.3 @@ -24,6 +24,7 @@ XEN_SCRIPTS += network-route vif-route 27.4 XEN_SCRIPTS += network-nat vif-nat 27.5 XEN_SCRIPTS += block 27.6 XEN_SCRIPTS += block-enbd 27.7 +XEN_SCRIPTS += xen-hotplug-common.sh 27.8 27.9 XEN_HOTPLUG_DIR = /etc/hotplug 27.10 XEN_HOTPLUG_SCRIPTS = xen-backend.agent
28.1 --- a/tools/examples/block Tue Oct 11 15:50:21 2005 -0600 28.2 +++ b/tools/examples/block Tue Oct 11 16:57:44 2005 -0600 28.3 @@ -1,8 +1,7 @@ 28.4 #!/bin/sh 28.5 28.6 -set -e 28.7 - 28.8 -export PATH=/sbin:/bin:/usr/bin:/usr/sbin:$PATH 28.9 +dir=$(dirname "$0") 28.10 +. "$dir/xen-hotplug-common.sh" 28.11 28.12 expand_dev() { 28.13 local dev 28.14 @@ -25,15 +24,15 @@ write_dev() { 28.15 major=$(stat -L -c %t "$1") 28.16 minor=$(stat -L -c %T "$1") 28.17 pdev=$(printf "0x%02x%02x" 0x$major 0x$minor) 28.18 - xenstore-write "$XENBUS_PATH"/physical-device $pdev \ 28.19 + xenstore_write "$XENBUS_PATH"/physical-device $pdev \ 28.20 "$XENBUS_PATH"/node $1 28.21 } 28.22 28.23 -t=$(xenstore-read "$XENBUS_PATH"/type) 28.24 +t=$(xenstore_read "$XENBUS_PATH"/type || true) 28.25 28.26 case $1 in 28.27 bind) 28.28 - p=$(xenstore-read "$XENBUS_PATH"/params) 28.29 + p=$(xenstore_read "$XENBUS_PATH"/params) 28.30 case $t in 28.31 phy) 28.32 dev=$(expand_dev $p) 28.33 @@ -60,7 +59,7 @@ case $1 in 28.34 ;; 28.35 28.36 unbind) 28.37 - node=$(xenstore-read "$XENBUS_PATH"/node) 28.38 + node=$(xenstore_read "$XENBUS_PATH"/node) 28.39 case $t in 28.40 phy) 28.41 exit 0
29.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 29.2 +++ b/tools/examples/xen-hotplug-common.sh Tue Oct 11 16:57:44 2005 -0600 29.3 @@ -0,0 +1,26 @@ 29.4 +set -e 29.5 + 29.6 +export PATH=/sbin:/bin:/usr/bin:/usr/sbin:$PATH 29.7 + 29.8 +log() { 29.9 + local level="$1" 29.10 + shift 29.11 + logger -p "daemon.$level" -- "$0:" "$@" || echo "$0 $@" >&2 29.12 +} 29.13 + 29.14 +xenstore_read() { 29.15 + local v=$(xenstore-read "$@" || true) 29.16 + if [ "$v" == "" ] 29.17 + then 29.18 + log error "xenstore-read $@ failed." 29.19 + exit 1 29.20 + fi 29.21 + echo "$v" 29.22 +} 29.23 + 29.24 +xenstore_write() { 29.25 + log debug "Writing $@ to xenstore." 29.26 + xenstore-write "$@" || log error "Writing $@ to xenstore failed." 29.27 +} 29.28 + 29.29 +log debug "$@" "XENBUS_PATH=$XENBUS_PATH"
30.1 --- a/tools/libxc/xc_linux_save.c Tue Oct 11 15:50:21 2005 -0600 30.2 +++ b/tools/libxc/xc_linux_save.c Tue Oct 11 16:57:44 2005 -0600 30.3 @@ -35,7 +35,7 @@ 30.4 #define DEBUG 0 30.5 30.6 #if 1 30.7 -#define ERR(_f, _a...) do { fprintf(stderr, _f , ## _a); fflush(stderr); } while (0) 30.8 +#define ERR(_f, _a...) do { fprintf(stderr, _f "\n" , ## _a); fflush(stderr); } while (0) 30.9 #else 30.10 #define ERR(_f, _a...) ((void)0) 30.11 #endif
31.1 --- a/tools/misc/xend Tue Oct 11 15:50:21 2005 -0600 31.2 +++ b/tools/misc/xend Tue Oct 11 16:57:44 2005 -0600 31.3 @@ -2,9 +2,10 @@ 31.4 # -*- mode: python; -*- 31.5 #============================================================================ 31.6 # Copyright (C) 2004 Mike Wray <mike.wray@hp.com> 31.7 +# Copyright (C) 2005 XenSource Ltd 31.8 #============================================================================ 31.9 31.10 -"""Xen management daemon. Lives in /usr/sbin. 31.11 +"""Xen management daemon. 31.12 Provides console server and HTTP management api. 31.13 31.14 Run: 31.15 @@ -67,14 +68,14 @@ def check_user(): 31.16 31.17 def start_xenstored(): 31.18 XENSTORED_TRACE = os.getenv("XENSTORED_TRACE") 31.19 - cmd = "/usr/sbin/xenstored --pid-file=/var/run/xenstore.pid" 31.20 + cmd = "xenstored --pid-file=/var/run/xenstore.pid" 31.21 if XENSTORED_TRACE: 31.22 cmd += " -T /var/log/xenstored-trace.log" 31.23 s,o = commands.getstatusoutput(cmd) 31.24 31.25 def start_consoled(): 31.26 if os.fork() == 0: 31.27 - os.execvp('/usr/sbin/xenconsoled', ['/usr/sbin/xenconsoled']) 31.28 + os.execvp('xenconsoled', ['xenconsoled']) 31.29 31.30 def main(): 31.31 try:
32.1 --- a/tools/pygrub/src/fsys/reiser/reisermodule.c Tue Oct 11 15:50:21 2005 -0600 32.2 +++ b/tools/pygrub/src/fsys/reiser/reisermodule.c Tue Oct 11 16:57:44 2005 -0600 32.3 @@ -46,7 +46,7 @@ void file_dal_close(dal_t *dal) { 32.4 32.5 if (!dal) return; 32.6 32.7 - close((int)dal->dev); 32.8 + close((size_t)dal->dev); 32.9 dal_free(dal); 32.10 } 32.11
33.1 --- a/tools/python/xen/lowlevel/xs/xs.c Tue Oct 11 15:50:21 2005 -0600 33.2 +++ b/tools/python/xen/lowlevel/xs/xs.c Tue Oct 11 16:57:44 2005 -0600 33.3 @@ -80,8 +80,8 @@ static inline PyObject *pyvalue_str(char 33.4 33.5 static PyObject *xspy_read(PyObject *self, PyObject *args, PyObject *kwds) 33.6 { 33.7 - static char *kwd_spec[] = { "path", NULL }; 33.8 - static char *arg_spec = "s|"; 33.9 + static char *kwd_spec[] = { "transaction", "path", NULL }; 33.10 + static char *arg_spec = "ss"; 33.11 char *path = NULL; 33.12 33.13 struct xs_handle *xh = xshandle(self); 33.14 @@ -89,13 +89,19 @@ static PyObject *xspy_read(PyObject *sel 33.15 unsigned int xsval_n = 0; 33.16 PyObject *val = NULL; 33.17 33.18 + struct xs_transaction_handle *th; 33.19 + char *thstr; 33.20 + 33.21 if (!xh) 33.22 goto exit; 33.23 if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec, 33.24 - &path)) 33.25 + &thstr, &path)) 33.26 goto exit; 33.27 + 33.28 + th = (struct xs_transaction_handle *)strtoul(thstr, NULL, 16); 33.29 + 33.30 Py_BEGIN_ALLOW_THREADS 33.31 - xsval = xs_read(xh, path, &xsval_n); 33.32 + xsval = xs_read(xh, th, path, &xsval_n); 33.33 Py_END_ALLOW_THREADS 33.34 if (!xsval) { 33.35 if (errno == ENOENT) { 33.36 @@ -123,8 +129,8 @@ static PyObject *xspy_read(PyObject *sel 33.37 33.38 static PyObject *xspy_write(PyObject *self, PyObject *args, PyObject *kwds) 33.39 { 33.40 - static char *kwd_spec[] = { "path", "data", NULL }; 33.41 - static char *arg_spec = "ss#"; 33.42 + static char *kwd_spec[] = { "transaction", "path", "data", NULL }; 33.43 + static char *arg_spec = "sss#"; 33.44 char *path = NULL; 33.45 char *data = NULL; 33.46 int data_n = 0; 33.47 @@ -133,13 +139,19 @@ static PyObject *xspy_write(PyObject *se 33.48 PyObject *val = NULL; 33.49 int xsval = 0; 33.50 33.51 + struct xs_transaction_handle *th; 33.52 + char *thstr; 33.53 + 33.54 if (!xh) 33.55 goto exit; 33.56 if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec, 33.57 - &path, &data, &data_n)) 33.58 + &thstr, &path, &data, &data_n)) 33.59 goto exit; 33.60 + 33.61 + th = (struct xs_transaction_handle *)strtoul(thstr, NULL, 16); 33.62 + 33.63 Py_BEGIN_ALLOW_THREADS 33.64 - xsval = xs_write(xh, path, data, data_n); 33.65 + xsval = xs_write(xh, th, path, data, data_n); 33.66 Py_END_ALLOW_THREADS 33.67 if (!xsval) { 33.68 PyErr_SetFromErrno(PyExc_RuntimeError); 33.69 @@ -162,8 +174,8 @@ static PyObject *xspy_write(PyObject *se 33.70 33.71 static PyObject *xspy_ls(PyObject *self, PyObject *args, PyObject *kwds) 33.72 { 33.73 - static char *kwd_spec[] = { "path", NULL }; 33.74 - static char *arg_spec = "s|"; 33.75 + static char *kwd_spec[] = { "transaction", "path", NULL }; 33.76 + static char *arg_spec = "ss"; 33.77 char *path = NULL; 33.78 33.79 struct xs_handle *xh = xshandle(self); 33.80 @@ -172,12 +184,20 @@ static PyObject *xspy_ls(PyObject *self, 33.81 unsigned int xsval_n = 0; 33.82 int i; 33.83 33.84 + struct xs_transaction_handle *th; 33.85 + char *thstr; 33.86 + 33.87 if (!xh) 33.88 goto exit; 33.89 - if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec, &path)) 33.90 + if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec, 33.91 + &thstr, &path)) 33.92 goto exit; 33.93 + 33.94 + 33.95 + th = (struct xs_transaction_handle *)strtoul(thstr, NULL, 16); 33.96 + 33.97 Py_BEGIN_ALLOW_THREADS 33.98 - xsval = xs_directory(xh, path, &xsval_n); 33.99 + xsval = xs_directory(xh, th, path, &xsval_n); 33.100 Py_END_ALLOW_THREADS 33.101 if (!xsval) { 33.102 if (errno == ENOENT) { 33.103 @@ -205,20 +225,27 @@ static PyObject *xspy_ls(PyObject *self, 33.104 33.105 static PyObject *xspy_mkdir(PyObject *self, PyObject *args, PyObject *kwds) 33.106 { 33.107 - static char *kwd_spec[] = { "path", NULL }; 33.108 - static char *arg_spec = "s|"; 33.109 + static char *kwd_spec[] = { "transaction", "path", NULL }; 33.110 + static char *arg_spec = "ss"; 33.111 char *path = NULL; 33.112 33.113 struct xs_handle *xh = xshandle(self); 33.114 PyObject *val = NULL; 33.115 int xsval = 0; 33.116 33.117 + struct xs_transaction_handle *th; 33.118 + char *thstr; 33.119 + 33.120 if (!xh) 33.121 goto exit; 33.122 - if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec, &path)) 33.123 + if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec, 33.124 + &thstr, &path)) 33.125 goto exit; 33.126 + 33.127 + th = (struct xs_transaction_handle *)strtoul(thstr, NULL, 16); 33.128 + 33.129 Py_BEGIN_ALLOW_THREADS 33.130 - xsval = xs_mkdir(xh, path); 33.131 + xsval = xs_mkdir(xh, th, path); 33.132 Py_END_ALLOW_THREADS 33.133 if (!xsval) { 33.134 PyErr_SetFromErrno(PyExc_RuntimeError); 33.135 @@ -240,20 +267,27 @@ static PyObject *xspy_mkdir(PyObject *se 33.136 33.137 static PyObject *xspy_rm(PyObject *self, PyObject *args, PyObject *kwds) 33.138 { 33.139 - static char *kwd_spec[] = { "path", NULL }; 33.140 - static char *arg_spec = "s|"; 33.141 + static char *kwd_spec[] = { "transaction", "path", NULL }; 33.142 + static char *arg_spec = "ss"; 33.143 char *path = NULL; 33.144 33.145 struct xs_handle *xh = xshandle(self); 33.146 PyObject *val = NULL; 33.147 int xsval = 0; 33.148 33.149 + struct xs_transaction_handle *th; 33.150 + char *thstr; 33.151 + 33.152 if (!xh) 33.153 goto exit; 33.154 - if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec, &path)) 33.155 + if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec, 33.156 + &thstr, &path)) 33.157 goto exit; 33.158 + 33.159 + th = (struct xs_transaction_handle *)strtoul(thstr, NULL, 16); 33.160 + 33.161 Py_BEGIN_ALLOW_THREADS 33.162 - xsval = xs_rm(xh, path); 33.163 + xsval = xs_rm(xh, th, path); 33.164 Py_END_ALLOW_THREADS 33.165 if (!xsval && errno != ENOENT) { 33.166 PyErr_SetFromErrno(PyExc_RuntimeError); 33.167 @@ -276,8 +310,8 @@ static PyObject *xspy_rm(PyObject *self, 33.168 static PyObject *xspy_get_permissions(PyObject *self, PyObject *args, 33.169 PyObject *kwds) 33.170 { 33.171 - static char *kwd_spec[] = { "path", NULL }; 33.172 - static char *arg_spec = "s|"; 33.173 + static char *kwd_spec[] = { "transaction", "path", NULL }; 33.174 + static char *arg_spec = "ss"; 33.175 char *path = NULL; 33.176 33.177 struct xs_handle *xh = xshandle(self); 33.178 @@ -286,12 +320,19 @@ static PyObject *xspy_get_permissions(Py 33.179 unsigned int perms_n = 0; 33.180 int i; 33.181 33.182 + struct xs_transaction_handle *th; 33.183 + char *thstr; 33.184 + 33.185 if (!xh) 33.186 goto exit; 33.187 - if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec, &path)) 33.188 + if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec, 33.189 + &thstr, &path)) 33.190 goto exit; 33.191 + 33.192 + th = (struct xs_transaction_handle *)strtoul(thstr, NULL, 16); 33.193 + 33.194 Py_BEGIN_ALLOW_THREADS 33.195 - perms = xs_get_permissions(xh, path, &perms_n); 33.196 + perms = xs_get_permissions(xh, th, path, &perms_n); 33.197 Py_END_ALLOW_THREADS 33.198 if (!perms) { 33.199 PyErr_SetFromErrno(PyExc_RuntimeError); 33.200 @@ -321,8 +362,8 @@ static PyObject *xspy_get_permissions(Py 33.201 static PyObject *xspy_set_permissions(PyObject *self, PyObject *args, 33.202 PyObject *kwds) 33.203 { 33.204 - static char *kwd_spec[] = { "path", "perms", NULL }; 33.205 - static char *arg_spec = "sO"; 33.206 + static char *kwd_spec[] = { "transaction", "path", "perms", NULL }; 33.207 + static char *arg_spec = "ssO"; 33.208 char *path = NULL; 33.209 PyObject *perms = NULL; 33.210 static char *perm_names[] = { "dom", "read", "write", NULL }; 33.211 @@ -335,11 +376,17 @@ static PyObject *xspy_set_permissions(Py 33.212 PyObject *tuple0 = NULL; 33.213 PyObject *val = NULL; 33.214 33.215 + struct xs_transaction_handle *th; 33.216 + char *thstr; 33.217 + 33.218 if (!xh) 33.219 goto exit; 33.220 if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec, 33.221 - &path, &perms)) 33.222 + &thstr, &path, &perms)) 33.223 goto exit; 33.224 + 33.225 + th = (struct xs_transaction_handle *)strtoul(thstr, NULL, 16); 33.226 + 33.227 if (!PyList_Check(perms)) { 33.228 PyErr_SetString(PyExc_RuntimeError, "perms must be a list"); 33.229 goto exit; 33.230 @@ -369,7 +416,7 @@ static PyObject *xspy_set_permissions(Py 33.231 xsperms[i].perms |= XS_PERM_WRITE; 33.232 } 33.233 Py_BEGIN_ALLOW_THREADS 33.234 - xsval = xs_set_permissions(xh, path, xsperms, xsperms_n); 33.235 + xsval = xs_set_permissions(xh, th, path, xsperms, xsperms_n); 33.236 Py_END_ALLOW_THREADS 33.237 if (!xsval) { 33.238 PyErr_SetFromErrno(PyExc_RuntimeError); 33.239 @@ -442,9 +489,6 @@ static PyObject *xspy_watch(PyObject *se 33.240 33.241 #define xspy_read_watch_doc "\n" \ 33.242 "Read a watch notification.\n" \ 33.243 - "The notification must be acknowledged by passing\n" \ 33.244 - "the token to acknowledge_watch().\n" \ 33.245 - " path [string]: xenstore path.\n" \ 33.246 "\n" \ 33.247 "Returns: [tuple] (path, token).\n" \ 33.248 "Raises RuntimeError on error.\n" \ 33.249 @@ -495,44 +539,6 @@ static PyObject *xspy_read_watch(PyObjec 33.250 return val; 33.251 } 33.252 33.253 -#define xspy_acknowledge_watch_doc "\n" \ 33.254 - "Acknowledge a watch notification that has been read.\n" \ 33.255 - " token [string] : from the watch notification\n" \ 33.256 - "\n" \ 33.257 - "Returns None on success.\n" \ 33.258 - "Raises RuntimeError on error.\n" \ 33.259 - "\n" 33.260 - 33.261 -static PyObject *xspy_acknowledge_watch(PyObject *self, PyObject *args, 33.262 - PyObject *kwds) 33.263 -{ 33.264 - static char *kwd_spec[] = { "token", NULL }; 33.265 - static char *arg_spec = "O"; 33.266 - PyObject *token; 33.267 - char token_str[MAX_STRLEN(unsigned long) + 1]; 33.268 - 33.269 - struct xs_handle *xh = xshandle(self); 33.270 - PyObject *val = NULL; 33.271 - int xsval = 0; 33.272 - 33.273 - if (!xh) 33.274 - goto exit; 33.275 - if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec, &token)) 33.276 - goto exit; 33.277 - sprintf(token_str, "%li", (unsigned long)token); 33.278 - Py_BEGIN_ALLOW_THREADS 33.279 - xsval = xs_acknowledge_watch(xh, token_str); 33.280 - Py_END_ALLOW_THREADS 33.281 - if (!xsval) { 33.282 - PyErr_SetFromErrno(PyExc_RuntimeError); 33.283 - goto exit; 33.284 - } 33.285 - Py_INCREF(Py_None); 33.286 - val = Py_None; 33.287 - exit: 33.288 - return val; 33.289 -} 33.290 - 33.291 #define xspy_unwatch_doc "\n" \ 33.292 "Stop watching a path.\n" \ 33.293 " path [string] : xenstore path.\n" \ 33.294 @@ -584,9 +590,8 @@ static PyObject *xspy_unwatch(PyObject * 33.295 33.296 #define xspy_transaction_start_doc "\n" \ 33.297 "Start a transaction.\n" \ 33.298 - "Only one transaction can be active at a time.\n" \ 33.299 "\n" \ 33.300 - "Returns None on success.\n" \ 33.301 + "Returns transaction handle on success.\n" \ 33.302 "Raises RuntimeError on error.\n" \ 33.303 "\n" 33.304 33.305 @@ -599,21 +604,23 @@ static PyObject *xspy_transaction_start( 33.306 33.307 struct xs_handle *xh = xshandle(self); 33.308 PyObject *val = NULL; 33.309 - int xsval = 0; 33.310 + struct xs_transaction_handle *th; 33.311 + char thstr[20]; 33.312 33.313 if (!xh) 33.314 goto exit; 33.315 if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec, &path)) 33.316 goto exit; 33.317 Py_BEGIN_ALLOW_THREADS 33.318 - xsval = xs_transaction_start(xh); 33.319 + th = xs_transaction_start(xh); 33.320 Py_END_ALLOW_THREADS 33.321 - if (!xsval) { 33.322 + if (th == NULL) { 33.323 PyErr_SetFromErrno(PyExc_RuntimeError); 33.324 goto exit; 33.325 } 33.326 - Py_INCREF(Py_None); 33.327 - val = Py_None; 33.328 + 33.329 + sprintf(thstr, "%lX", (unsigned long)th); 33.330 + val = PyString_FromString(thstr); 33.331 exit: 33.332 return val; 33.333 } 33.334 @@ -630,20 +637,27 @@ static PyObject *xspy_transaction_start( 33.335 static PyObject *xspy_transaction_end(PyObject *self, PyObject *args, 33.336 PyObject *kwds) 33.337 { 33.338 - static char *kwd_spec[] = { "abort", NULL }; 33.339 - static char *arg_spec = "|i"; 33.340 + static char *kwd_spec[] = { "transaction", "abort", NULL }; 33.341 + static char *arg_spec = "s|i"; 33.342 int abort = 0; 33.343 33.344 struct xs_handle *xh = xshandle(self); 33.345 PyObject *val = NULL; 33.346 int xsval = 0; 33.347 33.348 + struct xs_transaction_handle *th; 33.349 + char *thstr; 33.350 + 33.351 if (!xh) 33.352 goto exit; 33.353 - if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec, &abort)) 33.354 + if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec, 33.355 + &thstr, &abort)) 33.356 goto exit; 33.357 + 33.358 + th = (struct xs_transaction_handle *)strtoul(thstr, NULL, 16); 33.359 + 33.360 Py_BEGIN_ALLOW_THREADS 33.361 - xsval = xs_transaction_end(xh, abort); 33.362 + xsval = xs_transaction_end(xh, th, abort); 33.363 Py_END_ALLOW_THREADS 33.364 if (!xsval) { 33.365 if (errno == EAGAIN) { 33.366 @@ -833,7 +847,6 @@ static PyMethodDef xshandle_methods[] = 33.367 XSPY_METH(set_permissions), 33.368 XSPY_METH(watch), 33.369 XSPY_METH(read_watch), 33.370 - XSPY_METH(acknowledge_watch), 33.371 XSPY_METH(unwatch), 33.372 XSPY_METH(transaction_start), 33.373 XSPY_METH(transaction_end),
34.1 --- a/tools/python/xen/util/Brctl.py Tue Oct 11 15:50:21 2005 -0600 34.2 +++ b/tools/python/xen/util/Brctl.py Tue Oct 11 16:57:44 2005 -0600 34.3 @@ -5,7 +5,6 @@ import os.path 34.4 import re 34.5 import sys 34.6 34.7 -os.defpath = os.defpath + ':/sbin:/usr/sbin:/usr/local/sbin' 34.8 CMD_IFCONFIG = 'ifconfig' 34.9 CMD_ROUTE = 'route' 34.10 CMD_BRCTL = 'brctl'
35.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 35.2 +++ b/tools/python/xen/util/asserts.py Tue Oct 11 16:57:44 2005 -0600 35.3 @@ -0,0 +1,27 @@ 35.4 +#=========================================================================== 35.5 +# This library is free software; you can redistribute it and/or 35.6 +# modify it under the terms of version 2.1 of the GNU Lesser General Public 35.7 +# License as published by the Free Software Foundation. 35.8 +# 35.9 +# This library is distributed in the hope that it will be useful, 35.10 +# but WITHOUT ANY WARRANTY; without even the implied warranty of 35.11 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 35.12 +# Lesser General Public License for more details. 35.13 +# 35.14 +# You should have received a copy of the GNU Lesser General Public 35.15 +# License along with this library; if not, write to the Free Software 35.16 +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 35.17 +#============================================================================ 35.18 +# Copyright (C) 2005 XenSource Ltd 35.19 +#============================================================================ 35.20 + 35.21 + 35.22 +def isCharConvertible(c): 35.23 + """Assert that the given value is convertible to a character using the %c 35.24 + conversion. This implies that c is either an integer, or a character 35.25 + (i.e. a string of length 1). 35.26 + """ 35.27 + 35.28 + assert (isinstance(c, int) or 35.29 + (isinstance(c, str) and 35.30 + len(c) == 1)), "%s is not convertible to a character" % c
36.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 36.2 +++ b/tools/python/xen/util/auxbin.py Tue Oct 11 16:57:44 2005 -0600 36.3 @@ -0,0 +1,44 @@ 36.4 +#============================================================================ 36.5 +# This library is free software; you can redistribute it and/or 36.6 +# modify it under the terms of version 2.1 of the GNU Lesser General Public 36.7 +# License as published by the Free Software Foundation. 36.8 +# 36.9 +# This library is distributed in the hope that it will be useful, 36.10 +# but WITHOUT ANY WARRANTY; without even the implied warranty of 36.11 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 36.12 +# Lesser General Public License for more details. 36.13 +# 36.14 +# You should have received a copy of the GNU Lesser General Public 36.15 +# License along with this library; if not, write to the Free Software 36.16 +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 36.17 +#============================================================================ 36.18 +# Copyright (C) 2005 XenSource Ltd 36.19 +#============================================================================ 36.20 + 36.21 + 36.22 +LIB_BIN_32 = "/usr/lib/xen/bin" 36.23 +LIB_BIN_64 = "/usr/lib64/xen/bin" 36.24 + 36.25 + 36.26 +import os 36.27 +import os.path 36.28 + 36.29 + 36.30 +def execute(exe, args = None): 36.31 + exepath = pathTo(exe) 36.32 + a = [ exepath ] 36.33 + if args: 36.34 + a.extend(args) 36.35 + os.execv(exepath, a) 36.36 + 36.37 + 36.38 +def pathTo(exe): 36.39 + return os.path.join(path(), exe) 36.40 + 36.41 + 36.42 +def path(): 36.43 + machine = os.uname()[4] 36.44 + if machine.find('64') != -1 and os.path.exists(LIB_BIN_64): 36.45 + return LIB_BIN_64 36.46 + else: 36.47 + return LIB_BIN_32
37.1 --- a/tools/python/xen/xend/XendCheckpoint.py Tue Oct 11 15:50:21 2005 -0600 37.2 +++ b/tools/python/xen/xend/XendCheckpoint.py Tue Oct 11 16:57:44 2005 -0600 37.3 @@ -14,6 +14,8 @@ from struct import pack, unpack, calcsiz 37.4 37.5 from xen.util.xpopen import xPopen3 37.6 37.7 +import xen.util.auxbin 37.8 + 37.9 import xen.lowlevel.xc 37.10 37.11 from xen.xend.xenstore.xsutil import IntroduceDomain 37.12 @@ -21,9 +23,11 @@ from xen.xend.xenstore.xsutil import Int 37.13 from XendError import XendError 37.14 from XendLogging import log 37.15 37.16 + 37.17 SIGNATURE = "LinuxGuestRecord" 37.18 -PATH_XC_SAVE = "/usr/libexec/xen/xc_save" 37.19 -PATH_XC_RESTORE = "/usr/libexec/xen/xc_restore" 37.20 +XC_SAVE = "xc_save" 37.21 +XC_RESTORE = "xc_restore" 37.22 + 37.23 37.24 sizeof_int = calcsize("i") 37.25 sizeof_unsigned_long = calcsize("L") 37.26 @@ -64,7 +68,7 @@ def save(fd, dominfo, live): 37.27 # enabled. Passing "0" simply uses the defaults compiled into 37.28 # libxenguest; see the comments and/or code in xc_linux_save() for 37.29 # more information. 37.30 - cmd = [PATH_XC_SAVE, str(xc.handle()), str(fd), 37.31 + cmd = [xen.util.auxbin.pathTo(XC_SAVE), str(xc.handle()), str(fd), 37.32 str(dominfo.getDomid()), "0", "0", str(int(live)) ] 37.33 log.debug("[xc_save]: %s", string.join(cmd)) 37.34 37.35 @@ -129,7 +133,7 @@ def restore(xd, fd): 37.36 store_evtchn = dominfo.store_channel 37.37 console_evtchn = dominfo.console_channel 37.38 37.39 - cmd = [PATH_XC_RESTORE, str(xc.handle()), str(fd), 37.40 + cmd = [xen.util.auxbin.pathTo(XC_RESTORE), str(xc.handle()), str(fd), 37.41 str(dominfo.getDomid()), str(nr_pfns), 37.42 str(store_evtchn), str(console_evtchn)] 37.43 log.debug("[xc_restore]: %s", string.join(cmd))
38.1 --- a/tools/python/xen/xend/XendClient.py Tue Oct 11 15:50:21 2005 -0600 38.2 +++ b/tools/python/xen/xend/XendClient.py Tue Oct 11 16:57:44 2005 -0600 38.3 @@ -196,6 +196,9 @@ class Xend: 38.4 def xend_domains(self): 38.5 return self.xendGet(self.domainurl()) 38.6 38.7 + def xend_list_domains(self): 38.8 + return self.xendGet(self.domainurl(), {'detail': '1'}) 38.9 + 38.10 def xend_domain_create(self, conf): 38.11 return self.xendPost(self.domainurl(), 38.12 {'op' : 'create',
39.1 --- a/tools/python/xen/xend/XendDomain.py Tue Oct 11 15:50:21 2005 -0600 39.2 +++ b/tools/python/xen/xend/XendDomain.py Tue Oct 11 16:57:44 2005 -0600 39.3 @@ -359,20 +359,6 @@ class XendDomain: 39.4 raise XendError(str(ex)) 39.5 39.6 39.7 - def domain_shutdown(self, domid, reason = 'poweroff'): 39.8 - """Shutdown domain (nicely). 39.9 - 39.10 - @param reason: shutdown reason: poweroff, reboot, suspend, halt 39.11 - """ 39.12 - self.callInfo(domid, XendDomainInfo.XendDomainInfo.shutdown, reason) 39.13 - 39.14 - 39.15 - def domain_sysrq(self, domid, key): 39.16 - """Send a SysRq to the specified domain.""" 39.17 - return self.callInfo(domid, XendDomainInfo.XendDomainInfo.send_sysrq, 39.18 - key) 39.19 - 39.20 - 39.21 def domain_destroy(self, domid): 39.22 """Terminate domain immediately.""" 39.23 39.24 @@ -475,37 +461,6 @@ class XendDomain: 39.25 raise XendError(str(ex)) 39.26 39.27 39.28 - def domain_device_create(self, domid, devconfig): 39.29 - """Create a new device for the specified domain. 39.30 - """ 39.31 - return self.callInfo(domid, 39.32 - XendDomainInfo.XendDomainInfo.device_create, 39.33 - devconfig) 39.34 - 39.35 - 39.36 - def domain_device_configure(self, domid, devconfig, devid): 39.37 - """Configure an existing device in the specified domain. 39.38 - @return: updated device configuration 39.39 - """ 39.40 - return self.callInfo(domid, 39.41 - XendDomainInfo.XendDomainInfo.device_configure, 39.42 - devconfig, devid) 39.43 - 39.44 - 39.45 - def domain_device_destroy(self, domid, devtype, devid): 39.46 - """Destroy a device.""" 39.47 - return self.callInfo(domid, 39.48 - XendDomainInfo.XendDomainInfo.destroyDevice, 39.49 - devtype, devid) 39.50 - 39.51 - 39.52 - def domain_devtype_ls(self, domid, devtype): 39.53 - """Get list of device sxprs for the specified domain.""" 39.54 - return self.callInfo(domid, 39.55 - XendDomainInfo.XendDomainInfo.getDeviceSxprs, 39.56 - devtype) 39.57 - 39.58 - 39.59 def domain_vif_limit_set(self, domid, vif, credit, period): 39.60 """Limit the vif's transmission rate 39.61 """ 39.62 @@ -537,44 +492,6 @@ class XendDomain: 39.63 except Exception, ex: 39.64 raise XendError(str(ex)) 39.65 39.66 - def domain_mem_target_set(self, domid, mem): 39.67 - """Set the memory target for a domain. 39.68 - 39.69 - @param mem: memory target (in MiB) 39.70 - """ 39.71 - self.callInfo(domid, XendDomainInfo.XendDomainInfo.setMemoryTarget, 39.72 - mem << 10) 39.73 - 39.74 - 39.75 - def domain_vcpu_hotplug(self, domid, vcpu, state): 39.76 - """Enable or disable specified VCPU in specified domain 39.77 - 39.78 - @param vcpu: target VCPU in domain 39.79 - @param state: which state VCPU will become 39.80 - """ 39.81 - self.callInfo(domid, XendDomainInfo.XendDomainInfo.vcpu_hotplug, vcpu, 39.82 - state) 39.83 - 39.84 - 39.85 - def domain_dumpcore(self, domid): 39.86 - """Save a core dump for a crashed domain.""" 39.87 - self.callInfo(domid, XendDomainInfo.XendDomainInfo.dumpCore) 39.88 - 39.89 - 39.90 - ## private: 39.91 - 39.92 - def callInfo(self, domid, fn, *args, **kwargs): 39.93 - try: 39.94 - self.refresh() 39.95 - dominfo = self.domains.get(domid) 39.96 - if dominfo: 39.97 - return fn(dominfo, *args, **kwargs) 39.98 - except XendError: 39.99 - raise 39.100 - except Exception, exn: 39.101 - log.exception("") 39.102 - raise XendError(str(exn)) 39.103 - 39.104 39.105 def instance(): 39.106 """Singleton constructor. Use this instead of the class constructor.
40.1 --- a/tools/python/xen/xend/XendDomainInfo.py Tue Oct 11 15:50:21 2005 -0600 40.2 +++ b/tools/python/xen/xend/XendDomainInfo.py Tue Oct 11 16:57:44 2005 -0600 40.3 @@ -30,6 +30,7 @@ import threading 40.4 import errno 40.5 40.6 import xen.lowlevel.xc 40.7 +from xen.util import asserts 40.8 from xen.util.blkif import blkdev_uname_to_file 40.9 40.10 from xen.xend import image 40.11 @@ -41,7 +42,8 @@ from xen.xend.XendLogging import log 40.12 from xen.xend.XendError import XendError, VmError 40.13 from xen.xend.XendRoot import get_component 40.14 40.15 -from xen.xend.uuid import getUuid 40.16 +from uuid import getUuid 40.17 + 40.18 from xen.xend.xenstore.xstransact import xstransact 40.19 from xen.xend.xenstore.xsutil import GetDomainPath, IntroduceDomain 40.20 40.21 @@ -217,17 +219,12 @@ def recreate(xeninfo): 40.22 def restore(config): 40.23 """Create a domain and a VM object to do a restore. 40.24 40.25 - @param config: domain configuration 40.26 + @param config: domain configuration 40.27 """ 40.28 40.29 log.debug("XendDomainInfo.restore(%s)", config) 40.30 40.31 - try: 40.32 - uuid = sxp.child_value(config, 'uuid') 40.33 - ssidref = int(sxp.child_value(config, 'ssidref')) 40.34 - except TypeError, exn: 40.35 - raise VmError('Invalid ssidref in config: %s' % exn) 40.36 - 40.37 + uuid = sxp.child_value(config, 'uuid') 40.38 vm = XendDomainInfo(uuid, parseConfig(config)) 40.39 try: 40.40 vm.construct() 40.41 @@ -257,7 +254,7 @@ def parseConfig(config): 40.42 return val 40.43 40.44 40.45 - log.debug("parseConfig: config is %s" % str(config)) 40.46 + log.debug("parseConfig: config is %s", config) 40.47 40.48 result = {} 40.49 40.50 @@ -315,7 +312,7 @@ def parseConfig(config): 40.51 log.warn("Ignoring malformed and deprecated config option " 40.52 "restart = %s", restart) 40.53 40.54 - log.debug("parseConfig: result is %s" % str(result)) 40.55 + log.debug("parseConfig: result is %s", result) 40.56 return result 40.57 40.58 40.59 @@ -529,7 +526,7 @@ class XendDomainInfo: 40.60 40.61 except KeyError, exn: 40.62 log.exception(exn) 40.63 - raise VmError('Unspecified domain detail: %s' % str(exn)) 40.64 + raise VmError('Unspecified domain detail: %s' % exn) 40.65 40.66 40.67 def readVm(self, *args): 40.68 @@ -579,7 +576,7 @@ class XendDomainInfo: 40.69 if self.infoIsSet(k): 40.70 to_store[k] = str(self.info[k]) 40.71 40.72 - log.debug("Storing VM details: %s" % str(to_store)) 40.73 + log.debug("Storing VM details: %s", to_store) 40.74 40.75 self.writeVm(to_store) 40.76 40.77 @@ -605,7 +602,7 @@ class XendDomainInfo: 40.78 for v in range(0, self.info['vcpus']): 40.79 to_store["cpu/%d/availability" % v] = availability(v) 40.80 40.81 - log.debug("Storing domain details: %s" % str(to_store)) 40.82 + log.debug("Storing domain details: %s", to_store) 40.83 40.84 self.writeDom(to_store) 40.85 40.86 @@ -746,7 +743,7 @@ class XendDomainInfo: 40.87 40.88 def shutdown(self, reason): 40.89 if not reason in shutdown_reasons.values(): 40.90 - raise XendError('invalid reason:' + reason) 40.91 + raise XendError('Invalid reason: %s' % reason) 40.92 self.storeDom("control/shutdown", reason) 40.93 if reason != 'suspend': 40.94 self.storeDom('xend/shutdown_start_time', time.time()) 40.95 @@ -793,10 +790,12 @@ class XendDomainInfo: 40.96 40.97 def setMemoryTarget(self, target): 40.98 """Set the memory target of this domain. 40.99 - @param target In KiB. 40.100 + @param target In MiB. 40.101 """ 40.102 - self.info['memory_KiB'] = target 40.103 - self.storeDom("memory/target", target) 40.104 + # Internally we use KiB, but the command interface uses MiB. 40.105 + t = target << 10 40.106 + self.info['memory_KiB'] = t 40.107 + self.storeDom("memory/target", t) 40.108 40.109 40.110 def update(self, info = None): 40.111 @@ -986,8 +985,8 @@ class XendDomainInfo: 40.112 """ 40.113 40.114 log.debug('XendDomainInfo.construct: %s %s', 40.115 - str(self.domid), 40.116 - str(self.info['ssidref'])) 40.117 + self.domid, 40.118 + self.info['ssidref']) 40.119 40.120 self.domid = xc.domain_create(dom = 0, ssidref = self.info['ssidref']) 40.121 40.122 @@ -1004,9 +1003,9 @@ class XendDomainInfo: 40.123 40.124 def initDomain(self): 40.125 log.debug('XendDomainInfo.initDomain: %s %s %s', 40.126 - str(self.domid), 40.127 - str(self.info['memory_KiB']), 40.128 - str(self.info['cpu_weight'])) 40.129 + self.domid, 40.130 + self.info['memory_KiB'], 40.131 + self.info['cpu_weight']) 40.132 40.133 if not self.infoIsSet('image'): 40.134 raise VmError('Missing image in configuration') 40.135 @@ -1085,14 +1084,15 @@ class XendDomainInfo: 40.136 def destroy(self): 40.137 """Cleanup VM and destroy domain. Nothrow guarantee.""" 40.138 40.139 - log.debug("XendDomainInfo.destroy: domid=%s", str(self.domid)) 40.140 + log.debug("XendDomainInfo.destroy: domid=%s", self.domid) 40.141 40.142 self.cleanupVm() 40.143 - self.destroyDomain() 40.144 + if self.dompath is not None: 40.145 + self.destroyDomain() 40.146 40.147 40.148 def destroyDomain(self): 40.149 - log.debug("XendDomainInfo.destroyDomain(%s)", str(self.domid)) 40.150 + log.debug("XendDomainInfo.destroyDomain(%s)", self.domid) 40.151 40.152 try: 40.153 if self.domid is not None: 40.154 @@ -1366,7 +1366,10 @@ class XendDomainInfo: 40.155 self.storeVm('vcpu_avail', self.info['vcpu_avail']) 40.156 self.storeDom("cpu/%d/availability" % vcpu, availability) 40.157 40.158 - def send_sysrq(self, key=0): 40.159 + 40.160 + def send_sysrq(self, key): 40.161 + asserts.isCharConvertible(key) 40.162 + 40.163 self.storeDom("control/sysrq", '%c' % key) 40.164 40.165 40.166 @@ -1388,18 +1391,18 @@ class XendDomainInfo: 40.167 dom = 0 40.168 # get max number of vcpus to use for dom0 from config 40.169 target = int(xroot.get_dom0_vcpus()) 40.170 - log.debug("number of vcpus to use is %d" % (target)) 40.171 + log.debug("number of vcpus to use is %d", target) 40.172 40.173 # target = 0 means use all processors 40.174 if target > 0: 40.175 # count the number of online vcpus (cpu values in v2c map >= 0) 40.176 vcpu_to_cpu = dom_get(dom)['vcpu_to_cpu'] 40.177 vcpus_online = len(filter(lambda x: x >= 0, vcpu_to_cpu)) 40.178 - log.debug("found %d vcpus online" % (vcpus_online)) 40.179 + log.debug("found %d vcpus online", vcpus_online) 40.180 40.181 # disable any extra vcpus that are online over the requested target 40.182 for vcpu in range(target, vcpus_online): 40.183 - log.info("enforcement is disabling DOM%d VCPU%d" % (dom, vcpu)) 40.184 + log.info("enforcement is disabling DOM%d VCPU%d", dom, vcpu) 40.185 self.vcpu_hotplug(vcpu, 0) 40.186 40.187
41.1 --- a/tools/python/xen/xend/XendLogging.py Tue Oct 11 15:50:21 2005 -0600 41.2 +++ b/tools/python/xen/xend/XendLogging.py Tue Oct 11 16:57:44 2005 -0600 41.3 @@ -13,79 +13,84 @@ 41.4 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 41.5 #============================================================================ 41.6 # Copyright (C) 2004, 2005 Mike Wray <mike.wray@hp.com> 41.7 +# Copyright (C) 2005 XenSource Ltd 41.8 #============================================================================ 41.9 41.10 + 41.11 +import tempfile 41.12 import types 41.13 import logging 41.14 -from logging import Formatter, StreamHandler 41.15 -from logging.handlers import RotatingFileHandler 41.16 - 41.17 -class XendLogging: 41.18 - 41.19 - KB = 1024 41.20 - MB = 1024 * KB 41.21 - 41.22 - maxBytes = 1 * MB 41.23 - backupCount = 5 41.24 - 41.25 - logStderrFormat = "[%(name)s] %(levelname)s (%(module)s:%(lineno)d) %(message)s" 41.26 - logFileFormat = "[%(asctime)s %(name)s] %(levelname)s (%(module)s:%(lineno)d) %(message)s" 41.27 - dateFormat = "%Y-%m-%d %H:%M:%S" 41.28 +import logging.handlers 41.29 41.30 - def __init__(self, filename, level=logging.INFO, maxBytes=None, backupCount=None): 41.31 - """Initialise logging. Logs to 'filename' by default, but does not log to 41.32 - stderr unless addLogStderr() is called. 41.33 - """ 41.34 - self.setLevel(level) 41.35 - if maxBytes: 41.36 - self.maxBytes = maxBytes 41.37 - if backupCount: 41.38 - self.backupCount = backupCount 41.39 - self.initLogFile(filename) 41.40 - self.initLogStderr() 41.41 - 41.42 - def setLevel(self, level): 41.43 - if isinstance(level, types.StringType): 41.44 - level = logging._levelNames[level] 41.45 - self.getLogger().setLevel(level) 41.46 - self.level = level 41.47 41.48 - def getLogger(self): 41.49 - return logging.getLogger("xend") 41.50 - 41.51 - def initLogFile(self, filename): 41.52 - """Create the file logger and add it. 41.53 - """ 41.54 - self.logfile = RotatingFileHandler(filename, 41.55 - mode='a', 41.56 - maxBytes=self.maxBytes, 41.57 - backupCount=self.backupCount) 41.58 - self.logfilename = filename 41.59 - self.logfile.setFormatter(Formatter(self.logFileFormat, self.dateFormat)) 41.60 - self.getLogger().addHandler(self.logfile) 41.61 - 41.62 - def getLogFile(self): 41.63 - return self.logfile 41.64 +__all__ = [ 'log', 'init', 'getLogFilename', 'addLogStderr', 41.65 + 'removeLogStderr' ] 41.66 41.67 - def getLogFilename(self): 41.68 - return self.logfilename 41.69 - 41.70 - def initLogStderr(self): 41.71 - """Create the stderr logger, but don't add it. 41.72 - """ 41.73 - self.logstderr = StreamHandler() 41.74 - self.logstderr.setFormatter(Formatter(self.logStderrFormat, self.dateFormat)) 41.75 - 41.76 - def addLogStderr(self): 41.77 - """Add logging to stderr.""" 41.78 - self.getLogger().addHandler(self.logstderr) 41.79 - 41.80 - def removeLogStderr(self): 41.81 - """Remove logging to stderr.""" 41.82 - self.getLogger().removeHandler(self.logstderr) 41.83 - 41.84 - def getLogStderr(self): 41.85 - return self.logstderr 41.86 41.87 log = logging.getLogger("xend") 41.88 - 41.89 + 41.90 + 41.91 +DEFAULT_MAX_BYTES = 1 << 20 # 1MB 41.92 +DEFAULT_BACKUP_COUNT = 5 41.93 + 41.94 +STDERR_FORMAT = "[%(name)s] %(levelname)s (%(module)s:%(lineno)d) %(message)s" 41.95 +LOGFILE_FORMAT = "[%(asctime)s %(name)s] %(levelname)s (%(module)s:%(lineno)d) %(message)s" 41.96 +DATE_FORMAT = "%Y-%m-%d %H:%M:%S" 41.97 + 41.98 + 41.99 +stderrHandler = logging.StreamHandler() 41.100 +stderrHandler.setFormatter(logging.Formatter(STDERR_FORMAT, DATE_FORMAT)) 41.101 + 41.102 +logfilename = None 41.103 + 41.104 + 41.105 +def init(filename, level=logging.INFO, maxBytes=None, backupCount=None): 41.106 + """Initialise logging. Logs to 'filename' by default, but does not log to 41.107 + stderr unless addLogStderr() is called. 41.108 + """ 41.109 + 41.110 + global logfilename 41.111 + 41.112 + def openFileHandler(fname): 41.113 + return logging.handlers.RotatingFileHandler(fname, 41.114 + mode='a', 41.115 + maxBytes=maxBytes, 41.116 + backupCount=backupCount) 41.117 + 41.118 + if not maxBytes: 41.119 + maxBytes = DEFAULT_MAX_BYTES 41.120 + if not backupCount: 41.121 + backupCount = DEFAULT_BACKUP_COUNT 41.122 + 41.123 + # Rather unintuitively, getLevelName will get the number corresponding to 41.124 + # a level name, as well as getting the name corresponding to a level 41.125 + # number. setLevel seems to take the number only though, so convert if we 41.126 + # are given a string. 41.127 + if isinstance(level, types.StringType): 41.128 + level = logging.getLevelName(level) 41.129 + 41.130 + log.setLevel(level) 41.131 + 41.132 + try: 41.133 + fileHandler = openFileHandler(filename) 41.134 + logfilename = filename 41.135 + except IOError: 41.136 + logfilename = tempfile.mkstemp("-xend.log")[1] 41.137 + fileHandler = openFileHandler(logfilename) 41.138 + 41.139 + fileHandler.setFormatter(logging.Formatter(LOGFILE_FORMAT, DATE_FORMAT)) 41.140 + log.addHandler(fileHandler) 41.141 + 41.142 + 41.143 +def getLogFilename(): 41.144 + return logfilename 41.145 + 41.146 + 41.147 +def addLogStderr(): 41.148 + """Add logging to stderr.""" 41.149 + log.addHandler(stderrHandler) 41.150 + 41.151 + 41.152 +def removeLogStderr(): 41.153 + """Remove logging to stderr.""" 41.154 + log.removeHandler(stderrHandler)
42.1 --- a/tools/python/xen/xend/XendRoot.py Tue Oct 11 15:50:21 2005 -0600 42.2 +++ b/tools/python/xen/xend/XendRoot.py Tue Oct 11 16:57:44 2005 -0600 42.3 @@ -13,6 +13,7 @@ 42.4 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 42.5 #============================================================================ 42.6 # Copyright (C) 2004, 2005 Mike Wray <mike.wray@hp.com> 42.7 +# Copyright (C) 2005 XenSource Ltd 42.8 #============================================================================ 42.9 42.10 """Xend root class. 42.11 @@ -29,7 +30,7 @@ import os.path 42.12 import string 42.13 import sys 42.14 42.15 -from XendLogging import XendLogging 42.16 +import XendLogging 42.17 from XendError import XendError 42.18 42.19 import sxp 42.20 @@ -92,7 +93,6 @@ class XendRoot: 42.21 def __init__(self): 42.22 self.config_path = None 42.23 self.config = None 42.24 - self.logging = None 42.25 self.configure() 42.26 42.27 42.28 @@ -114,84 +114,22 @@ class XendRoot: 42.29 """ 42.30 return self.components.get(name) 42.31 42.32 - def _format(self, msg, args): 42.33 - if args: 42.34 - return str(msg) % args 42.35 - else: 42.36 - return str(msg) 42.37 - 42.38 - def _log(self, mode, fmt, args): 42.39 - """Logging function that uses the logger if it exists, otherwise 42.40 - logs to stderr. We use this for XendRoot log messages because 42.41 - they may be logged before the logger has been configured. 42.42 - Other components can safely use the logger. 42.43 - """ 42.44 - log = self.get_logger() 42.45 - if mode not in ['warning', 'info', 'debug', 'error']: 42.46 - mode = 'info' 42.47 - level = mode.upper() 42.48 - if log: 42.49 - getattr(log, mode)(fmt, *args) 42.50 - else: 42.51 - print >>sys.stderr, "xend", "[%s]" % level, self._format(fmt, args) 42.52 - 42.53 - def logDebug(self, fmt, *args): 42.54 - """Log a debug message. 42.55 - 42.56 - @param fmt: message format 42.57 - @param args: arguments 42.58 + def _logError(self, fmt, args): 42.59 + """Logging function to log to stderr. We use this for XendRoot log 42.60 + messages because they may be logged before the logger has been 42.61 + configured. Other components can safely use the logger. 42.62 """ 42.63 - self._log('debug', fmt, args) 42.64 - 42.65 - def logInfo(self, fmt, *args): 42.66 - """Log an info message. 42.67 - 42.68 - @param fmt: message format 42.69 - @param args: arguments 42.70 - """ 42.71 - self._log('info', fmt, args) 42.72 - 42.73 - def logWarning(self, fmt, *args): 42.74 - """Log a warning message. 42.75 - 42.76 - @param fmt: message format 42.77 - @param args: arguments 42.78 - """ 42.79 - self._log('warning', fmt, args) 42.80 - 42.81 - def logError(self, fmt, *args): 42.82 - """Log an error message. 42.83 - 42.84 - @param fmt: message format 42.85 - @param args: arguments 42.86 - """ 42.87 - self._log('error', fmt, args) 42.88 - 42.89 - def event_handler(self, event, val): 42.90 - self.logInfo("EVENT> %s %s", str(event), str(val)) 42.91 + print >>sys.stderr, "xend [ERROR]", fmt % args 42.92 42.93 def configure(self): 42.94 self.set_config() 42.95 - self.configure_logger() 42.96 - 42.97 - def configure_logger(self): 42.98 logfile = self.get_config_value("logfile", self.logfile_default) 42.99 loglevel = self.get_config_value("loglevel", self.loglevel_default) 42.100 - self.logging = XendLogging(logfile, level=loglevel) 42.101 + XendLogging.init(logfile, level = loglevel) 42.102 42.103 from xen.xend.server import params 42.104 if params.XEND_DEBUG: 42.105 - self.logging.addLogStderr() 42.106 - 42.107 - def get_logging(self): 42.108 - """Get the XendLogging instance. 42.109 - """ 42.110 - return self.logging 42.111 - 42.112 - def get_logger(self): 42.113 - """Get the logger. 42.114 - """ 42.115 - return self.logging and self.logging.getLogger() 42.116 + XendLogging.addLogStderr() 42.117 42.118 def set_config(self): 42.119 """If the config file exists, read it. If not, ignore it. 42.120 @@ -200,7 +138,6 @@ class XendRoot: 42.121 """ 42.122 self.config_path = os.getenv(self.config_var, self.config_default) 42.123 if os.path.exists(self.config_path): 42.124 - #self.logInfo('Reading config file %s', self.config_path) 42.125 try: 42.126 fin = file(self.config_path, 'rb') 42.127 try: 42.128 @@ -210,10 +147,12 @@ class XendRoot: 42.129 config.insert(0, 'xend-config') 42.130 self.config = config 42.131 except Exception, ex: 42.132 - self.logError('Reading config file %s: %s', self.config_path, str(ex)) 42.133 + self._logError('Reading config file %s: %s', 42.134 + self.config_path, str(ex)) 42.135 raise 42.136 else: 42.137 - self.logError('Config file does not exist: %s', self.config_path) 42.138 + self._logError('Config file does not exist: %s', 42.139 + self.config_path) 42.140 self.config = ['xend-config'] 42.141 42.142 def get_config(self, name=None): 42.143 @@ -339,11 +278,6 @@ def instance(): 42.144 inst = XendRoot() 42.145 return inst 42.146 42.147 -def logger(): 42.148 - """Get the logger. 42.149 - """ 42.150 - return instance().get_logger() 42.151 - 42.152 def add_component(name, val): 42.153 """Register a component with XendRoot. 42.154 This is used to work-round import cycles.
43.1 --- a/tools/python/xen/xend/server/SrvDaemon.py Tue Oct 11 15:50:21 2005 -0600 43.2 +++ b/tools/python/xen/xend/server/SrvDaemon.py Tue Oct 11 16:57:44 2005 -0600 43.3 @@ -38,7 +38,7 @@ class Daemon: 43.4 pythonex = '(?P<python>\S*python\S*)' 43.5 cmdex = '(?P<cmd>.*)' 43.6 procre = re.compile('^\s*' + pidex + '\s*' + pythonex + '\s*' + cmdex + '$') 43.7 - xendre = re.compile('^/usr/sbin/xend\s*(start|restart)\s*.*$') 43.8 + xendre = re.compile('^\S+/xend\s*(start|restart)\s*.*$') 43.9 procs = os.popen('ps -e -o pid,args 2>/dev/null') 43.10 for proc in procs: 43.11 pm = procre.match(proc)
44.1 --- a/tools/python/xen/xend/server/SrvDomain.py Tue Oct 11 15:50:21 2005 -0600 44.2 +++ b/tools/python/xen/xend/server/SrvDomain.py Tue Oct 11 16:57:44 2005 -0600 44.3 @@ -51,40 +51,28 @@ class SrvDomain(SrvDir): 44.4 val = self.xd.domain_pause(self.dom.domid) 44.5 return val 44.6 44.7 - def op_shutdown(self, op, req): 44.8 - fn = FormFn(self.xd.domain_shutdown, 44.9 - [['dom', 'int'], 44.10 - ['reason', 'str']]) 44.11 - val = fn(req.args, {'dom': self.dom.domid}) 44.12 + def acceptCommand(self, req): 44.13 req.setResponseCode(http.ACCEPTED) 44.14 req.setHeader("Location", "%s/.." % req.prePathURL()) 44.15 - return val 44.16 + 44.17 + def op_shutdown(self, op, req): 44.18 + self.acceptCommand(req) 44.19 + return self.dom.shutdown(req.args['reason'][0]) 44.20 44.21 def op_sysrq(self, op, req): 44.22 - fn = FormFn(self.xd.domain_sysrq, 44.23 - [['dom', 'int'], 44.24 - ['key', 'int']]) 44.25 - val = fn(req.args, {'dom' : self.dom.domid}) 44.26 - req.setResponseCode(http.ACCEPTED) 44.27 - req.setHeader("Location", "%s/.." % req.prePathURL()) 44.28 - return val 44.29 + self.acceptCommand(req) 44.30 + return self.dom.send_sysrq(int(req.args['key'][0])) 44.31 44.32 def op_destroy(self, op, req): 44.33 - fn = FormFn(self.xd.domain_destroy, 44.34 - [['dom', 'int']]) 44.35 - val = fn(req.args, {'dom': self.dom.domid}) 44.36 - req.setHeader("Location", "%s/.." % req.prePathURL()) 44.37 - return val 44.38 + self.acceptCommand(req) 44.39 + return self.xd.domain_destroy(self.dom.domid) 44.40 44.41 def op_save(self, op, req): 44.42 + self.acceptCommand(req) 44.43 return req.threadRequest(self.do_save, op, req) 44.44 44.45 def do_save(self, op, req): 44.46 - fn = FormFn(self.xd.domain_save, 44.47 - [['dom', 'int'], 44.48 - ['file', 'str']]) 44.49 - val = fn(req.args, {'dom': self.dom.domid}) 44.50 - return 0 44.51 + return self.xd.domain_save(self.dom.domid, req.args['file'][0]) 44.52 44.53 def op_migrate(self, op, req): 44.54 return req.threadRequest(self.do_migrate, op, req) 44.55 @@ -134,43 +122,39 @@ class SrvDomain(SrvDir): 44.56 ['memory', 'int']]) 44.57 val = fn(req.args, {'dom': self.dom.domid}) 44.58 return val 44.59 + 44.60 44.61 + def call(self, fn, args, req): 44.62 + return FormFn(fn, args)(req.args) 44.63 + 44.64 + 44.65 def op_mem_target_set(self, op, req): 44.66 - fn = FormFn(self.xd.domain_mem_target_set, 44.67 - [['dom', 'int'], 44.68 - ['target', 'int']]) 44.69 - val = fn(req.args, {'dom': self.dom.domid}) 44.70 - return val 44.71 + return self.call(self.dom.setMemoryTarget, 44.72 + [['target', 'int']], 44.73 + req) 44.74 44.75 def op_devices(self, op, req): 44.76 - fn = FormFn(self.xd.domain_devtype_ls, 44.77 - [['dom', 'int'], 44.78 - ['type', 'str']]) 44.79 - val = fn(req.args, {'dom': self.dom.domid}) 44.80 - return val 44.81 + return self.call(self.dom.getDeviceSxprs, 44.82 + [['type', 'str']], 44.83 + req) 44.84 44.85 def op_device_create(self, op, req): 44.86 - fn = FormFn(self.xd.domain_device_create, 44.87 - [['dom', 'int'], 44.88 - ['config', 'sxpr']]) 44.89 - val = fn(req.args, {'dom': self.dom.domid}) 44.90 - return val 44.91 + return self.call(self.dom.device_create, 44.92 + [['config', 'sxpr']], 44.93 + req) 44.94 44.95 def op_device_destroy(self, op, req): 44.96 - fn = FormFn(self.xd.domain_device_destroy, 44.97 - [['dom', 'int'], 44.98 - ['type', 'str'], 44.99 - ['dev', 'str']]) 44.100 - val = fn(req.args, {'dom': self.dom.domid}) 44.101 - return val 44.102 + return self.call(self.dom.destroyDevice, 44.103 + [['type', 'str'], 44.104 + ['dev', 'int']], 44.105 + req) 44.106 44.107 def op_device_configure(self, op, req): 44.108 - fn = FormFn(self.xd.domain_device_configure, 44.109 - [['dom', 'int'], 44.110 - ['config', 'sxpr'], 44.111 - ['dev', 'str']]) 44.112 - val = fn(req.args, {'dom': self.dom.domid}) 44.113 - return val 44.114 + return self.call(self.dom.device_configure, 44.115 + [['config', 'sxpr'], 44.116 + ['dev', 'int']], 44.117 + req) 44.118 + 44.119 44.120 def op_vif_limit_set(self, op, req): 44.121 fn = FormFn(self.xd.domain_vif_limit_set, 44.122 @@ -182,12 +166,10 @@ class SrvDomain(SrvDir): 44.123 return val 44.124 44.125 def op_vcpu_hotplug(self, op, req): 44.126 - fn = FormFn(self.xd.domain_vcpu_hotplug, 44.127 - [['dom', 'int'], 44.128 - ['vcpu', 'int'], 44.129 - ['state', 'int']]) 44.130 - val = fn(req.args, {'dom': self.dom.domid}) 44.131 - return val 44.132 + return self.call(self.dom.vcpu_hotplug, 44.133 + [['vcpu', 'int'], 44.134 + ['state', 'int']], 44.135 + req) 44.136 44.137 def render_POST(self, req): 44.138 return self.perform(req) 44.139 @@ -201,7 +183,6 @@ class SrvDomain(SrvDir): 44.140 # 44.141 # if op and op[0] in ['vifs', 'vif', 'vbds', 'vbd', 'mem_target_set']: 44.142 # return self.perform(req) 44.143 - self.dom.update() 44.144 if self.use_sxp(req): 44.145 req.setHeader("Content-Type", sxp.mime_type) 44.146 sxp.show(self.dom.sxpr(), out=req)
45.1 --- a/tools/python/xen/xend/server/SrvDomainDir.py Tue Oct 11 15:50:21 2005 -0600 45.2 +++ b/tools/python/xen/xend/server/SrvDomainDir.py Tue Oct 11 16:57:44 2005 -0600 45.3 @@ -22,6 +22,7 @@ from xen.web import http 45.4 45.5 from xen.xend import sxp 45.6 from xen.xend import XendDomain 45.7 +from xen.xend.XendDomainInfo import XendDomainInfo 45.8 from xen.xend.Args import FormFn 45.9 from xen.xend.XendError import XendError 45.10 from xen.xend.XendLogging import log 45.11 @@ -29,6 +30,7 @@ from xen.xend.XendLogging import log 45.12 from xen.web.SrvDir import SrvDir 45.13 from SrvDomain import SrvDomain 45.14 45.15 + 45.16 class SrvDomainDir(SrvDir): 45.17 """Service that manages the domain directory. 45.18 """ 45.19 @@ -124,28 +126,41 @@ class SrvDomainDir(SrvDir): 45.20 out.close() 45.21 return val 45.22 45.23 + 45.24 + def op_list(self, _, req): 45.25 + """List the details for this domain.""" 45.26 + self._list(req, True) 45.27 + 45.28 + 45.29 def render_POST(self, req): 45.30 return self.perform(req) 45.31 45.32 def render_GET(self, req): 45.33 + self._list(req, 'detail' in req.args and req.args['detail'] == ['1']) 45.34 + 45.35 + 45.36 + def _list(self, req, detail): 45.37 if self.use_sxp(req): 45.38 req.setHeader("Content-Type", sxp.mime_type) 45.39 - self.ls_domain(req, 1) 45.40 + self.ls_domain(req, detail, True) 45.41 else: 45.42 req.write("<html><head></head><body>") 45.43 self.print_path(req) 45.44 self.ls(req) 45.45 - self.ls_domain(req) 45.46 + self.ls_domain(req, detail, False) 45.47 self.form(req) 45.48 req.write("</body></html>") 45.49 45.50 - def ls_domain(self, req, use_sxp=0): 45.51 + 45.52 + def ls_domain(self, req, detail, use_sxp): 45.53 url = req.prePathURL() 45.54 if not url.endswith('/'): 45.55 url += '/' 45.56 if use_sxp: 45.57 - domains = self.xd.list_names() 45.58 - sxp.show(domains, out=req) 45.59 + if detail: 45.60 + sxp.show(map(XendDomainInfo.sxpr, self.xd.list()), out=req) 45.61 + else: 45.62 + sxp.show(self.xd.list_names(), out=req) 45.63 else: 45.64 domains = self.xd.list_sorted() 45.65 req.write('<ul>') 45.66 @@ -158,6 +173,7 @@ class SrvDomainDir(SrvDir): 45.67 req.write('</li>') 45.68 req.write('</ul>') 45.69 45.70 + 45.71 def form(self, req): 45.72 """Generate the form(s) for domain dir operations. 45.73 """
46.1 --- a/tools/python/xen/xend/server/SrvServer.py Tue Oct 11 15:50:21 2005 -0600 46.2 +++ b/tools/python/xen/xend/server/SrvServer.py Tue Oct 11 16:57:44 2005 -0600 46.3 @@ -1,4 +1,3 @@ 46.4 -#!/usr/bin/python 46.5 #============================================================================ 46.6 # This library is free software; you can redistribute it and/or 46.7 # modify it under the terms of version 2.1 of the GNU Lesser General Public
47.1 --- a/tools/python/xen/xend/server/SrvXendLog.py Tue Oct 11 15:50:21 2005 -0600 47.2 +++ b/tools/python/xen/xend/server/SrvXendLog.py Tue Oct 11 16:57:44 2005 -0600 47.3 @@ -13,11 +13,12 @@ 47.4 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 47.5 #============================================================================ 47.6 # Copyright (C) 2004, 2005 Mike Wray <mike.wray@hp.com> 47.7 +# Copyright (C) 2005 XenSource Ltd 47.8 #============================================================================ 47.9 47.10 from xen.web import static 47.11 47.12 -from xen.xend import XendRoot 47.13 +from xen.xend import XendLogging 47.14 47.15 from xen.web.SrvDir import SrvDir 47.16 47.17 @@ -27,8 +28,8 @@ class SrvXendLog(SrvDir): 47.18 47.19 def __init__(self): 47.20 SrvDir.__init__(self) 47.21 - logging = XendRoot.instance().get_logging() 47.22 - self.logfile = static.File(logging.getLogFilename(), defaultType="text/plain") 47.23 + self.logfile = static.File(XendLogging.getLogFilename(), 47.24 + defaultType="text/plain") 47.25 self.logfile.type = "text/plain" 47.26 self.logfile.encoding = None 47.27
48.1 --- a/tools/python/xen/xend/server/event.py Tue Oct 11 15:50:21 2005 -0600 48.2 +++ b/tools/python/xen/xend/server/event.py Tue Oct 11 16:57:44 2005 -0600 48.3 @@ -25,6 +25,7 @@ from xen.xend import scheduler 48.4 from xen.xend import sxp 48.5 from xen.xend import PrettyPrint 48.6 from xen.xend.XendError import XendError 48.7 +from xen.xend import XendLogging 48.8 from xen.xend import XendRoot 48.9 48.10 48.11 @@ -146,11 +147,10 @@ class EventProtocol(protocol.Protocol): 48.12 48.13 def op_log_stderr(self, _, v): 48.14 mode = v[1] 48.15 - logging = xroot.get_logging() 48.16 if mode == 'on': 48.17 - logging.addLogStderr() 48.18 + XendLogging.addLogStderr() 48.19 else: 48.20 - logging.removeLogStderr() 48.21 + XendLogging.removeLogStderr() 48.22 48.23 def op_domain_ls(self, _1, _2): 48.24 xd = xroot.get_component("xen.xend.XendDomain")
49.1 --- a/tools/python/xen/xend/sxp.py Tue Oct 11 15:50:21 2005 -0600 49.2 +++ b/tools/python/xen/xend/sxp.py Tue Oct 11 16:57:44 2005 -0600 49.3 @@ -1,4 +1,4 @@ 49.4 -#!/usr/bin/python 49.5 +#!/usr/bin/env python 49.6 #============================================================================ 49.7 # This library is free software; you can redistribute it and/or 49.8 # modify it under the terms of version 2.1 of the GNU Lesser General Public
50.1 --- a/tools/python/xen/xend/uuid.py Tue Oct 11 15:50:21 2005 -0600 50.2 +++ b/tools/python/xen/xend/uuid.py Tue Oct 11 16:57:44 2005 -0600 50.3 @@ -13,14 +13,19 @@ 50.4 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 50.5 #============================================================================ 50.6 # Copyright (C) 2005 Mike Wray <mike.wray@hp.com> 50.7 +# Copyright (C) 2005 XenSource Ltd 50.8 #============================================================================ 50.9 50.10 + 50.11 """Universal(ly) Unique Identifiers (UUIDs). 50.12 """ 50.13 + 50.14 + 50.15 import commands 50.16 import random 50.17 50.18 -def uuidgen(random=True): 50.19 + 50.20 +def getUuidUuidgen(random = True): 50.21 """Generate a UUID using the command uuidgen. 50.22 50.23 If random is true (default) generates a random uuid. 50.24 @@ -33,50 +38,21 @@ def uuidgen(random=True): 50.25 cmd += " -t" 50.26 return commands.getoutput(cmd) 50.27 50.28 -class UuidFactoryUuidgen: 50.29 - 50.30 - """A uuid factory using uuidgen.""" 50.31 - 50.32 - def __init__(self): 50.33 - pass 50.34 - 50.35 - def getUuid(self): 50.36 - return uuidgen() 50.37 - 50.38 -class UuidFactoryRandom: 50.39 - 50.40 - """A random uuid factory.""" 50.41 - 50.42 - def __init__(self): 50.43 - f = file("/dev/urandom", "r") 50.44 - seed = f.read(16) 50.45 - f.close() 50.46 - self.rand = random.Random(seed) 50.47 50.48 - def randBytes(self, n): 50.49 - return [ self.rand.randint(0, 255) for i in range(0, n) ] 50.50 - 50.51 - def getUuid(self): 50.52 - bytes = self.randBytes(16) 50.53 - # Encode the variant. 50.54 - bytes[6] = (bytes[6] & 0x0f) | 0x40 50.55 - bytes[8] = (bytes[8] & 0x3f) | 0x80 50.56 - f = "%02x" 50.57 - return ( "-".join([f*4, f*2, f*2, f*2, f*6]) % tuple(bytes) ) 50.58 +def getUuidRandom(): 50.59 + """Generate a random UUID.""" 50.60 + 50.61 + bytes = [ random.randint(0, 255) for i in range(0, 16) ] 50.62 + # Encode the variant. 50.63 + bytes[6] = (bytes[6] & 0x0f) | 0x40 50.64 + bytes[8] = (bytes[8] & 0x3f) | 0x80 50.65 + f = "%02x" 50.66 + return ( "-".join([f*4, f*2, f*2, f*2, f*6]) % tuple(bytes) ) 50.67 50.68 -def getFactory(): 50.69 - """Get the factory to use for creating uuids. 50.70 - This is so it's easy to change the uuid factory. 50.71 - For example, for testing we might want repeatable uuids 50.72 - rather than the random ones we normally use. 50.73 - """ 50.74 - global uuidFactory 50.75 - try: 50.76 - uuidFactory 50.77 - except: 50.78 - #uuidFactory = UuidFactoryUuidgen() 50.79 - uuidFactory = UuidFactoryRandom() 50.80 - return uuidFactory 50.81 + 50.82 +#uuidFactory = getUuidUuidgen 50.83 +uuidFactory = getUuidRandom 50.84 + 50.85 50.86 def getUuid(): 50.87 - return getFactory().getUuid() 50.88 + return uuidFactory()
51.1 --- a/tools/python/xen/xend/xenstore/xstransact.py Tue Oct 11 15:50:21 2005 -0600 51.2 +++ b/tools/python/xen/xend/xenstore/xstransact.py Tue Oct 11 16:57:44 2005 -0600 51.3 @@ -14,29 +14,34 @@ from xen.xend.xenstore.xsutil import xsh 51.4 class xstransact: 51.5 51.6 def __init__(self, path): 51.7 - self.in_transaction = False 51.8 self.path = path.rstrip("/") 51.9 - xshandle().transaction_start() 51.10 + self.transaction = xshandle().transaction_start() 51.11 self.in_transaction = True 51.12 51.13 def __del__(self): 51.14 if self.in_transaction: 51.15 - xshandle().transaction_end(True) 51.16 + xshandle().transaction_end(self.transaction, True) 51.17 51.18 def commit(self): 51.19 if not self.in_transaction: 51.20 raise RuntimeError 51.21 self.in_transaction = False 51.22 - return xshandle().transaction_end(False) 51.23 + rc = xshandle().transaction_end(self.transaction, False) 51.24 + self.transaction = "0" 51.25 + return rc 51.26 51.27 def abort(self): 51.28 + if not self.in_transaction: 51.29 + return True 51.30 self.in_transaction = False 51.31 - return xshandle().transaction_end(True) 51.32 + rc = xshandle().transaction_end(self.transaction, True) 51.33 + self.transaction = "0" 51.34 + return rc 51.35 51.36 def _read(self, key): 51.37 path = "%s/%s" % (self.path, key) 51.38 try: 51.39 - return xshandle().read(path) 51.40 + return xshandle().read(self.transaction, path) 51.41 except RuntimeError, ex: 51.42 raise RuntimeError(ex.args[0], 51.43 '%s, while reading %s' % (ex.args[1], path)) 51.44 @@ -50,7 +55,7 @@ class xstransact: 51.45 instead. 51.46 """ 51.47 if len(args) == 0: 51.48 - return xshandle().read(self.path) 51.49 + return xshandle().read(self.transaction, self.path) 51.50 if len(args) == 1: 51.51 return self._read(args[0]) 51.52 ret = [] 51.53 @@ -61,7 +66,7 @@ class xstransact: 51.54 def _write(self, key, data): 51.55 path = "%s/%s" % (self.path, key) 51.56 try: 51.57 - xshandle().write(path, data) 51.58 + xshandle().write(self.transaction, path, data) 51.59 except RuntimeError, ex: 51.60 raise RuntimeError(ex.args[0], 51.61 ('%s, while writing %s : %s' % 51.62 @@ -93,7 +98,7 @@ class xstransact: 51.63 51.64 def _remove(self, key): 51.65 path = "%s/%s" % (self.path, key) 51.66 - return xshandle().rm(path) 51.67 + return xshandle().rm(self.transaction, path) 51.68 51.69 def remove(self, *args): 51.70 """If no arguments are given, remove this transaction's path. 51.71 @@ -101,14 +106,14 @@ class xstransact: 51.72 path, and remove each of those instead. 51.73 """ 51.74 if len(args) == 0: 51.75 - xshandle().rm(self.path) 51.76 + xshandle().rm(self.transaction, self.path) 51.77 else: 51.78 for key in args: 51.79 self._remove(key) 51.80 51.81 def _list(self, key): 51.82 path = "%s/%s" % (self.path, key) 51.83 - l = xshandle().ls(path) 51.84 + l = xshandle().ls(self.transaction, path) 51.85 if l: 51.86 return map(lambda x: key + "/" + x, l) 51.87 return [] 51.88 @@ -120,7 +125,7 @@ class xstransact: 51.89 path, and return the cumulative listing of each of those instead. 51.90 """ 51.91 if len(args) == 0: 51.92 - ret = xshandle().ls(self.path) 51.93 + ret = xshandle().ls(self.transaction, self.path) 51.94 if ret is None: 51.95 return [] 51.96 else: 51.97 @@ -136,11 +141,11 @@ class xstransact: 51.98 ret = [] 51.99 for key in keys: 51.100 new_subdir = subdir + "/" + key 51.101 - l = xshandle().ls(new_subdir) 51.102 + l = xshandle().ls(self.transaction, new_subdir) 51.103 if l: 51.104 ret.append([key, self.list_recursive_(new_subdir, l)]) 51.105 else: 51.106 - ret.append([key, xshandle().read(new_subdir)]) 51.107 + ret.append([key, xshandle().read(self.transaction, new_subdir)]) 51.108 return ret 51.109 51.110
52.1 --- a/tools/python/xen/xend/xenstore/xswatch.py Tue Oct 11 15:50:21 2005 -0600 52.2 +++ b/tools/python/xen/xend/xenstore/xswatch.py Tue Oct 11 16:57:44 2005 -0600 52.3 @@ -8,6 +8,7 @@ 52.4 import select 52.5 import threading 52.6 from xen.lowlevel import xs 52.7 +from xen.xend.xenstore.xsutil import xshandle 52.8 52.9 class xswatch: 52.10 52.11 @@ -27,10 +28,7 @@ class xswatch: 52.12 if cls.watchThread: 52.13 cls.xslock.release() 52.14 return 52.15 - # XXX: When we fix xenstored to have better watch semantics, 52.16 - # this can change to shared xshandle(). Currently that would result 52.17 - # in duplicate watch firings, thus failed extra xs.acknowledge_watch. 52.18 - cls.xs = xs.open() 52.19 + cls.xs = xshandle() 52.20 cls.watchThread = threading.Thread(name="Watcher", 52.21 target=cls.watchMain) 52.22 cls.watchThread.setDaemon(True) 52.23 @@ -43,11 +41,10 @@ class xswatch: 52.24 while True: 52.25 try: 52.26 we = cls.xs.read_watch() 52.27 - watch = we[1] 52.28 - cls.xs.acknowledge_watch(watch) 52.29 except RuntimeError, ex: 52.30 print ex 52.31 raise 52.32 + watch = we[1] 52.33 watch.fn(*watch.args, **watch.kwargs) 52.34 52.35 watchMain = classmethod(watchMain)
53.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 53.2 +++ b/tools/python/xen/xm/console.py Tue Oct 11 16:57:44 2005 -0600 53.3 @@ -0,0 +1,26 @@ 53.4 +#============================================================================ 53.5 +# This library is free software; you can redistribute it and/or 53.6 +# modify it under the terms of version 2.1 of the GNU Lesser General Public 53.7 +# License as published by the Free Software Foundation. 53.8 +# 53.9 +# This library is distributed in the hope that it will be useful, 53.10 +# but WITHOUT ANY WARRANTY; without even the implied warranty of 53.11 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 53.12 +# Lesser General Public License for more details. 53.13 +# 53.14 +# You should have received a copy of the GNU Lesser General Public 53.15 +# License along with this library; if not, write to the Free Software 53.16 +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 53.17 +#============================================================================ 53.18 +# Copyright (C) 2005 XenSource Ltd 53.19 +#============================================================================ 53.20 + 53.21 + 53.22 +XENCONSOLE = "xenconsole" 53.23 + 53.24 + 53.25 +import xen.util.auxbin 53.26 + 53.27 + 53.28 +def execConsole(domid): 53.29 + xen.util.auxbin.execute(XENCONSOLE, [str(domid)])
54.1 --- a/tools/python/xen/xm/create.py Tue Oct 11 15:50:21 2005 -0600 54.2 +++ b/tools/python/xen/xm/create.py Tue Oct 11 16:57:44 2005 -0600 54.3 @@ -14,11 +14,14 @@ 54.4 #============================================================================ 54.5 # Copyright (C) 2004, 2005 Mike Wray <mike.wray@hp.com> 54.6 # Copyright (C) 2005 Nguyen Anh Quynh <aquynh@gmail.com> 54.7 +# Copyright (C) 2005 XenSource Ltd 54.8 #============================================================================ 54.9 54.10 """Domain creation. 54.11 """ 54.12 import random 54.13 +import os 54.14 +import os.path 54.15 import string 54.16 import sys 54.17 import socket 54.18 @@ -36,6 +39,9 @@ from xen.util import blkif 54.19 54.20 from xen.xm.opts import * 54.21 54.22 +import console 54.23 + 54.24 + 54.25 gopts = Opts(use="""[options] [vars] 54.26 54.27 Create a domain. 54.28 @@ -879,8 +885,7 @@ def main(argv): 54.29 54.30 dom = make_domain(opts, config) 54.31 if opts.vals.console_autoconnect: 54.32 - cmd = "/usr/libexec/xen/xenconsole %d" % dom 54.33 - os.execvp('/usr/libexec/xen/xenconsole', cmd.split()) 54.34 + console.execConsole(dom) 54.35 54.36 if __name__ == '__main__': 54.37 main(sys.argv)
55.1 --- a/tools/python/xen/xm/main.py Tue Oct 11 15:50:21 2005 -0600 55.2 +++ b/tools/python/xen/xm/main.py Tue Oct 11 16:57:44 2005 -0600 55.3 @@ -38,6 +38,8 @@ from xen.xend import PrettyPrint 55.4 from xen.xend import sxp 55.5 from xen.xm.opts import * 55.6 55.7 +import console 55.8 + 55.9 55.10 shorthelp = """Usage: xm <subcommand> [args] 55.11 Control, list, and manipulate Xen guest instances 55.12 @@ -225,25 +227,22 @@ def xm_list(args): 55.13 if k in ['-v', '--vcpus']: 55.14 show_vcpus = 1 55.15 55.16 - domsinfo = [] 55.17 from xen.xend.XendClient import server 55.18 if n == 0: 55.19 - doms = server.xend_domains() 55.20 - doms.sort() 55.21 + doms = server.xend_list_domains() 55.22 else: 55.23 - doms = params 55.24 - for dom in doms: 55.25 - info = server.xend_domain(dom) 55.26 - domsinfo.append(parse_doms_info(info)) 55.27 + doms = map(server.xend_domain, params) 55.28 55.29 if use_long: 55.30 for dom in doms: 55.31 - info = server.xend_domain(dom) 55.32 - PrettyPrint.prettyprint(info) 55.33 - elif show_vcpus: 55.34 - xm_show_vcpus(domsinfo) 55.35 + PrettyPrint.prettyprint(doms) 55.36 else: 55.37 - xm_brief_list(domsinfo) 55.38 + domsinfo = map(parse_doms_info, doms) 55.39 + 55.40 + if show_vcpus: 55.41 + xm_show_vcpus(domsinfo) 55.42 + else: 55.43 + xm_brief_list(domsinfo) 55.44 55.45 def parse_doms_info(info): 55.46 dominfo = {} 55.47 @@ -279,12 +278,12 @@ def parse_doms_info(info): 55.48 return dominfo 55.49 55.50 def xm_brief_list(domsinfo): 55.51 - print 'Name Id Mem(MB) CPU VCPU(s) State Time(s)' 55.52 + print 'Name ID Mem(MiB) CPU VCPUs State Time(s)' 55.53 for dominfo in domsinfo: 55.54 if dominfo.has_key("ssidref1"): 55.55 - print ("%(name)-16s %(dom)3d %(mem)7d %(cpu)3s %(vcpus)5d %(state)5s %(cpu_time)7.1f s:%(ssidref2)02x/p:%(ssidref1)02x" % dominfo) 55.56 + print ("%(name)-16s %(dom)3d %(mem)8d %(cpu)3s %(vcpus)5d %(state)5s %(cpu_time)7.1f s:%(ssidref2)02x/p:%(ssidref1)02x" % dominfo) 55.57 else: 55.58 - print ("%(name)-16s %(dom)3d %(mem)7d %(cpu)3s %(vcpus)5d %(state)5s %(cpu_time)7.1f" % dominfo) 55.59 + print ("%(name)-16s %(dom)3d %(mem)8d %(cpu)3s %(vcpus)5d %(state)5s %(cpu_time)7.1f" % dominfo) 55.60 55.61 def xm_show_vcpus(domsinfo): 55.62 print 'Name Id VCPU CPU CPUMAP' 55.63 @@ -445,12 +444,11 @@ def xm_console(args): 55.64 from xen.xend.XendClient import server 55.65 info = server.xend_domain(dom) 55.66 domid = int(sxp.child_value(info, 'domid', '-1')) 55.67 - cmd = "/usr/libexec/xen/xenconsole %d" % domid 55.68 - os.execvp('/usr/libexec/xen/xenconsole', cmd.split()) 55.69 - console = sxp.child(info, "console") 55.70 + console.execConsole(domid) 55.71 + 55.72 55.73 def xm_top(args): 55.74 - os.execv('/usr/sbin/xentop', ['/usr/sbin/xentop']) 55.75 + os.execvp('xentop', ['xentop']) 55.76 55.77 def xm_dmesg(args): 55.78
56.1 --- a/tools/python/xen/xm/sysrq.py Tue Oct 11 15:50:21 2005 -0600 56.2 +++ b/tools/python/xen/xm/sysrq.py Tue Oct 11 16:57:44 2005 -0600 56.3 @@ -1,17 +1,12 @@ 56.4 # (C) Matthew Bloch <matthew@bytemark.co.uk> 2004 56.5 +# Copyright (C) 2005 XenSource Ltd 56.6 56.7 -"""Domain shutdown. 56.8 +"""Domain sysrq. 56.9 """ 56.10 -import string 56.11 -import sys 56.12 -import time 56.13 56.14 from xen.xend.XendClient import server 56.15 from xen.xm.opts import * 56.16 56.17 -DOM0_NAME = 'Domain-0' 56.18 -DOM0_ID = '0' 56.19 - 56.20 gopts = Opts(use="""[DOM] [letter] 56.21 56.22 Sends a Linux sysrq to a domain.
57.1 --- a/tools/xcutils/Makefile Tue Oct 11 15:50:21 2005 -0600 57.2 +++ b/tools/xcutils/Makefile Tue Oct 11 16:57:44 2005 -0600 57.3 @@ -15,7 +15,7 @@ INSTALL_DIR = $(INSTALL) -d -m0755 57.4 XEN_ROOT = ../.. 57.5 include $(XEN_ROOT)/tools/Rules.mk 57.6 57.7 -PROGRAMS_INSTALL_DIR = /usr/libexec/xen 57.8 +PROGRAMS_INSTALL_DIR = /usr/$(LIBDIR)/xen/bin 57.9 57.10 INCLUDES += -I $(XEN_LIBXC) 57.11
58.1 --- a/tools/xenstore/Makefile Tue Oct 11 15:50:21 2005 -0600 58.2 +++ b/tools/xenstore/Makefile Tue Oct 11 16:57:44 2005 -0600 58.3 @@ -8,7 +8,7 @@ INSTALL_PROG = $(INSTALL) -m0755 58.4 INSTALL_DIR = $(INSTALL) -d -m0755 58.5 58.6 PROFILE=#-pg 58.7 -BASECFLAGS=-Wall -W -g -Werror 58.8 +BASECFLAGS=-Wall -g -Werror 58.9 # Make gcc generate dependencies. 58.10 BASECFLAGS += -Wp,-MD,.$(@F).d 58.11 PROG_DEP = .*.d 58.12 @@ -27,7 +27,7 @@ CLIENTS := xenstore-exists xenstore-list 58.13 CLIENTS += xenstore-write 58.14 CLIENTS_OBJS := $(patsubst xenstore-%,xenstore_%.o,$(CLIENTS)) 58.15 58.16 -all: libxenstore.so xenstored $(CLIENTS) xs_tdb_dump 58.17 +all: libxenstore.so xenstored $(CLIENTS) xs_tdb_dump xsls 58.18 58.19 testcode: xs_test xenstored_test xs_random 58.20 58.21 @@ -40,6 +40,9 @@ xenstored: xenstored_core.o xenstored_wa 58.22 $(CLIENTS_OBJS): xenstore_%.o: xenstore_client.c 58.23 $(COMPILE.c) -DCLIENT_$(*F) -o $@ $< 58.24 58.25 +xsls: xsls.o 58.26 + $(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -lxenctrl -L. -lxenstore -o $@ 58.27 + 58.28 xenstored_test: xenstored_core_test.o xenstored_watch_test.o xenstored_domain_test.o xenstored_transaction_test.o xs_lib.o talloc_test.o fake_libxc.o utils.o tdb.o 58.29 $(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -o $@ 58.30 58.31 @@ -126,7 +129,7 @@ TAGS: 58.32 tarball: clean 58.33 cd .. && tar -c -j -v -h -f xenstore.tar.bz2 xenstore/ 58.34 58.35 -install: libxenstore.so xenstored $(CLIENTS) 58.36 +install: libxenstore.so xenstored xsls $(CLIENTS) 58.37 $(INSTALL_DIR) -p $(DESTDIR)/var/run/xenstored 58.38 $(INSTALL_DIR) -p $(DESTDIR)/var/lib/xenstored 58.39 $(INSTALL_DIR) -p $(DESTDIR)/usr/bin 58.40 @@ -134,6 +137,7 @@ install: libxenstore.so xenstored $(CLIE 58.41 $(INSTALL_DIR) -p $(DESTDIR)/usr/include 58.42 $(INSTALL_PROG) xenstored $(DESTDIR)/usr/sbin 58.43 $(INSTALL_PROG) $(CLIENTS) $(DESTDIR)/usr/bin 58.44 + $(INSTALL_PROG) xsls $(DESTDIR)/usr/bin 58.45 $(INSTALL_DIR) -p $(DESTDIR)/usr/$(LIBDIR) 58.46 $(INSTALL_DATA) libxenstore.so $(DESTDIR)/usr/$(LIBDIR) 58.47 $(INSTALL_DATA) xs.h $(DESTDIR)/usr/include
59.1 --- a/tools/xenstore/testsuite/07watch.test Tue Oct 11 15:50:21 2005 -0600 59.2 +++ b/tools/xenstore/testsuite/07watch.test Tue Oct 11 16:57:44 2005 -0600 59.3 @@ -5,7 +5,6 @@ 1 watch /test token 59.4 2 write /test contents2 59.5 expect 1:/test:token 59.6 1 waitwatch 59.7 -1 ackwatch token 59.8 1 close 59.9 59.10 # Check that reads don't set it off. 59.11 @@ -22,15 +21,12 @@ 1 watch /dir token 59.12 2 mkdir /dir/newdir 59.13 expect 1:/dir/newdir:token 59.14 1 waitwatch 59.15 -1 ackwatch token 59.16 2 setperm /dir/newdir 0 READ 59.17 expect 1:/dir/newdir:token 59.18 1 waitwatch 59.19 -1 ackwatch token 59.20 2 rm /dir/newdir 59.21 expect 1:/dir/newdir:token 59.22 1 waitwatch 59.23 -1 ackwatch token 59.24 1 close 59.25 2 close 59.26 59.27 @@ -49,7 +45,6 @@ expect contents 59.28 read /dir/test 59.29 expect /dir/test:token 59.30 waitwatch 59.31 -ackwatch token 59.32 close 59.33 59.34 # watch priority test: all simultaneous 59.35 @@ -59,13 +54,10 @@ 2 watch /dir token2 59.36 write /dir/test contents 59.37 expect 3:/dir/test:token3 59.38 3 waitwatch 59.39 -3 ackwatch token3 59.40 expect 2:/dir/test:token2 59.41 2 waitwatch 59.42 -2 ackwatch token2 59.43 expect 1:/dir/test:token1 59.44 1 waitwatch 59.45 -1 ackwatch token1 59.46 1 close 59.47 2 close 59.48 3 close 59.49 @@ -79,7 +71,6 @@ 2 waitwatch 59.50 2 close 59.51 expect 1:/dir/test:token1 59.52 1 waitwatch 59.53 -1 ackwatch token1 59.54 1 close 59.55 59.56 # If one dies (without reading at all), the other should still get ack. 59.57 @@ -89,7 +80,6 @@ write /dir/test contents 59.58 2 close 59.59 expect 1:/dir/test:token1 59.60 1 waitwatch 59.61 -1 ackwatch token1 59.62 1 close 59.63 2 close 59.64 59.65 @@ -111,7 +101,6 @@ write /dir/test contents 59.66 2 unwatch /dir token2 59.67 expect 1:/dir/test:token1 59.68 1 waitwatch 59.69 -1 ackwatch token1 59.70 1 close 59.71 2 close 59.72 59.73 @@ -123,14 +112,12 @@ 1 watch /dir/test token2 59.74 write /dir/test contents2 59.75 expect 1:/dir/test:token2 59.76 1 waitwatch 59.77 -1 ackwatch token2 59.78 59.79 # check we only get notified once. 59.80 1 watch /test token 59.81 2 write /test contents2 59.82 expect 1:/test:token 59.83 1 waitwatch 59.84 -1 ackwatch token 59.85 expect 1: waitwatch failed: Connection timed out 59.86 1 waitwatch 59.87 1 close 59.88 @@ -142,13 +129,10 @@ 2 write /test2 contents 59.89 2 write /test3 contents 59.90 expect 1:/test1:token 59.91 1 waitwatch 59.92 -1 ackwatch token 59.93 expect 1:/test2:token 59.94 1 waitwatch 59.95 -1 ackwatch token 59.96 expect 1:/test3:token 59.97 1 waitwatch 59.98 -1 ackwatch token 59.99 1 close 59.100 59.101 # Creation of subpaths should be covered correctly. 59.102 @@ -157,10 +141,8 @@ 2 write /test/subnode contents2 59.103 2 write /test/subnode/subnode contents2 59.104 expect 1:/test/subnode:token 59.105 1 waitwatch 59.106 -1 ackwatch token 59.107 expect 1:/test/subnode/subnode:token 59.108 1 waitwatch 59.109 -1 ackwatch token 59.110 expect 1: waitwatch failed: Connection timed out 59.111 1 waitwatch 59.112 1 close 59.113 @@ -171,7 +153,6 @@ 2 write /test/subnode contents2 59.114 1 watchnoack / token2 0 59.115 expect 1:/test/subnode:token 59.116 1 waitwatch 59.117 -1 ackwatch token 59.118 expect 1:/:token2 59.119 1 waitwatch 59.120 expect 1: waitwatch failed: Connection timed out 59.121 @@ -183,7 +164,6 @@ 1 watch /test/subnode token 59.122 2 rm /test 59.123 expect 1:/test/subnode:token 59.124 1 waitwatch 59.125 -1 ackwatch token 59.126 59.127 # Watch should not double-send after we ack, even if we did something in between. 59.128 1 watch /test2 token 59.129 @@ -192,6 +172,5 @@ expect 1:/test2/foo:token 59.130 1 waitwatch 59.131 expect 1:contents2 59.132 1 read /test2/foo 59.133 -1 ackwatch token 59.134 expect 1: waitwatch failed: Connection timed out 59.135 1 waitwatch
60.1 --- a/tools/xenstore/testsuite/08transaction.test Tue Oct 11 15:50:21 2005 -0600 60.2 +++ b/tools/xenstore/testsuite/08transaction.test Tue Oct 11 16:57:44 2005 -0600 60.3 @@ -68,7 +68,6 @@ 2 mkdir /test/dir/sub 60.4 2 commit 60.5 expect 1:/test/dir/sub:token 60.6 1 waitwatch 60.7 -1 ackwatch token 60.8 1 close 60.9 60.10 # Rm inside transaction works like rm outside: children get notified. 60.11 @@ -78,7 +77,6 @@ 2 rm /test/dir 60.12 2 commit 60.13 expect 1:/test/dir/sub:token 60.14 1 waitwatch 60.15 -1 ackwatch token 60.16 1 close 60.17 60.18 # Multiple events from single transaction don't trigger assert 60.19 @@ -89,8 +87,6 @@ 2 write /test/2 contents 60.20 2 commit 60.21 expect 1:/test/1:token 60.22 1 waitwatch 60.23 -1 ackwatch token 60.24 expect 1:/test/2:token 60.25 1 waitwatch 60.26 -1 ackwatch token 60.27 1 close
61.1 --- a/tools/xenstore/testsuite/10domain-homedir.test Tue Oct 11 15:50:21 2005 -0600 61.2 +++ b/tools/xenstore/testsuite/10domain-homedir.test Tue Oct 11 16:57:44 2005 -0600 61.3 @@ -16,4 +16,3 @@ 1 watch foo token 61.4 write /home/foo/bar contents 61.5 expect 1:foo/bar:token 61.6 1 waitwatch 61.7 -1 ackwatch token
62.1 --- a/tools/xenstore/testsuite/11domain-watch.test Tue Oct 11 15:50:21 2005 -0600 62.2 +++ b/tools/xenstore/testsuite/11domain-watch.test Tue Oct 11 16:57:44 2005 -0600 62.3 @@ -10,7 +10,6 @@ 1 watch /test token 62.4 write /test contents2 62.5 expect 1:/test:token 62.6 1 waitwatch 62.7 -1 ackwatch token 62.8 1 unwatch /test token 62.9 release 1 62.10 1 close 62.11 @@ -25,7 +24,6 @@ 1 write /dir/test3 contents3 62.12 1 write /dir/test4 contents4 62.13 expect 1:/dir/test:token 62.14 1 waitwatch 62.15 -1 ackwatch token 62.16 release 1 62.17 1 close 62.18
63.1 --- a/tools/xenstore/testsuite/12readonly.test Tue Oct 11 15:50:21 2005 -0600 63.2 +++ b/tools/xenstore/testsuite/12readonly.test Tue Oct 11 16:57:44 2005 -0600 63.3 @@ -36,4 +36,3 @@ 1 readwrite 63.4 1 write /test contents 63.5 expect /test:token 63.6 waitwatch 63.7 -ackwatch token
64.1 --- a/tools/xenstore/testsuite/13watch-ack.test Tue Oct 11 15:50:21 2005 -0600 64.2 +++ b/tools/xenstore/testsuite/13watch-ack.test Tue Oct 11 16:57:44 2005 -0600 64.3 @@ -18,5 +18,4 @@ expect 1:/test/2:token2 64.4 1 waitwatch 64.5 3 write /test/1 contents1 64.6 4 write /test/3 contents3 64.7 -1 ackwatch token2 64.8 1 close
65.1 --- a/tools/xenstore/utils.h Tue Oct 11 15:50:21 2005 -0600 65.2 +++ b/tools/xenstore/utils.h Tue Oct 11 16:57:44 2005 -0600 65.3 @@ -55,4 +55,34 @@ void xprintf(const char *fmt, ...); 65.4 #define dprintf(_fmt, _args...) ((void)0) 65.5 #endif 65.6 65.7 +/* 65.8 + * Mux errno values onto returned pointers. 65.9 + */ 65.10 + 65.11 +static inline void *ERR_PTR(long error) 65.12 +{ 65.13 + return (void *)error; 65.14 +} 65.15 + 65.16 +static inline long PTR_ERR(const void *ptr) 65.17 +{ 65.18 + return (long)ptr; 65.19 +} 65.20 + 65.21 +static inline long IS_ERR(const void *ptr) 65.22 +{ 65.23 + return ((unsigned long)ptr > (unsigned long)-1000L); 65.24 +} 65.25 + 65.26 + 65.27 #endif /* _UTILS_H */ 65.28 + 65.29 +/* 65.30 + * Local variables: 65.31 + * c-file-style: "linux" 65.32 + * indent-tabs-mode: t 65.33 + * c-indent-level: 8 65.34 + * c-basic-offset: 8 65.35 + * tab-width: 8 65.36 + * End: 65.37 + */
66.1 --- a/tools/xenstore/xenstore_client.c Tue Oct 11 15:50:21 2005 -0600 66.2 +++ b/tools/xenstore/xenstore_client.c Tue Oct 11 16:57:44 2005 -0600 66.3 @@ -20,11 +20,11 @@ static void 66.4 usage(const char *progname) 66.5 { 66.6 #if defined(CLIENT_read) 66.7 - errx(1, "Usage: %s [-h] [-p] key [...]", progname); 66.8 + errx(1, "Usage: %s [-h] [-p] [-s] key [...]", progname); 66.9 #elif defined(CLIENT_write) 66.10 - errx(1, "Usage: %s [-h] key value [...]", progname); 66.11 + errx(1, "Usage: %s [-h] [-s] key value [...]", progname); 66.12 #elif defined(CLIENT_rm) || defined(CLIENT_exists) || defined(CLIENT_list) 66.13 - errx(1, "Usage: %s [-h] key [...]", progname); 66.14 + errx(1, "Usage: %s [-h] [-s] key [...]", progname); 66.15 #endif 66.16 } 66.17 66.18 @@ -32,16 +32,13 @@ int 66.19 main(int argc, char **argv) 66.20 { 66.21 struct xs_handle *xsh; 66.22 + struct xs_transaction_handle *xth; 66.23 bool success; 66.24 - int ret = 0; 66.25 + int ret = 0, socket = 0; 66.26 #if defined(CLIENT_read) || defined(CLIENT_list) 66.27 int prefix = 0; 66.28 #endif 66.29 66.30 - xsh = xs_domain_open(); 66.31 - if (xsh == NULL) 66.32 - err(1, "xs_domain_open"); 66.33 - 66.34 while (1) { 66.35 int c, index = 0; 66.36 static struct option long_options[] = { 66.37 @@ -49,10 +46,11 @@ main(int argc, char **argv) 66.38 #if defined(CLIENT_read) || defined(CLIENT_list) 66.39 {"prefix", 0, 0, 'p'}, 66.40 #endif 66.41 + {"socket", 0, 0, 's'}, 66.42 {0, 0, 0, 0} 66.43 }; 66.44 66.45 - c = getopt_long(argc, argv, "h" 66.46 + c = getopt_long(argc, argv, "hs" 66.47 #if defined(CLIENT_read) || defined(CLIENT_list) 66.48 "p" 66.49 #endif 66.50 @@ -64,6 +62,9 @@ main(int argc, char **argv) 66.51 case 'h': 66.52 usage(argv[0]); 66.53 /* NOTREACHED */ 66.54 + case 's': 66.55 + socket = 1; 66.56 + break; 66.57 #if defined(CLIENT_read) || defined(CLIENT_list) 66.58 case 'p': 66.59 prefix = 1; 66.60 @@ -83,14 +84,18 @@ main(int argc, char **argv) 66.61 } 66.62 #endif 66.63 66.64 + xsh = socket ? xs_daemon_open() : xs_domain_open(); 66.65 + if (xsh == NULL) 66.66 + err(1, socket ? "xs_daemon_open" : "xs_domain_open"); 66.67 + 66.68 again: 66.69 - success = xs_transaction_start(xsh); 66.70 - if (!success) 66.71 + xth = xs_transaction_start(xsh); 66.72 + if (xth == NULL) 66.73 errx(1, "couldn't start transaction"); 66.74 66.75 while (optind < argc) { 66.76 #if defined(CLIENT_read) 66.77 - char *val = xs_read(xsh, argv[optind], NULL); 66.78 + char *val = xs_read(xsh, xth, argv[optind], NULL); 66.79 if (val == NULL) { 66.80 warnx("couldn't read path %s", argv[optind]); 66.81 ret = 1; 66.82 @@ -102,7 +107,7 @@ main(int argc, char **argv) 66.83 free(val); 66.84 optind++; 66.85 #elif defined(CLIENT_write) 66.86 - success = xs_write(xsh, argv[optind], argv[optind + 1], 66.87 + success = xs_write(xsh, xth, argv[optind], argv[optind + 1], 66.88 strlen(argv[optind + 1])); 66.89 if (!success) { 66.90 warnx("could not write path %s", argv[optind]); 66.91 @@ -111,7 +116,7 @@ main(int argc, char **argv) 66.92 } 66.93 optind += 2; 66.94 #elif defined(CLIENT_rm) 66.95 - success = xs_rm(xsh, argv[optind]); 66.96 + success = xs_rm(xsh, xth, argv[optind]); 66.97 if (!success) { 66.98 warnx("could not remove path %s", argv[optind]); 66.99 ret = 1; 66.100 @@ -119,7 +124,7 @@ main(int argc, char **argv) 66.101 } 66.102 optind++; 66.103 #elif defined(CLIENT_exists) 66.104 - char *val = xs_read(xsh, argv[optind], NULL); 66.105 + char *val = xs_read(xsh, xth, argv[optind], NULL); 66.106 if (val == NULL) { 66.107 ret = 1; 66.108 goto out; 66.109 @@ -128,7 +133,7 @@ main(int argc, char **argv) 66.110 optind++; 66.111 #elif defined(CLIENT_list) 66.112 unsigned int i, num; 66.113 - char **list = xs_directory(xsh, argv[optind], &num); 66.114 + char **list = xs_directory(xsh, xth, argv[optind], &num); 66.115 if (list == NULL) { 66.116 warnx("could not list path %s", argv[optind]); 66.117 ret = 1; 66.118 @@ -145,7 +150,7 @@ main(int argc, char **argv) 66.119 } 66.120 66.121 out: 66.122 - success = xs_transaction_end(xsh, ret ? true : false); 66.123 + success = xs_transaction_end(xsh, xth, ret ? true : false); 66.124 if (!success) { 66.125 if (ret == 0 && errno == EAGAIN) 66.126 goto again;
67.1 --- a/tools/xenstore/xenstored_core.c Tue Oct 11 15:50:21 2005 -0600 67.2 +++ b/tools/xenstore/xenstored_core.c Tue Oct 11 16:57:44 2005 -0600 67.3 @@ -154,7 +154,6 @@ static char *sockmsg_string(enum xsd_soc 67.4 case XS_READ: return "READ"; 67.5 case XS_GET_PERMS: return "GET_PERMS"; 67.6 case XS_WATCH: return "WATCH"; 67.7 - case XS_WATCH_ACK: return "WATCH_ACK"; 67.8 case XS_UNWATCH: return "UNWATCH"; 67.9 case XS_TRANSACTION_START: return "TRANSACTION_START"; 67.10 case XS_TRANSACTION_END: return "TRANSACTION_END"; 67.11 @@ -236,10 +235,14 @@ void trace(const char *fmt, ...) 67.12 talloc_free(str); 67.13 } 67.14 67.15 -static bool write_message(struct connection *conn) 67.16 +static bool write_messages(struct connection *conn) 67.17 { 67.18 int ret; 67.19 - struct buffered_data *out = conn->out; 67.20 + struct buffered_data *out; 67.21 + 67.22 + out = list_top(&conn->out_list, struct buffered_data, list); 67.23 + if (out == NULL) 67.24 + return true; 67.25 67.26 if (out->inhdr) { 67.27 if (verbose) 67.28 @@ -265,7 +268,6 @@ static bool write_message(struct connect 67.29 67.30 ret = conn->write(conn, out->buffer + out->used, 67.31 out->hdr.msg.len - out->used); 67.32 - 67.33 if (ret < 0) 67.34 return false; 67.35 67.36 @@ -274,14 +276,10 @@ static bool write_message(struct connect 67.37 return true; 67.38 67.39 trace_io(conn, "OUT", out); 67.40 - conn->out = NULL; 67.41 + 67.42 + list_del(&out->list); 67.43 talloc_free(out); 67.44 67.45 - queue_next_event(conn); 67.46 - 67.47 - /* No longer busy? */ 67.48 - if (!conn->out) 67.49 - conn->state = OK; 67.50 return true; 67.51 } 67.52 67.53 @@ -298,9 +296,9 @@ static int destroy_conn(void *_conn) 67.54 FD_SET(conn->fd, &set); 67.55 none.tv_sec = none.tv_usec = 0; 67.56 67.57 - while (conn->out 67.58 + while (!list_empty(&conn->out_list) 67.59 && select(conn->fd+1, NULL, &set, NULL, &none) == 1) 67.60 - if (!write_message(conn)) 67.61 + if (!write_messages(conn)) 67.62 break; 67.63 close(conn->fd); 67.64 } 67.65 @@ -327,9 +325,8 @@ static int initialize_set(fd_set *inset, 67.66 list_for_each_entry(i, &connections, list) { 67.67 if (i->domain) 67.68 continue; 67.69 - if (i->state == OK) 67.70 - FD_SET(i->fd, inset); 67.71 - if (i->out) 67.72 + FD_SET(i->fd, inset); 67.73 + if (!list_empty(&i->out_list)) 67.74 FD_SET(i->fd, outset); 67.75 if (i->fd > max) 67.76 max = i->fd; 67.77 @@ -542,6 +539,9 @@ static struct buffered_data *new_buffer( 67.78 struct buffered_data *data; 67.79 67.80 data = talloc(ctx, struct buffered_data); 67.81 + if (data == NULL) 67.82 + return NULL; 67.83 + 67.84 data->inhdr = true; 67.85 data->used = 0; 67.86 data->buffer = NULL; 67.87 @@ -586,23 +586,25 @@ void send_reply(struct connection *conn, 67.88 { 67.89 struct buffered_data *bdata; 67.90 67.91 - /* When data gets freed, we want list entry is destroyed (so 67.92 - * list entry is a child). */ 67.93 + /* Message is a child of the connection context for auto-cleanup. */ 67.94 bdata = new_buffer(conn); 67.95 bdata->buffer = talloc_array(bdata, char, len); 67.96 67.97 + /* Echo request header in reply unless this is an async watch event. */ 67.98 + if (type != XS_WATCH_EVENT) { 67.99 + memcpy(&bdata->hdr.msg, &conn->in->hdr.msg, 67.100 + sizeof(struct xsd_sockmsg)); 67.101 + } else { 67.102 + memset(&bdata->hdr.msg, 0, sizeof(struct xsd_sockmsg)); 67.103 + } 67.104 + 67.105 + /* Update relevant header fields and fill in the message body. */ 67.106 bdata->hdr.msg.type = type; 67.107 bdata->hdr.msg.len = len; 67.108 memcpy(bdata->buffer, data, len); 67.109 67.110 - /* There might be an event going out now. Queue behind it. */ 67.111 - if (conn->out) { 67.112 - assert(conn->out->hdr.msg.type == XS_WATCH_EVENT); 67.113 - assert(!conn->waiting_reply); 67.114 - conn->waiting_reply = bdata; 67.115 - } else 67.116 - conn->out = bdata; 67.117 - conn->state = BUSY; 67.118 + /* Queue for later transmission. */ 67.119 + list_add_tail(&bdata->list, &conn->out_list); 67.120 } 67.121 67.122 /* Some routines (write, mkdir, etc) just need a non-error return */ 67.123 @@ -1053,6 +1055,17 @@ static void do_set_perms(struct connecti 67.124 */ 67.125 static void process_message(struct connection *conn, struct buffered_data *in) 67.126 { 67.127 + struct transaction *trans; 67.128 + 67.129 + trans = transaction_lookup(conn, in->hdr.msg.tx_id); 67.130 + if (IS_ERR(trans)) { 67.131 + send_error(conn, -PTR_ERR(trans)); 67.132 + return; 67.133 + } 67.134 + 67.135 + assert(conn->transaction == NULL); 67.136 + conn->transaction = trans; 67.137 + 67.138 switch (in->hdr.msg.type) { 67.139 case XS_DIRECTORY: 67.140 send_directory(conn, onearg(in)); 67.141 @@ -1103,10 +1116,6 @@ static void process_message(struct conne 67.142 do_watch(conn, in); 67.143 break; 67.144 67.145 - case XS_WATCH_ACK: 67.146 - do_watch_ack(conn, onearg(in)); 67.147 - break; 67.148 - 67.149 case XS_UNWATCH: 67.150 do_unwatch(conn, in); 67.151 break; 67.152 @@ -1131,11 +1140,13 @@ static void process_message(struct conne 67.153 do_get_domain_path(conn, onearg(in)); 67.154 break; 67.155 67.156 - case XS_WATCH_EVENT: 67.157 default: 67.158 eprintf("Client unknown operation %i", in->hdr.msg.type); 67.159 send_error(conn, ENOSYS); 67.160 + break; 67.161 } 67.162 + 67.163 + conn->transaction = NULL; 67.164 } 67.165 67.166 static int out_of_mem(void *data) 67.167 @@ -1145,43 +1156,25 @@ static int out_of_mem(void *data) 67.168 67.169 static void consider_message(struct connection *conn) 67.170 { 67.171 - /* 67.172 - * 'volatile' qualifier prevents register allocation which fixes: 67.173 - * warning: variable 'xxx' might be clobbered by 'longjmp' or 'vfork' 67.174 - */ 67.175 - struct buffered_data *volatile in = NULL; 67.176 - enum xsd_sockmsg_type volatile type = conn->in->hdr.msg.type; 67.177 jmp_buf talloc_fail; 67.178 67.179 - assert(conn->state == OK); 67.180 + if (verbose) 67.181 + xprintf("Got message %s len %i from %p\n", 67.182 + sockmsg_string(conn->in->hdr.msg.type), 67.183 + conn->in->hdr.msg.len, conn); 67.184 67.185 /* For simplicity, we kill the connection on OOM. */ 67.186 talloc_set_fail_handler(out_of_mem, &talloc_fail); 67.187 if (setjmp(talloc_fail)) { 67.188 - /* Free in before conn, in case it needs something. */ 67.189 - talloc_free(in); 67.190 talloc_free(conn); 67.191 goto end; 67.192 } 67.193 67.194 - if (verbose) 67.195 - xprintf("Got message %s len %i from %p\n", 67.196 - sockmsg_string(type), conn->in->hdr.msg.len, conn); 67.197 - 67.198 - /* We might get a command while waiting for an ack: this means 67.199 - * the other end discarded it: we will re-transmit. */ 67.200 - if (type != XS_WATCH_ACK) 67.201 - conn->waiting_for_ack = NULL; 67.202 + process_message(conn, conn->in); 67.203 67.204 - /* Careful: process_message may free connection. We detach 67.205 - * "in" beforehand and allocate the new buffer to avoid 67.206 - * touching conn after process_message. 67.207 - */ 67.208 - in = talloc_steal(talloc_autofree_context(), conn->in); 67.209 + talloc_free(conn->in); 67.210 conn->in = new_buffer(conn); 67.211 - process_message(conn, in); 67.212 67.213 - talloc_free(in); 67.214 end: 67.215 talloc_set_fail_handler(NULL, NULL); 67.216 if (talloc_total_blocks(NULL) 67.217 @@ -1196,10 +1189,7 @@ end: 67.218 static void handle_input(struct connection *conn) 67.219 { 67.220 int bytes; 67.221 - struct buffered_data *in; 67.222 - 67.223 - assert(conn->state == OK); 67.224 - in = conn->in; 67.225 + struct buffered_data *in = conn->in; 67.226 67.227 /* Not finished header yet? */ 67.228 if (in->inhdr) { 67.229 @@ -1247,42 +1237,32 @@ bad_client: 67.230 67.231 static void handle_output(struct connection *conn) 67.232 { 67.233 - if (!write_message(conn)) 67.234 + if (!write_messages(conn)) 67.235 talloc_free(conn); 67.236 } 67.237 67.238 struct connection *new_connection(connwritefn_t *write, connreadfn_t *read) 67.239 { 67.240 - /* 67.241 - * 'volatile' qualifier prevents register allocation which fixes: 67.242 - * warning: variable 'xxx' might be clobbered by 'longjmp' or 'vfork' 67.243 - */ 67.244 - struct connection *volatile new; 67.245 - jmp_buf talloc_fail; 67.246 + struct connection *new; 67.247 67.248 new = talloc(talloc_autofree_context(), struct connection); 67.249 if (!new) 67.250 return NULL; 67.251 67.252 - new->state = OK; 67.253 - new->out = new->waiting_reply = NULL; 67.254 - new->waiting_for_ack = NULL; 67.255 + memset(new, 0, sizeof(*new)); 67.256 new->fd = -1; 67.257 - new->id = 0; 67.258 - new->domain = NULL; 67.259 - new->transaction = NULL; 67.260 new->write = write; 67.261 new->read = read; 67.262 new->can_write = true; 67.263 + INIT_LIST_HEAD(&new->out_list); 67.264 INIT_LIST_HEAD(&new->watches); 67.265 + INIT_LIST_HEAD(&new->transaction_list); 67.266 67.267 - talloc_set_fail_handler(out_of_mem, &talloc_fail); 67.268 - if (setjmp(talloc_fail)) { 67.269 + new->in = new_buffer(new); 67.270 + if (new->in == NULL) { 67.271 talloc_free(new); 67.272 return NULL; 67.273 } 67.274 - new->in = new_buffer(new); 67.275 - talloc_set_fail_handler(NULL, NULL); 67.276 67.277 list_add_tail(&new->list, &connections); 67.278 talloc_set_destructor(new, destroy_conn); 67.279 @@ -1328,23 +1308,17 @@ void dump_connection(void) 67.280 list_for_each_entry(i, &connections, list) { 67.281 printf("Connection %p:\n", i); 67.282 printf(" state = %s\n", 67.283 - i->state == OK ? "OK" 67.284 - : i->state == BUSY ? "BUSY" 67.285 - : "INVALID"); 67.286 + list_empty(&i->out_list) ? "OK" : "BUSY"); 67.287 if (i->id) 67.288 printf(" id = %i\n", i->id); 67.289 if (!i->in->inhdr || i->in->used) 67.290 printf(" got %i bytes of %s\n", 67.291 i->in->used, i->in->inhdr ? "header" : "data"); 67.292 +#if 0 67.293 if (i->out) 67.294 printf(" sending message %s (%s) out\n", 67.295 sockmsg_string(i->out->hdr.msg.type), 67.296 i->out->buffer); 67.297 - if (i->waiting_reply) 67.298 - printf(" ... and behind is queued %s (%s)\n", 67.299 - sockmsg_string(i->waiting_reply->hdr.msg.type), 67.300 - i->waiting_reply->buffer); 67.301 -#if 0 67.302 if (i->transaction) 67.303 dump_transaction(i); 67.304 if (i->domain) 67.305 @@ -1443,6 +1417,7 @@ static void daemonize(void) 67.306 67.307 67.308 static struct option options[] = { 67.309 + { "no-domain-init", 0, NULL, 'D' }, 67.310 { "pid-file", 1, NULL, 'F' }, 67.311 { "no-fork", 0, NULL, 'N' }, 67.312 { "output-pid", 0, NULL, 'P' }, 67.313 @@ -1457,11 +1432,15 @@ int main(int argc, char *argv[]) 67.314 fd_set inset, outset; 67.315 bool dofork = true; 67.316 bool outputpid = false; 67.317 + bool no_domain_init = false; 67.318 const char *pidfile = NULL; 67.319 67.320 - while ((opt = getopt_long(argc, argv, "F:NPT:V", options, 67.321 + while ((opt = getopt_long(argc, argv, "DF:NPT:V", options, 67.322 NULL)) != -1) { 67.323 switch (opt) { 67.324 + case 'D': 67.325 + no_domain_init = true; 67.326 + break; 67.327 case 'F': 67.328 pidfile = optarg; 67.329 break; 67.330 @@ -1534,7 +1513,8 @@ int main(int argc, char *argv[]) 67.331 setup_structure(); 67.332 67.333 /* Listen to hypervisor. */ 67.334 - event_fd = domain_init(); 67.335 + if (!no_domain_init) 67.336 + event_fd = domain_init(); 67.337 67.338 /* Restore existing connections. */ 67.339 restore_existing_connections(); 67.340 @@ -1615,3 +1595,13 @@ int main(int argc, char *argv[]) 67.341 max = initialize_set(&inset, &outset, *sock, *ro_sock); 67.342 } 67.343 } 67.344 + 67.345 +/* 67.346 + * Local variables: 67.347 + * c-file-style: "linux" 67.348 + * indent-tabs-mode: t 67.349 + * c-indent-level: 8 67.350 + * c-basic-offset: 8 67.351 + * tab-width: 8 67.352 + * End: 67.353 + */
68.1 --- a/tools/xenstore/xenstored_core.h Tue Oct 11 15:50:21 2005 -0600 68.2 +++ b/tools/xenstore/xenstored_core.h Tue Oct 11 16:57:44 2005 -0600 68.3 @@ -31,14 +31,19 @@ 68.4 68.5 struct buffered_data 68.6 { 68.7 + struct list_head list; 68.8 + 68.9 /* Are we still doing the header? */ 68.10 bool inhdr; 68.11 + 68.12 /* How far are we? */ 68.13 unsigned int used; 68.14 + 68.15 union { 68.16 struct xsd_sockmsg msg; 68.17 char raw[sizeof(struct xsd_sockmsg)]; 68.18 } hdr; 68.19 + 68.20 /* The actual data. */ 68.21 char *buffer; 68.22 }; 68.23 @@ -47,14 +52,6 @@ struct connection; 68.24 typedef int connwritefn_t(struct connection *, const void *, unsigned int); 68.25 typedef int connreadfn_t(struct connection *, void *, unsigned int); 68.26 68.27 -enum state 68.28 -{ 68.29 - /* Doing action, not listening */ 68.30 - BUSY, 68.31 - /* Completed */ 68.32 - OK, 68.33 -}; 68.34 - 68.35 struct connection 68.36 { 68.37 struct list_head list; 68.38 @@ -62,29 +59,24 @@ struct connection 68.39 /* The file descriptor we came in on. */ 68.40 int fd; 68.41 68.42 - /* Who am I? 0 for socket connections. */ 68.43 + /* Who am I? 0 for socket connections. */ 68.44 domid_t id; 68.45 68.46 - /* Blocked on transaction? Busy? */ 68.47 - enum state state; 68.48 - 68.49 /* Is this a read-only connection? */ 68.50 bool can_write; 68.51 68.52 - /* Are we waiting for a watch event ack? */ 68.53 - struct watch *waiting_for_ack; 68.54 - 68.55 /* Buffered incoming data. */ 68.56 struct buffered_data *in; 68.57 68.58 /* Buffered output data */ 68.59 - struct buffered_data *out; 68.60 + struct list_head out_list; 68.61 68.62 - /* If we had a watch fire outgoing when we needed to reply... */ 68.63 - struct buffered_data *waiting_reply; 68.64 + /* Transaction context for current request (NULL if none). */ 68.65 + struct transaction *transaction; 68.66 68.67 - /* My transaction, if any. */ 68.68 - struct transaction *transaction; 68.69 + /* List of in-progress transactions. */ 68.70 + struct list_head transaction_list; 68.71 + u32 next_transaction_id; 68.72 68.73 /* The domain I'm associated with, if any. */ 68.74 struct domain *domain; 68.75 @@ -175,3 +167,13 @@ void trace(const char *fmt, ...); 68.76 extern int event_fd; 68.77 68.78 #endif /* _XENSTORED_CORE_H */ 68.79 + 68.80 +/* 68.81 + * Local variables: 68.82 + * c-file-style: "linux" 68.83 + * indent-tabs-mode: t 68.84 + * c-indent-level: 8 68.85 + * c-basic-offset: 8 68.86 + * tab-width: 8 68.87 + * End: 68.88 + */
69.1 --- a/tools/xenstore/xenstored_domain.c Tue Oct 11 15:50:21 2005 -0600 69.2 +++ b/tools/xenstore/xenstored_domain.c Tue Oct 11 16:57:44 2005 -0600 69.3 @@ -53,6 +53,14 @@ struct domain 69.4 /* Event channel port */ 69.5 u16 port; 69.6 69.7 + /* The remote end of the event channel, used only to validate 69.8 + repeated domain introductions. */ 69.9 + u16 remote_port; 69.10 + 69.11 + /* The mfn associated with the event channel, used only to validate 69.12 + repeated domain introductions. */ 69.13 + unsigned long mfn; 69.14 + 69.15 /* Domain path in store. */ 69.16 char *path; 69.17 69.18 @@ -276,12 +284,13 @@ void handle_event(void) 69.19 69.20 bool domain_can_read(struct connection *conn) 69.21 { 69.22 - return conn->state == OK && buffer_has_input(conn->domain->input); 69.23 + return buffer_has_input(conn->domain->input); 69.24 } 69.25 69.26 bool domain_can_write(struct connection *conn) 69.27 { 69.28 - return conn->out && buffer_has_output_room(conn->domain->output); 69.29 + return (!list_empty(&conn->out_list) && 69.30 + buffer_has_output_room(conn->domain->output)); 69.31 } 69.32 69.33 static struct domain *new_domain(void *context, domid_t domid, 69.34 @@ -321,14 +330,35 @@ static struct domain *new_domain(void *c 69.35 domain->port = rc; 69.36 domain->conn = new_connection(writechn, readchn); 69.37 domain->conn->domain = domain; 69.38 + 69.39 + domain->remote_port = port; 69.40 + domain->mfn = mfn; 69.41 + 69.42 return domain; 69.43 } 69.44 69.45 + 69.46 +static struct domain *find_domain_by_domid(domid_t domid) 69.47 +{ 69.48 + struct domain *i; 69.49 + 69.50 + list_for_each_entry(i, &domains, list) { 69.51 + if (i->domid == domid) 69.52 + return i; 69.53 + } 69.54 + return NULL; 69.55 +} 69.56 + 69.57 + 69.58 /* domid, mfn, evtchn, path */ 69.59 void do_introduce(struct connection *conn, struct buffered_data *in) 69.60 { 69.61 struct domain *domain; 69.62 char *vec[4]; 69.63 + domid_t domid; 69.64 + unsigned long mfn; 69.65 + u16 port; 69.66 + const char *path; 69.67 69.68 if (get_strings(in, vec, ARRAY_SIZE(vec)) < ARRAY_SIZE(vec)) { 69.69 send_error(conn, EINVAL); 69.70 @@ -340,38 +370,46 @@ void do_introduce(struct connection *con 69.71 return; 69.72 } 69.73 69.74 + domid = atoi(vec[0]); 69.75 + mfn = atol(vec[1]); 69.76 + port = atoi(vec[2]); 69.77 + path = vec[3]; 69.78 + 69.79 /* Sanity check args. */ 69.80 - if ((atoi(vec[2]) <= 0) || !is_valid_nodename(vec[3])) { 69.81 + if ((port <= 0) || !is_valid_nodename(path)) { 69.82 send_error(conn, EINVAL); 69.83 return; 69.84 } 69.85 - /* Hang domain off "in" until we're finished. */ 69.86 - domain = new_domain(in, atoi(vec[0]), atol(vec[1]), atol(vec[2]), 69.87 - vec[3]); 69.88 - if (!domain) { 69.89 - send_error(conn, errno); 69.90 - return; 69.91 - } 69.92 69.93 - /* Now domain belongs to its connection. */ 69.94 - talloc_steal(domain->conn, domain); 69.95 + domain = find_domain_by_domid(domid); 69.96 + 69.97 + if (domain == NULL) { 69.98 + /* Hang domain off "in" until we're finished. */ 69.99 + domain = new_domain(in, domid, mfn, port, path); 69.100 + if (!domain) { 69.101 + send_error(conn, errno); 69.102 + return; 69.103 + } 69.104 + 69.105 + /* Now domain belongs to its connection. */ 69.106 + talloc_steal(domain->conn, domain); 69.107 69.108 - fire_watches(conn, "@introduceDomain", false); 69.109 + fire_watches(conn, "@introduceDomain", false); 69.110 + } 69.111 + else { 69.112 + /* Check that the given details match the ones we have 69.113 + previously recorded. */ 69.114 + if (port != domain->remote_port || 69.115 + mfn != domain->mfn || 69.116 + strcmp(path, domain->path) != 0) { 69.117 + send_error(conn, EINVAL); 69.118 + return; 69.119 + } 69.120 + } 69.121 69.122 send_ack(conn, XS_INTRODUCE); 69.123 } 69.124 69.125 -static struct domain *find_domain_by_domid(domid_t domid) 69.126 -{ 69.127 - struct domain *i; 69.128 - 69.129 - list_for_each_entry(i, &domains, list) { 69.130 - if (i->domid == domid) 69.131 - return i; 69.132 - } 69.133 - return NULL; 69.134 -} 69.135 - 69.136 /* domid */ 69.137 void do_release(struct connection *conn, const char *domid_str) 69.138 {
70.1 --- a/tools/xenstore/xenstored_transaction.c Tue Oct 11 15:50:21 2005 -0600 70.2 +++ b/tools/xenstore/xenstored_transaction.c Tue Oct 11 16:57:44 2005 -0600 70.3 @@ -37,7 +37,7 @@ 70.4 70.5 struct changed_node 70.6 { 70.7 - /* The list within this transaction. */ 70.8 + /* List of all changed nodes in the context of this transaction. */ 70.9 struct list_head list; 70.10 70.11 /* The name of the node. */ 70.12 @@ -49,15 +49,15 @@ struct changed_node 70.13 70.14 struct transaction 70.15 { 70.16 - /* Global list of transactions. */ 70.17 + /* List of all transactions active on this connection. */ 70.18 struct list_head list; 70.19 70.20 + /* Connection-local identifier for this transaction. */ 70.21 + u32 id; 70.22 + 70.23 /* Generation when transaction started. */ 70.24 unsigned int generation; 70.25 70.26 - /* My owner (conn->transaction == me). */ 70.27 - struct connection *conn; 70.28 - 70.29 /* TDB to work on, and filename */ 70.30 TDB_CONTEXT *tdb; 70.31 char *tdb_name; 70.32 @@ -65,7 +65,7 @@ struct transaction 70.33 /* List of changed nodes. */ 70.34 struct list_head changes; 70.35 }; 70.36 -static LIST_HEAD(transactions); 70.37 + 70.38 static unsigned int generation; 70.39 70.40 /* Return tdb context to use for this connection. */ 70.41 @@ -100,7 +100,6 @@ static int destroy_transaction(void *_tr 70.42 { 70.43 struct transaction *trans = _transaction; 70.44 70.45 - list_del(&trans->list); 70.46 trace_destroy(trans, "transaction"); 70.47 if (trans->tdb) 70.48 tdb_close(trans->tdb); 70.49 @@ -108,10 +107,26 @@ static int destroy_transaction(void *_tr 70.50 return 0; 70.51 } 70.52 70.53 -void do_transaction_start(struct connection *conn, struct buffered_data *in) 70.54 +struct transaction *transaction_lookup(struct connection *conn, u32 id) 70.55 { 70.56 struct transaction *trans; 70.57 70.58 + if (id == 0) 70.59 + return NULL; 70.60 + 70.61 + list_for_each_entry(trans, &conn->transaction_list, list) 70.62 + if (trans->id == id) 70.63 + return trans; 70.64 + 70.65 + return ERR_PTR(-ENOENT); 70.66 +} 70.67 + 70.68 +void do_transaction_start(struct connection *conn, struct buffered_data *in) 70.69 +{ 70.70 + struct transaction *trans, *exists; 70.71 + char id_str[20]; 70.72 + 70.73 + /* We don't support nested transactions. */ 70.74 if (conn->transaction) { 70.75 send_error(conn, EBUSY); 70.76 return; 70.77 @@ -120,7 +135,6 @@ void do_transaction_start(struct connect 70.78 /* Attach transaction to input for autofree until it's complete */ 70.79 trans = talloc(in, struct transaction); 70.80 INIT_LIST_HEAD(&trans->changes); 70.81 - trans->conn = conn; 70.82 trans->generation = generation; 70.83 trans->tdb_name = talloc_asprintf(trans, "%s.%p", 70.84 xs_daemon_tdb(), trans); 70.85 @@ -132,11 +146,19 @@ void do_transaction_start(struct connect 70.86 /* Make it close if we go away. */ 70.87 talloc_steal(trans, trans->tdb); 70.88 70.89 + /* Pick an unused transaction identifier. */ 70.90 + do { 70.91 + trans->id = conn->next_transaction_id; 70.92 + exists = transaction_lookup(conn, conn->next_transaction_id++); 70.93 + } while (!IS_ERR(exists)); 70.94 + 70.95 /* Now we own it. */ 70.96 - conn->transaction = talloc_steal(conn, trans); 70.97 - list_add_tail(&trans->list, &transactions); 70.98 + list_add_tail(&trans->list, &conn->transaction_list); 70.99 + talloc_steal(conn, trans); 70.100 talloc_set_destructor(trans, destroy_transaction); 70.101 - send_ack(conn, XS_TRANSACTION_START); 70.102 + 70.103 + sprintf(id_str, "%u", trans->id); 70.104 + send_reply(conn, XS_TRANSACTION_START, id_str, strlen(id_str)+1); 70.105 } 70.106 70.107 void do_transaction_end(struct connection *conn, const char *arg) 70.108 @@ -149,14 +171,14 @@ void do_transaction_end(struct connectio 70.109 return; 70.110 } 70.111 70.112 - if (!conn->transaction) { 70.113 + if ((trans = conn->transaction) == NULL) { 70.114 send_error(conn, ENOENT); 70.115 return; 70.116 } 70.117 70.118 - /* Set to NULL so fire_watches sends events, tdb_context works. */ 70.119 - trans = conn->transaction; 70.120 conn->transaction = NULL; 70.121 + list_del(&trans->list); 70.122 + 70.123 /* Attach transaction to arg for auto-cleanup */ 70.124 talloc_steal(arg, trans); 70.125 70.126 @@ -181,3 +203,12 @@ void do_transaction_end(struct connectio 70.127 send_ack(conn, XS_TRANSACTION_END); 70.128 } 70.129 70.130 +/* 70.131 + * Local variables: 70.132 + * c-file-style: "linux" 70.133 + * indent-tabs-mode: t 70.134 + * c-indent-level: 8 70.135 + * c-basic-offset: 8 70.136 + * tab-width: 8 70.137 + * End: 70.138 + */
71.1 --- a/tools/xenstore/xenstored_transaction.h Tue Oct 11 15:50:21 2005 -0600 71.2 +++ b/tools/xenstore/xenstored_transaction.h Tue Oct 11 16:57:44 2005 -0600 71.3 @@ -25,10 +25,11 @@ struct transaction; 71.4 void do_transaction_start(struct connection *conn, struct buffered_data *node); 71.5 void do_transaction_end(struct connection *conn, const char *arg); 71.6 71.7 -bool transaction_block(struct connection *conn); 71.8 +struct transaction *transaction_lookup(struct connection *conn, u32 id); 71.9 71.10 /* This node was changed: can fail and longjmp. */ 71.11 -void add_change_node(struct transaction *trans, const char *node, bool recurse); 71.12 +void add_change_node(struct transaction *trans, const char *node, 71.13 + bool recurse); 71.14 71.15 /* Return tdb context to use for this connection. */ 71.16 TDB_CONTEXT *tdb_transaction_context(struct transaction *trans);
72.1 --- a/tools/xenstore/xenstored_watch.c Tue Oct 11 15:50:21 2005 -0600 72.2 +++ b/tools/xenstore/xenstored_watch.c Tue Oct 11 16:57:44 2005 -0600 72.3 @@ -32,17 +32,6 @@ 72.4 #include "xenstored_test.h" 72.5 #include "xenstored_domain.h" 72.6 72.7 -/* FIXME: time out unacked watches. */ 72.8 -struct watch_event 72.9 -{ 72.10 - /* The events on this watch. */ 72.11 - struct list_head list; 72.12 - 72.13 - /* Data to send (node\0token\0). */ 72.14 - unsigned int len; 72.15 - char *data; 72.16 -}; 72.17 - 72.18 struct watch 72.19 { 72.20 /* Watches on this connection */ 72.21 @@ -58,54 +47,17 @@ struct watch 72.22 char *node; 72.23 }; 72.24 72.25 -/* Look through our watches: if any of them have an event, queue it. */ 72.26 -void queue_next_event(struct connection *conn) 72.27 -{ 72.28 - struct watch_event *event; 72.29 - struct watch *watch; 72.30 - 72.31 - /* We had a reply queued already? Send it: other end will 72.32 - * discard watch. */ 72.33 - if (conn->waiting_reply) { 72.34 - conn->out = conn->waiting_reply; 72.35 - conn->waiting_reply = NULL; 72.36 - conn->waiting_for_ack = NULL; 72.37 - return; 72.38 - } 72.39 - 72.40 - /* If we're already waiting for ack, don't queue more. */ 72.41 - if (conn->waiting_for_ack) 72.42 - return; 72.43 - 72.44 - list_for_each_entry(watch, &conn->watches, list) { 72.45 - event = list_top(&watch->events, struct watch_event, list); 72.46 - if (event) { 72.47 - conn->waiting_for_ack = watch; 72.48 - send_reply(conn,XS_WATCH_EVENT,event->data,event->len); 72.49 - break; 72.50 - } 72.51 - } 72.52 -} 72.53 - 72.54 -static int destroy_watch_event(void *_event) 72.55 -{ 72.56 - struct watch_event *event = _event; 72.57 - 72.58 - trace_destroy(event, "watch_event"); 72.59 - return 0; 72.60 -} 72.61 - 72.62 static void add_event(struct connection *conn, 72.63 struct watch *watch, 72.64 const char *name) 72.65 { 72.66 - struct watch_event *event; 72.67 + /* Data to send (node\0token\0). */ 72.68 + unsigned int len; 72.69 + char *data; 72.70 72.71 if (!check_event_node(name)) { 72.72 /* Can this conn load node, or see that it doesn't exist? */ 72.73 - struct node *node; 72.74 - 72.75 - node = get_node(conn, name, XS_PERM_READ); 72.76 + struct node *node = get_node(conn, name, XS_PERM_READ); 72.77 if (!node && errno != ENOENT) 72.78 return; 72.79 } 72.80 @@ -116,14 +68,12 @@ static void add_event(struct connection 72.81 name++; 72.82 } 72.83 72.84 - event = talloc(watch, struct watch_event); 72.85 - event->len = strlen(name) + 1 + strlen(watch->token) + 1; 72.86 - event->data = talloc_array(event, char, event->len); 72.87 - strcpy(event->data, name); 72.88 - strcpy(event->data + strlen(name) + 1, watch->token); 72.89 - talloc_set_destructor(event, destroy_watch_event); 72.90 - list_add_tail(&event->list, &watch->events); 72.91 - trace_create(event, "watch_event"); 72.92 + len = strlen(name) + 1 + strlen(watch->token) + 1; 72.93 + data = talloc_array(watch, char, len); 72.94 + strcpy(data, name); 72.95 + strcpy(data + strlen(name) + 1, watch->token); 72.96 + send_reply(conn, XS_WATCH_EVENT, data, len); 72.97 + talloc_free(data); 72.98 } 72.99 72.100 /* FIXME: we fail to fire on out of memory. Should drop connections. */ 72.101 @@ -143,11 +93,6 @@ void fire_watches(struct connection *con 72.102 add_event(i, watch, name); 72.103 else if (recurse && is_child(watch->node, name)) 72.104 add_event(i, watch, watch->node); 72.105 - else 72.106 - continue; 72.107 - /* If connection not doing anything, queue this. */ 72.108 - if (i->state == OK) 72.109 - queue_next_event(i); 72.110 } 72.111 } 72.112 } 72.113 @@ -181,6 +126,15 @@ void do_watch(struct connection *conn, s 72.114 } 72.115 } 72.116 72.117 + /* Check for duplicates. */ 72.118 + list_for_each_entry(watch, &conn->watches, list) { 72.119 + if (streq(watch->node, vec[0]) && 72.120 + streq(watch->token, vec[1])) { 72.121 + send_error(conn, EEXIST); 72.122 + return; 72.123 + } 72.124 + } 72.125 + 72.126 watch = talloc(conn, struct watch); 72.127 watch->node = talloc_strdup(watch, vec[0]); 72.128 watch->token = talloc_strdup(watch, vec[1]); 72.129 @@ -200,37 +154,6 @@ void do_watch(struct connection *conn, s 72.130 add_event(conn, watch, watch->node); 72.131 } 72.132 72.133 -void do_watch_ack(struct connection *conn, const char *token) 72.134 -{ 72.135 - struct watch_event *event; 72.136 - 72.137 - if (!token) { 72.138 - send_error(conn, EINVAL); 72.139 - return; 72.140 - } 72.141 - 72.142 - if (!conn->waiting_for_ack) { 72.143 - send_error(conn, ENOENT); 72.144 - return; 72.145 - } 72.146 - 72.147 - if (!streq(conn->waiting_for_ack->token, token)) { 72.148 - /* They're confused: this will cause us to send event again */ 72.149 - conn->waiting_for_ack = NULL; 72.150 - send_error(conn, EINVAL); 72.151 - return; 72.152 - } 72.153 - 72.154 - /* Remove event: after ack sent, core will call queue_next_event */ 72.155 - event = list_top(&conn->waiting_for_ack->events, struct watch_event, 72.156 - list); 72.157 - list_del(&event->list); 72.158 - talloc_free(event); 72.159 - 72.160 - conn->waiting_for_ack = NULL; 72.161 - send_ack(conn, XS_WATCH_ACK); 72.162 -} 72.163 - 72.164 void do_unwatch(struct connection *conn, struct buffered_data *in) 72.165 { 72.166 struct watch *watch; 72.167 @@ -241,9 +164,6 @@ void do_unwatch(struct connection *conn, 72.168 return; 72.169 } 72.170 72.171 - /* We don't need to worry if we're waiting for an ack for the 72.172 - * watch we're deleting: conn->waiting_for_ack was reset by 72.173 - * this command in consider_message anyway. */ 72.174 node = canonicalize(conn, vec[0]); 72.175 list_for_each_entry(watch, &conn->watches, list) { 72.176 if (streq(watch->node, node) && streq(watch->token, vec[1])) { 72.177 @@ -260,18 +180,19 @@ void do_unwatch(struct connection *conn, 72.178 void dump_watches(struct connection *conn) 72.179 { 72.180 struct watch *watch; 72.181 - struct watch_event *event; 72.182 72.183 - if (conn->waiting_for_ack) 72.184 - printf(" waiting_for_ack for watch on %s token %s\n", 72.185 - conn->waiting_for_ack->node, 72.186 - conn->waiting_for_ack->token); 72.187 - 72.188 - list_for_each_entry(watch, &conn->watches, list) { 72.189 + list_for_each_entry(watch, &conn->watches, list) 72.190 printf(" watch on %s token %s\n", 72.191 watch->node, watch->token); 72.192 - list_for_each_entry(event, &watch->events, list) 72.193 - printf(" event: %s\n", event->data); 72.194 - } 72.195 } 72.196 #endif 72.197 + 72.198 +/* 72.199 + * Local variables: 72.200 + * c-file-style: "linux" 72.201 + * indent-tabs-mode: t 72.202 + * c-indent-level: 8 72.203 + * c-basic-offset: 8 72.204 + * tab-width: 8 72.205 + * End: 72.206 + */
73.1 --- a/tools/xenstore/xenstored_watch.h Tue Oct 11 15:50:21 2005 -0600 73.2 +++ b/tools/xenstore/xenstored_watch.h Tue Oct 11 16:57:44 2005 -0600 73.3 @@ -23,17 +23,9 @@ 73.4 #include "xenstored_core.h" 73.5 73.6 void do_watch(struct connection *conn, struct buffered_data *in); 73.7 -void do_watch_ack(struct connection *conn, const char *token); 73.8 void do_unwatch(struct connection *conn, struct buffered_data *in); 73.9 73.10 -/* Is this a watch event message for this connection? */ 73.11 -bool is_watch_event(struct connection *conn, struct buffered_data *out); 73.12 - 73.13 -/* Look through our watches: if any of them have an event, queue it. */ 73.14 -void queue_next_event(struct connection *conn); 73.15 - 73.16 -/* Fire all watches: recurse means all the children are affected (ie. rm). 73.17 - */ 73.18 +/* Fire all watches: recurse means all the children are affected (ie. rm). */ 73.19 void fire_watches(struct connection *conn, const char *name, bool recurse); 73.20 73.21 void dump_watches(struct connection *conn);
74.1 --- a/tools/xenstore/xs.c Tue Oct 11 15:50:21 2005 -0600 74.2 +++ b/tools/xenstore/xs.c Tue Oct 11 16:57:44 2005 -0600 74.3 @@ -52,6 +52,7 @@ struct xs_handle { 74.4 * signals waiters. 74.5 */ 74.6 pthread_t read_thr; 74.7 + int read_thr_exists; 74.8 74.9 /* 74.10 * A list of fired watch messages, protected by a mutex. Users can 74.11 @@ -75,11 +76,9 @@ struct xs_handle { 74.12 74.13 /* One request at a time. */ 74.14 pthread_mutex_t request_mutex; 74.15 - 74.16 - /* One transaction at a time. */ 74.17 - pthread_mutex_t transaction_mutex; 74.18 }; 74.19 74.20 +static int read_message(struct xs_handle *h); 74.21 static void *read_thread(void *arg); 74.22 74.23 int xs_fileno(struct xs_handle *h) 74.24 @@ -134,7 +133,7 @@ static struct xs_handle *get_handle(cons 74.25 int fd = -1, saved_errno; 74.26 74.27 if (stat(connect_to, &buf) != 0) 74.28 - goto error; 74.29 + return NULL; 74.30 74.31 if (S_ISSOCK(buf.st_mode)) 74.32 fd = get_socket(connect_to); 74.33 @@ -142,11 +141,17 @@ static struct xs_handle *get_handle(cons 74.34 fd = get_dev(connect_to); 74.35 74.36 if (fd == -1) 74.37 - goto error; 74.38 + return NULL; 74.39 74.40 h = malloc(sizeof(*h)); 74.41 - if (h == NULL) 74.42 - goto error; 74.43 + if (h == NULL) { 74.44 + saved_errno = errno; 74.45 + close(fd); 74.46 + errno = saved_errno; 74.47 + return NULL; 74.48 + } 74.49 + 74.50 + memset(h, 0, sizeof(*h)); 74.51 74.52 h->fd = fd; 74.53 74.54 @@ -162,21 +167,8 @@ static struct xs_handle *get_handle(cons 74.55 pthread_cond_init(&h->reply_condvar, NULL); 74.56 74.57 pthread_mutex_init(&h->request_mutex, NULL); 74.58 - pthread_mutex_init(&h->transaction_mutex, NULL); 74.59 - 74.60 - if (pthread_create(&h->read_thr, NULL, read_thread, h) != 0) 74.61 - goto error; 74.62 74.63 return h; 74.64 - 74.65 - error: 74.66 - saved_errno = errno; 74.67 - if (h != NULL) 74.68 - free(h); 74.69 - if (fd != -1) 74.70 - close(fd); 74.71 - errno = saved_errno; 74.72 - return NULL; 74.73 } 74.74 74.75 struct xs_handle *xs_daemon_open(void) 74.76 @@ -198,14 +190,15 @@ void xs_daemon_close(struct xs_handle *h 74.77 { 74.78 struct xs_stored_msg *msg, *tmsg; 74.79 74.80 - pthread_mutex_lock(&h->transaction_mutex); 74.81 pthread_mutex_lock(&h->request_mutex); 74.82 pthread_mutex_lock(&h->reply_mutex); 74.83 pthread_mutex_lock(&h->watch_mutex); 74.84 74.85 - /* XXX FIXME: May leak an unpublished message buffer. */ 74.86 - pthread_cancel(h->read_thr); 74.87 - pthread_join(h->read_thr, NULL); 74.88 + if (h->read_thr_exists) { 74.89 + /* XXX FIXME: May leak an unpublished message buffer. */ 74.90 + pthread_cancel(h->read_thr); 74.91 + pthread_join(h->read_thr, NULL); 74.92 + } 74.93 74.94 list_for_each_entry_safe(msg, tmsg, &h->reply_list, list) { 74.95 free(msg->body); 74.96 @@ -217,7 +210,6 @@ void xs_daemon_close(struct xs_handle *h 74.97 free(msg); 74.98 } 74.99 74.100 - pthread_mutex_unlock(&h->transaction_mutex); 74.101 pthread_mutex_unlock(&h->request_mutex); 74.102 pthread_mutex_unlock(&h->reply_mutex); 74.103 pthread_mutex_unlock(&h->watch_mutex); 74.104 @@ -277,6 +269,10 @@ static void *read_reply( 74.105 struct xs_stored_msg *msg; 74.106 char *body; 74.107 74.108 + /* Read from comms channel ourselves if there is no reader thread. */ 74.109 + if (!h->read_thr_exists && (read_message(h) == -1)) 74.110 + return NULL; 74.111 + 74.112 pthread_mutex_lock(&h->reply_mutex); 74.113 while (list_empty(&h->reply_list)) 74.114 pthread_cond_wait(&h->reply_condvar, &h->reply_mutex); 74.115 @@ -296,8 +292,10 @@ static void *read_reply( 74.116 } 74.117 74.118 /* Send message to xs, get malloc'ed reply. NULL and set errno on error. */ 74.119 -static void *xs_talkv(struct xs_handle *h, enum xsd_sockmsg_type type, 74.120 - const struct iovec *iovec, unsigned int num_vecs, 74.121 +static void *xs_talkv(struct xs_handle *h, struct xs_transaction_handle *t, 74.122 + enum xsd_sockmsg_type type, 74.123 + const struct iovec *iovec, 74.124 + unsigned int num_vecs, 74.125 unsigned int *len) 74.126 { 74.127 struct xsd_sockmsg msg; 74.128 @@ -306,6 +304,7 @@ static void *xs_talkv(struct xs_handle * 74.129 unsigned int i; 74.130 struct sigaction ignorepipe, oldact; 74.131 74.132 + msg.tx_id = (u32)(unsigned long)t; 74.133 msg.type = type; 74.134 msg.len = 0; 74.135 for (i = 0; i < num_vecs; i++) 74.136 @@ -368,14 +367,16 @@ static void free_no_errno(void *p) 74.137 } 74.138 74.139 /* Simplified version of xs_talkv: single message. */ 74.140 -static void *xs_single(struct xs_handle *h, enum xsd_sockmsg_type type, 74.141 - const char *string, unsigned int *len) 74.142 +static void *xs_single(struct xs_handle *h, struct xs_transaction_handle *t, 74.143 + enum xsd_sockmsg_type type, 74.144 + const char *string, 74.145 + unsigned int *len) 74.146 { 74.147 struct iovec iovec; 74.148 74.149 iovec.iov_base = (void *)string; 74.150 iovec.iov_len = strlen(string) + 1; 74.151 - return xs_talkv(h, type, &iovec, 1, len); 74.152 + return xs_talkv(h, t, type, &iovec, 1, len); 74.153 } 74.154 74.155 static bool xs_bool(char *reply) 74.156 @@ -386,12 +387,13 @@ static bool xs_bool(char *reply) 74.157 return true; 74.158 } 74.159 74.160 -char **xs_directory(struct xs_handle *h, const char *path, unsigned int *num) 74.161 +char **xs_directory(struct xs_handle *h, struct xs_transaction_handle *t, 74.162 + const char *path, unsigned int *num) 74.163 { 74.164 char *strings, *p, **ret; 74.165 unsigned int len; 74.166 74.167 - strings = xs_single(h, XS_DIRECTORY, path, &len); 74.168 + strings = xs_single(h, t, XS_DIRECTORY, path, &len); 74.169 if (!strings) 74.170 return NULL; 74.171 74.172 @@ -417,16 +419,17 @@ char **xs_directory(struct xs_handle *h, 74.173 * Returns a malloced value: call free() on it after use. 74.174 * len indicates length in bytes, not including the nul. 74.175 */ 74.176 -void *xs_read(struct xs_handle *h, const char *path, unsigned int *len) 74.177 +void *xs_read(struct xs_handle *h, struct xs_transaction_handle *t, 74.178 + const char *path, unsigned int *len) 74.179 { 74.180 - return xs_single(h, XS_READ, path, len); 74.181 + return xs_single(h, t, XS_READ, path, len); 74.182 } 74.183 74.184 /* Write the value of a single file. 74.185 * Returns false on failure. 74.186 */ 74.187 -bool xs_write(struct xs_handle *h, const char *path, 74.188 - const void *data, unsigned int len) 74.189 +bool xs_write(struct xs_handle *h, struct xs_transaction_handle *t, 74.190 + const char *path, const void *data, unsigned int len) 74.191 { 74.192 struct iovec iovec[2]; 74.193 74.194 @@ -435,36 +438,40 @@ bool xs_write(struct xs_handle *h, const 74.195 iovec[1].iov_base = (void *)data; 74.196 iovec[1].iov_len = len; 74.197 74.198 - return xs_bool(xs_talkv(h, XS_WRITE, iovec, ARRAY_SIZE(iovec), NULL)); 74.199 + return xs_bool(xs_talkv(h, t, XS_WRITE, iovec, 74.200 + ARRAY_SIZE(iovec), NULL)); 74.201 } 74.202 74.203 /* Create a new directory. 74.204 * Returns false on failure, or success if it already exists. 74.205 */ 74.206 -bool xs_mkdir(struct xs_handle *h, const char *path) 74.207 +bool xs_mkdir(struct xs_handle *h, struct xs_transaction_handle *t, 74.208 + const char *path) 74.209 { 74.210 - return xs_bool(xs_single(h, XS_MKDIR, path, NULL)); 74.211 + return xs_bool(xs_single(h, t, XS_MKDIR, path, NULL)); 74.212 } 74.213 74.214 /* Destroy a file or directory (directories must be empty). 74.215 * Returns false on failure, or success if it doesn't exist. 74.216 */ 74.217 -bool xs_rm(struct xs_handle *h, const char *path) 74.218 +bool xs_rm(struct xs_handle *h, struct xs_transaction_handle *t, 74.219 + const char *path) 74.220 { 74.221 - return xs_bool(xs_single(h, XS_RM, path, NULL)); 74.222 + return xs_bool(xs_single(h, t, XS_RM, path, NULL)); 74.223 } 74.224 74.225 /* Get permissions of node (first element is owner). 74.226 * Returns malloced array, or NULL: call free() after use. 74.227 */ 74.228 struct xs_permissions *xs_get_permissions(struct xs_handle *h, 74.229 + struct xs_transaction_handle *t, 74.230 const char *path, unsigned int *num) 74.231 { 74.232 char *strings; 74.233 unsigned int len; 74.234 struct xs_permissions *ret; 74.235 74.236 - strings = xs_single(h, XS_GET_PERMS, path, &len); 74.237 + strings = xs_single(h, t, XS_GET_PERMS, path, &len); 74.238 if (!strings) 74.239 return NULL; 74.240 74.241 @@ -490,7 +497,9 @@ struct xs_permissions *xs_get_permission 74.242 /* Set permissions of node (must be owner). 74.243 * Returns false on failure. 74.244 */ 74.245 -bool xs_set_permissions(struct xs_handle *h, const char *path, 74.246 +bool xs_set_permissions(struct xs_handle *h, 74.247 + struct xs_transaction_handle *t, 74.248 + const char *path, 74.249 struct xs_permissions *perms, 74.250 unsigned int num_perms) 74.251 { 74.252 @@ -512,7 +521,7 @@ bool xs_set_permissions(struct xs_handle 74.253 goto unwind; 74.254 } 74.255 74.256 - if (!xs_bool(xs_talkv(h, XS_SET_PERMS, iov, 1+num_perms, NULL))) 74.257 + if (!xs_bool(xs_talkv(h, t, XS_SET_PERMS, iov, 1+num_perms, NULL))) 74.258 goto unwind; 74.259 for (i = 0; i < num_perms; i++) 74.260 free(iov[i+1].iov_base); 74.261 @@ -534,12 +543,24 @@ bool xs_watch(struct xs_handle *h, const 74.262 { 74.263 struct iovec iov[2]; 74.264 74.265 + /* We dynamically create a reader thread on demand. */ 74.266 + pthread_mutex_lock(&h->request_mutex); 74.267 + if (!h->read_thr_exists) { 74.268 + if (pthread_create(&h->read_thr, NULL, read_thread, h) != 0) { 74.269 + pthread_mutex_unlock(&h->request_mutex); 74.270 + return false; 74.271 + } 74.272 + h->read_thr_exists = 1; 74.273 + } 74.274 + pthread_mutex_unlock(&h->request_mutex); 74.275 + 74.276 iov[0].iov_base = (void *)path; 74.277 iov[0].iov_len = strlen(path) + 1; 74.278 iov[1].iov_base = (void *)token; 74.279 iov[1].iov_len = strlen(token) + 1; 74.280 74.281 - return xs_bool(xs_talkv(h, XS_WATCH, iov, ARRAY_SIZE(iov), NULL)); 74.282 + return xs_bool(xs_talkv(h, NULL, XS_WATCH, iov, 74.283 + ARRAY_SIZE(iov), NULL)); 74.284 } 74.285 74.286 /* Find out what node change was on (will block if nothing pending). 74.287 @@ -593,15 +614,6 @@ char **xs_read_watch(struct xs_handle *h 74.288 return ret; 74.289 } 74.290 74.291 -/* Acknowledge watch on node. Watches must be acknowledged before 74.292 - * any other watches can be read. 74.293 - * Returns false on failure. 74.294 - */ 74.295 -bool xs_acknowledge_watch(struct xs_handle *h, const char *token) 74.296 -{ 74.297 - return xs_bool(xs_single(h, XS_WATCH_ACK, token, NULL)); 74.298 -} 74.299 - 74.300 /* Remove a watch on a node. 74.301 * Returns false on failure (no watch on that node). 74.302 */ 74.303 @@ -614,18 +626,28 @@ bool xs_unwatch(struct xs_handle *h, con 74.304 iov[1].iov_base = (char *)token; 74.305 iov[1].iov_len = strlen(token) + 1; 74.306 74.307 - return xs_bool(xs_talkv(h, XS_UNWATCH, iov, ARRAY_SIZE(iov), NULL)); 74.308 + return xs_bool(xs_talkv(h, NULL, XS_UNWATCH, iov, 74.309 + ARRAY_SIZE(iov), NULL)); 74.310 } 74.311 74.312 /* Start a transaction: changes by others will not be seen during this 74.313 * transaction, and changes will not be visible to others until end. 74.314 * You can only have one transaction at any time. 74.315 - * Returns false on failure. 74.316 + * Returns NULL on failure. 74.317 */ 74.318 -bool xs_transaction_start(struct xs_handle *h) 74.319 +struct xs_transaction_handle *xs_transaction_start(struct xs_handle *h) 74.320 { 74.321 - pthread_mutex_lock(&h->transaction_mutex); 74.322 - return xs_bool(xs_single(h, XS_TRANSACTION_START, "", NULL)); 74.323 + char *id_str; 74.324 + unsigned long id; 74.325 + 74.326 + id_str = xs_single(h, NULL, XS_TRANSACTION_START, "", NULL); 74.327 + if (id_str == NULL) 74.328 + return NULL; 74.329 + 74.330 + id = strtoul(id_str, NULL, 0); 74.331 + free(id_str); 74.332 + 74.333 + return (struct xs_transaction_handle *)id; 74.334 } 74.335 74.336 /* End a transaction. 74.337 @@ -633,21 +655,17 @@ bool xs_transaction_start(struct xs_hand 74.338 * Returns false on failure, which indicates an error: transactions will 74.339 * not fail spuriously. 74.340 */ 74.341 -bool xs_transaction_end(struct xs_handle *h, bool abort) 74.342 +bool xs_transaction_end(struct xs_handle *h, struct xs_transaction_handle *t, 74.343 + bool abort) 74.344 { 74.345 char abortstr[2]; 74.346 - bool rc; 74.347 74.348 if (abort) 74.349 strcpy(abortstr, "F"); 74.350 else 74.351 strcpy(abortstr, "T"); 74.352 74.353 - rc = xs_bool(xs_single(h, XS_TRANSACTION_END, abortstr, NULL)); 74.354 - 74.355 - pthread_mutex_unlock(&h->transaction_mutex); 74.356 - 74.357 - return rc; 74.358 + return xs_bool(xs_single(h, t, XS_TRANSACTION_END, abortstr, NULL)); 74.359 } 74.360 74.361 /* Introduce a new domain. 74.362 @@ -675,7 +693,8 @@ bool xs_introduce_domain(struct xs_handl 74.363 iov[3].iov_base = (char *)path; 74.364 iov[3].iov_len = strlen(path) + 1; 74.365 74.366 - return xs_bool(xs_talkv(h, XS_INTRODUCE, iov, ARRAY_SIZE(iov), NULL)); 74.367 + return xs_bool(xs_talkv(h, NULL, XS_INTRODUCE, iov, 74.368 + ARRAY_SIZE(iov), NULL)); 74.369 } 74.370 74.371 bool xs_release_domain(struct xs_handle *h, domid_t domid) 74.372 @@ -684,7 +703,7 @@ bool xs_release_domain(struct xs_handle 74.373 74.374 sprintf(domid_str, "%u", domid); 74.375 74.376 - return xs_bool(xs_single(h, XS_RELEASE, domid_str, NULL)); 74.377 + return xs_bool(xs_single(h, NULL, XS_RELEASE, domid_str, NULL)); 74.378 } 74.379 74.380 char *xs_get_domain_path(struct xs_handle *h, domid_t domid) 74.381 @@ -693,7 +712,7 @@ char *xs_get_domain_path(struct xs_handl 74.382 74.383 sprintf(domid_str, "%u", domid); 74.384 74.385 - return xs_single(h, XS_GET_DOMAIN_PATH, domid_str, NULL); 74.386 + return xs_single(h, NULL, XS_GET_DOMAIN_PATH, domid_str, NULL); 74.387 } 74.388 74.389 /* Only useful for DEBUG versions */ 74.390 @@ -707,68 +726,76 @@ char *xs_debug_command(struct xs_handle 74.391 iov[1].iov_base = data; 74.392 iov[1].iov_len = len; 74.393 74.394 - return xs_talkv(h, XS_DEBUG, iov, ARRAY_SIZE(iov), NULL); 74.395 + return xs_talkv(h, NULL, XS_DEBUG, iov, 74.396 + ARRAY_SIZE(iov), NULL); 74.397 +} 74.398 + 74.399 +static int read_message(struct xs_handle *h) 74.400 +{ 74.401 + struct xs_stored_msg *msg = NULL; 74.402 + char *body = NULL; 74.403 + int saved_errno; 74.404 + 74.405 + /* Allocate message structure and read the message header. */ 74.406 + msg = malloc(sizeof(*msg)); 74.407 + if (msg == NULL) 74.408 + goto error; 74.409 + if (!read_all(h->fd, &msg->hdr, sizeof(msg->hdr))) 74.410 + goto error; 74.411 + 74.412 + /* Allocate and read the message body. */ 74.413 + body = msg->body = malloc(msg->hdr.len + 1); 74.414 + if (body == NULL) 74.415 + goto error; 74.416 + if (!read_all(h->fd, body, msg->hdr.len)) 74.417 + goto error; 74.418 + body[msg->hdr.len] = '\0'; 74.419 + 74.420 + if (msg->hdr.type == XS_WATCH_EVENT) { 74.421 + pthread_mutex_lock(&h->watch_mutex); 74.422 + 74.423 + /* Kick users out of their select() loop. */ 74.424 + if (list_empty(&h->watch_list) && 74.425 + (h->watch_pipe[1] != -1)) 74.426 + while (write(h->watch_pipe[1], body, 1) != 1) 74.427 + continue; 74.428 + 74.429 + list_add_tail(&msg->list, &h->watch_list); 74.430 + pthread_cond_signal(&h->watch_condvar); 74.431 + 74.432 + pthread_mutex_unlock(&h->watch_mutex); 74.433 + } else { 74.434 + pthread_mutex_lock(&h->reply_mutex); 74.435 + 74.436 + /* There should only ever be one response pending! */ 74.437 + if (!list_empty(&h->reply_list)) { 74.438 + pthread_mutex_unlock(&h->reply_mutex); 74.439 + goto error; 74.440 + } 74.441 + 74.442 + list_add_tail(&msg->list, &h->reply_list); 74.443 + pthread_cond_signal(&h->reply_condvar); 74.444 + 74.445 + pthread_mutex_unlock(&h->reply_mutex); 74.446 + } 74.447 + 74.448 + return 0; 74.449 + 74.450 + error: 74.451 + saved_errno = errno; 74.452 + free(msg); 74.453 + free(body); 74.454 + errno = saved_errno; 74.455 + return -1; 74.456 } 74.457 74.458 static void *read_thread(void *arg) 74.459 { 74.460 struct xs_handle *h = arg; 74.461 - struct xs_stored_msg *msg = NULL; 74.462 - char *body = NULL; 74.463 - 74.464 - for (;;) { 74.465 - msg = NULL; 74.466 - body = NULL; 74.467 - 74.468 - /* Allocate message structure and read the message header. */ 74.469 - msg = malloc(sizeof(*msg)); 74.470 - if (msg == NULL) 74.471 - goto error; 74.472 - if (!read_all(h->fd, &msg->hdr, sizeof(msg->hdr))) 74.473 - goto error; 74.474 - 74.475 - /* Allocate and read the message body. */ 74.476 - body = msg->body = malloc(msg->hdr.len + 1); 74.477 - if (body == NULL) 74.478 - goto error; 74.479 - if (!read_all(h->fd, body, msg->hdr.len)) 74.480 - goto error; 74.481 - body[msg->hdr.len] = '\0'; 74.482 - 74.483 - if (msg->hdr.type == XS_WATCH_EVENT) { 74.484 - pthread_mutex_lock(&h->watch_mutex); 74.485 74.486 - /* Kick users out of their select() loop. */ 74.487 - if (list_empty(&h->watch_list) && 74.488 - (h->watch_pipe[1] != -1)) 74.489 - while (write(h->watch_pipe[1], body, 1) != 1) 74.490 - continue; 74.491 - 74.492 - list_add_tail(&msg->list, &h->watch_list); 74.493 - pthread_cond_signal(&h->watch_condvar); 74.494 - 74.495 - pthread_mutex_unlock(&h->watch_mutex); 74.496 - } else { 74.497 - pthread_mutex_lock(&h->reply_mutex); 74.498 + while (read_message(h) != -1) 74.499 + continue; 74.500 74.501 - /* There should only ever be one response pending! */ 74.502 - if (!list_empty(&h->reply_list)) { 74.503 - pthread_mutex_unlock(&h->reply_mutex); 74.504 - goto error; 74.505 - } 74.506 - 74.507 - list_add_tail(&msg->list, &h->reply_list); 74.508 - pthread_cond_signal(&h->reply_condvar); 74.509 - 74.510 - pthread_mutex_unlock(&h->reply_mutex); 74.511 - } 74.512 - } 74.513 - 74.514 - error: 74.515 - if (body != NULL) 74.516 - free(body); 74.517 - if (msg != NULL) 74.518 - free(msg); 74.519 return NULL; 74.520 } 74.521
75.1 --- a/tools/xenstore/xs.h Tue Oct 11 15:50:21 2005 -0600 75.2 +++ b/tools/xenstore/xs.h Tue Oct 11 16:57:44 2005 -0600 75.3 @@ -23,6 +23,7 @@ 75.4 #include <xs_lib.h> 75.5 75.6 struct xs_handle; 75.7 +struct xs_transaction_handle; 75.8 75.9 /* On failure, these routines set errno. */ 75.10 75.11 @@ -44,41 +45,47 @@ void xs_daemon_close(struct xs_handle *) 75.12 * Returns a malloced array: call free() on it after use. 75.13 * Num indicates size. 75.14 */ 75.15 -char **xs_directory(struct xs_handle *h, const char *path, unsigned int *num); 75.16 +char **xs_directory(struct xs_handle *h, struct xs_transaction_handle *t, 75.17 + const char *path, unsigned int *num); 75.18 75.19 /* Get the value of a single file, nul terminated. 75.20 * Returns a malloced value: call free() on it after use. 75.21 * len indicates length in bytes, not including terminator. 75.22 */ 75.23 -void *xs_read(struct xs_handle *h, const char *path, unsigned int *len); 75.24 +void *xs_read(struct xs_handle *h, struct xs_transaction_handle *t, 75.25 + const char *path, unsigned int *len); 75.26 75.27 /* Write the value of a single file. 75.28 * Returns false on failure. 75.29 */ 75.30 -bool xs_write(struct xs_handle *h, const char *path, const void *data, 75.31 - unsigned int len); 75.32 +bool xs_write(struct xs_handle *h, struct xs_transaction_handle *t, 75.33 + const char *path, const void *data, unsigned int len); 75.34 75.35 /* Create a new directory. 75.36 * Returns false on failure, or success if it already exists. 75.37 */ 75.38 -bool xs_mkdir(struct xs_handle *h, const char *path); 75.39 +bool xs_mkdir(struct xs_handle *h, struct xs_transaction_handle *t, 75.40 + const char *path); 75.41 75.42 /* Destroy a file or directory (and children). 75.43 * Returns false on failure, or success if it doesn't exist. 75.44 */ 75.45 -bool xs_rm(struct xs_handle *h, const char *path); 75.46 +bool xs_rm(struct xs_handle *h, struct xs_transaction_handle *t, 75.47 + const char *path); 75.48 75.49 /* Get permissions of node (first element is owner, first perms is "other"). 75.50 * Returns malloced array, or NULL: call free() after use. 75.51 */ 75.52 struct xs_permissions *xs_get_permissions(struct xs_handle *h, 75.53 + struct xs_transaction_handle *t, 75.54 const char *path, unsigned int *num); 75.55 75.56 /* Set permissions of node (must be owner). 75.57 * Returns false on failure. 75.58 */ 75.59 -bool xs_set_permissions(struct xs_handle *h, const char *path, 75.60 - struct xs_permissions *perms, unsigned int num_perms); 75.61 +bool xs_set_permissions(struct xs_handle *h, struct xs_transaction_handle *t, 75.62 + const char *path, struct xs_permissions *perms, 75.63 + unsigned int num_perms); 75.64 75.65 /* Watch a node for changes (poll on fd to detect, or call read_watch()). 75.66 * When the node (or any child) changes, fd will become readable. 75.67 @@ -96,12 +103,6 @@ int xs_fileno(struct xs_handle *h); 75.68 */ 75.69 char **xs_read_watch(struct xs_handle *h, unsigned int *num); 75.70 75.71 -/* Acknowledge watch on node. Watches must be acknowledged before 75.72 - * any other watches can be read. 75.73 - * Returns false on failure. 75.74 - */ 75.75 -bool xs_acknowledge_watch(struct xs_handle *h, const char *token); 75.76 - 75.77 /* Remove a watch on a node: implicitly acks any outstanding watch. 75.78 * Returns false on failure (no watch on that node). 75.79 */ 75.80 @@ -110,16 +111,17 @@ bool xs_unwatch(struct xs_handle *h, con 75.81 /* Start a transaction: changes by others will not be seen during this 75.82 * transaction, and changes will not be visible to others until end. 75.83 * You can only have one transaction at any time. 75.84 - * Returns false on failure. 75.85 + * Returns NULL on failure. 75.86 */ 75.87 -bool xs_transaction_start(struct xs_handle *h); 75.88 +struct xs_transaction_handle *xs_transaction_start(struct xs_handle *h); 75.89 75.90 /* End a transaction. 75.91 * If abandon is true, transaction is discarded instead of committed. 75.92 * Returns false on failure: if errno == EAGAIN, you have to restart 75.93 * transaction. 75.94 */ 75.95 -bool xs_transaction_end(struct xs_handle *h, bool abort); 75.96 +bool xs_transaction_end(struct xs_handle *h, struct xs_transaction_handle *t, 75.97 + bool abort); 75.98 75.99 /* Introduce a new domain. 75.100 * This tells the store daemon about a shared memory page, event channel 75.101 @@ -142,3 +144,13 @@ char *xs_debug_command(struct xs_handle 75.102 void *data, unsigned int len); 75.103 75.104 #endif /* _XS_H */ 75.105 + 75.106 +/* 75.107 + * Local variables: 75.108 + * c-file-style: "linux" 75.109 + * indent-tabs-mode: t 75.110 + * c-indent-level: 8 75.111 + * c-basic-offset: 8 75.112 + * tab-width: 8 75.113 + * End: 75.114 + */
76.1 --- a/tools/xenstore/xs_test.c Tue Oct 11 15:50:21 2005 -0600 76.2 +++ b/tools/xenstore/xs_test.c Tue Oct 11 16:57:44 2005 -0600 76.3 @@ -42,6 +42,7 @@ 76.4 #define XSTEST 76.5 76.6 static struct xs_handle *handles[10] = { NULL }; 76.7 +static struct xs_transaction_handle *txh[10] = { NULL }; 76.8 76.9 static unsigned int timeout_ms = 500; 76.10 static bool timeout_suppressed = true; 76.11 @@ -201,7 +202,6 @@ static void __attribute__((noreturn)) us 76.12 " watch <path> <token>\n" 76.13 " watchnoack <path> <token>\n" 76.14 " waitwatch\n" 76.15 - " ackwatch <token>\n" 76.16 " unwatch <path> <token>\n" 76.17 " close\n" 76.18 " start <node>\n" 76.19 @@ -313,7 +313,7 @@ static void do_dir(unsigned int handle, 76.20 char **entries; 76.21 unsigned int i, num; 76.22 76.23 - entries = xs_directory(handles[handle], path, &num); 76.24 + entries = xs_directory(handles[handle], txh[handle], path, &num); 76.25 if (!entries) { 76.26 failed(handle); 76.27 return; 76.28 @@ -332,7 +332,7 @@ static void do_read(unsigned int handle, 76.29 char *value; 76.30 unsigned int len; 76.31 76.32 - value = xs_read(handles[handle], path, &len); 76.33 + value = xs_read(handles[handle], txh[handle], path, &len); 76.34 if (!value) { 76.35 failed(handle); 76.36 return; 76.37 @@ -348,7 +348,7 @@ static void do_read(unsigned int handle, 76.38 76.39 static void do_write(unsigned int handle, char *path, char *data) 76.40 { 76.41 - if (!xs_write(handles[handle], path, data, strlen(data))) 76.42 + if (!xs_write(handles[handle], txh[handle], path, data, strlen(data))) 76.43 failed(handle); 76.44 } 76.45 76.46 @@ -361,13 +361,13 @@ static void do_setid(unsigned int handle 76.47 76.48 static void do_mkdir(unsigned int handle, char *path) 76.49 { 76.50 - if (!xs_mkdir(handles[handle], path)) 76.51 + if (!xs_mkdir(handles[handle], txh[handle], path)) 76.52 failed(handle); 76.53 } 76.54 76.55 static void do_rm(unsigned int handle, char *path) 76.56 { 76.57 - if (!xs_rm(handles[handle], path)) 76.58 + if (!xs_rm(handles[handle], txh[handle], path)) 76.59 failed(handle); 76.60 } 76.61 76.62 @@ -376,7 +376,7 @@ static void do_getperm(unsigned int hand 76.63 unsigned int i, num; 76.64 struct xs_permissions *perms; 76.65 76.66 - perms = xs_get_permissions(handles[handle], path, &num); 76.67 + perms = xs_get_permissions(handles[handle], txh[handle], path, &num); 76.68 if (!perms) { 76.69 failed(handle); 76.70 return; 76.71 @@ -437,7 +437,7 @@ static void do_setperm(unsigned int hand 76.72 barf("bad flags %s\n", arg); 76.73 } 76.74 76.75 - if (!xs_set_permissions(handles[handle], path, perms, i)) 76.76 + if (!xs_set_permissions(handles[handle], txh[handle], path, perms, i)) 76.77 failed(handle); 76.78 } 76.79 76.80 @@ -455,8 +455,6 @@ static void do_watch(unsigned int handle 76.81 !streq(vec[XS_WATCH_PATH], node) || 76.82 !streq(vec[XS_WATCH_TOKEN], token)) 76.83 failed(handle); 76.84 - if (!xs_acknowledge_watch(handles[handle], token)) 76.85 - failed(handle); 76.86 } 76.87 } 76.88 76.89 @@ -515,12 +513,6 @@ static void do_waitwatch(unsigned int ha 76.90 free(vec); 76.91 } 76.92 76.93 -static void do_ackwatch(unsigned int handle, const char *token) 76.94 -{ 76.95 - if (!xs_acknowledge_watch(handles[handle], token)) 76.96 - failed(handle); 76.97 -} 76.98 - 76.99 static void do_unwatch(unsigned int handle, const char *node, const char *token) 76.100 { 76.101 if (!xs_unwatch(handles[handle], node, token)) 76.102 @@ -529,14 +521,16 @@ static void do_unwatch(unsigned int hand 76.103 76.104 static void do_start(unsigned int handle) 76.105 { 76.106 - if (!xs_transaction_start(handles[handle])) 76.107 + txh[handle] = xs_transaction_start(handles[handle]); 76.108 + if (txh[handle] == NULL) 76.109 failed(handle); 76.110 } 76.111 76.112 static void do_end(unsigned int handle, bool abort) 76.113 { 76.114 - if (!xs_transaction_end(handles[handle], abort)) 76.115 + if (!xs_transaction_end(handles[handle], txh[handle], abort)) 76.116 failed(handle); 76.117 + txh[handle] = NULL; 76.118 } 76.119 76.120 static void do_introduce(unsigned int handle, 76.121 @@ -626,7 +620,8 @@ static void dump_dir(unsigned int handle 76.122 76.123 sprintf(subnode, "%s/%s", node, dir[i]); 76.124 76.125 - perms = xs_get_permissions(handles[handle], subnode,&numperms); 76.126 + perms = xs_get_permissions(handles[handle], txh[handle], 76.127 + subnode,&numperms); 76.128 if (!perms) { 76.129 failed(handle); 76.130 return; 76.131 @@ -643,7 +638,8 @@ static void dump_dir(unsigned int handle 76.132 output("\n"); 76.133 76.134 /* Even directories can have contents. */ 76.135 - contents = xs_read(handles[handle], subnode, &len); 76.136 + contents = xs_read(handles[handle], txh[handle], 76.137 + subnode, &len); 76.138 if (!contents) { 76.139 if (errno != EISDIR) 76.140 failed(handle); 76.141 @@ -653,7 +649,8 @@ static void dump_dir(unsigned int handle 76.142 } 76.143 76.144 /* Every node is a directory. */ 76.145 - subdirs = xs_directory(handles[handle], subnode, &subnum); 76.146 + subdirs = xs_directory(handles[handle], txh[handle], 76.147 + subnode, &subnum); 76.148 if (!subdirs) { 76.149 failed(handle); 76.150 return; 76.151 @@ -668,7 +665,7 @@ static void dump(int handle) 76.152 char **subdirs; 76.153 unsigned int subnum; 76.154 76.155 - subdirs = xs_directory(handles[handle], "/", &subnum); 76.156 + subdirs = xs_directory(handles[handle], txh[handle], "/", &subnum); 76.157 if (!subdirs) { 76.158 failed(handle); 76.159 return; 76.160 @@ -746,13 +743,12 @@ static void do_command(unsigned int defa 76.161 do_watch(handle, arg(line, 1), arg(line, 2), false); 76.162 else if (streq(command, "waitwatch")) 76.163 do_waitwatch(handle); 76.164 - else if (streq(command, "ackwatch")) 76.165 - do_ackwatch(handle, arg(line, 1)); 76.166 else if (streq(command, "unwatch")) 76.167 do_unwatch(handle, arg(line, 1), arg(line, 2)); 76.168 else if (streq(command, "close")) { 76.169 xs_daemon_close(handles[handle]); 76.170 handles[handle] = NULL; 76.171 + txh[handle] = NULL; 76.172 } else if (streq(command, "start")) 76.173 do_start(handle); 76.174 else if (streq(command, "commit")) 76.175 @@ -836,3 +832,13 @@ int main(int argc, char *argv[]) 76.176 76.177 return 0; 76.178 } 76.179 + 76.180 +/* 76.181 + * Local variables: 76.182 + * c-file-style: "linux" 76.183 + * indent-tabs-mode: t 76.184 + * c-indent-level: 8 76.185 + * c-basic-offset: 8 76.186 + * tab-width: 8 76.187 + * End: 76.188 + */
77.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 77.2 +++ b/tools/xenstore/xsls.c Tue Oct 11 16:57:44 2005 -0600 77.3 @@ -0,0 +1,47 @@ 77.4 +#include <stdio.h> 77.5 +#include <stdlib.h> 77.6 +#include <string.h> 77.7 +#include <err.h> 77.8 +#include <xs.h> 77.9 + 77.10 +void print_dir(struct xs_handle *h, char *path, int cur_depth) 77.11 +{ 77.12 + char **e; 77.13 + char newpath[512], *val; 77.14 + int num, i, len; 77.15 + 77.16 + e = xs_directory(h, NULL, path, &num); 77.17 + if (e == NULL) 77.18 + err(1, "xs_directory (%s)", path); 77.19 + 77.20 + for (i = 0; i<num; i++) { 77.21 + int j; 77.22 + for (j=0; j<cur_depth; j++) printf(" "); 77.23 + printf("%s", e[i]); 77.24 + sprintf(newpath, "%s%s%s", path, 77.25 + path[strlen(path)-1] == '/' ? "" : "/", 77.26 + e[i]); 77.27 + val = xs_read(h, NULL, newpath, &len); 77.28 + if (val == NULL) 77.29 + printf(":\n"); 77.30 + else if ((unsigned)len > (151 - strlen(e[i]))) 77.31 + printf(" = \"%.*s...\"\n", 148 - strlen(e[i]), val); 77.32 + else 77.33 + printf(" = \"%s\"\n", val); 77.34 + free(val); 77.35 + print_dir(h, newpath, cur_depth+1); 77.36 + } 77.37 + free(e); 77.38 +} 77.39 + 77.40 +int main(int argc, char *argv[]) 77.41 +{ 77.42 + struct xs_handle *xsh = xs_daemon_open(); 77.43 + 77.44 + if (xsh == NULL) 77.45 + err(1, "xs_daemon_open"); 77.46 + 77.47 + print_dir(xsh, argc == 1 ? "/" : argv[1], 0); 77.48 + 77.49 + return 0; 77.50 +}
78.1 --- a/xen/Makefile Tue Oct 11 15:50:21 2005 -0600 78.2 +++ b/xen/Makefile Tue Oct 11 16:57:44 2005 -0600 78.3 @@ -95,7 +95,7 @@ include/xen/compile.h: include/xen/compi 78.4 -e 's/@@version@@/$(XEN_VERSION)/g' \ 78.5 -e 's/@@subversion@@/$(XEN_SUBVERSION)/g' \ 78.6 -e 's/@@extraversion@@/$(XEN_EXTRAVERSION)/g' \ 78.7 - -e 's!@@changeset@@!$(shell (hg parents | awk -F: '/^changeset/{CS=$$3};{FS="date:[ ]+"}/^date/{D=$$2}; END {print D, CS}') 2>/dev/null || (head -n 6 ChangeLog | awk -F: '/^changeset/{CS=$$3};{FS="date:[ ]+"}/^date/{D=$$2}; END {print D, CS}') 2>/dev/null || echo information unavailable)!g' \ 78.8 + -e 's!@@changeset@@!$(shell ((hg parents || head -n 7 ../ChangeLog || echo date: unavailable) | awk '{FS="changeset:[ ]+"}/^changeset/{CS=$$2};{FS="date:[ ]+"}/^date/{D=$$2}; END {print D, CS}') 2>/dev/null)!g' \ 78.9 < include/xen/compile.h.in > $@.new 78.10 @cat include/xen/banner.h >> $@.new 78.11 @mv -f $@.new $@
79.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 79.2 +++ b/xen/include/public/io/console.h Tue Oct 11 16:57:44 2005 -0600 79.3 @@ -0,0 +1,23 @@ 79.4 +/****************************************************************************** 79.5 + * console.h 79.6 + * 79.7 + * Console I/O interface for Xen guest OSes. 79.8 + * 79.9 + * Copyright (c) 2005, Keir Fraser 79.10 + */ 79.11 + 79.12 +#ifndef __XEN_PUBLIC_IO_CONSOLE_H__ 79.13 +#define __XEN_PUBLIC_IO_CONSOLE_H__ 79.14 + 79.15 +typedef u32 XENCONS_RING_IDX; 79.16 + 79.17 +#define MASK_XENCONS_IDX(idx, ring) ((idx) & (sizeof(ring)-1)) 79.18 + 79.19 +struct xencons_interface { 79.20 + char in[1024]; 79.21 + char out[2048]; 79.22 + XENCONS_RING_IDX in_cons, in_prod; 79.23 + XENCONS_RING_IDX out_cons, out_prod; 79.24 +}; 79.25 + 79.26 +#endif /* __XEN_PUBLIC_IO_CONSOLE_H__ */
80.1 --- a/xen/include/public/io/xs_wire.h Tue Oct 11 15:50:21 2005 -0600 80.2 +++ b/xen/include/public/io/xs_wire.h Tue Oct 11 16:57:44 2005 -0600 80.3 @@ -30,25 +30,23 @@ 80.4 80.5 enum xsd_sockmsg_type 80.6 { 80.7 - XS_DEBUG, 80.8 - XS_DIRECTORY, 80.9 - XS_READ, 80.10 - XS_GET_PERMS, 80.11 - XS_WATCH, 80.12 - XS_WATCH_ACK, 80.13 - XS_UNWATCH, 80.14 - XS_TRANSACTION_START, 80.15 - XS_TRANSACTION_END, 80.16 - XS_OP_READ_ONLY = XS_TRANSACTION_END, 80.17 - XS_INTRODUCE, 80.18 - XS_RELEASE, 80.19 - XS_GET_DOMAIN_PATH, 80.20 - XS_WRITE, 80.21 - XS_MKDIR, 80.22 - XS_RM, 80.23 - XS_SET_PERMS, 80.24 - XS_WATCH_EVENT, 80.25 - XS_ERROR, 80.26 + XS_DEBUG, 80.27 + XS_DIRECTORY, 80.28 + XS_READ, 80.29 + XS_GET_PERMS, 80.30 + XS_WATCH, 80.31 + XS_UNWATCH, 80.32 + XS_TRANSACTION_START, 80.33 + XS_TRANSACTION_END, 80.34 + XS_INTRODUCE, 80.35 + XS_RELEASE, 80.36 + XS_GET_DOMAIN_PATH, 80.37 + XS_WRITE, 80.38 + XS_MKDIR, 80.39 + XS_RM, 80.40 + XS_SET_PERMS, 80.41 + XS_WATCH_EVENT, 80.42 + XS_ERROR, 80.43 }; 80.44 80.45 #define XS_WRITE_NONE "NONE" 80.46 @@ -58,38 +56,40 @@ enum xsd_sockmsg_type 80.47 /* We hand errors as strings, for portability. */ 80.48 struct xsd_errors 80.49 { 80.50 - int errnum; 80.51 - const char *errstring; 80.52 + int errnum; 80.53 + const char *errstring; 80.54 }; 80.55 #define XSD_ERROR(x) { x, #x } 80.56 static struct xsd_errors xsd_errors[] __attribute__((unused)) = { 80.57 - XSD_ERROR(EINVAL), 80.58 - XSD_ERROR(EACCES), 80.59 - XSD_ERROR(EEXIST), 80.60 - XSD_ERROR(EISDIR), 80.61 - XSD_ERROR(ENOENT), 80.62 - XSD_ERROR(ENOMEM), 80.63 - XSD_ERROR(ENOSPC), 80.64 - XSD_ERROR(EIO), 80.65 - XSD_ERROR(ENOTEMPTY), 80.66 - XSD_ERROR(ENOSYS), 80.67 - XSD_ERROR(EROFS), 80.68 - XSD_ERROR(EBUSY), 80.69 - XSD_ERROR(EAGAIN), 80.70 - XSD_ERROR(EISCONN), 80.71 + XSD_ERROR(EINVAL), 80.72 + XSD_ERROR(EACCES), 80.73 + XSD_ERROR(EEXIST), 80.74 + XSD_ERROR(EISDIR), 80.75 + XSD_ERROR(ENOENT), 80.76 + XSD_ERROR(ENOMEM), 80.77 + XSD_ERROR(ENOSPC), 80.78 + XSD_ERROR(EIO), 80.79 + XSD_ERROR(ENOTEMPTY), 80.80 + XSD_ERROR(ENOSYS), 80.81 + XSD_ERROR(EROFS), 80.82 + XSD_ERROR(EBUSY), 80.83 + XSD_ERROR(EAGAIN), 80.84 + XSD_ERROR(EISCONN), 80.85 }; 80.86 struct xsd_sockmsg 80.87 { 80.88 - u32 type; 80.89 - u32 len; /* Length of data following this. */ 80.90 + u32 type; /* XS_??? */ 80.91 + u32 req_id;/* Request identifier, echoed in daemon's response. */ 80.92 + u32 tx_id; /* Transaction id (0 if not related to a transaction). */ 80.93 + u32 len; /* Length of data following this. */ 80.94 80.95 - /* Generally followed by nul-terminated string(s). */ 80.96 + /* Generally followed by nul-terminated string(s). */ 80.97 }; 80.98 80.99 enum xs_watch_type 80.100 { 80.101 - XS_WATCH_PATH = 0, 80.102 - XS_WATCH_TOKEN, 80.103 + XS_WATCH_PATH = 0, 80.104 + XS_WATCH_TOKEN, 80.105 }; 80.106 80.107 #endif /* _XS_WIRE_H */