From patchwork Thu Jan 9 11:48:13 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Durrant X-Patchwork-Id: 11325505 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id D3BB314B4 for ; Thu, 9 Jan 2020 11:49:59 +0000 (UTC) Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id AEE602072A for ; Thu, 9 Jan 2020 11:49:59 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=amazon.com header.i=@amazon.com header.b="udddu2kt" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org AEE602072A Authentication-Results: mail.kernel.org; dmarc=fail (p=quarantine dis=none) header.from=amazon.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1ipWIt-0000J2-L6; Thu, 09 Jan 2020 11:48:43 +0000 Received: from all-amaz-eas1.inumbo.com ([34.197.232.57] helo=us1-amaz-eas2.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1ipWIs-0000IT-1L for xen-devel@lists.xenproject.org; Thu, 09 Jan 2020 11:48:42 +0000 X-Inumbo-ID: f864fda6-32d5-11ea-b9a8-12813bfff9fa Received: from smtp-fw-9102.amazon.com (unknown [207.171.184.29]) by us1-amaz-eas2.inumbo.com (Halon) with ESMTPS id f864fda6-32d5-11ea-b9a8-12813bfff9fa; Thu, 09 Jan 2020 11:48:37 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amazon.com; i=@amazon.com; q=dns/txt; s=amazon201209; t=1578570518; x=1610106518; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=B2i9pGs24DU8NIGtFWxC8KYSG+io8j9E8ByIwdA5SvM=; b=udddu2ktQK3nmoaKJdsy2blMRki+mwS2izna0o4p4YRfwvm0D8XUj4z0 XvY742EVUPGKtXYABECQMr57Va+3M7kSKRKyB4a3Vlh1X8wh1zYEQz/PE nVEz9PBns8uQy2I8M3m7Lo1lKsFPRDN6uSqeFOFKC3Vzo068aHKgglJO/ I=; IronPort-SDR: Fbr72Vkd458rciRq8boljZMAVqCabHwn2rD6fgpS58qemL/yORYmQ6ikL3oek4r+nwoewkZR24 +2ADYILEQi/A== X-IronPort-AV: E=Sophos;i="5.69,413,1571702400"; d="scan'208";a="17662319" Received: from sea32-co-svc-lb4-vlan3.sea.corp.amazon.com (HELO email-inbound-relay-2c-87a10be6.us-west-2.amazon.com) ([10.47.23.38]) by smtp-border-fw-out-9102.sea19.amazon.com with ESMTP; 09 Jan 2020 11:48:33 +0000 Received: from EX13MTAUEA002.ant.amazon.com (pdx4-ws-svc-p6-lb7-vlan2.pdx.amazon.com [10.170.41.162]) by email-inbound-relay-2c-87a10be6.us-west-2.amazon.com (Postfix) with ESMTPS id 700A4A31F3; Thu, 9 Jan 2020 11:48:32 +0000 (UTC) Received: from EX13D32EUC001.ant.amazon.com (10.43.164.159) by EX13MTAUEA002.ant.amazon.com (10.43.61.77) with Microsoft SMTP Server (TLS) id 15.0.1236.3; Thu, 9 Jan 2020 11:48:31 +0000 Received: from EX13MTAUWC001.ant.amazon.com (10.43.162.135) by EX13D32EUC001.ant.amazon.com (10.43.164.159) with Microsoft SMTP Server (TLS) id 15.0.1367.3; Thu, 9 Jan 2020 11:48:29 +0000 Received: from u2f063a87eabd5f.cbg10.amazon.com (10.125.106.135) by mail-relay.amazon.com (10.43.162.232) with Microsoft SMTP Server id 15.0.1367.3 via Frontend Transport; Thu, 9 Jan 2020 11:48:27 +0000 From: Paul Durrant To: Date: Thu, 9 Jan 2020 11:48:13 +0000 Message-ID: <20200109114816.2293-4-pdurrant@amazon.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200109114816.2293-1-pdurrant@amazon.com> References: <20200109114816.2293-1-pdurrant@amazon.com> MIME-Version: 1.0 Precedence: Bulk Subject: [Xen-devel] [PATCH v2 3/6] libxl: add infrastructure to track and query 'retired' domids X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.23 List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Cc: Anthony PERARD , Paul Durrant , Ian Jackson , Wei Liu Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" A domid is considered retired if the domain it represents was destroyed less than a specified number of seconds ago. The number can be set using the environment variable LIBXL_DOMID_MAX_RETIREMENT. If the variable does not exist then a default value of 60s is used. Whenever a domain is destroyed, a time-stamped record will be written into a history file (/var/run/xen/domid-history). To avoid the history file growing too large, any records with time-stamps that indicate that the domid has exceeded maximum retirement will also be purged. A new utility function, libxl__is_retired_domid(), has been added. This function reads the same history file checking whether a specified domid has a record that does not exceed maximum retirement. Since this utility function does not write to the file, no records are actually purged by it. NOTE: Since the history file is hosted by a tmpfs file system, it is automatically purged on boot thus allowing safe use of CLOCK_MONOTONIC as a time source. Signed-off-by: Paul Durrant --- Cc: Ian Jackson Cc: Wei Liu Cc: Anthony PERARD v2: - New in v2 --- tools/libxl/libxl_domain.c | 132 +++++++++++++++++++++++++++++++++++ tools/libxl/libxl_internal.h | 10 +++ 2 files changed, 142 insertions(+) diff --git a/tools/libxl/libxl_domain.c b/tools/libxl/libxl_domain.c index 5714501778..7f255f184c 100644 --- a/tools/libxl/libxl_domain.c +++ b/tools/libxl/libxl_domain.c @@ -1268,6 +1268,137 @@ static void dm_destroy_cb(libxl__egc *egc, libxl__devices_destroy(egc, &dis->drs); } +static unsigned int libxl__get_max_retirement(void) +{ + const char *env_max_retirement = getenv("LIBXL_DOMID_MAX_RETIREMENT"); + + return env_max_retirement ? strtol(env_max_retirement, NULL, 0) : + LIBXL_DOMID_MAX_RETIREMENT; +} + +static int libxl__open_domid_history(libxl__gc *gc) +{ + const char *name; + int fd; + int ret; + + name = GCSPRINTF("%s/domid-history", libxl__run_dir_path()); + + fd = open(name, O_RDWR|O_CREAT, 0644); + if (fd < 0) { + LOGE(ERROR, "unexpected error while trying open %s, errno=%d", + name, errno); + goto fail; + } + + for (;;) { + ret = flock(fd, LOCK_EX); + if (!ret) + break; + if (errno != EINTR) { + /* All other errno: EBADF, EINVAL, ENOLCK, EWOULDBLOCK */ + LOGE(ERROR, + "unexpected error while trying to lock %s, fd=%d, errno=%d", + name, fd, errno); + goto fail; + } + } + + return fd; + +fail: + if (fd >= 0) + close(fd); + + return -1; +} + +/* Write a domid retirement record */ +static void libxl__retire_domid(libxl__gc *gc, uint32_t domid) +{ + long max_retirement = libxl__get_max_retirement(); + int fd; + FILE *f; + long roff, woff; + char line[64]; + struct timespec ts; + + fd = libxl__open_domid_history(gc); + if (fd < 0) + return; + + clock_gettime(CLOCK_MONOTONIC, &ts); + + /* Purge old retirement records */ + + f = fdopen(fd, "r+"); + woff = ftell(f); + + while (fgets(line, sizeof(line), f)) { + unsigned long sec; + unsigned int ignored; + + roff = ftell(f); + + if (sscanf(line, "%lu %u", &sec, &ignored) != 2) + continue; /* Purge malformed lines */ + + if (ts.tv_sec - sec > max_retirement) + continue; + + fseek(f, woff, SEEK_SET); + fputs(line, f); + woff = ftell(f); + + fseek(f, roff, SEEK_SET); + } + + fseek(f, woff, SEEK_SET); + fprintf(f, "%lu %u\n", ts.tv_sec, domid); + woff = ftell(f); + fflush(f); + + ftruncate(fd, woff); /* may now be fewer records */ + + close(fd); +} + +bool libxl__is_retired_domid(libxl__gc *gc, uint32_t domid) +{ + long max_retirement = libxl__get_max_retirement(); + bool retired = false; + int fd; + FILE *f; + char line[64]; + struct timespec ts; + + fd = libxl__open_domid_history(gc); + if (fd < 0) + return false; + + clock_gettime(CLOCK_MONOTONIC, &ts); + + f = fdopen(fd, "r"); + + while (fgets(line, sizeof(line), f)) { + unsigned long sec; + unsigned int check; + + if (sscanf(line, "%lu %u", &sec, &check) != 2) + continue; + + if (check == domid && + ts.tv_sec - sec <= max_retirement) { + retired = true; + break; + } + } + + close(fd); + + return retired; +} + static void devices_destroy_cb(libxl__egc *egc, libxl__devices_remove_state *drs, int rc) @@ -1331,6 +1462,7 @@ static void devices_destroy_cb(libxl__egc *egc, if (!ctx->xch) goto badchild; if (!dis->soft_reset) { + libxl__retire_domid(gc, domid); rc = xc_domain_destroy(ctx->xch, domid); } else { rc = xc_domain_pause(ctx->xch, domid); diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h index cb23490c59..fcac8a93c5 100644 --- a/tools/libxl/libxl_internal.h +++ b/tools/libxl/libxl_internal.h @@ -4770,6 +4770,16 @@ _hidden int libxl__domain_pvcontrol(libxl__egc *egc, libxl__xswait_state *pvcontrol, domid_t domid, const char *cmd); +/* + * Maximum number of seconds a domid remains in retirement after domain + * destruction. This can be overidden by the environment variable of the + * same name. + */ +#define LIBXL_DOMID_MAX_RETIREMENT 60 + +/* Check whether a domid is in retirement */ +bool libxl__is_retired_domid(libxl__gc *gc, uint32_t domid); + #endif /*