Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 208280
b: refs/heads/master
c: 5b61cb9
h: refs/heads/master
v: v3
  • Loading branch information
Daniel Stodden authored and Jens Axboe committed Aug 7, 2010
1 parent bd2a223 commit 820dd83
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 25 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 2def141e71d54eccac98dc2c2ba71a82c91b324e
refs/heads/master: 5b61cb90c2ad8c853b4dd53eec200bacd2f02172
90 changes: 66 additions & 24 deletions trunk/drivers/xen/xenbus/xenbus_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -133,17 +133,12 @@ int xenbus_watch_pathfmt(struct xenbus_device *dev,
}
EXPORT_SYMBOL_GPL(xenbus_watch_pathfmt);

static void xenbus_switch_fatal(struct xenbus_device *, int, int,
const char *, ...);

/**
* xenbus_switch_state
* @dev: xenbus device
* @state: new state
*
* Advertise in the store a change of the given driver to the given new_state.
* Return 0 on success, or -errno on error. On error, the device will switch
* to XenbusStateClosing, and the error will be saved in the store.
*/
int xenbus_switch_state(struct xenbus_device *dev, enum xenbus_state state)
static int
__xenbus_switch_state(struct xenbus_device *dev,
enum xenbus_state state, int depth)
{
/* We check whether the state is currently set to the given value, and
if not, then the state is set. We don't want to unconditionally
Expand All @@ -152,35 +147,65 @@ int xenbus_switch_state(struct xenbus_device *dev, enum xenbus_state state)
to it, as the device will be tearing down, and we don't want to
resurrect that directory.
Note that, because of this cached value of our state, this function
will not work inside a Xenstore transaction (something it was
trying to in the past) because dev->state would not get reset if
the transaction was aborted.
Note that, because of this cached value of our state, this
function will not take a caller's Xenstore transaction
(something it was trying to in the past) because dev->state
would not get reset if the transaction was aborted.
*/

struct xenbus_transaction xbt;
int current_state;
int err;
int err, abort;

if (state == dev->state)
return 0;

err = xenbus_scanf(XBT_NIL, dev->nodename, "state", "%d",
&current_state);
if (err != 1)
again:
abort = 1;

err = xenbus_transaction_start(&xbt);
if (err) {
xenbus_switch_fatal(dev, depth, err, "starting transaction");
return 0;
}

err = xenbus_scanf(xbt, dev->nodename, "state", "%d", &current_state);
if (err != 1)
goto abort;

err = xenbus_printf(XBT_NIL, dev->nodename, "state", "%d", state);
err = xenbus_printf(xbt, dev->nodename, "state", "%d", state);
if (err) {
if (state != XenbusStateClosing) /* Avoid looping */
xenbus_dev_fatal(dev, err, "writing new state");
return err;
xenbus_switch_fatal(dev, depth, err, "writing new state");
goto abort;
}

dev->state = state;
abort = 0;
abort:
err = xenbus_transaction_end(xbt, abort);
if (err) {
if (err == -EAGAIN && !abort)
goto again;
xenbus_switch_fatal(dev, depth, err, "ending transaction");
} else
dev->state = state;

return 0;
}

/**
* xenbus_switch_state
* @dev: xenbus device
* @state: new state
*
* Advertise in the store a change of the given driver to the given new_state.
* Return 0 on success, or -errno on error. On error, the device will switch
* to XenbusStateClosing, and the error will be saved in the store.
*/
int xenbus_switch_state(struct xenbus_device *dev, enum xenbus_state state)
{
return __xenbus_switch_state(dev, state, 0);
}

EXPORT_SYMBOL_GPL(xenbus_switch_state);

int xenbus_frontend_closed(struct xenbus_device *dev)
Expand Down Expand Up @@ -283,6 +308,23 @@ void xenbus_dev_fatal(struct xenbus_device *dev, int err, const char *fmt, ...)
}
EXPORT_SYMBOL_GPL(xenbus_dev_fatal);

/**
* Equivalent to xenbus_dev_fatal(dev, err, fmt, args), but helps
* avoiding recursion within xenbus_switch_state.
*/
static void xenbus_switch_fatal(struct xenbus_device *dev, int depth, int err,
const char *fmt, ...)
{
va_list ap;

va_start(ap, fmt);
xenbus_va_dev_error(dev, err, fmt, ap);
va_end(ap);

if (!depth)
__xenbus_switch_state(dev, XenbusStateClosing, 1);
}

/**
* xenbus_grant_ring
* @dev: xenbus device
Expand Down

0 comments on commit 820dd83

Please sign in to comment.