All of lore.kernel.org
 help / color / mirror / Atom feed
* xenstore watch not working under 32 bit domU (xen stable 2.6.32 from jeremy git tree)
@ 2010-11-22 11:53 Vasiliy G Tolstov
  2010-12-05 18:39 ` Vasiliy G Tolstov
  2010-12-06 18:22 ` Jeremy Fitzhardinge
  0 siblings, 2 replies; 4+ messages in thread
From: Vasiliy G Tolstov @ 2010-11-22 11:53 UTC (permalink / raw)
  To: xen-devel@lists.xensource.com

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

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2010-12-30 15:15 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-11-22 11:53 xenstore watch not working under 32 bit domU (xen stable 2.6.32 from jeremy git tree) Vasiliy G Tolstov
2010-12-05 18:39 ` Vasiliy G Tolstov
2010-12-30 15:15   ` Vasiliy G Tolstov
2010-12-06 18:22 ` Jeremy Fitzhardinge

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.