WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] libxl: disks: new xlu_disk_parse function

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] libxl: disks: new xlu_disk_parse function
From: Xen patchbot-unstable <patchbot@xxxxxxx>
Date: Fri, 08 Jul 2011 06:22:14 +0100
Delivery-date: Thu, 07 Jul 2011 22:24:07 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Ian Jackson <ian.jackson@xxxxxxxxxxxxx>
# Date 1309259951 -3600
# Node ID 77a235e95b47435871120c108606cca55c150f46
# Parent  3173b68c8a945deaeb2642f8bdb97c52ca0eaec7
libxl: disks: new xlu_disk_parse function

Introduce new flex/regexp-based parser for disk configuration strings.
Callers will be updated in following patches.

The existing xm command line syntax for block-attach expects multiple
arguments containing different parameters for different parts of the
disk specification, so we supply a parser function which can take
multiple strings and scan them in sequence.

Signed-off-by: Ian Jackson <Ian.Jackson@xxxxxxxxxxxxx>
Committed-by: Ian Jackson <Ian.Jackson@xxxxxxxxxxxxx>
---


diff -r 3173b68c8a94 -r 77a235e95b47 tools/libxl/Makefile
--- a/tools/libxl/Makefile      Tue Jun 28 12:19:10 2011 +0100
+++ b/tools/libxl/Makefile      Tue Jun 28 12:19:11 2011 +0100
@@ -41,7 +41,8 @@
 
 AUTOINCS= libxlu_cfg_y.h libxlu_cfg_l.h
 AUTOSRCS= libxlu_cfg_y.c libxlu_cfg_l.c
-LIBXLU_OBJS = libxlu_cfg_y.o libxlu_cfg_l.o libxlu_cfg.o
+LIBXLU_OBJS = libxlu_cfg_y.o libxlu_cfg_l.o libxlu_cfg.o \
+       libxlu_disk_l.o libxlu_disk.o
 $(LIBXLU_OBJS): CFLAGS += $(CFLAGS_libxenctrl) # For xentoollog.h
 
 CLIENTS = xl testenum
diff -r 3173b68c8a94 -r 77a235e95b47 tools/libxl/libxlu_disk.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libxl/libxlu_disk.c Tue Jun 28 12:19:11 2011 +0100
@@ -0,0 +1,93 @@
+#include "libxlu_internal.h"
+#include "libxlu_disk_l.h"
+#include "libxlu_disk_i.h"
+#include "libxlu_cfg_i.h"
+
+void xlu__disk_err(DiskParseContext *dpc, const char *erroneous,
+                   const char *message) {
+    fprintf(dpc->cfg->report,
+            "%s: config parsing error in disk specification: %s"
+            "%s%s%s"
+            " in `%s'\n",
+            dpc->cfg->filename, message,
+            erroneous?": near `":"", erroneous?erroneous:"", erroneous?"'":"",
+            dpc->spec);
+    if (!dpc->err) dpc->err= EINVAL;
+}
+
+static int dpc_prep(DiskParseContext *dpc, const char *spec) {
+    int e;
+
+    dpc->spec = spec;
+    
+    e = xlu__disk_yylex_init_extra(dpc, &dpc->scanner);
+    if (e) goto fail;
+
+    dpc->buf = xlu__disk_yy_scan_bytes(spec, strlen(spec), dpc->scanner);
+    if (!dpc->buf) { e = ENOMEM; goto fail; }
+
+    return 0;
+
+ fail:
+    fprintf(dpc->cfg->report, "cannot init disk scanner: %s\n",
+            strerror(errno));
+    return e;
+}
+
+static void dpc_dispose(DiskParseContext *dpc) {
+    if (dpc->buf) {
+        xlu__disk_yy_delete_buffer(dpc->buf, dpc->scanner);
+        dpc->buf = 0;
+    }
+    if (dpc->scanner) {
+        xlu__disk_yylex_destroy(dpc->scanner);
+        dpc->scanner = 0;
+    }
+}
+
+int xlu_disk_parse(XLU_Config *cfg,
+                   int nspecs, const char *const *specs,
+                   libxl_device_disk *disk) {
+    DiskParseContext dpc;
+    int i, e;
+
+    memset(&dpc,0,sizeof(dpc));
+    dpc.cfg = cfg;
+    dpc.scanner = 0;
+    dpc.disk = disk;
+
+    disk->readwrite = 1;
+
+    for (i=0; i<nspecs; i++) {
+        e = dpc_prep(&dpc, specs[i]);
+        if (e) { dpc.err = e; goto x_err; }
+
+        xlu__disk_yylex(dpc.scanner);
+        assert(!e);
+        if (dpc.err) goto x_err;
+
+        dpc_dispose(&dpc);
+    }
+
+    if (disk->format == LIBXL_DISK_FORMAT_UNKNOWN) {
+        disk->format = LIBXL_DISK_FORMAT_RAW;
+    }
+    if (disk->is_cdrom) {
+        disk->removable = 1;
+        disk->readwrite = 0;
+    }
+
+    if (!disk->vdev) {
+        xlu__disk_err(&dpc,0, "no vdev specified");
+        goto x_err;
+    }
+    if (!disk->pdev_path && !disk->removable) {
+        xlu__disk_err(&dpc,0,"no target specified (and device not removable)");
+        goto x_err;
+    }
+
+ x_err:
+    dpc_dispose(&dpc);
+    return dpc.err;
+}
+
diff -r 3173b68c8a94 -r 77a235e95b47 tools/libxl/libxlu_disk_i.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libxl/libxlu_disk_i.h       Tue Jun 28 12:19:11 2011 +0100
@@ -0,0 +1,21 @@
+#ifndef LIBXLU_DISK_I_H
+#define LIBXLU_DISK_I_H
+
+#include "libxlu_internal.h"
+
+
+typedef struct {
+    XLU_Config *cfg;
+    int err;
+    void *scanner;
+    YY_BUFFER_STATE buf;
+    libxl_device_disk *disk;
+    int access_set, had_depr_prefix;
+    const char *spec;
+} DiskParseContext;
+
+void xlu__disk_err(DiskParseContext *dpc, const char *erroneous,
+                   const char *message);
+
+
+#endif /*LIBXLU_DISK_I_H*/
diff -r 3173b68c8a94 -r 77a235e95b47 tools/libxl/libxlu_disk_l.l
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libxl/libxlu_disk_l.l       Tue Jun 28 12:19:11 2011 +0100
@@ -0,0 +1,217 @@
+/* -*- fundamental -*- */
+/*
+ * libxlu_disk_l.l - parser for disk specification strings
+ *
+ * Copyright (C) 2011      Citrix Ltd.
+ * Author Ian Jackson <ian.jackson@xxxxxxxxxxxxx>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; version 2.1 only. with the special
+ * exception on linking described in file LICENSE.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+/*
+ * Parsing the old xm/xend/xl-4.1 disk specs is a tricky problem,
+ * because the target string might in theory contain "," which is the
+ * delimiter we use for stripping off things on the RHS, and ":",
+ * which is the delimiter we use for stripping off things on the LHS.
+ *
+ * In this parser we do not support such target strings in the old
+ * syntax; if the target string has to contain "," or ":" the new
+ * syntax's "target=" should be used.
+ */
+
+%{
+#include "libxlu_disk_i.h"
+
+#define YY_NO_INPUT
+
+/* Some versions of flex have a bug (Fedora bugzilla 612465) which causes
+ * it to fail to declare these functions, which it defines.  So declare
+ * them ourselves.  Hopefully we won't have to simultaneously support
+ * a flex version which declares these differently somehow. */
+int xlu__disk_yyget_column(yyscan_t yyscanner);
+void xlu__disk_yyset_column(int  column_no, yyscan_t yyscanner);
+
+
+/*----- useful macros and functions used in actions -----
+ * we use macros in the actual rules to keep the actions short
+ * and particularly to avoid repeating boilerplate values such as
+ * DPC->disk, yytext, etc. */
+
+#define DPC ((DiskParseContext*)yyextra)
+
+/* Sets an enum, checking it hasn't already been set to a different value  */
+#define DSET(dpc,member,enumname,str,valname) do{                      \
+       if (dpc->disk->member != LIBXL_DISK_##enumname##_UNKNOWN &&     \
+           dpc->disk->member != LIBXL_DISK_##enumname##_##valname) {   \
+           xlu__disk_err(dpc, str, TOSTRING(member) " respecified");   \
+       } else {                                                        \
+           dpc->disk->member = LIBXL_DISK_##enumname##_##valname;      \
+       }                                                               \
+    }while(0)
+
+/* For actions whose patterns contain '=', finds the start of the value */
+#define FROMEQUALS (strchr(yytext,'=')+1)
+
+/* Chops the delimiter off, modifying yytext and yyleng. */
+#define STRIP(delim) do{                                                \
+       if (yyleng>0 && yytext[yyleng-1]==(delim))                      \
+           yytext[--yyleng] = 0;                                       \
+    }while(0)
+
+/* Sets a string value, checking it hasn't been set already. */
+#define SAVESTRING(what,loc,val) do{                                   \
+       savestring(DPC, what " respecified", &DPC->disk->loc, (val));   \
+    }while(0)
+static void savestring(DiskParseContext *dpc, const char *what_respecified,
+                      char **update, const char *value) {
+    if (*update) {
+        if (**update) { xlu__disk_err(dpc,value,what_respecified); return; }
+        free(*update); /* do not complain about overwriting empty strings */
+    }
+    *update = strdup(value);
+}
+
+/* Sets ->readwrite from the string.  This ought to be an enum, perhaps. */
+static void setaccess(DiskParseContext *dpc, const char *str) {
+    if (!strcmp(str, "r") || !strcmp(str, "ro")) {
+        dpc->disk->readwrite = 0;
+    } else if (!strcmp(str, "rw") || !strcmp(str, "w") || !strcmp(str,"")) {
+       dpc->disk->readwrite = 1;
+    } else {
+       xlu__disk_err(dpc,str,"unknown value for access");
+    }
+}
+
+/* Sets ->format from the string.  IDL should provide something for this. */
+static void setformat(DiskParseContext *dpc, const char *str) {
+    if (!strcmp(str,"") ||
+             !strcmp(str,"raw"))    DSET(dpc,format,FORMAT,str,RAW);
+    else if (!strcmp(str,"qcow"))   DSET(dpc,format,FORMAT,str,QCOW);
+    else if (!strcmp(str,"qcow2"))  DSET(dpc,format,FORMAT,str,QCOW2);
+    else if (!strcmp(str,"vhd"))    DSET(dpc,format,FORMAT,str,VHD);
+    else xlu__disk_err(dpc,str,"unknown value for format");
+}
+ 
+#define DEPRECATE(usewhatinstead) /* not currently reported */
+
+%}
+
+%option warn
+%option nodefault
+%option batch
+%option 8bit
+%option noyywrap
+%option reentrant
+%option prefix="xlu__disk_yy"
+%option nounput
+
+%x LEXERR
+
+%%
+
+ /*----- the scanner rules which do the parsing -----*/
+
+[ \t\n]+/([^ \t\n].*)? { /* ignore whitespace before parameters */ }
+
+ /* ordinary parameters setting enums or strings */
+
+format=[^,]*,? { STRIP(','); setformat(DPC, FROMEQUALS); }
+
+cdrom,?                { DPC->disk->is_cdrom = 1; }
+devtype=cdrom,?        { DPC->disk->is_cdrom = 1; }
+devtype=disk,? { DPC->disk->is_cdrom = 0; }
+devtype=[^,]*,?        { xlu__disk_err(DPC,yytext,"unknown value for type"); }
+
+access=[^,]*,? { STRIP(','); setaccess(DPC, FROMEQUALS); }
+
+vdev=[^,]*,?   { STRIP(','); SAVESTRING("vdev", vdev, FROMEQUALS); }
+script=[^,]*,? { STRIP(','); SAVESTRING("script", script, FROMEQUALS); }
+
+ /* the target magic parameter, eats the rest of the string */
+
+target=.*      { STRIP(','); SAVESTRING("target", pdev_path, FROMEQUALS); }
+
+ /* unknown parameters */
+
+[a-z][-a-z0-9]*=[^,],? { xlu__disk_err(DPC,yytext,"unknown parameter"); }
+
+ /* deprecated prefixes */
+
+  /* the "/.*" in these patterns ensures that they count as if they
+   * matched the whole string, so these patterns take precedence */
+
+(raw|qcow2?|vhd):/.* {
+                    STRIP(':');
+                    DPC->had_depr_prefix=1; DEPRECATE("use `[format=]...,'");
+                    setformat(DPC, yytext);
+                 }
+
+iscsi:|e?nbd:drbd:/.* {
+                   STRIP(':');
+                    DPC->had_depr_prefix=1; DEPRECATE("use `script=...'");
+                   SAVESTRING("script", script, yytext);
+               }
+
+tapdisk:/.*    { DPC->had_depr_prefix=1; DEPRECATE(0); }
+tap2?:/.*      { DPC->had_depr_prefix=1; DEPRECATE(0); }
+aio:/.*                { DPC->had_depr_prefix=1; DEPRECATE(0); }
+ioemu:/.*      { DPC->had_depr_prefix=1; DEPRECATE(0); }
+file:/.*       { DPC->had_depr_prefix=1; DEPRECATE(0); }
+phy:/.*                { DPC->had_depr_prefix=1; DEPRECATE(0); }
+
+[a-z][a-z0-9]*:/([^a-z0-9].*)? {
+                 xlu__disk_err(DPC,yytext,"unknown deprecated disk prefix");
+                 return 0;
+               }
+
+ /* positional parameters */
+
+[^=,]*,|[^=,]+,?  {
+    char *colon;
+    STRIP(',');
+
+    if (DPC->err) {
+        /* previous errors may just lead to subsequent ones */
+    } else if (!DPC->disk->pdev_path) {
+        SAVESTRING("target", pdev_path, yytext);
+    } else if (!DPC->had_depr_prefix &&
+               DPC->disk->format == LIBXL_DISK_FORMAT_UNKNOWN) {
+        setformat(DPC,yytext);
+    } else if (!DPC->disk->vdev) {
+        colon = strrchr(yytext, ':');
+        if (colon) {
+            DEPRECATE("use `devtype=...'");
+            *colon++ = 0;
+            if (!strcmp(colon,"cdrom")) {
+                DPC->disk->is_cdrom = 1;
+            } else if (!strcmp(colon,"disk")) {
+                DPC->disk->is_cdrom = 0;
+            } else {
+                xlu__disk_err(DPC,colon,"unknown deprecated type");
+            }
+        }
+        SAVESTRING("vdev", vdev, yytext);
+    } else if (!DPC->access_set) {
+        DPC->access_set = 1;
+        setaccess(DPC,yytext);
+    } else {
+        xlu__disk_err(DPC,yytext,"too many positional parameters");
+        return 0; /* don't print any more errors */
+    }
+}
+
+. {
+    BEGIN(LEXERR);
+    yymore();
+}
+<LEXERR>.* {
+    xlu__disk_err(DPC,yytext,"bad disk syntax"); return 0;
+}
diff -r 3173b68c8a94 -r 77a235e95b47 tools/libxl/libxlutil.h
--- a/tools/libxl/libxlutil.h   Tue Jun 28 12:19:10 2011 +0100
+++ b/tools/libxl/libxlutil.h   Tue Jun 28 12:19:11 2011 +0100
@@ -58,4 +58,27 @@
   /* xlu_cfg_get_listitem cannot fail, except that if entry is
    * out of range it returns 0 (not setting errno) */
 
+
+/*
+ * Disk specification parsing.
+ */
+
+int xlu_disk_parse(XLU_Config *cfg, int nspecs, const char *const *specs,
+                  libxl_device_disk *disk);
+  /* disk must have been initialised.
+   *
+   * On error, returns errno value.  Bad strings cause EINVAL and
+   * print a message to cfg's report (that's all cfg is used for).
+   *
+   * Normally one would pass nspecs==1 and only specs[0].  But it is
+   * permitted to pass more strings in which case each is parsed as a
+   * string containing a collection of parameters (but they all refer
+   * to of the configuration for a single disk).
+   *
+   * nspecs==0 is permitted but since it does not specify some mandatory
+   * properties, it produces a run-time configuration error if the
+   * resulting disk struct is used with libxl.
+   */
+
+
 #endif /* LIBXLUTIL_H */

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] libxl: disks: new xlu_disk_parse function, Xen patchbot-unstable <=