All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 7 of 8] xl: free memory before building a domain
@ 2010-08-27 11:19 Stefano Stabellini
  2010-08-27 11:37 ` Christoph Egger
  2010-08-31 17:37 ` Ian Jackson
  0 siblings, 2 replies; 6+ messages in thread
From: Stefano Stabellini @ 2010-08-27 11:19 UTC (permalink / raw)
  To: xen-devel

xl: free memory before building a domain

Free the needed amount of memory before proceeding with the domain
build.
Use a filelock to prevent other xl instances from conflicting during
this operation.

Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>

diff -r b80a1688b5c9 tools/examples/xl.conf
--- a/tools/examples/xl.conf	Thu Aug 26 18:03:20 2010 +0100
+++ b/tools/examples/xl.conf	Thu Aug 26 18:26:04 2010 +0100
@@ -3,3 +3,6 @@
 # automatically balloon down dom0 when xen doesn't have enough free
 # memory to create a domain
 autoballon=1
+
+# full path of the lockfile used by xl during domain creation
+lockfile="/var/lock/xl"
diff -r b80a1688b5c9 tools/libxl/xl.c
--- a/tools/libxl/xl.c	Thu Aug 26 18:03:20 2010 +0100
+++ b/tools/libxl/xl.c	Thu Aug 26 18:26:04 2010 +0100
@@ -34,6 +34,7 @@
 
 xentoollog_logger_stdiostream *logger;
 int autoballoon = 1;
+char *lockfile = "/var/lock/xl";
 
 static xentoollog_level minmsglevel = XTL_PROGRESS;
 
@@ -44,6 +45,7 @@ static void parse_global_config(const ch
     long l;
     XLU_Config *config;
     int e;
+    const char *buf;
 
     config = xlu_cfg_init(stderr, configfile);
     if (!config) {
@@ -60,6 +62,9 @@ static void parse_global_config(const ch
     if (!xlu_cfg_get_long (config, "autoballoon", &l))
         autoballoon = l;
 
+    if (!xlu_cfg_get_string (config, "lockfile", &buf))
+        lockfile = strdup(buf);
+
     xlu_cfg_destroy(config);
 }
  
diff -r b80a1688b5c9 tools/libxl/xl.h
--- a/tools/libxl/xl.h	Thu Aug 26 18:03:20 2010 +0100
+++ b/tools/libxl/xl.h	Thu Aug 26 18:26:04 2010 +0100
@@ -92,5 +92,6 @@ extern xentoollog_logger_stdiostream *lo
 
 /* global options */
 extern int autoballoon;
+extern char *lockfile;
 
 #endif /* XL_H */
diff -r b80a1688b5c9 tools/libxl/xl_cmdimpl.c
--- a/tools/libxl/xl_cmdimpl.c	Thu Aug 26 18:03:20 2010 +0100
+++ b/tools/libxl/xl_cmdimpl.c	Thu Aug 26 18:26:04 2010 +0100
@@ -68,6 +68,7 @@ libxl_ctx ctx;
 /* when we operate on a domain, it is this one: */
 static uint32_t domid;
 static const char *common_domname;
+static int fd_lock = -1;
 
 
 static const char savefileheader_magic[32]=
@@ -234,6 +235,65 @@ static void find_domain(const char *p)
     common_domname = was_name ? p : libxl_domid_to_name(&ctx, domid);
 }
 
+static int acquire_lock(void)
+{
+    int rc;
+    struct flock fl;
+
+    /* lock already acquired */
+    if (fd_lock >= 0)
+        return ERROR_INVAL;
+
+    fl.l_type = F_WRLCK;
+    fl.l_whence = SEEK_SET;
+    fl.l_start = 0;
+    fl.l_len = 0;
+    fd_lock = open(lockfile, O_WRONLY|O_CREAT, S_IWUSR);
+    if (fd_lock < 0) {
+        fprintf(stderr, "cannot open the lockfile %s errno=%d\n", lockfile, errno);
+        return ERROR_FAIL;
+    }
+get_lock:
+    rc = fcntl(fd_lock, F_SETLKW, &fl);
+    if (rc < 0 && errno == EINTR)
+        goto get_lock;
+    if (rc < 0) {
+        fprintf(stderr, "cannot acquire lock %s errno=%d\n", lockfile, errno);
+        rc = ERROR_FAIL;
+    } else
+        rc = 0;
+    return rc;
+}
+
+static int release_lock(void)
+{
+    int rc;
+    struct flock fl;
+
+    /* lock not acquired */
+    if (fd_lock < 0)
+        return ERROR_INVAL;
+
+release_lock:
+    fl.l_type = F_UNLCK;
+    fl.l_whence = SEEK_SET;
+    fl.l_start = 0;
+    fl.l_len = 0;
+
+    rc = fcntl(fd_lock, F_SETLKW, &fl);
+    if (rc < 0 && errno == EINTR)
+        goto release_lock;
+    if (rc < 0) {
+        fprintf(stderr, "cannot release lock %s, errno=%d\n", lockfile, errno);
+        rc = ERROR_FAIL;
+    } else
+        rc = 0;
+    close(fd_lock);
+    fd_lock = -1;
+
+    return rc;
+}
+
 #define LOG(_f, _a...)   dolog(__FILE__, __LINE__, __func__, _f "\n", ##_a)
 
 static void dolog(const char *file, int line, const char *func, char *fmt, ...)
@@ -1209,6 +1269,48 @@ struct domain_create {
     char **migration_domname_r;
 };
 
+static int freemem(libxl_domain_build_info *b_info, libxl_device_model_info *dm_info)
+{
+    int rc, retries = 3;
+    uint32_t need_memkb, free_memkb;
+
+    if (!autoballoon)
+        return 0;
+
+    rc = libxl_domain_need_memory(&ctx, b_info, dm_info, &need_memkb);
+    if (rc < 0)
+        return rc;
+
+    do {
+        rc = libxl_get_free_memory(&ctx, &free_memkb);
+        if (rc < 0)
+            return rc;
+
+        if (free_memkb >= need_memkb)
+            return 0;
+
+        rc = libxl_set_relative_memory_target(&ctx, 0, free_memkb - need_memkb, 0);
+        if (rc < 0)
+            return rc;
+
+        rc = libxl_wait_for_free_memory(&ctx, domid, need_memkb, 10);
+        if (!rc)
+            return 0;
+        else if (rc != ERROR_NOMEM)
+            return rc;
+
+        /* the memory target has been reached but the free memory is still
+         * not enough: loop over again */
+        rc = libxl_wait_for_memory_target(&ctx, 0, 1);
+        if (rc < 0)
+            return rc;
+
+        retries--;
+    } while (retries > 0);
+
+    return ERROR_NOMEM;
+}
+
 static int create_domain(struct domain_create *dom_info)
 {
     struct domain_config d_config;
@@ -1367,6 +1469,17 @@ static int create_domain(struct domain_c
 start:
     domid = 0;
 
+    rc = acquire_lock();
+    if (rc < 0)
+        goto error_out;
+
+    ret = freemem(&d_config.b_info, &dm_info);
+    if (ret < 0) {
+        fprintf(stderr, "failed to free memory for the domain\n");
+        ret = ERROR_FAIL;
+        goto error_out;
+    }
+
     ret = libxl_domain_make(&ctx, &d_config.c_info, &domid);
     if (ret) {
         fprintf(stderr, "cannot make domain: %d\n", ret);
@@ -1475,6 +1588,8 @@ start:
             goto error_out;
     }
 
+    release_lock();
+
     if (!paused)
         libxl_domain_unpause(&ctx, domid);
 
@@ -1612,6 +1727,7 @@ start:
     }
 
 error_out:
+    release_lock();
     if (domid)
         libxl_domain_destroy(&ctx, domid, 0);

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

* Re: [PATCH 7 of 8] xl: free memory before building a domain
  2010-08-27 11:19 [PATCH 7 of 8] xl: free memory before building a domain Stefano Stabellini
@ 2010-08-27 11:37 ` Christoph Egger
  2010-08-27 11:41   ` Stefano Stabellini
  2010-08-31 17:37 ` Ian Jackson
  1 sibling, 1 reply; 6+ messages in thread
From: Christoph Egger @ 2010-08-27 11:37 UTC (permalink / raw)
  To: xen-devel; +Cc: Stefano Stabellini

On Friday 27 August 2010 13:19:19 Stefano Stabellini wrote:
> xl: free memory before building a domain
>
> Free the needed amount of memory before proceeding with the domain
> build.
> Use a filelock to prevent other xl instances from conflicting during
> this operation.
>
> Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
>
> diff -r b80a1688b5c9 tools/examples/xl.conf
> --- a/tools/examples/xl.conf	Thu Aug 26 18:03:20 2010 +0100
> +++ b/tools/examples/xl.conf	Thu Aug 26 18:26:04 2010 +0100
> @@ -3,3 +3,6 @@
>  # automatically balloon down dom0 when xen doesn't have enough free
>  # memory to create a domain
>  autoballon=1
> +
> +# full path of the lockfile used by xl during domain creation
> +lockfile="/var/lock/xl"
> diff -r b80a1688b5c9 tools/libxl/xl.c
> --- a/tools/libxl/xl.c	Thu Aug 26 18:03:20 2010 +0100
> +++ b/tools/libxl/xl.c	Thu Aug 26 18:26:04 2010 +0100
> @@ -34,6 +34,7 @@
>
>  xentoollog_logger_stdiostream *logger;
>  int autoballoon = 1;
> +char *lockfile = "/var/lock/xl";

NetBSD doesn't have /var/lock. Is it ok to use /var/lib ?

Christoph


>
>  static xentoollog_level minmsglevel = XTL_PROGRESS;
>
> @@ -44,6 +45,7 @@ static void parse_global_config(const ch
>      long l;
>      XLU_Config *config;
>      int e;
> +    const char *buf;
>
>      config = xlu_cfg_init(stderr, configfile);
>      if (!config) {
> @@ -60,6 +62,9 @@ static void parse_global_config(const ch
>      if (!xlu_cfg_get_long (config, "autoballoon", &l))
>          autoballoon = l;
>
> +    if (!xlu_cfg_get_string (config, "lockfile", &buf))
> +        lockfile = strdup(buf);
> +
>      xlu_cfg_destroy(config);
>  }
>
> diff -r b80a1688b5c9 tools/libxl/xl.h
> --- a/tools/libxl/xl.h	Thu Aug 26 18:03:20 2010 +0100
> +++ b/tools/libxl/xl.h	Thu Aug 26 18:26:04 2010 +0100
> @@ -92,5 +92,6 @@ extern xentoollog_logger_stdiostream *lo
>
>  /* global options */
>  extern int autoballoon;
> +extern char *lockfile;
>
>  #endif /* XL_H */
> diff -r b80a1688b5c9 tools/libxl/xl_cmdimpl.c
> --- a/tools/libxl/xl_cmdimpl.c	Thu Aug 26 18:03:20 2010 +0100
> +++ b/tools/libxl/xl_cmdimpl.c	Thu Aug 26 18:26:04 2010 +0100
> @@ -68,6 +68,7 @@ libxl_ctx ctx;
>  /* when we operate on a domain, it is this one: */
>  static uint32_t domid;
>  static const char *common_domname;
> +static int fd_lock = -1;
>
>
>  static const char savefileheader_magic[32]=
> @@ -234,6 +235,65 @@ static void find_domain(const char *p)
>      common_domname = was_name ? p : libxl_domid_to_name(&ctx, domid);
>  }
>
> +static int acquire_lock(void)
> +{
> +    int rc;
> +    struct flock fl;
> +
> +    /* lock already acquired */
> +    if (fd_lock >= 0)
> +        return ERROR_INVAL;
> +
> +    fl.l_type = F_WRLCK;
> +    fl.l_whence = SEEK_SET;
> +    fl.l_start = 0;
> +    fl.l_len = 0;
> +    fd_lock = open(lockfile, O_WRONLY|O_CREAT, S_IWUSR);
> +    if (fd_lock < 0) {
> +        fprintf(stderr, "cannot open the lockfile %s errno=%d\n",
> lockfile, errno); +        return ERROR_FAIL;
> +    }
> +get_lock:
> +    rc = fcntl(fd_lock, F_SETLKW, &fl);
> +    if (rc < 0 && errno == EINTR)
> +        goto get_lock;
> +    if (rc < 0) {
> +        fprintf(stderr, "cannot acquire lock %s errno=%d\n", lockfile,
> errno); +        rc = ERROR_FAIL;
> +    } else
> +        rc = 0;
> +    return rc;
> +}
> +
> +static int release_lock(void)
> +{
> +    int rc;
> +    struct flock fl;
> +
> +    /* lock not acquired */
> +    if (fd_lock < 0)
> +        return ERROR_INVAL;
> +
> +release_lock:
> +    fl.l_type = F_UNLCK;
> +    fl.l_whence = SEEK_SET;
> +    fl.l_start = 0;
> +    fl.l_len = 0;
> +
> +    rc = fcntl(fd_lock, F_SETLKW, &fl);
> +    if (rc < 0 && errno == EINTR)
> +        goto release_lock;
> +    if (rc < 0) {
> +        fprintf(stderr, "cannot release lock %s, errno=%d\n", lockfile,
> errno); +        rc = ERROR_FAIL;
> +    } else
> +        rc = 0;
> +    close(fd_lock);
> +    fd_lock = -1;
> +
> +    return rc;
> +}
> +
>  #define LOG(_f, _a...)   dolog(__FILE__, __LINE__, __func__, _f "\n",
> ##_a)
>
>  static void dolog(const char *file, int line, const char *func, char *fmt,
> ...) @@ -1209,6 +1269,48 @@ struct domain_create {
>      char **migration_domname_r;
>  };
>
> +static int freemem(libxl_domain_build_info *b_info,
> libxl_device_model_info *dm_info) +{
> +    int rc, retries = 3;
> +    uint32_t need_memkb, free_memkb;
> +
> +    if (!autoballoon)
> +        return 0;
> +
> +    rc = libxl_domain_need_memory(&ctx, b_info, dm_info, &need_memkb);
> +    if (rc < 0)
> +        return rc;
> +
> +    do {
> +        rc = libxl_get_free_memory(&ctx, &free_memkb);
> +        if (rc < 0)
> +            return rc;
> +
> +        if (free_memkb >= need_memkb)
> +            return 0;
> +
> +        rc = libxl_set_relative_memory_target(&ctx, 0, free_memkb -
> need_memkb, 0); +        if (rc < 0)
> +            return rc;
> +
> +        rc = libxl_wait_for_free_memory(&ctx, domid, need_memkb, 10);
> +        if (!rc)
> +            return 0;
> +        else if (rc != ERROR_NOMEM)
> +            return rc;
> +
> +        /* the memory target has been reached but the free memory is still
> +         * not enough: loop over again */
> +        rc = libxl_wait_for_memory_target(&ctx, 0, 1);
> +        if (rc < 0)
> +            return rc;
> +
> +        retries--;
> +    } while (retries > 0);
> +
> +    return ERROR_NOMEM;
> +}
> +
>  static int create_domain(struct domain_create *dom_info)
>  {
>      struct domain_config d_config;
> @@ -1367,6 +1469,17 @@ static int create_domain(struct domain_c
>  start:
>      domid = 0;
>
> +    rc = acquire_lock();
> +    if (rc < 0)
> +        goto error_out;
> +
> +    ret = freemem(&d_config.b_info, &dm_info);
> +    if (ret < 0) {
> +        fprintf(stderr, "failed to free memory for the domain\n");
> +        ret = ERROR_FAIL;
> +        goto error_out;
> +    }
> +
>      ret = libxl_domain_make(&ctx, &d_config.c_info, &domid);
>      if (ret) {
>          fprintf(stderr, "cannot make domain: %d\n", ret);
> @@ -1475,6 +1588,8 @@ start:
>              goto error_out;
>      }
>
> +    release_lock();
> +
>      if (!paused)
>          libxl_domain_unpause(&ctx, domid);
>
> @@ -1612,6 +1727,7 @@ start:
>      }
>
>  error_out:
> +    release_lock();
>      if (domid)
>          libxl_domain_destroy(&ctx, domid, 0);
>
>
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xensource.com
> http://lists.xensource.com/xen-devel



-- 
---to satisfy European Law for business letters:
Advanced Micro Devices GmbH
Einsteinring 24, 85609 Dornach b. Muenchen
Geschaeftsfuehrer: Alberto Bozzo, Andrew Bowd
Sitz: Dornach, Gemeinde Aschheim, Landkreis Muenchen
Registergericht Muenchen, HRB Nr. 43632

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

* Re: [PATCH 7 of 8] xl: free memory before building a domain
  2010-08-27 11:37 ` Christoph Egger
@ 2010-08-27 11:41   ` Stefano Stabellini
  2010-08-31 17:38     ` Ian Jackson
  0 siblings, 1 reply; 6+ messages in thread
From: Stefano Stabellini @ 2010-08-27 11:41 UTC (permalink / raw)
  To: Christoph Egger; +Cc: xen-devel@lists.xensource.com, Stabellini

On Fri, 27 Aug 2010, Christoph Egger wrote:
> On Friday 27 August 2010 13:19:19 Stefano Stabellini wrote:
> > xl: free memory before building a domain
> >
> > Free the needed amount of memory before proceeding with the domain
> > build.
> > Use a filelock to prevent other xl instances from conflicting during
> > this operation.
> >
> > Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
> >
> > diff -r b80a1688b5c9 tools/examples/xl.conf
> > --- a/tools/examples/xl.conf	Thu Aug 26 18:03:20 2010 +0100
> > +++ b/tools/examples/xl.conf	Thu Aug 26 18:26:04 2010 +0100
> > @@ -3,3 +3,6 @@
> >  # automatically balloon down dom0 when xen doesn't have enough free
> >  # memory to create a domain
> >  autoballon=1
> > +
> > +# full path of the lockfile used by xl during domain creation
> > +lockfile="/var/lock/xl"
> > diff -r b80a1688b5c9 tools/libxl/xl.c
> > --- a/tools/libxl/xl.c	Thu Aug 26 18:03:20 2010 +0100
> > +++ b/tools/libxl/xl.c	Thu Aug 26 18:26:04 2010 +0100
> > @@ -34,6 +34,7 @@
> >
> >  xentoollog_logger_stdiostream *logger;
> >  int autoballoon = 1;
> > +char *lockfile = "/var/lock/xl";
> 
> NetBSD doesn't have /var/lock. Is it ok to use /var/lib ?
> 

you can set it in the global xl config file to /var/lib or anything you
want.

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

* Re: [PATCH 7 of 8] xl: free memory before building a domain
  2010-08-27 11:19 [PATCH 7 of 8] xl: free memory before building a domain Stefano Stabellini
  2010-08-27 11:37 ` Christoph Egger
@ 2010-08-31 17:37 ` Ian Jackson
  1 sibling, 0 replies; 6+ messages in thread
From: Ian Jackson @ 2010-08-31 17:37 UTC (permalink / raw)
  To: Stefano Stabellini; +Cc: xen-devel

Stefano Stabellini writes ("[Xen-devel] [PATCH 7 of 8] xl: free memory before building a domain"):
...
> +# full path of the lockfile used by xl during domain creation
> +lockfile="/var/lock/xl"

I think the default config file should contain commented-out copies of
the compiled-in defaults, not uncommented versions.

> +char *lockfile = "/var/lock/xl";

And the value should be from libx_paths.h et al surely ?

Ian.

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

* Re: [PATCH 7 of 8] xl: free memory before building a domain
  2010-08-27 11:41   ` Stefano Stabellini
@ 2010-08-31 17:38     ` Ian Jackson
  2010-09-01 11:46       ` Stefano Stabellini
  0 siblings, 1 reply; 6+ messages in thread
From: Ian Jackson @ 2010-08-31 17:38 UTC (permalink / raw)
  To: Stefano Stabellini; +Cc: Christoph Egger, xen-devel@lists.xensource.com

Stefano Stabellini writes ("Re: [Xen-devel] [PATCH 7 of 8] xl: free memory before building a domain"):
> you can set it in the global xl config file to /var/lib or anything you
> want.

The compiled-in default should be sensible for the build platform.  We
shouldn't be having people fiddle with config files to make the
software work.

Ian.

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

* Re: [PATCH 7 of 8] xl: free memory before building a domain
  2010-08-31 17:38     ` Ian Jackson
@ 2010-09-01 11:46       ` Stefano Stabellini
  0 siblings, 0 replies; 6+ messages in thread
From: Stefano Stabellini @ 2010-09-01 11:46 UTC (permalink / raw)
  To: Ian Jackson
  Cc: Christoph Egger, xen-devel@lists.xensource.com,
	Stefano Stabellini

On Tue, 31 Aug 2010, Ian Jackson wrote:
> Stefano Stabellini writes ("Re: [Xen-devel] [PATCH 7 of 8] xl: free memory before building a domain"):
> > you can set it in the global xl config file to /var/lib or anything you
> > want.
> 
> The compiled-in default should be sensible for the build platform.  We
> shouldn't be having people fiddle with config files to make the
> software work.
 
Yes, I had already repented and sent an update with this fix (it
contains one more patch called "introduce XEN_LOCK_DIR").

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

end of thread, other threads:[~2010-09-01 11:46 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-08-27 11:19 [PATCH 7 of 8] xl: free memory before building a domain Stefano Stabellini
2010-08-27 11:37 ` Christoph Egger
2010-08-27 11:41   ` Stefano Stabellini
2010-08-31 17:38     ` Ian Jackson
2010-09-01 11:46       ` Stefano Stabellini
2010-08-31 17:37 ` Ian Jackson

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.