From nobody Wed May 14 10:11:00 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=fail(p=none dis=none) header.from=gmail.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1527449194882889.2293020934816; Sun, 27 May 2018 12:26:34 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 6EEDA30A81B2; Sun, 27 May 2018 19:26:33 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 424E958B8; Sun, 27 May 2018 19:26:33 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id EC31E4CA83; Sun, 27 May 2018 19:26:32 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id w4RJQCE1021811 for ; Sun, 27 May 2018 15:26:12 -0400 Received: by smtp.corp.redhat.com (Postfix) id A3BB936FA; Sun, 27 May 2018 19:26:12 +0000 (UTC) Received: from mx1.redhat.com (ext-mx02.extmail.prod.ext.phx2.redhat.com [10.5.110.26]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 9A89A5DD6B for ; Sun, 27 May 2018 19:26:12 +0000 (UTC) Received: from mail-qk0-f193.google.com (mail-qk0-f193.google.com [209.85.220.193]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 55FF9A7036 for ; Sun, 27 May 2018 19:26:01 +0000 (UTC) Received: by mail-qk0-f193.google.com with SMTP id j12-v6so4424248qkk.4 for ; Sun, 27 May 2018 12:26:01 -0700 (PDT) Received: from localhost.localdomain ([186.223.96.215]) by smtp.gmail.com with ESMTPSA id 73-v6sm5901971qkc.96.2018.05.27.12.25.58 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 27 May 2018 12:25:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id:in-reply-to:references; bh=gE2vnrCv8hanjvWJ/9YJyhQpISCpiwWO9UTpCPpvH3U=; b=Pm2XbOLEvXA+IBxEFvZdpZANNrpDLTSdMMsIIsgM9g18E0wznKKvjSf5LYnYh9/6Ck i3Ym4M1URdwN/Wo1xbo0kwld/UF+FBvY2wFZK3QbiCob56mx/tEWC4SviZYIIMIbqUj4 V2AWg/w6LpNC0l7IfR9G4WCW6Yz32D0vCDqcWHkvg2zKPhtTRzcuTCNpICE0X5y9ur59 8joM374aWM/fFMwgYOlxT0pX1hsdIOZd3jvb0k6P2AD7CiRkw3Sb1PcdHRNiYmqbIm3a pTfQMGCy+oKg1Abd5i3uJhLOKwlzDlEHs8d7WeKiasCcdjJQB9B7km3VfwD5PYaNm+ue gx4w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=gE2vnrCv8hanjvWJ/9YJyhQpISCpiwWO9UTpCPpvH3U=; b=eO1oLTkC1VQ1zAfYk6Ccbx8hFR7mJLQGBip2D+rKf6bYB09DRHhTrefbpdUKw7lq8r xaAnGSmXHFHQMD7ouWOoeAY4nQY74kWRCKmIAQmmKyAhINq9kALfA4KJpjOUk+9I3LyC k0r99nOtoePsqlTzVF0rTE3NsCLAUdh1ikLPAiWPXdGQmtNpz2hGz2HubstU5zpzhs+b 1XivetmzIX4ymf+k1mG7psM8MfYy5lLxMyo6FopPsb/KI8C76cwdcM2R3qkQ7jEaNwKy 9L5Z84wuEK9gjfNKbQuFBr6+kL1va/biyIaFzVF5wxb+mgB2HPgZlC9hVI6DITRgTpYF oKig== X-Gm-Message-State: ALKqPwfkl7eWmQdiYw/GbtobnzE3PH7wOH8iYnJiIDi0HSjpbJo9mDf3 Wfxuz7vUAzHr18HqLG8zejJXhw== X-Google-Smtp-Source: ADUXVKJeTXqKDzr4LwC6tLs6q/GguN2XS9LidtAa7gLmUZjv8zaqOx3oEVE9Zmgwn/LqoUrRLgfptA== X-Received: by 2002:a37:7844:: with SMTP id t65-v6mr9509325qkc.56.1527449160266; Sun, 27 May 2018 12:26:00 -0700 (PDT) From: Julio Faracco To: libvir-list@redhat.com Date: Sun, 27 May 2018 16:25:38 -0300 Message-Id: <20180527192539.17922-5-jcfaracco@gmail.com> In-Reply-To: <20180527192539.17922-1-jcfaracco@gmail.com> References: <20180527192539.17922-1-jcfaracco@gmail.com> X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.26]); Sun, 27 May 2018 19:26:01 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.26]); Sun, 27 May 2018 19:26:01 +0000 (UTC) for IP:'209.85.220.193' DOMAIN:'mail-qk0-f193.google.com' HELO:'mail-qk0-f193.google.com' FROM:'jcfaracco@gmail.com' RCPT:'' X-RedHat-Spam-Score: 1.281 * (DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, NML_ADSP_CUSTOM_MED, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_PASS, T_DKIM_INVALID) 209.85.220.193 mail-qk0-f193.google.com 209.85.220.193 mail-qk0-f193.google.com X-Scanned-By: MIMEDefang 2.78 on 10.5.110.26 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH 4/5] virsh: implementing 'vol-event' command. X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.40]); Sun, 27 May 2018 19:26:33 +0000 (UTC) X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" As we have some basics events for volumes, virsh can have the 'vol-event' command to check some events related to volumes. Signed-off-by: Julio Faracco --- tools/virsh-completer.c | 27 ++++++ tools/virsh-completer.h | 4 + tools/virsh-volume.c | 192 ++++++++++++++++++++++++++++++++++++++++ tools/virsh-volume.h | 8 ++ 4 files changed, 231 insertions(+) diff --git a/tools/virsh-completer.c b/tools/virsh-completer.c index d3effe59ea..30cc595376 100644 --- a/tools/virsh-completer.c +++ b/tools/virsh-completer.c @@ -26,6 +26,7 @@ #include "virsh-domain.h" #include "virsh.h" #include "virsh-pool.h" +#include "virsh-volume.h" #include "virsh-nodedev.h" #include "virsh-util.h" #include "virsh-secret.h" @@ -732,6 +733,32 @@ virshPoolEventNameCompleter(vshControl *ctl ATTRIBUTE_= UNUSED, } =20 =20 +char ** +virshVolEventNameCompleter(vshControl *ctl ATTRIBUTE_UNUSED, + const vshCmd *cmd ATTRIBUTE_UNUSED, + unsigned int flags) +{ + size_t i =3D 0; + char **ret =3D NULL; + + virCheckFlags(0, NULL); + + if (VIR_ALLOC_N(ret, VIR_STORAGE_VOL_EVENT_ID_LAST) < 0) + goto error; + + for (i =3D 0; i < VIR_STORAGE_VOL_EVENT_ID_LAST; i++) { + if (VIR_STRDUP(ret[i], virshVolEventCallbacks[i].name) < 0) + goto error; + } + + return ret; + + error: + virStringListFree(ret); + return NULL; +} + + char ** virshNodedevEventNameCompleter(vshControl *ctl ATTRIBUTE_UNUSED, const vshCmd *cmd ATTRIBUTE_UNUSED, diff --git a/tools/virsh-completer.h b/tools/virsh-completer.h index ee7eec68c5..831be73d7e 100644 --- a/tools/virsh-completer.h +++ b/tools/virsh-completer.h @@ -90,6 +90,10 @@ char ** virshPoolEventNameCompleter(vshControl *ctl, const vshCmd *cmd, unsigned int flags); =20 +char ** virshVolEventNameCompleter(vshControl *ctl, + const vshCmd *cmd, + unsigned int flags); + char ** virshNodedevEventNameCompleter(vshControl *ctl, const vshCmd *cmd, unsigned int flags); diff --git a/tools/virsh-volume.c b/tools/virsh-volume.c index 9d6ebd2325..63497b7d8c 100644 --- a/tools/virsh-volume.c +++ b/tools/virsh-volume.c @@ -42,6 +42,7 @@ #include "virsh-pool.h" #include "virxml.h" #include "virstring.h" +#include "virtime.h" =20 #define VIRSH_COMMON_OPT_POOL_FULL \ VIRSH_COMMON_OPT_POOL(N_("pool name or uuid"), \ @@ -1772,6 +1773,191 @@ cmdVolPath(vshControl *ctl, const vshCmd *cmd) return true; } =20 +/* + * "vol-event" command + */ +VIR_ENUM_DECL(virshVolEvent) +VIR_ENUM_IMPL(virshVolEvent, + VIR_STORAGE_VOL_EVENT_LAST, + N_("Created"), + N_("Deleted")) + +static const char * +virshVolEventToString(int event) +{ + const char *str =3D virshVolEventTypeToString(event); + return str ? _(str) : _("unknown"); +} + +struct virshVolEventData { + vshControl *ctl; + bool loop; + bool timestamp; + int count; + virshVolEventCallback *cb; +}; +typedef struct virshVolEventData virshVolEventData; + + +static void +vshEventLifecyclePrint(virConnectPtr conn ATTRIBUTE_UNUSED, + virStorageVolPtr vol, + int event, + int detail ATTRIBUTE_UNUSED, + void *opaque) +{ + virshVolEventData *data =3D opaque; + + if (!data->loop && data->count) + return; + + if (data->timestamp) { + char timestamp[VIR_TIME_STRING_BUFLEN]; + + if (virTimeStringNowRaw(timestamp) < 0) + timestamp[0] =3D '\0'; + + vshPrint(data->ctl, _("%s: event 'lifecycle' for storage vol %s: %= s\n"), + timestamp, + virStorageVolGetName(vol), + virshVolEventToString(event)); + } else { + vshPrint(data->ctl, _("event 'lifecycle' for storage vol %s: %s\n"= ), + virStorageVolGetName(vol), + virshVolEventToString(event)); + } + + data->count++; + if (!data->loop) + vshEventDone(data->ctl); +} + +virshVolEventCallback virshVolEventCallbacks[] =3D { + { "lifecycle", + VIR_STORAGE_VOL_EVENT_CALLBACK(vshEventLifecyclePrint), } +}; +verify(VIR_STORAGE_VOL_EVENT_ID_LAST =3D=3D ARRAY_CARDINALITY(virshVolEven= tCallbacks)); + + +static const vshCmdInfo info_vol_event[] =3D { + {.name =3D "help", + .data =3D N_("Storage Vol Events") + }, + {.name =3D "desc", + .data =3D N_("List event types, or wait for storage vol events to occ= ur") + }, + {.name =3D NULL} +}; + +static const vshCmdOptDef opts_vol_event[] =3D { + {.name =3D "vol", + .type =3D VSH_OT_STRING, + .help =3D N_("filter by storage vol name or uuid") + }, + {.name =3D "event", + .type =3D VSH_OT_STRING, + .completer =3D virshVolEventNameCompleter, + .help =3D N_("which event type to wait for") + }, + {.name =3D "loop", + .type =3D VSH_OT_BOOL, + .help =3D N_("loop until timeout or interrupt, rather than one-shot") + }, + {.name =3D "timeout", + .type =3D VSH_OT_INT, + .help =3D N_("timeout seconds") + }, + {.name =3D "list", + .type =3D VSH_OT_BOOL, + .help =3D N_("list valid event types") + }, + {.name =3D "timestamp", + .type =3D VSH_OT_BOOL, + .help =3D N_("show timestamp for each printed event") + }, + {.name =3D NULL} +}; + +static bool +cmdVolEvent(vshControl *ctl, const vshCmd *cmd) +{ + virStorageVolPtr vol =3D NULL; + bool ret =3D false; + int eventId =3D -1; + int timeout =3D 0; + virshVolEventData data; + const char *eventName =3D NULL; + int event; + virshControlPtr priv =3D ctl->privData; + + if (vshCommandOptBool(cmd, "list")) { + size_t i; + + for (i =3D 0; i < VIR_STORAGE_VOL_EVENT_ID_LAST; i++) + vshPrint(ctl, "%s\n", virshVolEventCallbacks[i].name); + return true; + } + + if (vshCommandOptStringReq(ctl, cmd, "event", &eventName) < 0) + return false; + if (!eventName) { + vshError(ctl, "%s", _("either --list or --event is required= ")); + return false; + } + + for (event =3D 0; event < VIR_STORAGE_VOL_EVENT_ID_LAST; event++) + if (STREQ(eventName, virshVolEventCallbacks[event].name)) + break; + if (event =3D=3D VIR_STORAGE_VOL_EVENT_ID_LAST) { + vshError(ctl, _("unknown event type %s"), eventName); + return false; + } + + data.ctl =3D ctl; + data.loop =3D vshCommandOptBool(cmd, "loop"); + data.timestamp =3D vshCommandOptBool(cmd, "timestamp"); + data.count =3D 0; + data.cb =3D &virshVolEventCallbacks[event]; + if (vshCommandOptTimeoutToMs(ctl, cmd, &timeout) < 0) + return false; + + if (vshCommandOptBool(cmd, "vol")) + vol =3D virshCommandOptVolBy(ctl, cmd, "vol", NULL, NULL, + VIRSH_BYUUID); + + if (vshEventStart(ctl, timeout) < 0) + goto cleanup; + + if ((eventId =3D virConnectStorageVolEventRegisterAny(priv->conn, vol,= event, + data.cb->cb, + &data, NULL)) < 0) + goto cleanup; + switch (vshEventWait(ctl)) { + case VSH_EVENT_INTERRUPT: + vshPrint(ctl, "%s", _("event loop interrupted\n")); + break; + case VSH_EVENT_TIMEOUT: + vshPrint(ctl, "%s", _("event loop timed out\n")); + break; + case VSH_EVENT_DONE: + break; + default: + goto cleanup; + } + vshPrint(ctl, _("events received: %d\n"), data.count); + if (data.count) + ret =3D true; + + cleanup: + vshEventCleanup(ctl); + if (eventId >=3D 0 && + virConnectStorageVolEventDeregisterAny(priv->conn, eventId) < 0) + ret =3D false; + if (vol) + virStorageVolFree(vol); + return ret; +} + const vshCmdDef storageVolCmds[] =3D { {.name =3D "vol-clone", .handler =3D cmdVolClone, @@ -1869,5 +2055,11 @@ const vshCmdDef storageVolCmds[] =3D { .info =3D info_vol_wipe, .flags =3D 0 }, + {.name =3D "vol-event", + .handler =3D cmdVolEvent, + .opts =3D opts_vol_event, + .info =3D info_vol_event, + .flags =3D 0 + }, {.name =3D NULL} }; diff --git a/tools/virsh-volume.h b/tools/virsh-volume.h index 60f647776e..7869d3bfaf 100644 --- a/tools/virsh-volume.h +++ b/tools/virsh-volume.h @@ -38,6 +38,14 @@ virStorageVolPtr virshCommandOptVolBy(vshControl *ctl, c= onst vshCmd *cmd, virshCommandOptVolBy(_ctl, _cmd, _optname, _pooloptname, _name, \ VIRSH_BYUUID | VIRSH_BYNAME) =20 +struct virshVolEventCallback { + const char *name; + virConnectStorageVolEventGenericCallback cb; +}; +typedef struct virshVolEventCallback virshVolEventCallback; + +extern virshVolEventCallback virshVolEventCallbacks[]; + extern const vshCmdDef storageVolCmds[]; =20 #endif /* VIRSH_VOLUME_H */ --=20 2.17.0 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list