From nobody Sun Feb 8 22:07:09 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=reject dis=none) header.from=citrix.com ARC-Seal: i=1; a=rsa-sha256; t=1610749842; cv=none; d=zohomail.com; s=zohoarc; b=QpW4USL+5BqDcAFNHR5vBgyQPBclfrCKd48oU0BmQXVEZHDnP/qI3MyUAnNIS0hFcD/UknARXBgRh6/rCziuCkrEkL8O2kkxcOhgrivpU9rANbg3QqHbPfGSH7ZmnJSgGjuQpI2pMNeQQJ1JCk7bNZfVjcgsckoxGwa1SO7Ydpo= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1610749842; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=G7ZS4UNr6N35h+zSn8uGfaLi+HBIZgNfkcMWYSpatgg=; b=LI8VBHrdCBfSInx4pyCdHaLFBX4WItIZ6a0StWfQuW1RRk77SPV72E0xtkDb4qDRPXIJ+bVtbVS4XO60JeRI/8XWWfsBO7VWWo4oMwcD20CQC+nzib+cdfoB71398576lI31GKGiwC9ICuEqyRxOi5UnpAlhh0KFgAE1InZ9yzY= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass header.from= (p=reject dis=none) header.from= Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1610749842405679.7428971046984; Fri, 15 Jan 2021 14:30:42 -0800 (PST) Received: from list by lists.xenproject.org with outflank-mailman.68679.123032 (Exim 4.92) (envelope-from ) id 1l0Xbt-0007OG-8N; Fri, 15 Jan 2021 22:30:25 +0000 Received: by outflank-mailman (output) from mailman id 68679.123032; Fri, 15 Jan 2021 22:30:25 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1l0Xbt-0007O8-4P; Fri, 15 Jan 2021 22:30:25 +0000 Received: by outflank-mailman (input) for mailman id 68679; Fri, 15 Jan 2021 22:30:24 +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.92) (envelope-from ) id 1l0Xbs-00062b-8r for xen-devel@lists.xenproject.org; Fri, 15 Jan 2021 22:30:24 +0000 Received: from esa6.hc3370-68.iphmx.com (unknown [216.71.155.175]) by us1-amaz-eas2.inumbo.com (Halon) with ESMTPS id ef7b5529-d612-4839-bc0f-62c474490687; Fri, 15 Jan 2021 22:29:59 +0000 (UTC) X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: ef7b5529-d612-4839-bc0f-62c474490687 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=citrix.com; s=securemail; t=1610749799; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=ChX2rsVn5ssD/dNJKc5/y7eY+C7iouZky4Y2USpFMDg=; b=H6sUoNR2i7+FwKh1s7RElUORLN1i5UTL7SXUSmU8OMyW7NLHrAUo9pI9 9N9vYG6l9WEgmhNLKHK51QOMHMWU5L3GMPWDlUtfGfDs2rqQ/GW7wIy5U KESqckmy5KrKdmgSf7s0yoKt2FKuTYg4aUVPVFkvhQjmLqhm7Zd6Ju2f3 Q=; Authentication-Results: esa6.hc3370-68.iphmx.com; dkim=none (message not signed) header.i=none IronPort-SDR: mHx+RKLkQwzT3oeD7dsMnyR42Pl540jrfqcz7L7sfXLrey9EYa01zjmVv4vetuOp0N8lNlWXUG UczC7I/oZuEu7xb9VYVO9QS9+nyEy89N9W1YJGoC1vp/IDoQwxAN3g+u4eYnFv5FQW+8GE4Bw2 iEZ7VTKFerwgBtIkj4y2c/gyoAnhia0FmkOdnZHkk/iOO/FVAqVf9U5Ca+CJOett8qdCSdiz3V D0b5qENmEU3sBb+AZGYy3neH6v5o9rtq4VmTZRNnco8te6VujdIjgUTu/oNUCMHpnPZzoDURY/ lDw= X-SBRS: 5.1 X-MesageID: 35434458 X-Ironport-Server: esa6.hc3370-68.iphmx.com X-Remote-IP: 162.221.158.21 X-Policy: $RELAYED X-IronPort-AV: E=Sophos;i="5.79,350,1602561600"; d="scan'208";a="35434458" From: =?UTF-8?q?Edwin=20T=C3=B6r=C3=B6k?= To: CC: =?UTF-8?q?Edwin=20T=C3=B6r=C3=B6k?= , "Christian Lindig" , David Scott , "Ian Jackson" , Wei Liu , Pau Ruiz Safont Subject: [PATCH v2 6/8] tools/ocaml/xenstored: add cooperative live-update command Date: Fri, 15 Jan 2021 22:28:48 +0000 Message-ID: <0ed42a4cb25f53620c31594de9949f150c4833cc.1610748224.git.edvin.torok@citrix.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: References: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @citrix.com) See docs/misc/xenstore.txt for documentation on live-update command. Validate that the binary exists and that the cmdline is valid, to prevent typos from taking down xenstore (if live-update fails there is no way back due to the use of execve). Live update only proceeds if there are no active transactions, and no unprocess input or unflushed output. It is not yet possible to force the live-update. Signed-off-by: Edwin T=C3=B6r=C3=B6k Reviewed-by: Pau Ruiz Safont Reviewed-by: Christian Lindig --- Changed since V1: * post publicly now that the XSA is out --- tools/ocaml/xenstored/process.ml | 112 +++++++++++++++++++++++++++++++ tools/ocaml/xenstored/stdext.ml | 6 ++ 2 files changed, 118 insertions(+) diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/proce= ss.ml index 437d2dcf9e..c3c5dc58c0 100644 --- a/tools/ocaml/xenstored/process.ml +++ b/tools/ocaml/xenstored/process.ml @@ -15,6 +15,7 @@ *) =20 let error fmt =3D Logging.error "process" fmt +let warn fmt =3D Logging.warn "process" fmt let info fmt =3D Logging.info "process" fmt let debug fmt =3D Logging.debug "process" fmt =20 @@ -84,11 +85,122 @@ let create_implicit_path t perm path =3D List.iter (fun s -> Transaction.mkdir ~with_watch:false t perm s) ret ) =20 +module LiveUpdate =3D struct +type t =3D + { binary: string + ; cmdline: string list + ; deadline: float + ; force: bool + ; pending: bool } + +let state =3D + ref + { binary=3D Sys.executable_name + ; cmdline=3D [] + ; deadline=3D 0. + ; force=3D false + ; pending=3D false } + +let debug =3D Printf.eprintf + +let args_of_t t =3D (t.binary, "--restart" :: t.cmdline) + +let string_of_t t =3D + let executable, rest =3D args_of_t t in + Filename.quote_command executable rest + +let launch_exn t =3D + let executable, rest =3D args_of_t t in + let args =3D Array.of_list (executable :: rest) in + Unix.execv args.(0) args + +let validate_exn t =3D + (* --help must be last to check validity of earlier arguments *) + let t =3D {t with cmdline=3D t.cmdline @ ["--help"]} in + let cmd =3D string_of_t t in + debug "Executing %s" cmd ; + match Unix.fork () with + | 0 -> + ( try launch_exn t with _ -> exit 2 ) + | pid -> ( + match Unix.waitpid [] pid with + | _, Unix.WEXITED 0 -> + debug "Live update validated cmdline %s" cmd; + t + | _, Unix.WEXITED n -> + invalid_arg (Printf.sprintf "Command %s exited with code %d" cmd n) + | _, Unix.WSIGNALED n -> + invalid_arg + (Printf.sprintf "Command %s killed by ocaml signal number %d" cmd n) + | _, Unix.WSTOPPED n -> + invalid_arg + (Printf.sprintf "Command %s stopped by ocaml signal number %d" cmd n) + ) + +let parse_live_update args =3D + try + (state :=3D + match args with + | ["-f"; file] -> + validate_exn {!state with binary=3D file} + | ["-a"] -> + debug "Live update aborted" ; + {!state with pending=3D false} + | "-c" :: cmdline -> + validate_exn {!state with cmdline} + | "-s" :: _ -> + let timeout =3D ref 60 in + let force =3D ref false in + Arg.parse_argv ~current:(ref 1) (Array.of_list args) + [ ( "-t" + , Arg.Set_int timeout + , "timeout in seconds to wait for active transactions to finish" + ) + (*; ( "-F" + , Arg.Set force + , "force live update to happen even with running transactions \ + after timeout elapsed" )*) ] + (fun x -> raise (Arg.Bad x)) + "live-update -s" ; + debug "Live update process queued" ; + {!state with deadline =3D Unix.gettimeofday () +. float !timeout + ; force=3D !force; pending=3D true} + | _ -> + invalid_arg ("Unknown arguments: " ^ String.concat " " args)) ; + None + with + | Arg.Bad s | Arg.Help s | Invalid_argument s -> + Some s + | Unix.Unix_error (e, fn, args) -> + Some (Printf.sprintf "%s(%s): %s" fn args (Unix.error_message e)) + + let should_run cons =3D + let t =3D !state in + if t.pending then begin + match Connections.prevents_quit cons with + | [] -> true + | _ when Unix.gettimeofday () < t.deadline -> false + | l -> + info "Live update timeout reached: %d active connections" (List.lengt= h l); + List.iter (fun con -> warn "%s prevents live update" (Connection.get_= domstr con)) l; + if t.force then begin + warn "Live update forced, some domain connections may break!"; + true + end else begin + warn "Live update aborted, try migrating or shutting down the domain= s/toolstack"; + state :=3D { t with pending =3D false }; + false + end + end else false +end + (* packets *) let do_debug con t _domains cons data =3D if not (Connection.is_dom0 con) && not !allow_debug then None else try match split None '\000' data with + | "live-update" :: params -> + LiveUpdate.parse_live_update params | "print" :: msg :: _ -> Logging.xb_op ~tid:0 ~ty:Xenbus.Xb.Op.Debug ~con:"=3D=3D=3D=3D=3D=3D=3D>= " msg; None diff --git a/tools/ocaml/xenstored/stdext.ml b/tools/ocaml/xenstored/stdext= .ml index 4f2f3a2c8c..e1567c4dfa 100644 --- a/tools/ocaml/xenstored/stdext.ml +++ b/tools/ocaml/xenstored/stdext.ml @@ -44,6 +44,12 @@ let default d v =3D let maybe f v =3D match v with None -> () | Some x -> f x =20 +module Filename =3D struct + include Filename + let quote_command cmd args =3D + cmd :: args |> List.map quote |> String.concat " " +end + module String =3D struct include String =20 let of_char c =3D String.make 1 c --=20 2.29.2