int ldbRepl(lua_State *lua) {
    sds *argv;
    int argc;

    /* We continue processing commands until a command that should return
     * to the Lua interpreter is found. */
    while(1) {
        while((argv = ldbReplParseCommand(&argc)) == NULL) {
            char buf[1024];
            int nread = connRead(ldb.conn,buf,sizeof(buf));
            if (nread <= 0) {
                /* Make sure the script runs without user input since the
                 * client is no longer connected. */
                ldb.step = 0;
                ldb.bpcount = 0;
                return C_ERR;
            }
            ldb.cbuf = sdscatlen(ldb.cbuf,buf,nread);
        }

        /* Flush the old buffer. */
        sdsfree(ldb.cbuf);
        ldb.cbuf = sdsempty();

        /* Execute the command. */
        if (!strcasecmp(argv[0],"h") || !strcasecmp(argv[0],"help")) {
ldbLog(sdsnew("Redis Lua debugger help:"));
ldbLog(sdsnew("[h]elp               Show this help."));
ldbLog(sdsnew("[s]tep               Run current line and stop again."));
ldbLog(sdsnew("[n]ext               Alias for step."));
ldbLog(sdsnew("[c]continue          Run till next breakpoint."));
ldbLog(sdsnew("[l]list              List source code around current line."));
ldbLog(sdsnew("[l]list [line]       List source code around [line]."));
ldbLog(sdsnew("                     line = 0 means: current position."));
ldbLog(sdsnew("[l]list [line] [ctx] In this form [ctx] specifies how many lines"));
ldbLog(sdsnew("                     to show before/after [line]."));
ldbLog(sdsnew("[w]hole              List all source code. Alias for 'list 1 1000000'."));
ldbLog(sdsnew("[p]rint              Show all the local variables."));
ldbLog(sdsnew("[p]rint <var>        Show the value of the specified variable."));
ldbLog(sdsnew("                     Can also show global vars KEYS and ARGV."));
ldbLog(sdsnew("[b]reak              Show all breakpoints."));
ldbLog(sdsnew("[b]reak <line>       Add a breakpoint to the specified line."));
ldbLog(sdsnew("[b]reak -<line>      Remove breakpoint from the specified line."));
ldbLog(sdsnew("[b]reak 0            Remove all breakpoints."));
ldbLog(sdsnew("[t]race              Show a backtrace."));
ldbLog(sdsnew("[e]eval <code>       Execute some Lua code (in a different callframe)."));
ldbLog(sdsnew("[r]edis <cmd>        Execute a Redis command."));
ldbLog(sdsnew("[m]axlen [len]       Trim logged Redis replies and Lua var dumps to len."));
ldbLog(sdsnew("                     Specifying zero as <len> means unlimited."));
ldbLog(sdsnew("[a]bort              Stop the execution of the script. In sync"));
ldbLog(sdsnew("                     mode dataset changes will be retained."));
ldbLog(sdsnew(""));
ldbLog(sdsnew("Debugger functions you can call from Lua scripts:"));
ldbLog(sdsnew("redis.debug()        Produce logs in the debugger console."));
ldbLog(sdsnew("redis.breakpoint()   Stop execution like if there was a breakpoint in the"));
ldbLog(sdsnew("                     next line of code."));
            ldbSendLogs();
        } else if (!strcasecmp(argv[0],"s") || !strcasecmp(argv[0],"step") ||
                   !strcasecmp(argv[0],"n") || !strcasecmp(argv[0],"next")) {
            ldb.step = 1;
            break;
        } else if (!strcasecmp(argv[0],"c") || !strcasecmp(argv[0],"continue")){
            break;
        } else if (!strcasecmp(argv[0],"t") || !strcasecmp(argv[0],"trace")) {
            ldbTrace(lua);
            ldbSendLogs();
        } else if (!strcasecmp(argv[0],"m") || !strcasecmp(argv[0],"maxlen")) {
            ldbMaxlen(argv,argc);
            ldbSendLogs();
        } else if (!strcasecmp(argv[0],"b") || !strcasecmp(argv[0],"break")) {
            ldbBreak(argv,argc);
            ldbSendLogs();
        } else if (!strcasecmp(argv[0],"e") || !strcasecmp(argv[0],"eval")) {
            ldbEval(lua,argv,argc);
            ldbSendLogs();
        } else if (!strcasecmp(argv[0],"a") || !strcasecmp(argv[0],"abort")) {
            lua_pushstring(lua, "script aborted for user request");
            lua_error(lua);
        } else if (argc > 1 &&
                   (!strcasecmp(argv[0],"r") || !strcasecmp(argv[0],"redis"))) {
            ldbRedis(lua,argv,argc);
            ldbSendLogs();
        } else if ((!strcasecmp(argv[0],"p") || !strcasecmp(argv[0],"print"))) {
            if (argc == 2)
                ldbPrint(lua,argv[1]);
            else
                ldbPrintAll(lua);
            ldbSendLogs();
        } else if (!strcasecmp(argv[0],"l") || !strcasecmp(argv[0],"list")){
            int around = ldb.currentline, ctx = 5;
            if (argc > 1) {
                int num = atoi(argv[1]);
                if (num > 0) around = num;
            }
            if (argc > 2) ctx = atoi(argv[2]);
            ldbList(around,ctx);
            ldbSendLogs();
        } else if (!strcasecmp(argv[0],"w") || !strcasecmp(argv[0],"whole")){
            ldbList(1,1000000);
            ldbSendLogs();
        } else {
            ldbLog(sdsnew("<error> Unknown Redis Lua debugger command or "
                          "wrong number of arguments."));
            ldbSendLogs();
        }

        /* Free the command vector. */
        sdsfreesplitres(argv,argc);
    }

    /* Free the current command argv if we break inside the while loop. */
    sdsfreesplitres(argv,argc);
    return C_OK;
}


int quicklistPushTail(quicklist *quicklist, void *value, size_t sz) {
    quicklistNode *orig_tail = quicklist->tail;
    if (likely(
            _quicklistNodeAllowInsert(quicklist->tail, quicklist->fill, sz))) {
        quicklist->tail->zl =
            ziplistPush(quicklist->tail->zl, value, sz, ZIPLIST_TAIL);
        quicklistNodeUpdateSz(quicklist->tail);
    } else {
        quicklistNode *node = quicklistCreateNode();
        node->zl = ziplistPush(ziplistNew(), value, sz, ZIPLIST_TAIL);

        quicklistNodeUpdateSz(node);
        _quicklistInsertNodeAfter(quicklist, quicklist->tail, node);
    }
    quicklist->count++;
    quicklist->tail->count++;
    return (orig_tail != quicklist->tail);
}


void lposCommand(client *c) {
    robj *o, *ele;
    ele = c->argv[2];
    int direction = LIST_TAIL;
    long rank = 1, count = -1, maxlen = 0; /* Count -1: option not given. */

    /* Parse the optional arguments. */
    for (int j = 3; j < c->argc; j++) {
        char *opt = c->argv[j]->ptr;
        int moreargs = (c->argc-1)-j;

        if (!strcasecmp(opt,"RANK") && moreargs) {
            j++;
            if (getLongFromObjectOrReply(c, c->argv[j], &rank, NULL) != C_OK)
                return;
            if (rank == 0) {
                addReplyError(c,"RANK can't be zero: use 1 to start from "
                                "the first match, 2 from the second, ...");
                return;
            }
        } else if (!strcasecmp(opt,"COUNT") && moreargs) {
            j++;
            if (getLongFromObjectOrReply(c, c->argv[j], &count, NULL) != C_OK)
                return;
            if (count < 0) {
                addReplyError(c,"COUNT can't be negative");
                return;
            }
        } else if (!strcasecmp(opt,"MAXLEN") && moreargs) {
            j++;
            if (getLongFromObjectOrReply(c, c->argv[j], &maxlen, NULL) != C_OK)
                return;
            if (maxlen < 0) {
                addReplyError(c,"MAXLEN can't be negative");
                return;
            }
        } else {
            addReply(c,shared.syntaxerr);
            return;
        }
    }

    /* A negative rank means start from the tail. */
    if (rank < 0) {
        rank = -rank;
        direction = LIST_HEAD;
    }

    /* We return NULL or an empty array if there is no such key (or
     * if we find no matches, depending on the presence of the COUNT option. */
    if ((o = lookupKeyRead(c->db,c->argv[1])) == NULL) {
        if (count != -1)
            addReply(c,shared.emptyarray);
        else
            addReply(c,shared.null[c->resp]);
        return;
    }
    if (checkType(c,o,OBJ_LIST)) return;

    /* If we got the COUNT option, prepare to emit an array. */
    void *arraylenptr = NULL;
    if (count != -1) arraylenptr = addReplyDeferredLen(c);

    /* Seek the element. */
    listTypeIterator *li;
    li = listTypeInitIterator(o,direction == LIST_HEAD ? -1 : 0,direction);
    listTypeEntry entry;
    long llen = listTypeLength(o);
    long index = 0, matches = 0, matchindex = -1, arraylen = 0;
    while (listTypeNext(li,&entry) && (maxlen == 0 || index < maxlen)) {
        if (listTypeEqual(&entry,ele)) {
            matches++;
            matchindex = (direction == LIST_TAIL) ? index : llen - index - 1;
            if (matches >= rank) {
                if (arraylenptr) {
                    arraylen++;
                    addReplyLongLong(c,matchindex);
                    if (count && matches-rank+1 >= count) break;
                } else {
                    break;
                }
            }
        }
        index++;
        matchindex = -1; /* Remember if we exit the loop without a match. */
    }
    listTypeReleaseIterator(li);

    /* Reply to the client. Note that arraylenptr is not NULL only if
     * the COUNT option was selected. */
    if (arraylenptr != NULL) {
        setDeferredArrayLen(c,arraylenptr,arraylen);
    } else {
        if (matchindex != -1)
            addReplyLongLong(c,matchindex);
        else
            addReply(c,shared.null[c->resp]);
    }
}


int fpm_request_last_activity(struct fpm_child_s *child, struct timeval *tv) /* {{{ */
{
	struct fpm_scoreboard_proc_s *proc;

	if (!tv) return -1;

	proc = fpm_scoreboard_proc_get(child->wp->scoreboard, child->scoreboard_i);
	if (!proc) {
		return -1;
	}

	*tv = proc->tv;

	return 1;
}


static uint16_t nvme_map_addr(NvmeCtrl *n, NvmeSg *sg, hwaddr addr, size_t len)
{
    bool cmb = false, pmr = false;

    if (!len) {
        return NVME_SUCCESS;
    }

    trace_pci_nvme_map_addr(addr, len);

    if (nvme_addr_is_cmb(n, addr)) {
        cmb = true;
    } else if (nvme_addr_is_pmr(n, addr)) {
        pmr = true;
    }

    if (cmb || pmr) {
        if (sg->flags & NVME_SG_DMA) {
            return NVME_INVALID_USE_OF_CMB | NVME_DNR;
        }

        if (sg->iov.niov + 1 > IOV_MAX) {
            goto max_mappings_exceeded;
        }

        if (cmb) {
            return nvme_map_addr_cmb(n, &sg->iov, addr, len);
        } else {
            return nvme_map_addr_pmr(n, &sg->iov, addr, len);
        }
    }

    if (!(sg->flags & NVME_SG_DMA)) {
        return NVME_INVALID_USE_OF_CMB | NVME_DNR;
    }

    if (sg->qsg.nsg + 1 > IOV_MAX) {
        goto max_mappings_exceeded;
    }

    qemu_sglist_add(&sg->qsg, addr, len);

    return NVME_SUCCESS;

max_mappings_exceeded:
    NVME_GUEST_ERR(pci_nvme_ub_too_many_mappings,
                   "number of mappings exceed 1024");
    return NVME_INTERNAL_DEV_ERROR | NVME_DNR;
}


date_s_jisx0301(int argc, VALUE *argv, VALUE klass)
{
    VALUE str, sg;

    rb_scan_args(argc, argv, "02", &str, &sg);

    switch (argc) {
      case 0:
	str = rb_str_new2("-4712-01-01");
      case 1:
	sg = INT2FIX(DEFAULT_SG);
    }

    {
	VALUE hash = date_s__jisx0301(klass, str);
	return d_new_by_frags(klass, hash, sg);
    }
}


check_limit(VALUE str, VALUE opt)
{
    if (NIL_P(str)) return;

    StringValue(str);
    size_t slen = RSTRING_LEN(str);
    size_t limit = get_limit(opt);
    if (slen > limit) {
	rb_raise(rb_eArgError,
		 "string length (%"PRI_SIZE_PREFIX"u) exceeds the limit %"PRI_SIZE_PREFIX"u", slen, limit);
    }
}


static int bpf_map_mmap(struct file *filp, struct vm_area_struct *vma)
{
	struct bpf_map *map = filp->private_data;
	int err;

	if (!map->ops->map_mmap || map_value_has_spin_lock(map) ||
	    map_value_has_timer(map))
		return -ENOTSUPP;

	if (!(vma->vm_flags & VM_SHARED))
		return -EINVAL;

	mutex_lock(&map->freeze_mutex);

	if (vma->vm_flags & VM_WRITE) {
		if (map->frozen) {
			err = -EPERM;
			goto out;
		}
		/* map is meant to be read-only, so do not allow mapping as
		 * writable, because it's possible to leak a writable page
		 * reference and allows user-space to still modify it after
		 * freezing, while verifier will assume contents do not change
		 */
		if (map->map_flags & BPF_F_RDONLY_PROG) {
			err = -EACCES;
			goto out;
		}
	}

	/* set default open/close callbacks */
	vma->vm_ops = &bpf_map_default_vmops;
	vma->vm_private_data = map;
	vma->vm_flags &= ~VM_MAYEXEC;
	if (!(vma->vm_flags & VM_WRITE))
		/* disallow re-mapping with PROT_WRITE */
		vma->vm_flags &= ~VM_MAYWRITE;

	err = map->ops->map_mmap(map, vma);
	if (err)
		goto out;

	if (vma->vm_flags & VM_MAYWRITE)
		map->writecnt++;
out:
	mutex_unlock(&map->freeze_mutex);
	return err;
}


static int map_lookup_and_delete_elem(union bpf_attr *attr)
{
	void __user *ukey = u64_to_user_ptr(attr->key);
	void __user *uvalue = u64_to_user_ptr(attr->value);
	int ufd = attr->map_fd;
	struct bpf_map *map;
	void *key, *value;
	u32 value_size;
	struct fd f;
	int err;

	if (CHECK_ATTR(BPF_MAP_LOOKUP_AND_DELETE_ELEM))
		return -EINVAL;

	if (attr->flags & ~BPF_F_LOCK)
		return -EINVAL;

	f = fdget(ufd);
	map = __bpf_map_get(f);
	if (IS_ERR(map))
		return PTR_ERR(map);
	if (!(map_get_sys_perms(map, f) & FMODE_CAN_READ) ||
	    !(map_get_sys_perms(map, f) & FMODE_CAN_WRITE)) {
		err = -EPERM;
		goto err_put;
	}

	if (attr->flags &&
	    (map->map_type == BPF_MAP_TYPE_QUEUE ||
	     map->map_type == BPF_MAP_TYPE_STACK)) {
		err = -EINVAL;
		goto err_put;
	}

	if ((attr->flags & BPF_F_LOCK) &&
	    !map_value_has_spin_lock(map)) {
		err = -EINVAL;
		goto err_put;
	}

	key = __bpf_copy_key(ukey, map->key_size);
	if (IS_ERR(key)) {
		err = PTR_ERR(key);
		goto err_put;
	}

	value_size = bpf_map_value_size(map);

	err = -ENOMEM;
	value = kvmalloc(value_size, GFP_USER | __GFP_NOWARN);
	if (!value)
		goto free_key;

	err = -ENOTSUPP;
	if (map->map_type == BPF_MAP_TYPE_QUEUE ||
	    map->map_type == BPF_MAP_TYPE_STACK) {
		err = map->ops->map_pop_elem(map, value);
	} else if (map->map_type == BPF_MAP_TYPE_HASH ||
		   map->map_type == BPF_MAP_TYPE_PERCPU_HASH ||
		   map->map_type == BPF_MAP_TYPE_LRU_HASH ||
		   map->map_type == BPF_MAP_TYPE_LRU_PERCPU_HASH) {
		if (!bpf_map_is_dev_bound(map)) {
			bpf_disable_instrumentation();
			rcu_read_lock();
			err = map->ops->map_lookup_and_delete_elem(map, key, value, attr->flags);
			rcu_read_unlock();
			bpf_enable_instrumentation();
		}
	}

	if (err)
		goto free_value;

	if (copy_to_user(uvalue, value, value_size) != 0) {
		err = -EFAULT;
		goto free_value;
	}

	err = 0;

free_value:
	kvfree(value);
free_key:
	kvfree(key);
err_put:
	fdput(f);
	return err;
}


print_line_detail(
    Dwarf_Debug dbg,
    const char *prefix,
    int opcode,
    unsigned curr_line,
    struct Dwarf_Line_Registers_s * regs,
    Dwarf_Bool is_single_table, Dwarf_Bool is_actuals_table)
{
    dwarfstring m1;

    dwarfstring_constructor_static(&m1,locallinebuf,
        sizeof(locallinebuf));
    if(!is_single_table && is_actuals_table) {
        dwarfstring_append_printf_s(&m1,"%-15s ",(char *)prefix);
        dwarfstring_append_printf_i(&m1,"%3d ",opcode);
        dwarfstring_append_printf_u(&m1,"0x%" DW_PR_XZEROS DW_PR_DUx ,
            regs->lr_address);
        dwarfstring_append_printf_u(&m1,"/%01u",regs->lr_op_index);
        dwarfstring_append_printf_u(&m1," %5lu", regs->lr_line);
        dwarfstring_append_printf_u(&m1," %3d",regs->lr_isa);
        dwarfstring_append_printf_i(&m1,"   %1d", regs->lr_basic_block);
        dwarfstring_append_printf_i(&m1,"%1d\n",  regs->lr_end_sequence);
        _dwarf_printf(dbg,dwarfstring_string(&m1));
        dwarfstring_destructor(&m1);
        return;
    }
    if(!is_single_table && !is_actuals_table) {
        dwarfstring_append_printf_i(&m1,
            "[%3d] "  /* row number */, curr_line);
        dwarfstring_append_printf_s(&m1,
            "%-15s ",(char *)prefix);
        dwarfstring_append_printf_i(&m1,
            "%3d ",opcode);
        dwarfstring_append_printf_u(&m1,
            "x%" DW_PR_XZEROS DW_PR_DUx, regs->lr_address);
        dwarfstring_append_printf_u(&m1,
            "/%01u", regs->lr_op_index);
        dwarfstring_append_printf_u(&m1," %2lu ",regs->lr_file);
        dwarfstring_append_printf_u(&m1,"%4lu  ",regs->lr_line);
        dwarfstring_append_printf_u(&m1,"%1lu",regs->lr_column);
        if (regs->lr_discriminator ||
            regs->lr_prologue_end ||
            regs->lr_epilogue_begin ||
            regs->lr_isa ||
            regs->lr_is_stmt ||
            regs->lr_call_context ||
            regs->lr_subprogram) {
            dwarfstring_append_printf_u(&m1,
                "   x%02" DW_PR_DUx ,
                regs->lr_discriminator); /* DWARF4 */
            dwarfstring_append_printf_u(&m1,
                "  x%02" DW_PR_DUx , regs->lr_call_context); /* EXPERIMENTAL */
            dwarfstring_append_printf_u(&m1,
                "  x%02" DW_PR_DUx , regs->lr_subprogram); /* EXPERIMENTAL */
            dwarfstring_append_printf_i(&m1,
                "  %1d", regs->lr_is_stmt);
            dwarfstring_append_printf_i(&m1,
                "%1d", (int) regs->lr_isa);
            dwarfstring_append_printf_i(&m1,
                "%1d", regs->lr_prologue_end); /* DWARF3 */
            dwarfstring_append_printf_i(&m1,
                "%1d", regs->lr_epilogue_begin); /* DWARF3 */
        }
        dwarfstring_append(&m1,"\n");
        _dwarf_printf(dbg,dwarfstring_string(&m1));
        dwarfstring_destructor(&m1);
        return;
    }
    /*  In the first quoted line below:
        3d looks better than 2d, but best to do that as separate
        change and test from two-level-line-tables.  */
    dwarfstring_append_printf_s(&m1,
        "%-15s ",(char *)prefix);
    dwarfstring_append_printf_i(&m1,
        "%2d ",opcode);
    dwarfstring_append_printf_u(&m1,
        "0x%" DW_PR_XZEROS DW_PR_DUx " ",
        regs->lr_address);
    dwarfstring_append_printf_u(&m1,
        "%2lu   ", regs->lr_file);
    dwarfstring_append_printf_u(&m1,
        "%4lu ", regs->lr_line);
    dwarfstring_append_printf_u(&m1,
        "%2lu   ", regs->lr_column);
    dwarfstring_append_printf_i(&m1,
        "%1d ",regs->lr_is_stmt);
    dwarfstring_append_printf_i(&m1,
        "%1d ", regs->lr_basic_block);
    dwarfstring_append_printf_i(&m1,
        "%1d",regs->lr_end_sequence);
    if (regs->lr_discriminator ||
        regs->lr_prologue_end ||
        regs->lr_epilogue_begin ||
        regs->lr_isa) {
        dwarfstring_append_printf_i(&m1,
            " %1d", regs->lr_prologue_end); /* DWARF3 */
        dwarfstring_append_printf_i(&m1,
            " %1d", regs->lr_epilogue_begin); /* DWARF3 */
        dwarfstring_append_printf_i(&m1,
            " %1d", regs->lr_isa); /* DWARF3 */
        dwarfstring_append_printf_u(&m1,
            " 0x%" DW_PR_DUx , regs->lr_discriminator); /* DWARF4 */
    }
    dwarfstring_append(&m1, "\n");
    _dwarf_printf(dbg,dwarfstring_string(&m1));
    dwarfstring_destructor(&m1);
}


static int _open_and_activate_luks2(struct crypt_device *cd,
	int keyslot,
	const char *name,
	const char *passphrase,
	size_t passphrase_size,
	uint32_t flags)
{
	crypt_reencrypt_info ri;
	int r;
	struct luks2_hdr *hdr = &cd->u.luks2.hdr;

	ri = LUKS2_reencrypt_status(hdr);
	if (ri == CRYPT_REENCRYPT_INVALID)
		return -EINVAL;

	if (ri > CRYPT_REENCRYPT_NONE) {
		if (name)
			r = _open_and_activate_reencrypt_device(cd, hdr, keyslot, name, passphrase,
					passphrase_size, flags);
		else
			r = _open_all_keys(cd, hdr, keyslot, passphrase,
					   passphrase_size, flags, NULL);
	} else
		r = _open_and_activate(cd, keyslot, name, passphrase,
				passphrase_size, flags);

	return r;
}


libxlDomainEventHandler(void *data, libxl_event *event)
{
    libxlDriverPrivate *driver = data;
    libxl_shutdown_reason xl_reason = event->u.domain_shutdown.shutdown_reason;
    virDomainObj *vm = NULL;
    g_autoptr(libxlDriverConfig) cfg = NULL;

    VIR_DEBUG("Received libxl event '%d' for domid '%d'", event->type, event->domid);

    if (event->type != LIBXL_EVENT_TYPE_DOMAIN_SHUTDOWN &&
            event->type != LIBXL_EVENT_TYPE_DOMAIN_DEATH) {
        VIR_INFO("Unhandled event type %d", event->type);
        goto cleanup;
    }

    /*
     * Similar to the xl implementation, ignore SUSPEND.  Any actions needed
     * after calling libxl_domain_suspend() are handled by its callers.
     */
    if (xl_reason == LIBXL_SHUTDOWN_REASON_SUSPEND)
        goto cleanup;

    vm = virDomainObjListFindByID(driver->domains, event->domid);
    if (!vm) {
        /* Nothing to do if we can't find the virDomainObj */
        goto cleanup;
    }

    if (event->type == LIBXL_EVENT_TYPE_DOMAIN_SHUTDOWN) {
        libxlDomainObjPrivate *priv = vm->privateData;
        struct libxlShutdownThreadInfo *shutdown_info = NULL;
        virThread thread;
        g_autofree char *name = NULL;

        /*
         * Start a thread to handle shutdown.  We don't want to be tying up
         * libxl's event machinery by doing a potentially lengthy shutdown.
         */
        shutdown_info = g_new0(struct libxlShutdownThreadInfo, 1);

        shutdown_info->driver = driver;
        shutdown_info->vm = vm;
        shutdown_info->event = (libxl_event *)event;
        name = g_strdup_printf("ev-%d", event->domid);
        /*
         * Cleanup will be handled by the shutdown thread.
         * Ignore the forthcoming death event from libxl
         */
        priv->ignoreDeathEvent = true;
        if (virThreadCreateFull(&thread, false, libxlDomainShutdownThread,
                                name, false, shutdown_info) < 0) {
             priv->ignoreDeathEvent = false;
            /*
             * Not much we can do on error here except log it.
             */
            VIR_ERROR(_("Failed to create thread to handle domain shutdown"));
            VIR_FREE(shutdown_info);
            goto cleanup;
        }
        /*
         * virDomainObjEndAPI is called in the shutdown thread, where
         * libxlShutdownThreadInfo and libxl_event are also freed.
         */
        return;
    } else if (event->type == LIBXL_EVENT_TYPE_DOMAIN_DEATH) {
        /*
         * On death the domain is cleaned up from Xen's perspective.
         * Cleanup on the libvirt side can be done synchronously.
         */
        libxlDomainHandleDeath(driver, vm);
    }

 cleanup:
    virDomainObjEndAPI(&vm);
    cfg = libxlDriverConfigGet(driver);
    /* Cast away any const */
    libxl_event_free(cfg->ctx, (libxl_event *)event);
}


libxlDomainHandleDeath(libxlDriverPrivate *driver, virDomainObj *vm)
{
    virObjectEvent *dom_event = NULL;
    libxlDomainObjPrivate *priv = vm->privateData;

    if (priv->ignoreDeathEvent) {
        priv->ignoreDeathEvent = false;
        return;
    }

    if (libxlDomainObjBeginJob(driver, vm, LIBXL_JOB_MODIFY) < 0)
        return;

    virDomainObjSetState(vm, VIR_DOMAIN_SHUTOFF, VIR_DOMAIN_SHUTOFF_DESTROYED);
    dom_event = virDomainEventLifecycleNewFromObj(vm,
                                                  VIR_DOMAIN_EVENT_STOPPED,
                                                  VIR_DOMAIN_EVENT_STOPPED_DESTROYED);
    libxlDomainCleanup(driver, vm);
    if (!vm->persistent)
        virDomainObjListRemove(driver->domains, vm);
    libxlDomainObjEndJob(driver, vm);
    virObjectEventStateQueue(driver->domainEventState, dom_event);
}


libxlDomainHandleDeath(libxlDriverPrivate *driver, virDomainObj *vm)
{
    virObjectEvent *dom_event = NULL;

    if (libxlDomainObjBeginJob(driver, vm, LIBXL_JOB_MODIFY) < 0)
        return;

    virDomainObjSetState(vm, VIR_DOMAIN_SHUTOFF, VIR_DOMAIN_SHUTOFF_DESTROYED);
    dom_event = virDomainEventLifecycleNewFromObj(vm,
                                                  VIR_DOMAIN_EVENT_STOPPED,
                                                  VIR_DOMAIN_EVENT_STOPPED_DESTROYED);
    libxlDomainCleanup(driver, vm);
    if (!vm->persistent)
        virDomainObjListRemove(driver->domains, vm);
    libxlDomainObjEndJob(driver, vm);
    virObjectEventStateQueue(driver->domainEventState, dom_event);
}


static int vrend_renderer_transfer_write_iov(struct vrend_context *ctx,
                                             struct vrend_resource *res,
                                             const struct iovec *iov, int num_iovs,
                                             const struct vrend_transfer_info *info)
{
   void *data;

   if ((is_only_bit(res->storage_bits, VREND_STORAGE_GUEST_MEMORY) ||
       has_bit(res->storage_bits, VREND_STORAGE_HOST_SYSTEM_MEMORY)) && res->iov) {
      return vrend_copy_iovec(iov, num_iovs, info->offset,
                              res->iov, res->num_iovs, info->box->x,
                              info->box->width, res->ptr);
   }

   if (has_bit(res->storage_bits, VREND_STORAGE_HOST_SYSTEM_MEMORY)) {
      assert(!res->iov);
      vrend_read_from_iovec(iov, num_iovs, info->offset,
                            res->ptr + info->box->x, info->box->width);
      return 0;
   }

   if (has_bit(res->storage_bits, VREND_STORAGE_GL_BUFFER)) {
      GLuint map_flags = GL_MAP_INVALIDATE_RANGE_BIT | GL_MAP_WRITE_BIT;
      struct virgl_sub_upload_data d;
      d.box = info->box;
      d.target = res->target;

      if (!info->synchronized)
         map_flags |= GL_MAP_UNSYNCHRONIZED_BIT;

      glBindBufferARB(res->target, res->id);
      data = glMapBufferRange(res->target, info->box->x, info->box->width, map_flags);
      if (data == NULL) {
	 vrend_printf("map failed for element buffer\n");
	 vrend_read_from_iovec_cb(iov, num_iovs, info->offset, info->box->width, &iov_buffer_upload, &d);
      } else {
	 vrend_read_from_iovec(iov, num_iovs, info->offset, data, info->box->width);
	 glUnmapBuffer(res->target);
      }
      glBindBufferARB(res->target, 0);
   } else {
      GLenum glformat;
      GLenum gltype;
      int need_temp = 0;
      int elsize = util_format_get_blocksize(res->base.format);
      int x = 0, y = 0;
      bool compressed;
      bool invert = false;
      float depth_scale;
      GLuint send_size = 0;
      uint32_t stride = info->stride;
      uint32_t layer_stride = info->layer_stride;

      if (ctx)
         vrend_use_program(ctx->sub, 0);
      else
         glUseProgram(0);

      if (!stride)
         stride = util_format_get_nblocksx(res->base.format, u_minify(res->base.width0, info->level)) * elsize;

      if (!layer_stride)
         layer_stride = util_format_get_2d_size(res->base.format, stride,
                                                u_minify(res->base.height0, info->level));

      compressed = util_format_is_compressed(res->base.format);
      if (num_iovs > 1 || compressed) {
         need_temp = true;
      }

      if (vrend_state.use_gles && vrend_format_is_bgra(res->base.format) &&
          !vrend_resource_is_emulated_bgra(res))
          need_temp = true;

      if (vrend_state.use_core_profile == true &&
          (res->y_0_top || (res->base.format == VIRGL_FORMAT_Z24X8_UNORM))) {
         need_temp = true;
         if (res->y_0_top)
            invert = true;
      }

      send_size = util_format_get_nblocks(res->base.format, info->box->width,
                                          info->box->height) * elsize;
      if (res->target == GL_TEXTURE_3D ||
          res->target == GL_TEXTURE_2D_ARRAY ||
          res->target == GL_TEXTURE_CUBE_MAP_ARRAY)
          send_size *= info->box->depth;

      if (need_temp) {
         data = malloc(send_size);
         if (!data)
            return ENOMEM;
         read_transfer_data(iov, num_iovs, data, res->base.format, info->offset,
                            stride, layer_stride, info->box, invert);
      } else {
         if (send_size > iov[0].iov_len - info->offset)
            return EINVAL;
         data = (char*)iov[0].iov_base + info->offset;
      }

      if (!need_temp) {
         assert(stride);
         glPixelStorei(GL_UNPACK_ROW_LENGTH, stride / elsize);
         glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, layer_stride / stride);
      } else
         glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);

      switch (elsize) {
      case 1:
      case 3:
         glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
         break;
      case 2:
      case 6:
         glPixelStorei(GL_UNPACK_ALIGNMENT, 2);
         break;
      case 4:
      default:
         glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
         break;
      case 8:
         glPixelStorei(GL_UNPACK_ALIGNMENT, 8);
         break;
      }

      glformat = tex_conv_table[res->base.format].glformat;
      gltype = tex_conv_table[res->base.format].gltype;

      if ((!vrend_state.use_core_profile) && (res->y_0_top)) {
         GLuint buffers;
         GLuint fb_id;

         glGenFramebuffers(1, &fb_id);
         glBindFramebuffer(GL_FRAMEBUFFER, fb_id);
         vrend_fb_bind_texture(res, 0, info->level, 0);

         buffers = GL_COLOR_ATTACHMENT0;
         glDrawBuffers(1, &buffers);
         glDisable(GL_BLEND);
         if (ctx) {
            vrend_depth_test_enable(ctx, false);
            vrend_alpha_test_enable(ctx, false);
            vrend_stencil_test_enable(ctx->sub, false);
         } else {
            glDisable(GL_DEPTH_TEST);
            glDisable(GL_ALPHA_TEST);
            glDisable(GL_STENCIL_TEST);
         }
         glPixelZoom(1.0f, res->y_0_top ? -1.0f : 1.0f);
         glWindowPos2i(info->box->x, res->y_0_top ? (int)res->base.height0 - info->box->y : info->box->y);
         glDrawPixels(info->box->width, info->box->height, glformat, gltype,
                      data);
         glDeleteFramebuffers(1, &fb_id);
      } else {
         uint32_t comp_size;
         GLint old_tex = 0;
         get_current_texture(res->target, &old_tex);
         glBindTexture(res->target, res->id);

         if (compressed) {
            glformat = tex_conv_table[res->base.format].internalformat;
            comp_size = util_format_get_nblocks(res->base.format, info->box->width,
                                                info->box->height) * util_format_get_blocksize(res->base.format);
         }

         if (glformat == 0) {
            glformat = GL_BGRA;
            gltype = GL_UNSIGNED_BYTE;
         }

         x = info->box->x;
         y = invert ? (int)res->base.height0 - info->box->y - info->box->height : info->box->y;

         /* GLES doesn't allow format conversions, which we need for BGRA resources with RGBA
          * internal format. So we fallback to performing a CPU swizzle before uploading. */
         if (vrend_state.use_gles && vrend_format_is_bgra(res->base.format) &&
             !vrend_resource_is_emulated_bgra(res)) {
            VREND_DEBUG(dbg_bgra, ctx, "manually swizzling bgra->rgba on upload since gles+bgra\n");
            vrend_swizzle_data_bgra(send_size, data);
         }

         /* mipmaps are usually passed in one iov, and we need to keep the offset
          * into the data in case we want to read back the data of a surface
          * that can not be rendered. Since we can not assume that the whole texture
          * is filled, we evaluate the offset for origin (0,0,0). Since it is also
          * possible that a resource is reused and resized update the offset every time.
          */
         if (info->level < VR_MAX_TEXTURE_2D_LEVELS) {
            int64_t level_height = u_minify(res->base.height0, info->level);
            res->mipmap_offsets[info->level] = info->offset -
                                               ((info->box->z * level_height + y) * stride + x * elsize);
         }

         if (res->base.format == VIRGL_FORMAT_Z24X8_UNORM) {
            /* we get values from the guest as 24-bit scaled integers
               but we give them to the host GL and it interprets them
               as 32-bit scaled integers, so we need to scale them here */
            depth_scale = 256.0;
            if (!vrend_state.use_core_profile)
               glPixelTransferf(GL_DEPTH_SCALE, depth_scale);
            else
               vrend_scale_depth(data, send_size, depth_scale);
         }
         if (res->target == GL_TEXTURE_CUBE_MAP) {
            GLenum ctarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X + info->box->z;
            if (compressed) {
               glCompressedTexSubImage2D(ctarget, info->level, x, y,
                                         info->box->width, info->box->height,
                                         glformat, comp_size, data);
            } else {
               glTexSubImage2D(ctarget, info->level, x, y, info->box->width, info->box->height,
                               glformat, gltype, data);
            }
         } else if (res->target == GL_TEXTURE_3D || res->target == GL_TEXTURE_2D_ARRAY || res->target == GL_TEXTURE_CUBE_MAP_ARRAY) {
            if (compressed) {
               glCompressedTexSubImage3D(res->target, info->level, x, y, info->box->z,
                                         info->box->width, info->box->height, info->box->depth,
                                         glformat, comp_size, data);
            } else {
               glTexSubImage3D(res->target, info->level, x, y, info->box->z,
                               info->box->width, info->box->height, info->box->depth,
                               glformat, gltype, data);
            }
         } else if (res->target == GL_TEXTURE_1D) {
            if (vrend_state.use_gles) {
               /* Covers both compressed and none compressed. */
               report_gles_missing_func(ctx, "gl[Compressed]TexSubImage1D");
            } else if (compressed) {
               glCompressedTexSubImage1D(res->target, info->level, info->box->x,
                                         info->box->width,
                                         glformat, comp_size, data);
            } else {
               glTexSubImage1D(res->target, info->level, info->box->x, info->box->width,
                               glformat, gltype, data);
            }
         } else {
            if (compressed) {
               glCompressedTexSubImage2D(res->target, info->level, x, res->target == GL_TEXTURE_1D_ARRAY ? info->box->z : y,
                                         info->box->width, info->box->height,
                                         glformat, comp_size, data);
            } else {
               glTexSubImage2D(res->target, info->level, x, res->target == GL_TEXTURE_1D_ARRAY ? info->box->z : y,
                               info->box->width,
                               res->target == GL_TEXTURE_1D_ARRAY ? info->box->depth : info->box->height,
                               glformat, gltype, data);
            }
         }
         if (res->base.format == VIRGL_FORMAT_Z24X8_UNORM) {
            if (!vrend_state.use_core_profile)
               glPixelTransferf(GL_DEPTH_SCALE, 1.0);
         }
         glBindTexture(res->target, old_tex);
      }

      if (stride && !need_temp) {
         glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
         glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, 0);
      }

      glPixelStorei(GL_UNPACK_ALIGNMENT, 4);

      if (need_temp)
         free(data);
   }
   return 0;
}


int main()
{
   initialize_environment();

   test_format_wrong_size();
   test_format_fail_and_double_free();
   test_blit_info_format_check();
   test_blit_info_format_check_null_format();
   test_format_is_plain_nullptr_deref_trigger();
   test_format_util_format_is_rgb_nullptr_deref_trigger_illegal_resource();
   test_format_util_format_is_rgb_nullptr_deref_trigger();
   test_double_free_in_vrend_renderer_blit_int_trigger_invalid_formats();
   test_double_free_in_vrend_renderer_blit_int_trigger();
   test_format_is_has_alpha_nullptr_deref_trigger_original();
   test_format_is_has_alpha_nullptr_deref_trigger_legal_resource();

   test_heap_overflow_vrend_renderer_transfer_write_iov();
   test_heap_overflow_vrend_renderer_transfer_write_iov_compressed_tex();

   test_cs_nullpointer_deference();
   test_vrend_set_signle_abo_heap_overflow();

   virgl_renderer_context_destroy(ctx_id);
   virgl_renderer_cleanup(&cookie);
   virgl_egl_destroy(test_egl);

   return 0;
}


static int kvm_mmu_notifier_invalidate_range_start(struct mmu_notifier *mn,
					const struct mmu_notifier_range *range)
{
	struct kvm *kvm = mmu_notifier_to_kvm(mn);
	const struct kvm_hva_range hva_range = {
		.start		= range->start,
		.end		= range->end,
		.pte		= __pte(0),
		.handler	= kvm_unmap_gfn_range,
		.on_lock	= kvm_inc_notifier_count,
		.flush_on_ret	= true,
		.may_block	= mmu_notifier_range_blockable(range),
	};

	trace_kvm_unmap_hva_range(range->start, range->end);

	/*
	 * Prevent memslot modification between range_start() and range_end()
	 * so that conditionally locking provides the same result in both
	 * functions.  Without that guarantee, the mmu_notifier_count
	 * adjustments will be imbalanced.
	 *
	 * Pairs with the decrement in range_end().
	 */
	spin_lock(&kvm->mn_invalidate_lock);
	kvm->mn_active_invalidate_count++;
	spin_unlock(&kvm->mn_invalidate_lock);

	gfn_to_pfn_cache_invalidate_start(kvm, range->start, range->end,
					  hva_range.may_block);

	__kvm_handle_hva_range(kvm, &hva_range);

	return 0;


static int wrap_nettle_hash_fast(gnutls_digest_algorithm_t algo,
				 const void *text, size_t text_size,
				 void *digest)
{
	struct nettle_hash_ctx ctx;
	int ret;

	ret = _ctx_init(algo, &ctx);
	if (ret < 0)
		return gnutls_assert_val(ret);

	ctx.update(&ctx, text_size, text);
	ctx.digest(&ctx, ctx.length, digest);

	return 0;
}


static int rtsx_usb_ms_drv_remove(struct platform_device *pdev)
{
	struct rtsx_usb_ms *host = platform_get_drvdata(pdev);
	struct memstick_host *msh = host->msh;
	int err;

	host->eject = true;
	cancel_work_sync(&host->handle_req);

	mutex_lock(&host->host_mutex);
	if (host->req) {
		dev_dbg(ms_dev(host),
			"%s: Controller removed during transfer\n",
			dev_name(&msh->dev));
		host->req->error = -ENOMEDIUM;
		do {
			err = memstick_next_req(msh, &host->req);
			if (!err)
				host->req->error = -ENOMEDIUM;
		} while (!err);
	}
	mutex_unlock(&host->host_mutex);

	memstick_remove_host(msh);
	memstick_free_host(msh);

	/* Balance possible unbalanced usage count
	 * e.g. unconditional module removal
	 */
	if (pm_runtime_active(ms_dev(host)))
		pm_runtime_put(ms_dev(host));

	pm_runtime_disable(ms_dev(host));
	platform_set_drvdata(pdev, NULL);

	dev_dbg(ms_dev(host),
		": Realtek USB Memstick controller has been removed\n");

	return 0;
}


static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u,
		int closing, int tx_ring)
{
	struct pgv *pg_vec = NULL;
	struct packet_sock *po = pkt_sk(sk);
	unsigned long *rx_owner_map = NULL;
	int was_running, order = 0;
	struct packet_ring_buffer *rb;
	struct sk_buff_head *rb_queue;
	__be16 num;
	int err;
	/* Added to avoid minimal code churn */
	struct tpacket_req *req = &req_u->req;

	rb = tx_ring ? &po->tx_ring : &po->rx_ring;
	rb_queue = tx_ring ? &sk->sk_write_queue : &sk->sk_receive_queue;

	err = -EBUSY;
	if (!closing) {
		if (atomic_read(&po->mapped))
			goto out;
		if (packet_read_pending(rb))
			goto out;
	}

	if (req->tp_block_nr) {
		unsigned int min_frame_size;

		/* Sanity tests and some calculations */
		err = -EBUSY;
		if (unlikely(rb->pg_vec))
			goto out;

		switch (po->tp_version) {
		case TPACKET_V1:
			po->tp_hdrlen = TPACKET_HDRLEN;
			break;
		case TPACKET_V2:
			po->tp_hdrlen = TPACKET2_HDRLEN;
			break;
		case TPACKET_V3:
			po->tp_hdrlen = TPACKET3_HDRLEN;
			break;
		}

		err = -EINVAL;
		if (unlikely((int)req->tp_block_size <= 0))
			goto out;
		if (unlikely(!PAGE_ALIGNED(req->tp_block_size)))
			goto out;
		min_frame_size = po->tp_hdrlen + po->tp_reserve;
		if (po->tp_version >= TPACKET_V3 &&
		    req->tp_block_size <
		    BLK_PLUS_PRIV((u64)req_u->req3.tp_sizeof_priv) + min_frame_size)
			goto out;
		if (unlikely(req->tp_frame_size < min_frame_size))
			goto out;
		if (unlikely(req->tp_frame_size & (TPACKET_ALIGNMENT - 1)))
			goto out;

		rb->frames_per_block = req->tp_block_size / req->tp_frame_size;
		if (unlikely(rb->frames_per_block == 0))
			goto out;
		if (unlikely(rb->frames_per_block > UINT_MAX / req->tp_block_nr))
			goto out;
		if (unlikely((rb->frames_per_block * req->tp_block_nr) !=
					req->tp_frame_nr))
			goto out;

		err = -ENOMEM;
		order = get_order(req->tp_block_size);
		pg_vec = alloc_pg_vec(req, order);
		if (unlikely(!pg_vec))
			goto out;
		switch (po->tp_version) {
		case TPACKET_V3:
			/* Block transmit is not supported yet */
			if (!tx_ring) {
				init_prb_bdqc(po, rb, pg_vec, req_u);
			} else {
				struct tpacket_req3 *req3 = &req_u->req3;

				if (req3->tp_retire_blk_tov ||
				    req3->tp_sizeof_priv ||
				    req3->tp_feature_req_word) {
					err = -EINVAL;
					goto out_free_pg_vec;
				}
			}
			break;
		default:
			if (!tx_ring) {
				rx_owner_map = bitmap_alloc(req->tp_frame_nr,
					GFP_KERNEL | __GFP_NOWARN | __GFP_ZERO);
				if (!rx_owner_map)
					goto out_free_pg_vec;
			}
			break;
		}
	}
	/* Done */
	else {
		err = -EINVAL;
		if (unlikely(req->tp_frame_nr))
			goto out;
	}

	/* Detach socket from network */
	spin_lock(&po->bind_lock);
	was_running = po->running;
	num = po->num;
	if (was_running) {
		WRITE_ONCE(po->num, 0);
		__unregister_prot_hook(sk, false);
	}
	spin_unlock(&po->bind_lock);

	synchronize_net();

	err = -EBUSY;
	mutex_lock(&po->pg_vec_lock);
	if (closing || atomic_read(&po->mapped) == 0) {
		err = 0;
		spin_lock_bh(&rb_queue->lock);
		swap(rb->pg_vec, pg_vec);
		if (po->tp_version <= TPACKET_V2)
			swap(rb->rx_owner_map, rx_owner_map);
		rb->frame_max = (req->tp_frame_nr - 1);
		rb->head = 0;
		rb->frame_size = req->tp_frame_size;
		spin_unlock_bh(&rb_queue->lock);

		swap(rb->pg_vec_order, order);
		swap(rb->pg_vec_len, req->tp_block_nr);

		rb->pg_vec_pages = req->tp_block_size/PAGE_SIZE;
		po->prot_hook.func = (po->rx_ring.pg_vec) ?
						tpacket_rcv : packet_rcv;
		skb_queue_purge(rb_queue);
		if (atomic_read(&po->mapped))
			pr_err("packet_mmap: vma is busy: %d\n",
			       atomic_read(&po->mapped));
	}
	mutex_unlock(&po->pg_vec_lock);

	spin_lock(&po->bind_lock);
	if (was_running) {
		WRITE_ONCE(po->num, num);
		register_prot_hook(sk);
	}
	spin_unlock(&po->bind_lock);
	if (pg_vec && (po->tp_version > TPACKET_V2)) {
		/* Because we don't support block-based V3 on tx-ring */
		if (!tx_ring)
			prb_shutdown_retire_blk_timer(po, rb_queue);
	}

out_free_pg_vec:
	bitmap_free(rx_owner_map);
	if (pg_vec)
		free_pg_vec(pg_vec, order, req->tp_block_nr);
out:
	return err;
}


null_asynch_write (struct rw *rw,
                   struct command *command,
                   nbd_completion_callback cb)
{
  int dummy = 0;

  if (cb.callback (cb.user_data, &dummy) == -1) {
    perror (rw->name);
    exit (EXIT_FAILURE);
  }
}


int cgroup1_parse_param(struct fs_context *fc, struct fs_parameter *param)
{
	struct cgroup_fs_context *ctx = cgroup_fc2context(fc);
	struct cgroup_subsys *ss;
	struct fs_parse_result result;
	int opt, i;

	opt = fs_parse(fc, cgroup1_fs_parameters, param, &result);
	if (opt == -ENOPARAM) {
		int ret;

		ret = vfs_parse_fs_param_source(fc, param);
		if (ret != -ENOPARAM)
			return ret;
		for_each_subsys(ss, i) {
			if (strcmp(param->key, ss->legacy_name))
				continue;
			if (!cgroup_ssid_enabled(i) || cgroup1_ssid_disabled(i))
				return invalfc(fc, "Disabled controller '%s'",
					       param->key);
			ctx->subsys_mask |= (1 << i);
			return 0;
		}
		return invalfc(fc, "Unknown subsys name '%s'", param->key);
	}
	if (opt < 0)
		return opt;

	switch (opt) {
	case Opt_none:
		/* Explicitly have no subsystems */
		ctx->none = true;
		break;
	case Opt_all:
		ctx->all_ss = true;
		break;
	case Opt_noprefix:
		ctx->flags |= CGRP_ROOT_NOPREFIX;
		break;
	case Opt_clone_children:
		ctx->cpuset_clone_children = true;
		break;
	case Opt_cpuset_v2_mode:
		ctx->flags |= CGRP_ROOT_CPUSET_V2_MODE;
		break;
	case Opt_xattr:
		ctx->flags |= CGRP_ROOT_XATTR;
		break;
	case Opt_release_agent:
		/* Specifying two release agents is forbidden */
		if (ctx->release_agent)
			return invalfc(fc, "release_agent respecified");
		ctx->release_agent = param->string;
		param->string = NULL;
		break;
	case Opt_name:
		/* blocked by boot param? */
		if (cgroup_no_v1_named)
			return -ENOENT;
		/* Can't specify an empty name */
		if (!param->size)
			return invalfc(fc, "Empty name");
		if (param->size > MAX_CGROUP_ROOT_NAMELEN - 1)
			return invalfc(fc, "Name too long");
		/* Must match [\w.-]+ */
		for (i = 0; i < param->size; i++) {
			char c = param->string[i];
			if (isalnum(c))
				continue;
			if ((c == '.') || (c == '-') || (c == '_'))
				continue;
			return invalfc(fc, "Invalid name");
		}
		/* Specifying two names is forbidden */
		if (ctx->name)
			return invalfc(fc, "name respecified");
		ctx->name = param->string;
		param->string = NULL;
		break;
	}
	return 0;
}


static char ** split(const char *arg, const char *delim) {
  char *copy = dupstr(arg);
  char **result = NULL;
  int i = 0;

  for (char *cptr = strtok(copy, delim); cptr; cptr = strtok(NULL, delim)) {
    char **tmp = realloc (result, sizeof *result * (i + 1));
    if (!tmp && result) {
      while (i > 0) {
	free(result[--i]);
      }
      free(result);
      free(copy);
      return NULL;
    }
    result = tmp;
    result[i++] = dupstr(cptr);
  }

  free(copy);

  if (i) {
    char **tmp = realloc(result, sizeof *result * (i + 1));
    if (!tmp) {
      while (i > 0) {
	free(result[--i]);
      }
      free(result);
      free(copy);
      return NULL;
    }
    result = tmp;
    result[i++] = NULL;
  }

  return result;
}


phys_addr_t swiotlb_tbl_map_single(struct device *dev, phys_addr_t orig_addr,
		size_t mapping_size, size_t alloc_size,
		unsigned int alloc_align_mask, enum dma_data_direction dir,
		unsigned long attrs)
{
	struct io_tlb_mem *mem = dev->dma_io_tlb_mem;
	unsigned int offset = swiotlb_align_offset(dev, orig_addr);
	unsigned int i;
	int index;
	phys_addr_t tlb_addr;

	if (!mem)
		panic("Can not allocate SWIOTLB buffer earlier and can't now provide you with the DMA bounce buffer");

	if (cc_platform_has(CC_ATTR_MEM_ENCRYPT))
		pr_warn_once("Memory encryption is active and system is using DMA bounce buffers\n");

	if (mapping_size > alloc_size) {
		dev_warn_once(dev, "Invalid sizes (mapping: %zd bytes, alloc: %zd bytes)",
			      mapping_size, alloc_size);
		return (phys_addr_t)DMA_MAPPING_ERROR;
	}

	index = swiotlb_find_slots(dev, orig_addr,
				   alloc_size + offset, alloc_align_mask);
	if (index == -1) {
		if (!(attrs & DMA_ATTR_NO_WARN))
			dev_warn_ratelimited(dev,
	"swiotlb buffer is full (sz: %zd bytes), total %lu (slots), used %lu (slots)\n",
				 alloc_size, mem->nslabs, mem->used);
		return (phys_addr_t)DMA_MAPPING_ERROR;
	}

	/*
	 * Save away the mapping from the original address to the DMA address.
	 * This is needed when we sync the memory.  Then we sync the buffer if
	 * needed.
	 */
	for (i = 0; i < nr_slots(alloc_size + offset); i++)
		mem->slots[index + i].orig_addr = slot_addr(orig_addr, i);
	tlb_addr = slot_addr(mem->start, index) + offset;
	if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC) &&
	    (!(attrs & DMA_ATTR_OVERWRITE) || dir == DMA_TO_DEVICE ||
	    dir == DMA_BIDIRECTIONAL))
		swiotlb_bounce(dev, tlb_addr, mapping_size, DMA_TO_DEVICE);
	return tlb_addr;
}


int ax25_fwd_ioctl(unsigned int cmd, struct ax25_fwd_struct *fwd)
{
	ax25_dev *ax25_dev, *fwd_dev;

	if ((ax25_dev = ax25_addr_ax25dev(&fwd->port_from)) == NULL)
		return -EINVAL;

	switch (cmd) {
	case SIOCAX25ADDFWD:
		if ((fwd_dev = ax25_addr_ax25dev(&fwd->port_to)) == NULL)
			return -EINVAL;
		if (ax25_dev->forward != NULL)
			return -EINVAL;
		ax25_dev->forward = fwd_dev->dev;
		break;

	case SIOCAX25DELFWD:
		if (ax25_dev->forward == NULL)
			return -EINVAL;
		ax25_dev->forward = NULL;
		break;

	default:
		return -EINVAL;
	}

	return 0;
}


static int writeState(const char *stateFilename)
{
    struct logState *p;
    FILE *f;
    char *chptr;
    unsigned int i = 0;
    int error = 0;
    int bytes = 0;
    int fdcurr;
    int fdsave;
    struct stat sb;
    char *tmpFilename = NULL;
    struct tm now;
    time_t now_time, last_time;
    char *prevCtx;

    localtime_r(&nowSecs, &now);

    tmpFilename = malloc(strlen(stateFilename) + 5 );
    if (tmpFilename == NULL) {
        message_OOM();
        return 1;
    }
    strcpy(tmpFilename, stateFilename);
    strcat(tmpFilename, ".tmp");
    /* Remove possible tmp state file from previous run */
    error = unlink(tmpFilename);
    if (error == -1 && errno != ENOENT) {
        message(MESS_ERROR, "error removing old temporary state file %s: %s\n",
                tmpFilename, strerror(errno));
        free(tmpFilename);
        return 1;
    }
    error = 0;

    fdcurr = open(stateFilename, O_RDONLY);
    if (fdcurr == -1) {
        const char *state_header_v2 = "logrotate state -- version 2\n";
        const size_t state_header_v2_len = strlen(state_header_v2);
        size_t ret;

        /* no error if state file is just missing */
        if (errno != ENOENT) {
            message(MESS_ERROR, "error opening state file %s: %s\n",
                    stateFilename, strerror(errno));
            free(tmpFilename);
            return 1;
        }

        /* create a stub state file with mode 0644 */
        fdcurr = open(stateFilename, O_CREAT | O_EXCL | O_WRONLY,
                      S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
        if (fdcurr == -1) {
            message(MESS_ERROR, "error creating stub state file %s: %s\n",
                    stateFilename, strerror(errno));
            free(tmpFilename);
            return 1;
        }

        /* check write access */
        ret = full_write(fdcurr, state_header_v2, state_header_v2_len);
        if (ret != state_header_v2_len) {
            message(MESS_ERROR, "error writing to stub state file %s: %s\n",
                    stateFilename, strerror(errno));
            close(fdcurr);
            free(tmpFilename);
            return 1;
        }
    }

    /* get attributes, to assign them to the new state file */

    if (setSecCtx(fdcurr, stateFilename, &prevCtx) != 0) {
        /* error msg already printed */
        free(tmpFilename);
        close(fdcurr);
        return 1;
    }

#ifdef WITH_ACL
    if ((prev_acl = acl_get_fd(fdcurr)) == NULL) {
        if (is_acl_well_supported(errno)) {
            message(MESS_ERROR, "getting file ACL %s: %s\n",
                    stateFilename, strerror(errno));
            restoreSecCtx(&prevCtx);
            free(tmpFilename);
            close(fdcurr);
            return 1;
        }
    }
#endif

    if (fstat(fdcurr, &sb) == -1) {
        message(MESS_ERROR, "error stating %s: %s\n", stateFilename, strerror(errno));
        restoreSecCtx(&prevCtx);
        free(tmpFilename);
#ifdef WITH_ACL
        if (prev_acl) {
            acl_free(prev_acl);
            prev_acl = NULL;
        }
#endif
        return 1;
    }

    close(fdcurr);

    fdsave = createOutputFile(tmpFilename, O_RDWR | O_CREAT | O_TRUNC, &sb, prev_acl, 0);
#ifdef WITH_ACL
    if (prev_acl) {
        acl_free(prev_acl);
        prev_acl = NULL;
    }
#endif
    restoreSecCtx(&prevCtx);

    if (fdsave < 0) {
        free(tmpFilename);
        return 1;
    }

    f = fdopen(fdsave, "w");
    if (!f) {
        message(MESS_ERROR, "error creating temp state file %s: %s\n",
                tmpFilename, strerror(errno));
        free(tmpFilename);
        return 1;
    }

    bytes =  fprintf(f, "logrotate state -- version 2\n");
    if (bytes < 0)
        error = bytes;

    /*
     * Time in seconds it takes earth to go around sun.  The value is
     * astronomical measurement (solar year) rather than something derived from
     * a convention (calendar year).
     */
#define SECONDS_IN_YEAR 31556926

    for (i = 0; i < hashSize && error == 0; i++) {
        for (p = states[i]->head.lh_first; p != NULL && error == 0;
                p = p->list.le_next) {

            /* Skip states which are not used for more than a year. */
            now_time = mktime(&now);
            last_time = mktime(&p->lastRotated);
            if (!p->isUsed && difftime(now_time, last_time) > SECONDS_IN_YEAR) {
                message(MESS_DEBUG, "Removing %s from state file, "
                        "because it does not exist and has not been rotated for one year\n",
                        p->fn);
                continue;
            }

            error = fputc('"', f) == EOF;
            for (chptr = p->fn; *chptr && error == 0; chptr++) {
                switch (*chptr) {
                    case '"':
                    case '\\':
                        error = fputc('\\', f) == EOF;
                        break;
                    case '\n':
                        error = fputc('\\', f) == EOF;
                        if (error == 0) {
                            error = fputc('n', f) == EOF;
                        }
                        continue;
                    default:
                        break;
                }
                if (error == 0 && fputc(*chptr, f) == EOF) {
                    error = 1;
                }
            }

            if (error == 0 && fputc('"', f) == EOF)
                error = 1;

            if (error == 0) {
                bytes = fprintf(f, " %d-%d-%d-%d:%d:%d\n",
                                p->lastRotated.tm_year + 1900,
                                p->lastRotated.tm_mon + 1,
                                p->lastRotated.tm_mday,
                                p->lastRotated.tm_hour,
                                p->lastRotated.tm_min,
                                p->lastRotated.tm_sec);
                if (bytes < 0)
                    error = bytes;
            }
        }
    }

    if (error == 0)
        error = fflush(f);

    if (error == 0)
        error = fsync(fdsave);

    if (error == 0)
        error = fclose(f);
    else
        fclose(f);

    if (error == 0) {
        if (rename(tmpFilename, stateFilename)) {
            message(MESS_ERROR, "error renaming temp state file %s to %s: %s\n",
                    tmpFilename, stateFilename, strerror(errno));
            unlink(tmpFilename);
            error = 1;
        }
    }
    else {
        if (errno)
            message(MESS_ERROR, "error creating temp state file %s: %s\n",
                    tmpFilename, strerror(errno));
        else
            message(MESS_ERROR, "error creating temp state file %s%s\n",
                    tmpFilename, error == ENOMEM ?
                    ": Insufficient storage space is available." : "" );
        unlink(tmpFilename);
    }
    free(tmpFilename);
    return error;
}


ReadNextFunctionHandle(mat_t *mat, matvar_t *matvar)
{
    int err;
    size_t nelems = 1;

    err = Mat_MulDims(matvar, &nelems);
    matvar->data_size = sizeof(matvar_t *);
    err |= Mul(&matvar->nbytes, nelems, matvar->data_size);
    if ( err )
        return 0;

    matvar->data = malloc(matvar->nbytes);
    if ( matvar->data != NULL ) {
        size_t i;
        matvar_t **functions = (matvar_t **)matvar->data;
        for ( i = 0; i < nelems; i++ ) {
            functions[i] = Mat_VarReadNextInfo(mat);
            err = NULL == functions[i];
            if ( err )
                break;
        }
        if ( err ) {
            free(matvar->data);
            matvar->data = NULL;
            matvar->data_size = 0;
            matvar->nbytes = 0;
        }
    } else {
        matvar->data_size = 0;
        matvar->nbytes = 0;
    }

    return 0;
}


xmlBufGrowInternal(xmlBufPtr buf, size_t len) {
    size_t size;
    xmlChar *newbuf;

    if ((buf == NULL) || (buf->error != 0)) return(0);
    CHECK_COMPAT(buf)

    if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) return(0);
    if (buf->use + len < buf->size)
        return(buf->size - buf->use);

    /*
     * Windows has a BIG problem on realloc timing, so we try to double
     * the buffer size (if that's enough) (bug 146697)
     * Apparently BSD too, and it's probably best for linux too
     * On an embedded system this may be something to change
     */
#if 1
    if (buf->size > (size_t) len)
        size = buf->size * 2;
    else
        size = buf->use + len + 100;
#else
    size = buf->use + len + 100;
#endif

    if (buf->alloc == XML_BUFFER_ALLOC_BOUNDED) {
        /*
	 * Used to provide parsing limits
	 */
        if ((buf->use + len >= XML_MAX_TEXT_LENGTH) ||
	    (buf->size >= XML_MAX_TEXT_LENGTH)) {
	    xmlBufMemoryError(buf, "buffer error: text too long\n");
	    return(0);
	}
	if (size >= XML_MAX_TEXT_LENGTH)
	    size = XML_MAX_TEXT_LENGTH;
    }
    if ((buf->alloc == XML_BUFFER_ALLOC_IO) && (buf->contentIO != NULL)) {
        size_t start_buf = buf->content - buf->contentIO;

	newbuf = (xmlChar *) xmlRealloc(buf->contentIO, start_buf + size);
	if (newbuf == NULL) {
	    xmlBufMemoryError(buf, "growing buffer");
	    return(0);
	}
	buf->contentIO = newbuf;
	buf->content = newbuf + start_buf;
    } else {
	newbuf = (xmlChar *) xmlRealloc(buf->content, size);
	if (newbuf == NULL) {
	    xmlBufMemoryError(buf, "growing buffer");
	    return(0);
	}
	buf->content = newbuf;
    }
    buf->size = size;
    UPDATE_COMPAT(buf)
    return(buf->size - buf->use);
}


xmlBufferCreateSize(size_t size) {
    xmlBufferPtr ret;

    ret = (xmlBufferPtr) xmlMalloc(sizeof(xmlBuffer));
    if (ret == NULL) {
	xmlTreeErrMemory("creating buffer");
        return(NULL);
    }
    ret->use = 0;
    ret->alloc = xmlBufferAllocScheme;
    ret->size = (size ? size+2 : 0);         /* +1 for ending null */
    if (ret->size){
        ret->content = (xmlChar *) xmlMallocAtomic(ret->size * sizeof(xmlChar));
        if (ret->content == NULL) {
	    xmlTreeErrMemory("creating buffer");
            xmlFree(ret);
            return(NULL);
        }
        ret->content[0] = 0;
    } else
	ret->content = NULL;
    ret->contentIO = NULL;
    return(ret);
}


int nfc_dep_link_down(struct nfc_dev *dev)
{
	int rc = 0;

	pr_debug("dev_name=%s\n", dev_name(&dev->dev));

	if (!dev->ops->dep_link_down)
		return -EOPNOTSUPP;

	device_lock(&dev->dev);

	if (!device_is_registered(&dev->dev)) {
		rc = -ENODEV;
		goto error;
	}

	if (dev->dep_link_up == false) {
		rc = -EALREADY;
		goto error;
	}

	rc = dev->ops->dep_link_down(dev);
	if (!rc) {
		dev->dep_link_up = false;
		dev->active_target = NULL;
		dev->rf_mode = NFC_RF_NONE;
		nfc_llcp_mac_is_down(dev);
		nfc_genl_dep_link_down_event(dev);
	}

error:
	device_unlock(&dev->dev);

	return rc;
}


int nfc_dev_down(struct nfc_dev *dev)
{
	int rc = 0;

	pr_debug("dev_name=%s\n", dev_name(&dev->dev));

	device_lock(&dev->dev);

	if (!device_is_registered(&dev->dev)) {
		rc = -ENODEV;
		goto error;
	}

	if (!dev->dev_up) {
		rc = -EALREADY;
		goto error;
	}

	if (dev->polling || dev->active_target) {
		rc = -EBUSY;
		goto error;
	}

	if (dev->ops->dev_down)
		dev->ops->dev_down(dev);

	dev->dev_up = false;

error:
	device_unlock(&dev->dev);
	return rc;
}


int nfc_disable_se(struct nfc_dev *dev, u32 se_idx)
{
	struct nfc_se *se;
	int rc;

	pr_debug("%s se index %d\n", dev_name(&dev->dev), se_idx);

	device_lock(&dev->dev);

	if (!device_is_registered(&dev->dev)) {
		rc = -ENODEV;
		goto error;
	}

	if (!dev->dev_up) {
		rc = -ENODEV;
		goto error;
	}

	if (!dev->ops->enable_se || !dev->ops->disable_se) {
		rc = -EOPNOTSUPP;
		goto error;
	}

	se = nfc_find_se(dev, se_idx);
	if (!se) {
		rc = -EINVAL;
		goto error;
	}

	if (se->state == NFC_SE_DISABLED) {
		rc = -EALREADY;
		goto error;
	}

	rc = dev->ops->disable_se(dev, se_idx);
	if (rc >= 0)
		se->state = NFC_SE_DISABLED;

error:
	device_unlock(&dev->dev);
	return rc;
}