From f633d641c21f45e46aa9585fc38389da033c0212 Mon Sep 17 00:00:00 2001 From: "Sarang S. Dalal" Date: Sun, 29 Oct 2017 10:23:31 +0100 Subject: [PATCH 1/6] replace deprecated vfs_read with kernel_read See https://github.com/anbox/anbox/issues/486 and related issue with ashmem and ZFS: https://github.com/zfsonlinux/spl/issues/656 --- kernel/ashmem/ashmem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/ashmem/ashmem.c b/kernel/ashmem/ashmem.c index c846db6..4fde1d7 100644 --- a/kernel/ashmem/ashmem.c +++ b/kernel/ashmem/ashmem.c @@ -313,7 +313,7 @@ static ssize_t ashmem_read(struct file *file, char __user *buf, * be destroyed until all references to the file are dropped and * ashmem_release is called. */ - ret = __vfs_read(asma->file, buf, len, pos); + ret = kernel_read(asma->file, buf, len, pos); if (ret >= 0) /** Update backing file pos, since f_ops->read() doesn't */ asma->file->f_pos = *pos; From 1c7eef1fd364b6289972ef0487fc3a303d28f378 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 17 Nov 2017 12:24:20 +0000 Subject: [PATCH 2/6] anbox: qemu: qemud_message_processor: Handle multiple 'cat'ed messages It is possible for more than one message to be delivered concurrently. When this happens, messages are concatenated together (end-to-end). Current code errors out if the total received data is larger than the known header_size (4) + the body size (reported in the header). However, when >=2 messages arrive at the same time, the total received data will be far greater than this. The current code base actually handles multiple messages perfectly already, so all we need to do is remove the early return and everything "just works". Signed-off-by: Lee Jones --- src/anbox/qemu/qemud_message_processor.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/anbox/qemu/qemud_message_processor.cpp b/src/anbox/qemu/qemud_message_processor.cpp index c9d5b50..d9ee009 100644 --- a/src/anbox/qemu/qemud_message_processor.cpp +++ b/src/anbox/qemu/qemud_message_processor.cpp @@ -51,7 +51,6 @@ void QemudMessageProcessor::process_commands() { unsigned int body_size = 0; ::sscanf(header, "%04x", &body_size); - if (body_size != buffer_.size() - header_size) break; std::string command; // Make sure we only copy as much bytes as we have to and not more From 642330e22c367458ece2fe11dce68082d42e1d2b Mon Sep 17 00:00:00 2001 From: step21 Date: Thu, 4 Jan 2018 21:06:43 +0100 Subject: [PATCH 3/6] python 3 compatible --- scripts/gen-emugl-entries.py | 184 ++++++++++++++++++----------------- 1 file changed, 94 insertions(+), 90 deletions(-) diff --git a/scripts/gen-emugl-entries.py b/scripts/gen-emugl-entries.py index a122ef7..851dbe7 100755 --- a/scripts/gen-emugl-entries.py +++ b/scripts/gen-emugl-entries.py @@ -128,28 +128,28 @@ def gen_functions_header(entries, prefix_name, verbatim, filename, with_args): """ prefix_name = prefix_name.upper() - print "// Auto-generated with: %s" % banner_command(sys.argv) - print "// DO NOT EDIT THIS FILE" - print "" - print "#ifndef %s_FUNCTIONS_H" % prefix_name - print "#define %s_FUNCTIONS_H" % prefix_name - print "" + print("// Auto-generated with: %s" % banner_command(sys.argv)) + print("// DO NOT EDIT THIS FILE") + print("") + print("#ifndef %s_FUNCTIONS_H" % prefix_name) + print("#define %s_FUNCTIONS_H" % prefix_name) + print("") for line in verbatim: - print line + print(line) - print "#define LIST_%s_FUNCTIONS(X) \\" % prefix_name + print("#define LIST_%s_FUNCTIONS(X) \\" % prefix_name) for entry in entries: if with_args: - print " X(%s, %s, (%s), (%s)) \\" % \ + print(" X(%s, %s, (%s), (%s)) \\" % \ (entry.return_type, entry.func_name, entry.parameters, - entry.call) + entry.call)) else: - print " X(%s, %s, (%s)) \\" % \ - (entry.return_type, entry.func_name, entry.parameters) + print(" X(%s, %s, (%s)) \\" % \ + (entry.return_type, entry.func_name, entry.parameters)) - print "" - print "" - print "#endif // %s_FUNCTIONS_H" % prefix_name + print("") + print("") + print("#endif // %s_FUNCTIONS_H" % prefix_name) @@ -199,10 +199,10 @@ def gen_translator(entries): "glProgramUniform3ui": 1, "glProgramUniform4ui": 1, "glBindVertexBuffer": 1, - }; + } translator_nocontext_fail_codes = { "glClientWaitSync" : "GL_WAIT_FAILED", - }; + } def needExternC(entry): if translator_needexternc.has_key(entry.func_name): return "extern \"C\" " @@ -210,14 +210,14 @@ def gen_translator(entries): return "" def get_fail_code(entry): if translator_nocontext_fail_codes.has_key(entry.func_name): - return translator_nocontext_fail_codes[entry.func_name]; + return translator_nocontext_fail_codes[entry.func_name] else: return "0" def gen_cxt_getter(entry): if (entry.return_type == "void"): - print " GET_CTX_V2();" + print(" GET_CTX_V2();") else: - print " GET_CTX_V2_RET(%s);" % get_fail_code(entry) + print(" GET_CTX_V2_RET(%s);" % get_fail_code(entry)) def gen_validations_custom_impl(entry): isGen = entry.func_name.startswith("glGen") @@ -231,14 +231,14 @@ def gen_translator(entries): if entry.return_type == "void": return "SET_ERROR_IF(%s,%s)" % (condition, glerr); else: - return "RET_AND_SET_ERROR_IF(%s,%s,%s)" % (condition, glerr, get_fail_code(entry)); + return "RET_AND_SET_ERROR_IF(%s,%s,%s)" % (condition, glerr, get_fail_code(entry)) if (isGen or isDelete) and ("n" in entry.varnames): - print " %s;" % mySetError("n < 0", "GL_INVALID_VALUE"); + print(" %s;" % mySetError("n < 0", "GL_INVALID_VALUE")) if (isBufferOp and hasTargetArg): - print " %s;" % mySetError("!GLESv2Validate::bufferTarget(ctx, target)", "GL_INVALID_ENUM"); + print(" %s;" % mySetError("!GLESv2Validate::bufferTarget(ctx, target)", "GL_INVALID_ENUM")) if translator_custom_pre.has_key(entry.func_name): - print translator_custom_pre[entry.func_name], + print(translator_custom_pre[entry.func_name],) def gen_call_ret(entry): globalNameTypes = { @@ -262,53 +262,53 @@ def gen_translator(entries): needsShareGroup = True if needsShareGroup: - print " if (ctx->shareGroup().get()) {" + print(" if (ctx->shareGroup().get()) {") for key in zip(entry.vartypes, entry.varnames): vartype, varname = key if globalNames.has_key(key): - print " const GLuint %s = ctx->shareGroup()->getGlobalName(%s, %s);" % (globalNames[key], globalNameTypes[key], varname) + print(" const GLuint %s = ctx->shareGroup()->getGlobalName(%s, %s);" % (globalNames[key], globalNameTypes[key], varname)) globalCall = ", ".join(map(lambda k: globalNames.get(k, k[1]), zip(entry.vartypes, entry.varnames))) if needsShareGroup and translator_custom_share_processing.has_key(entry.func_name): - print translator_custom_share_processing[entry.func_name], + print(translator_custom_share_processing[entry.func_name]) if (entry.return_type == "void"): if (needsShareGroup): - print " ", + print(" "), if not translator_no_passthrough.has_key(entry.func_name): - print " ctx->dispatcher().%s(%s);" % (entry.func_name, globalCall) + print(" ctx->dispatcher().%s(%s);" % (entry.func_name, globalCall)) if needsShareGroup: - print " }" + print(" }") if translator_custom_post.has_key(entry.func_name): - print translator_custom_post[entry.func_name]; + print(translator_custom_post[entry.func_name]) else: if (needsShareGroup): - print " ", + print(" "), if not translator_no_passthrough.has_key(entry.func_name): - print " %s %s = ctx->dispatcher().%s(%s);" % (entry.return_type, entry.func_name + "RET", entry.func_name, globalCall) + print(" %s %s = ctx->dispatcher().%s(%s);" % (entry.return_type, entry.func_name + "RET", entry.func_name, globalCall)) else: - print " %s %s = %s" % (entry.return_type, entry_func_name + "RET", get_fail_code(entry)) + print(") %s %s = %s" % (entry.return_type, entry_func_name + "RET", get_fail_code(entry))) if translator_custom_post.has_key(entry.func_name): - print translator_custom_post[entry.func_name]; + print(translator_custom_post[entry.func_name]) - print " return %s;" % (entry.func_name + "RET"); + print(" return %s;" % (entry.func_name + "RET")) if needsShareGroup: - print " } else return %s;" % (get_fail_code(entry)) + print(" } else return %s;" % (get_fail_code(entry))) - print "// Auto-generated with: %s" % banner_command(sys.argv) - print "// This file is best left unedited." - print "// Try to make changes through gen_translator in gen-entries.py," - print "// and/or parcel out custom functionality in separate code." + print("// Auto-generated with: %s" % banner_command(sys.argv)) + print("// This file is best left unedited.") + print("// Try to make changes through gen_translator in gen-entries.py,") + print("// and/or parcel out custom functionality in separate code.") for entry in entries: - print "%sGL_APICALL %s GL_APIENTRY %s(%s) {" % (needExternC(entry), entry.return_type, entry.func_name, entry.parameters) - gen_cxt_getter(entry); - gen_validations_custom_impl(entry); - gen_call_ret(entry); - print "}\n" + print("%sGL_APICALL %s GL_APIENTRY %s(%s) {" % (needExternC(entry), entry.return_type, entry.func_name, entry.parameters)) + gen_cxt_getter(entry) + gen_validations_custom_impl(entry) + gen_call_ret(entry) + print("}\n") def gen_dll_wrapper(entries, prefix_name, verbatim, filename): """Generate a C source file that contains functions that act as wrappers @@ -322,77 +322,77 @@ def gen_dll_wrapper(entries, prefix_name, verbatim, filename): ENTRY_PREFIX = "__dll_" - print "// Auto-generated with: %s" % banner_command(sys.argv) - print "// DO NOT EDIT THIS FILE" - print "" - print "#include " + print("// Auto-generated with: %s" % banner_command(sys.argv)) + print("// DO NOT EDIT THIS FILE") + print("") + print("#include ") for line in verbatim: - print line + print(line) - print "" - print "///" - print "/// W R A P P E R P O I N T E R S" - print "///" - print "" + print("") + print("///") + print("/// W R A P P E R P O I N T E R S") + print("///") + print("") for entry in entries: ptr_name = ENTRY_PREFIX + entry.func_name - print "static %s (*%s)(%s) = 0;" % \ - (entry.return_type, ptr_name, entry.parameters) + print("static %s (*%s)(%s) = 0;" % \ + (entry.return_type, ptr_name, entry.parameters)) - print "" - print "///" - print "/// W R A P P E R F U N C T I O N S" - print "///" - print "" + print("") + print("///") + print("/// W R A P P E R F U N C T I O N S") + print("///") + print("") for entry in entries: - print "%s %s(%s) {" % \ - (entry.return_type, entry.func_name, entry.parameters) + print ("%s %s(%s) {" % \ + (entry.return_type, entry.func_name, entry.parameters)) ptr_name = ENTRY_PREFIX + entry.func_name if entry.return_type != "void": - print " return %s(%s);" % (ptr_name, entry.call) + print(" return %s(%s);" % (ptr_name, entry.call)) else: - print " %s(%s);" % (ptr_name, entry.call) - print "}\n" + print(" %s(%s);" % (ptr_name, entry.call)) + print("}\n") - print "" - print "///" - print "/// I N I T I A L I Z A T I O N F U N C T I O N" - print "///" - print "" + print("") + print("///") + print("/// I N I T I A L I Z A T I O N F U N C T I O N") + print("///") + print("") - print "int %s_dynlink_init(void* lib) {" % prefix_name + print("int %s_dynlink_init(void* lib) {" % prefix_name) for entry in entries: ptr_name = ENTRY_PREFIX + entry.func_name - print " %s = (%s(*)(%s))dlsym(lib, \"%s\");" % \ + print(" %s = (%s(*)(%s))dlsym(lib, \"%s\");" % \ (ptr_name, entry.return_type, entry.parameters, - entry.func_name) - print " if (!%s) return -1;" % ptr_name - print " return 0;" - print "}" + entry.func_name)) + print(" if (!%s) return -1;" % ptr_name) + print(" return 0;") + print("}") def gen_windows_def_file(entries): """Generate a windows DLL .def file. |entries| is a list of Entry instances. """ - print "EXPORTS" + print("EXPORTS") for entry in entries: - print " %s" % entry.func_name + print(" %s" % entry.func_name) def gen_unix_sym_file(entries): """Generate an ELF linker version file. |entries| is a list of Entry instances. """ - print "VERSION {" - print "\tglobal:" + print("VERSION {") + print("\tglobal:") for entry in entries: - print "\t\t%s;" % entry.func_name - print "\tlocal:" - print "\t\t*;" - print "};" + print("\t\t%s;" % entry.func_name) + print("\tlocal:") + print("\t\t*;") + print("};") def gen_symbols(entries, underscore): """Generate a list of symbols from |entries|, a list of Entry instances. @@ -403,7 +403,7 @@ def gen_symbols(entries, underscore): if underscore: prefix = "_" for entry in entries: - print "%s%s" % (prefix, entry.func_name) + print("%s%s" % (prefix, entry.func_name)) def parse_file(filename, lines, mode): """Generate one of possible outputs from |filename|. |lines| must be a list @@ -413,7 +413,9 @@ def parse_file(filename, lines, mode): entries, prefix_name, verbatim, errors = parse_entries_file(lines) if errors: for error in errors: - print >> sys.stderr, "ERROR: %s:%s" % (filename, error) + print("ERROR: %s:%s" % (filename, error)) + #FIXME + #print >> sys.stderr, "ERROR: %s:%s" % (filename, error) sys.exit(1) if not prefix_name: @@ -466,7 +468,9 @@ parser.add_argument("file", help=".entries file path") args = parser.parse_args() if not args.mode: - print >> sys.stderr, "ERROR: Please use --mode=, see --help." + print("ERROR: Please use --mode=, see --help.") + #FIXME + #print >> sys.stderr, "ERROR: Please use --mode=, see --help." sys.exit(1) if args.output: From 3882f3bfa50b6360784d886605bdebd36a1f8ecb Mon Sep 17 00:00:00 2001 From: step21 Date: Fri, 5 Jan 2018 15:29:32 +0100 Subject: [PATCH 4/6] fixed sys.stderr --- scripts/gen-emugl-entries.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/scripts/gen-emugl-entries.py b/scripts/gen-emugl-entries.py index 851dbe7..d651fb2 100755 --- a/scripts/gen-emugl-entries.py +++ b/scripts/gen-emugl-entries.py @@ -25,6 +25,7 @@ # # Anything else is an error. +from __future__ import print_function import re import sys import argparse @@ -32,6 +33,9 @@ import argparse re_func = re.compile(r"""^(.*[\* ])([A-Za-z_][A-Za-z0-9_]*)\((.*)\);$""") re_param = re.compile(r"""^(.*[\* ])([A-Za-z_][A-Za-z0-9_]*)$""") +def eprint(*args, **kwargs): + print(*args, file=sys.stderr, **kwargs) + class Entry: """Small class used to model a single DLL entry point.""" def __init__(self, func_name, return_type, parameters): @@ -413,9 +417,7 @@ def parse_file(filename, lines, mode): entries, prefix_name, verbatim, errors = parse_entries_file(lines) if errors: for error in errors: - print("ERROR: %s:%s" % (filename, error)) - #FIXME - #print >> sys.stderr, "ERROR: %s:%s" % (filename, error) + eprint("ERROR: %s:%s" % (filename, error), file=sys.stderr) sys.exit(1) if not prefix_name: @@ -468,9 +470,7 @@ parser.add_argument("file", help=".entries file path") args = parser.parse_args() if not args.mode: - print("ERROR: Please use --mode=, see --help.") - #FIXME - #print >> sys.stderr, "ERROR: Please use --mode=, see --help." + eprint("ERROR: Please use --mode=, see --help.", file=sys.stderr) sys.exit(1) if args.output: From 0af5a76743717abb1c5ecf0f9baf85085a90af40 Mon Sep 17 00:00:00 2001 From: "Sarang S. Dalal" Date: Tue, 23 Jan 2018 00:18:18 +0100 Subject: [PATCH 5/6] added kernel version check for calling kernel_read vs vfs_read added kernel version check for calling kernel_read vs vfs_read, as suggested here: https://github.com/Asmodee-Box/anbox/commit/55d56994295eae827421a5fffc7ec2370af6015e --- kernel/ashmem/ashmem.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/kernel/ashmem/ashmem.c b/kernel/ashmem/ashmem.c index 4fde1d7..dd15960 100644 --- a/kernel/ashmem/ashmem.c +++ b/kernel/ashmem/ashmem.c @@ -313,7 +313,11 @@ static ssize_t ashmem_read(struct file *file, char __user *buf, * be destroyed until all references to the file are dropped and * ashmem_release is called. */ - ret = kernel_read(asma->file, buf, len, pos); + #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 9, 0) + ret = __vfs_read(asma->file, buf, len, pos); + #else + ret = kernel_read(asma->file, buf, len, pos); + #endif if (ret >= 0) /** Update backing file pos, since f_ops->read() doesn't */ asma->file->f_pos = *pos; From ba3ae093ed16b76e2a787ae1fb5824ee8d0a6f7f Mon Sep 17 00:00:00 2001 From: "Sarang S. Dalal" Date: Tue, 23 Jan 2018 00:58:08 +0100 Subject: [PATCH 6/6] add comment to explain kernel_read --- kernel/ashmem/ashmem.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kernel/ashmem/ashmem.c b/kernel/ashmem/ashmem.c index dd15960..1831493 100644 --- a/kernel/ashmem/ashmem.c +++ b/kernel/ashmem/ashmem.c @@ -312,6 +312,8 @@ static ssize_t ashmem_read(struct file *file, char __user *buf, * once asma->file is set it will never be changed, and will not * be destroyed until all references to the file are dropped and * ashmem_release is called. + * + * kernel_read supersedes vfs_read from kernel version 3.9 */ #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 9, 0) ret = __vfs_read(asma->file, buf, len, pos);