All of lore.kernel.org
 help / color / mirror / Atom feed
From: Vasiliy G Tolstov <v.tolstov@selfip.ru>
To: "xen-devel@lists.xensource.com" <xen-devel@lists.xensource.com>
Subject: xenstore watch not working under 32 bit domU (xen stable 2.6.32 from jeremy git tree)
Date: Mon, 22 Nov 2010 14:53:35 +0300	[thread overview]
Message-ID: <1290426815.17994.111.camel@vase> (raw)

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

             reply	other threads:[~2010-11-22 11:53 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-11-22 11:53 Vasiliy G Tolstov [this message]
2010-12-05 18:39 ` xenstore watch not working under 32 bit domU (xen stable 2.6.32 from jeremy git tree) Vasiliy G Tolstov
2010-12-30 15:15   ` Vasiliy G Tolstov
2010-12-06 18:22 ` Jeremy Fitzhardinge

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1290426815.17994.111.camel@vase \
    --to=v.tolstov@selfip.ru \
    --cc=xen-devel@lists.xensource.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.