direct-io.hg

changeset 7479:5a728a884242

Instead of writing errors to
/local/domain/0/backend/<devclass>/<dom>/<devid>/error, write them instead to
/local/domain/0/error/backend/<yada>. This is not the best place for them
perhaps, but it moves them out of the backend directory, on which the drivers
have a watch. This fixes the problem whereby writing an error will trigger a
watch, causing the error message to be written again, and repeat. Fixes bug
#286.

Signed-off-by: Ewan Mellor <ewan@xensource.com>
author emellor@leeni.uk.xensource.com
date Sun Oct 23 22:34:13 2005 +0100 (2005-10-23)
parents 2c0b3b807756
children a90d670c98b9
files linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c tools/examples/xen-backend.agent tools/python/xen/util/diagnose.py
line diff
     1.1 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c	Sun Oct 23 16:54:51 2005 +0100
     1.2 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c	Sun Oct 23 22:34:13 2005 +0100
     1.3 @@ -516,17 +516,38 @@ int xenbus_printf(struct xenbus_transact
     1.4  }
     1.5  EXPORT_SYMBOL(xenbus_printf);
     1.6  
     1.7 +/**
     1.8 + * Return the path to the error node for the given device, or NULL on failure.
     1.9 + * If the value returned is non-NULL, then it is the caller's to kfree.
    1.10 + */
    1.11 +static char *error_path(struct xenbus_device *dev)
    1.12 +{
    1.13 +	char *path_buffer = kmalloc(strlen("error/") + strlen(dev->nodename) +
    1.14 +				    1, GFP_KERNEL);
    1.15 +	if (path_buffer == NULL) {
    1.16 +		return NULL;
    1.17 +	}
    1.18 +
    1.19 +	strcpy(path_buffer, "error/");
    1.20 +	strcpy(path_buffer + strlen("error/"), dev->nodename);
    1.21 +
    1.22 +	return path_buffer;
    1.23 +}
    1.24 +
    1.25  /* Report a (negative) errno into the store, with explanation. */
    1.26  void xenbus_dev_error(struct xenbus_device *dev, int err, const char *fmt, ...)
    1.27  {
    1.28  	va_list ap;
    1.29  	int ret;
    1.30  	unsigned int len;
    1.31 -	char *printf_buffer;
    1.32 +	char *printf_buffer = NULL, *path_buffer = NULL;
    1.33  
    1.34  	printf_buffer = kmalloc(PRINTF_BUFFER_SIZE, GFP_KERNEL);
    1.35 -	if (printf_buffer == NULL)
    1.36 +	if (printf_buffer == NULL) {
    1.37 +		printk("xenbus: failed to write error node for %s (%d): %d\n",
    1.38 +		       dev->nodename, err, errno);
    1.39  		goto fail;
    1.40 +	}
    1.41  
    1.42  	len = sprintf(printf_buffer, "%i ", -err);
    1.43  	va_start(ap, fmt);
    1.44 @@ -535,15 +556,26 @@ void xenbus_dev_error(struct xenbus_devi
    1.45  
    1.46  	BUG_ON(len + ret > PRINTF_BUFFER_SIZE-1);
    1.47  	dev->has_error = 1;
    1.48 -	if (xenbus_write(NULL, dev->nodename, "error", printf_buffer) != 0)
    1.49 +
    1.50 +	path_buffer = error_path(dev);
    1.51 +
    1.52 +	if (path_buffer == NULL) {
    1.53 +		printk("xenbus: failed to write error node for %s (%s): %d\n",
    1.54 +		       dev->nodename, printf_buffer, errno);
    1.55  		goto fail;
    1.56 +	}
    1.57  
    1.58 -	kfree(printf_buffer);
    1.59 -	return;
    1.60 +	if (xenbus_write(NULL, path_buffer, "error", printf_buffer) != 0) {
    1.61 +		printk("xenbus: failed to write error node for %s (%s)\n",
    1.62 +		       dev->nodename, printf_buffer);
    1.63 +		goto fail;
    1.64 +	}
    1.65  
    1.66 - fail:
    1.67 -	printk("xenbus: failed to write error node for %s (%s)\n",
    1.68 -	       dev->nodename, printf_buffer);
    1.69 +fail:
    1.70 +	if (printf_buffer)
    1.71 +		kfree(printf_buffer);
    1.72 +	if (path_buffer)
    1.73 +		kfree(path_buffer);
    1.74  }
    1.75  EXPORT_SYMBOL(xenbus_dev_error);
    1.76  
    1.77 @@ -551,11 +583,21 @@ EXPORT_SYMBOL(xenbus_dev_error);
    1.78  void xenbus_dev_ok(struct xenbus_device *dev)
    1.79  {
    1.80  	if (dev->has_error) {
    1.81 -		if (xenbus_rm(NULL, dev->nodename, "error") != 0)
    1.82 +		char *path_buffer = error_path(dev);
    1.83 +
    1.84 +		if (path_buffer == NULL) {
    1.85 +			printk("xenbus: failed to clear error node for %s: "
    1.86 +			       "%d\n", dev->nodename, errno);
    1.87 +			return;
    1.88 +		}
    1.89 +
    1.90 +		if (xenbus_rm(NULL, path_buffer, "error") != 0)
    1.91  			printk("xenbus: failed to clear error node for %s\n",
    1.92  			       dev->nodename);
    1.93  		else
    1.94  			dev->has_error = 0;
    1.95 +
    1.96 +		kfree(path_buffer);
    1.97  	}
    1.98  }
    1.99  EXPORT_SYMBOL(xenbus_dev_ok);
     2.1 --- a/tools/examples/xen-backend.agent	Sun Oct 23 16:54:51 2005 +0100
     2.2 +++ b/tools/examples/xen-backend.agent	Sun Oct 23 22:34:13 2005 +0100
     2.3 @@ -15,9 +15,13 @@ case "$ACTION" in
     2.4        vbd)
     2.5  	/etc/xen/scripts/block unbind
     2.6          ;;
     2.7 +      vif)
     2.8 +        [ -n "$script" ] && $script down
     2.9 +        ;;
    2.10      esac
    2.11      # remove device backend store entries
    2.12      xenstore-rm -t "$XENBUS_PATH"
    2.13 +    xenstore-rm -t "error/$XENBUS_PATH"
    2.14      ;;
    2.15    online)
    2.16      case "$XENBUS_TYPE" in
     3.1 --- a/tools/python/xen/util/diagnose.py	Sun Oct 23 16:54:51 2005 +0100
     3.2 +++ b/tools/python/xen/util/diagnose.py	Sun Oct 23 22:34:13 2005 +0100
     3.3 @@ -107,7 +107,9 @@ def diagnose_devices():
     3.4                  print ("Cannot find backend path for device %s, %s." %
     3.5                         (deviceClass, device))
     3.6              else:
     3.7 -                backend_error = xstransact.Read(backendPath, 'error')
     3.8 +                backend_error = xstransact.Read(
     3.9 +                    backendPath.replace('backend/', 'error/backend/'),
    3.10 +                    'error')
    3.11  
    3.12                  if backend_error:
    3.13                      diagnose_device_error(backend_error)