[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 4/5] scripts: qmp-shell: add transaction subshell
From: |
John Snow |
Subject: |
[Qemu-devel] [PATCH 4/5] scripts: qmp-shell: add transaction subshell |
Date: |
Tue, 21 Apr 2015 22:02:34 -0400 |
Add a special processing mode to craft transactions.
By entering "transaction(" the shell will enter a special
mode where each subsequent command will be saved as a transaction
instead of executed as an individual command.
The transaction can be submitted by entering ")" on a line by itself.
Examples:
Separate lines:
(QEMU) transaction(
TRANS> block-dirty-bitmap-add node=drive0 name=bitmap1
TRANS> block-dirty-bitmap-clear node=drive0 name=bitmap0
TRANS> )
With a transaction action included on the first line:
(QEMU) transaction( block-dirty-bitmap-add node=drive0 name=bitmap2
TRANS> block-dirty-bitmap-add node=drive0 name=bitmap3
TRANS> )
As a one-liner, with just one transation action:
(QEMU) transaction( block-dirty-bitmap-add node=drive0 name=bitmap0 )
Signed-off-by: John Snow <address@hidden>
---
scripts/qmp/qmp-shell | 43 ++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 42 insertions(+), 1 deletion(-)
diff --git a/scripts/qmp/qmp-shell b/scripts/qmp/qmp-shell
index d7cb33d..21d8f71 100755
--- a/scripts/qmp/qmp-shell
+++ b/scripts/qmp/qmp-shell
@@ -59,6 +59,8 @@ class QMPShell(qmp.QEMUMonitorProtocol):
self._greeting = None
self._completer = None
self._pp = pp
+ self._transmode = False
+ self._actions = list()
def __get_address(self, arg):
"""
@@ -130,6 +132,37 @@ class QMPShell(qmp.QEMUMonitorProtocol):
< command-name > [ arg-name1=arg1 ] ... [ arg-nameN=argN ]
"""
cmdargs = cmdline.replace("'", '"').split()
+
+ # Transactional CLI entry/exit:
+ if cmdargs[0] == 'transaction(':
+ self._transmode = True
+ cmdargs.pop(0)
+ elif cmdargs[0] == ')' and self._transmode:
+ self._transmode = False
+ cmdargs.pop(0)
+ if cmdargs:
+ raise QMPShellError("Unexpected input after close of
Transaction sub-shell")
+ qmpcmd = { 'execute': 'transaction',
+ 'arguments': { 'actions': self._actions } }
+ self._actions = list()
+ return qmpcmd
+
+ # Nothing to process?
+ if not cmdargs:
+ return None
+
+ # Parse and then cache this Transactional Action
+ if self._transmode:
+ finalize = False
+ action = { 'type': cmdargs[0], 'data': {} }
+ if cmdargs[-1] == ')':
+ cmdargs.pop(-1)
+ finalize = True
+ self.__cli_expr(cmdargs[1:], action['data'])
+ self._actions.append(action)
+ return self.__build_cmd(')') if finalize else None
+
+ # Standard command: parse and return it to be executed.
qmpcmd = { 'execute': cmdargs[0], 'arguments': {} }
self.__cli_expr(cmdargs[1:], qmpcmd['arguments'])
return qmpcmd
@@ -142,6 +175,9 @@ class QMPShell(qmp.QEMUMonitorProtocol):
print 'command format: <command-name> ',
print '[arg-name1=arg1] ... [arg-nameN=argN]'
return True
+ # For transaction mode, we may have just cached the action:
+ if qmpcmd is None:
+ return True
resp = self.cmd_obj(qmpcmd)
if resp is None:
print 'Disconnected'
@@ -162,6 +198,11 @@ class QMPShell(qmp.QEMUMonitorProtocol):
version = self._greeting['QMP']['version']['qemu']
print 'Connected to QEMU %d.%d.%d\n' %
(version['major'],version['minor'],version['micro'])
+ def get_prompt(self):
+ if self._transmode:
+ return "TRANS> "
+ return "(QEMU) "
+
def read_exec_command(self, prompt):
"""
Read and execute a command.
@@ -301,7 +342,7 @@ def main():
die('Could not connect to %s' % addr)
qemu.show_banner()
- while qemu.read_exec_command('(QEMU) '):
+ while qemu.read_exec_command(qemu.get_prompt()):
pass
qemu.close()
--
2.1.0
- [Qemu-devel] [PATCH 1/5] scripts: qmp-shell: refactor helpers, (continued)
- [Qemu-devel] [PATCH 4/5] scripts: qmp-shell: add transaction subshell,
John Snow <=
[Qemu-devel] [PATCH 5/5] scripts: qmp-shell: Add verbose flag, John Snow, 2015/04/21