Vasiliy G Tolstov
2010-Nov-22 11:53 UTC
[Xen-devel] xenstore watch not working under 32 bit domU (xen stable 2.6.32 from jeremy git tree)
Hello. Can You helps me, i''m try to investigate why under 64 bit domU this kernel module work''s correct, but under 686 watch does not work: compile and running aginst curent running kernel. #define LINUX #include <linux/module.h> #include <linux/kernel.h> #include <linux/version.h> #include <linux/init.h> //Xen specific #include <xen/xenbus.h> //Memory state #include <linux/mm.h> //Disk state #include <linux/statfs.h> #include <linux/namei.h> #include <linux/fs.h> //tokenize #include <linux/string.h> #define ENABLE_DEPRECATED 1 extern void *sys_call_table[]; #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,36) static void argv_cleanup(struct subprocess_info *info) { argv_free(info->argv); } #else static void argv_cleanup(char **argv, char **envp) { argv_free(argv); } #endif static int xenmgm_exec(char *cmd) { int argc; char **argv = argv_split(GFP_ATOMIC, cmd, &argc); static char *envp[] = { "HOME=/", "TERM=linux", "PATH=/sbin:/bin:/usr/sbin:/usr/bin", NULL }; int ret = -ENOMEM; struct subprocess_info *info; if (argv == NULL) { printk(KERN_WARNING "%s failed to allocate memory for \"%s\"\n", __func__, cmd); goto out; } info = call_usermodehelper_setup(argv[0], argv, envp, GFP_ATOMIC); if (info == NULL) { argv_free(argv); goto out; } #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,36) call_usermodehelper_setfns(info, NULL, argv_cleanup, NULL); #else call_usermodehelper_setcleanup(info, argv_cleanup); #endif ret = call_usermodehelper_exec(info, UMH_WAIT_PROC); out: return ret; } static void watch_cmd(struct xenbus_watch *watch, const char **vec, unsigned int len) { char *cmd; cmd = xenbus_read(XBT_NIL, "data/mgm", "cmd_in", NULL); if (IS_ERR(cmd)) { printk(KERN_ERR "Unable to read cmd_in string in data/mgm/cmd_in\n"); return; } if (strcmp(cmd, "\0") != 0) { char *key, *cp; cp = kstrdup(cmd, GFP_KERNEL); do { key = strsep(&cp, ";"); if (key) { xenmgm_exec(key); } } while (key); kfree(cp); } kfree(cmd); } static unsigned int memstat_interval_ms; static unsigned int diskstat_interval_ms; static struct workqueue_struct *xenmgm_memory_workqueue; static struct workqueue_struct *xenmgm_disk_workqueue; static void xenmgm_memory_process(struct work_struct *); static void xenmgm_disk_process(struct work_struct *); static DECLARE_DELAYED_WORK(xenmgm_memory_worker, xenmgm_memory_process); static DECLARE_DELAYED_WORK(xenmgm_disk_worker, xenmgm_disk_process); static void xenmgm_memory_queue_delayed_work(unsigned long delay) { if (!queue_delayed_work(xenmgm_memory_workqueue, &xenmgm_memory_worker, delay)) printk(KERN_ERR "xenmgm: bad xenmgm_memory_workqueue\n"); } static void xenmgm_disk_queue_delayed_work(unsigned long delay) { if (!queue_delayed_work(xenmgm_disk_workqueue, &xenmgm_disk_worker, delay)) printk(KERN_ERR "xenmgm: bad xenmgm_disk_workqueue\n"); } static void xenmgm_memory_process(struct work_struct *work) { struct sysinfo meminfo; int err; unsigned long long totalbytes, freebytes, usedbytes; si_meminfo(&meminfo); totalbytes = (unsigned long long) meminfo.totalram << PAGE_SHIFT; freebytes = ((unsigned long long) meminfo.freeram + (unsigned long long) global_page_state(NR_FILE_PAGES) + (unsigned long long) meminfo.bufferram) << PAGE_SHIFT; usedbytes = (unsigned long long) totalbytes - freebytes; err = xenbus_printf(XBT_NIL, "data/memory", "totalbytes", "%llu", totalbytes); if(err) printk("xenmgm: error writing to xenbus: /data/memory/totalbytes, %d\n", err); err = xenbus_printf(XBT_NIL, "data/memory", "freebytes", "%llu", freebytes); if(err) printk("xenmgm: error writing to xenbus: /data/memory/freebytes, %d\n", err); err = xenbus_printf(XBT_NIL, "data/memory", "usedbytes", "%llu", usedbytes); if(err) printk("xenmgm: error writing to xenbus: /data/memory/usedbytes, %d\n", err); #ifdef ENABLE_DEPRECATED err = xenbus_printf(XBT_NIL, "memory", "memtotalbytes", "%llu", totalbytes); if(err) printk("xenmgm: error writing to xenbus: /memory/memtotalbytes, %d\n", err); err = xenbus_printf(XBT_NIL, "memory", "memfreebytes", "%llu", freebytes); if(err) printk("xenmgm: error writing to xenbus: /memory/memfreebytes, %d\n", err); #endif xenmgm_memory_queue_delayed_work(memstat_interval_ms / (1000 / HZ)); } static void xenmgm_disk_process(struct work_struct *work) { struct path path; int err; struct kstatfs buf; unsigned long long totalbytes, freebytes, usedbytes; err = user_path("/", &path); if (!err) { #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,36) vfs_statfs(&path, &buf); #else vfs_statfs(path.dentry, &buf); #endif path_put(&path); totalbytes = buf.f_blocks * (u64) buf.f_bsize; freebytes = buf.f_bfree * (u64) buf.f_bsize; usedbytes = totalbytes - freebytes; err = xenbus_printf(XBT_NIL, "data/disk", "totalbytes", "%llu", totalbytes); if(err) printk("xenmgm: error writing to xenbus: /data/disk/totalbytes: %d\n", err); err = xenbus_printf(XBT_NIL, "data/disk", "freebytes", "%llu", freebytes); if(err) printk("xenmgm: error writing to xenbus: /data/disk/freebytes: %d\n", err); err = xenbus_printf(XBT_NIL, "data/disk", "usedbytes", "%llu", usedbytes); if(err) printk("xenmgm: error writing to xenbus: /data/disk/usedbytes: %d\n", err); #ifdef ENABLE_DEPRECATED err = xenbus_printf(XBT_NIL, "memory", "disktotalbytes", "%llu", totalbytes); if(err) printk("xenmgm: error writing to xenbus: /memory/disktotalbytes: %d\n", err); err = xenbus_printf(XBT_NIL, "memory", "diskfreebytes", "%llu", freebytes); if(err) printk("xenmgm: error writing to xenbus: /memory/diskfreebytes: %d\n", err); #endif } xenmgm_disk_queue_delayed_work(diskstat_interval_ms / (1000 / HZ)); } static int xenmgm_init_watcher(struct notifier_block *notifier, unsigned long event, void *data) { int err; static struct xenbus_watch xenmgm_xenbus_watch = { .node = "data/mgm/cmd_in", .callback = watch_cmd}; printk("xenmgm: xenstore watcher init\n"); err = register_xenbus_watch(&xenmgm_xenbus_watch); if (err) { printk(KERN_ERR "xenmgm: Failed to set xenmgm watcher \n"); return err; } return NOTIFY_DONE; } static int __init xenmgm_init(void) { static struct notifier_block xenmgm_xenstore_notifier = { .notifier_call = xenmgm_init_watcher }; diskstat_interval_ms = 1000; memstat_interval_ms = 1000; printk("xenmgm: module init\n"); register_xenstore_notifier(&xenmgm_xenstore_notifier); xenmgm_memory_workqueue create_singlethread_workqueue("xenmgm_memory"); xenmgm_disk_workqueue = create_singlethread_workqueue("xenmgm_disk"); xenmgm_memory_queue_delayed_work(60UL * HZ); printk("xenmgm: xenmgm_memory init\n"); xenmgm_disk_queue_delayed_work(60UL * HZ); printk("xenmgm: xenmgm_disk init\n"); return 0; } static void __exit xenmgm_exit(void) { cancel_delayed_work(&xenmgm_memory_worker); cancel_delayed_work(&xenmgm_disk_worker); flush_workqueue(xenmgm_memory_workqueue); flush_workqueue(xenmgm_disk_workqueue); destroy_workqueue(xenmgm_memory_workqueue); destroy_workqueue(xenmgm_disk_workqueue); // unregister_xenstore_notifier(&xenmgm_xenstore_notifier); printk("xenmgm: module exit\n"); return; } module_init(xenmgm_init); module_exit(xenmgm_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Vasiliy G Tolstov <v.tolstov@selfip.ru>"); MODULE_DESCRIPTION("Xen DomU management module"); MODULE_VERSION("0.0.1"); -- Vasiliy G Tolstov <v.tolstov@selfip.ru> Selfip.Ru _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Vasiliy G Tolstov
2010-Dec-05 18:39 UTC
Re: [Xen-devel] xenstore watch not working under 32 bit domU (xen stable 2.6.32 from jeremy git tree)
On Mon, 2010-11-22 at 14:53 +0300, Vasiliy G Tolstov wrote:> Hello. Can You helps me, i''m try to investigate why under 64 bit domU > this kernel module work''s correct, but under 686 watch does not work:Anybody check this? More simple example, from balloon.c driver #include <linux/kernel.h> #include <linux/module.h> #include <linux/sched.h> #include <linux/errno.h> #include <linux/mm.h> #include <linux/bootmem.h> #include <linux/pagemap.h> #include <linux/highmem.h> #include <linux/mutex.h> #include <linux/list.h> #include <linux/sysdev.h> #include <linux/swap.h> #include <asm/page.h> #include <asm/pgalloc.h> #include <asm/pgtable.h> #include <asm/uaccess.h> #include <asm/tlb.h> #include <asm/e820.h> #include <asm/xen/hypervisor.h> #include <asm/xen/hypercall.h> #include <xen/xen.h> #include <xen/interface/xen.h> #include <xen/interface/memory.h> #include <xen/xenbus.h> #include <xen/features.h> #include <xen/page.h> static struct xenbus_watch target_watch { .node = "data" }; /* React to a change in the target key */ static void watch_target(struct xenbus_watch *watch, const char **vec, unsigned int len) { char *cmd; int err; printk(KERN_ERR "watch_target\n"); } static int balloon_init_watcher(struct notifier_block *notifier, unsigned long event, void *data) { int err; printk(KERN_ERR "init_watcher\n"); err = register_xenbus_watch(&target_watch); if (err) printk(KERN_ERR "Failed to set balloon watcher\n"); return NOTIFY_DONE; } static struct notifier_block xenstore_notifier; static int __init balloon_init(void) { printk(KERN_ERR "init\n"); target_watch.callback = watch_target; xenstore_notifier.notifier_call = balloon_init_watcher; register_xenstore_notifier(&xenstore_notifier); return 0; } subsys_initcall(balloon_init); static void balloon_exit(void) { printk(KERN_ERR "exit\n"); return; } module_exit(balloon_exit); MODULE_LICENSE("GPL"); Watch not WORK! Compile with make file obj-m += xenmgm.o KDIR := /lib/modules/$(shell uname -r) PWD := $(shell pwd) all: $(MAKE) -C $(KDIR)/build SUBDIRS=$(PWD) M=$(PWD) modules clean: $(MAKE) -C $(KDIR)/build SUBDIRS=$(PWD) M=$(PWD) clean rm -f modules.order Module.* install: mkdir -p $(KDIR)/kernel/drivers/xen/xenmgm/ install -m 0644 -o root xenmgm.ko $(KDIR)/kernel/drivers/xen/xenmgm/ depmod -q I think, that is becouse i compiled module and not in kernel. Can somebody check this? (use stable-2.6.32.x commit diff b92d1ec0a86acd2dfe14d732c6a9304aae0ccf26) kernel config in attached file _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Jeremy Fitzhardinge
2010-Dec-06 18:22 UTC
Re: [Xen-devel] xenstore watch not working under 32 bit domU (xen stable 2.6.32 from jeremy git tree)
On 11/22/2010 03:53 AM, Vasiliy G Tolstov wrote:> Hello. Can You helps me, i''m try to investigate why under 64 bit domU > this kernel module work''s correct, but under 686 watch does not work:If you want help with this kind of programming problem, you need to be much more precise about what "does not work" means. Does it crash? Fail silently? Do something unexpected? It appears this code is very similar to drivers/xen/manage.c (including executing usermode code, via orderly_poweroff()), so perhaps you can look there for ideas. J _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Vasiliy G Tolstov
2010-Dec-30 15:15 UTC
Re: [Xen-devel] xenstore watch not working under 32 bit domU (xen stable 2.6.32 from jeremy git tree)
On Sun, 2010-12-05 at 21:39 +0300, Vasiliy G Tolstov wrote:> On Mon, 2010-11-22 at 14:53 +0300, Vasiliy G Tolstov wrote: > > Hello. Can You helps me, i''m try to investigate why under 64 bit domU > > this kernel module work''s correct, but under 686 watch does not work: >Sorry for long delay. I''m test some situations and investigate, that in pvops 2.6.32.26 in 64 bit or 32 bit xenstore notifier and xenbus watch not triggered. Under centos 32 bit domU (xenlinux kernel) module displays via printk (insmod xenmgm.ko; rmmod xenmgm;): xenwatch: module init xenwatch: xenstore watcher init xenwatch: test xenwatch: module exit Under centos 32 bit domU (2.6.32.26 from jeremy) module displays via printk (insmod xenmgm.ko; rmmod xenmgm;): xenwatch: module init xenwatch: module exit Kernel config in attached file Module source in e-mail: #include <linux/kernel.h> #include <linux/err.h> #include <linux/string.h> #include <linux/ctype.h> #include <linux/fcntl.h> #include <linux/mm.h> #include <linux/proc_fs.h> #include <linux/notifier.h> #include <linux/kthread.h> #include <linux/mutex.h> #include <linux/io.h> #include <asm/xen/hypervisor.h> #include <xen/xenbus.h> #include <xen/events.h> #include <xen/xen.h> #include <xen/platform_pci.h> static void xenwatch_watch(struct xenbus_watch *watch, const char **vec, unsigned int len) { printk("xenwatch: test"); } static struct xenbus_watch xenwatch_xenbus_watch = { .node = "data", .callback = xenwatch_watch, }; static int xenwatch_init_watcher(struct notifier_block *notifier, unsigned long event, void *data) { register_xenbus_watch(&xenwatch_xenbus_watch); printk("xenwatch: xenstore watcher init\n"); return NOTIFY_DONE; } static struct notifier_block xenwatch_xenstore_notifier = { .notifier_call = xenwatch_init_watcher, }; static int __init xenwatch_init(void) { printk("\n"); printk("xenwatch: module init\n"); register_xenstore_notifier(&xenwatch_xenstore_notifier); return 0; } static void __exit xenwatch_exit(void) { unregister_xenstore_notifier(&xenwatch_xenstore_notifier); printk("xenwatch: module exit\n"); printk("\n"); return; } subsys_initcall(xenwatch_init); module_exit(xenwatch_exit); MODULE_LICENSE("GPL"); -- Vasiliy G Tolstov <v.tolstov@selfip.ru> Selfip.Ru _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel