FYI: Couple of Coverity issues resulted from these patches. > int > +libxlDomainMigrationPrepareTunnel3(virConnectPtr dconn, > + virStreamPtr st, > + virDomainDefPtr *def, > + const char *cookiein, > + int cookieinlen, > + unsigned int flags) > +{ > + libxlMigrationCookiePtr mig = NULL; > + libxlDriverPrivatePtr driver = dconn->privateData; > + virDomainObjPtr vm = NULL; > + libxlMigrationDstArgs *args = NULL; > + virThread thread; > + bool taint_hook = false; > + libxlDomainObjPrivatePtr priv = NULL; > + char *xmlout = NULL; > + int dataFD[2] = { -1, -1 }; > + int ret = -1; > + > + if (libxlDomainMigrationPrepareAny(dconn, def, cookiein, cookieinlen, > + &mig, &xmlout, &taint_hook) < 0) Coverity notes that '@mig' will be leaked in this case when "if (!cookiein || !cookieinlen) {" is true in libxlMigrationEatCookie and failures from libxlDomainMigrationPrepareAny don't free it. > + goto error; > + > + if (!(vm = virDomainObjListAdd(driver->domains, *def, > + driver->xmlopt, > + VIR_DOMAIN_OBJ_LIST_ADD_LIVE | > + VIR_DOMAIN_OBJ_LIST_ADD_CHECK_LIVE, > + NULL))) > + goto error; > + > + *def = NULL; > + priv = vm->privateData; > + > + if (taint_hook) { > + /* Domain XML has been altered by a hook script. */ > + priv->hookRun = true; > + } > + > + /* > + * The data flow of tunnel3 migration in the dest side: > + * stream -> pipe -> recvfd of libxlDomainStartRestore > + */ > + if (pipe(dataFD) < 0) > + goto error; > + > + /* Stream data will be written to pipeIn */ > + if (virFDStreamOpen(st, dataFD[1]) < 0) > + goto error; > + dataFD[1] = -1; /* 'st' owns the FD now & will close it */ > + > + if (libxlMigrationDstArgsInitialize() < 0) > + goto error; > + > + if (!(args = virObjectNew(libxlMigrationDstArgsClass))) > + goto error; > + > + args->conn = dconn; > + args->vm = vm; > + args->flags = flags; > + args->migcookie = mig; > + /* Receive from pipeOut */ > + args->recvfd = dataFD[0]; > + args->nsocks = 0; > + if (virThreadCreate(&thread, false, libxlDoMigrateReceive, args) < 0) { > + virReportError(VIR_ERR_OPERATION_FAILED, "%s", > + _("Failed to create thread for receiving migration data")); > + goto error; > + } > + > + ret = 0; > + goto done; > + > + error: > + VIR_FORCE_CLOSE(dataFD[1]); > + VIR_FORCE_CLOSE(dataFD[0]); > + virObjectUnref(args); > + /* Remove virDomainObj from domain list */ > + if (vm) { > + virDomainObjListRemove(driver->domains, vm); > + vm = NULL; > + } > + > + done: > + if (vm) > + virObjectUnlock(vm); > + > + return ret; > +} [...] > + > +static int > +libxlMigrationStartTunnel(libxlDriverPrivatePtr driver, > + virDomainObjPtr vm, > + unsigned long flags, > + virStreamPtr st, > + struct libxlTunnelControl *tc) > +{ > + libxlTunnelMigrationThread *arg = NULL; > + int ret = -1; > + > + if (VIR_ALLOC(tc) < 0) > + goto out; > + > + tc->dataFD[0] = -1; > + tc->dataFD[1] = -1; > + if (pipe(tc->dataFD) < 0) { > + virReportError(errno, "%s", _("Unable to make pipes")); Coverity notes that failures would cause a leak for @tc (I assume here and of course if virThreadCreate fails. Perhaps the 'best' way to handle that would be to set tc = NULL after ThreadCreate success and just call libxlMigrationStopTunnel in "out:"... John > + goto out; > + } > + > + arg = &tc->tmThread; > + /* Read from pipe */ > + arg->srcFD = tc->dataFD[0]; > + /* Write to dest stream */ > + arg->st = st; > + if (virThreadCreate(&tc->thread, true, > + libxlTunnel3MigrationFunc, arg) < 0) { > + virReportError(errno, "%s", > + _("Unable to create tunnel migration thread")); > + goto out; > + } > + > + virObjectUnlock(vm); > + /* Send data to pipe */ > + ret = libxlDoMigrateSend(driver, vm, flags, tc->dataFD[1]); > + virObjectLock(vm); > + > + out: > + /* libxlMigrationStopTunnel will be called in libxlDoMigrateP2P to free > + * all resources for us. */ > + return ret; > +} > + [...] -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list