#22 add CoW
Merged a day ago by dcavalca. Opened 11 days ago by teknoraver.
rpms/ teknoraver/rpm c10s-sig-hyperscale  into  c10s-sig-hyperscale

@@ -0,0 +1,277 @@ 

+ From cf758158efa2832b38a49770f3489f408cb93b41 Mon Sep 17 00:00:00 2001

+ From: Matthew Almond <malmond@meta.com>

+ Date: Fri, 6 Dec 2024 08:00:31 +0100

+ Subject: [PATCH] Measure plugin

+ 

+ ---

+  macros.in              |   1 +

+  plugins/CMakeLists.txt |   1 +

+  plugins/measure.c      | 232 +++++++++++++++++++++++++++++++++++++++++

+  3 files changed, 234 insertions(+)

+  create mode 100644 plugins/measure.c

+ 

+ diff --git a/macros.in b/macros.in

+ index df7defe..1af187a 100644

+ --- a/macros.in

+ +++ b/macros.in

+ @@ -1189,6 +1189,7 @@ Supplements:   (%{name} = %{version}-%{release} and langpacks-%{1})\

+  # Transaction plugin macros

+  %__plugindir		%{_libdir}/rpm-plugins

+  %__transaction_reflink		%{__plugindir}/reflink.so

+ +%__transaction_measure		%{__plugindir}/measure.so

+  %__transaction_systemd_inhibit	%{__plugindir}/systemd_inhibit.so

+  %__transaction_selinux		%{__plugindir}/selinux.so

+  %__transaction_syslog		%{__plugindir}/syslog.so

+ diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt

+ index ed63a43..cda8f96 100644

+ --- a/plugins/CMakeLists.txt

+ +++ b/plugins/CMakeLists.txt

+ @@ -1,6 +1,7 @@

+  add_library(prioreset MODULE prioreset.c)

+  add_library(syslog MODULE syslog.c)

+  add_library(reflink MODULE reflink.c)

+ +add_library(measure MODULE measure.c)

+  

+  if(WITH_SELINUX)

+  	add_library(selinux MODULE selinux.c)

+ diff --git a/plugins/measure.c b/plugins/measure.c

+ new file mode 100644

+ index 0000000..593e463

+ --- /dev/null

+ +++ b/plugins/measure.c

+ @@ -0,0 +1,232 @@

+ +#include "system.h"

+ +#include "time.h"

+ +

+ +#include <rpm/rpmlog.h>

+ +#include <rpm/rpmmacro.h>

+ +#include <rpm/rpmts.h>

+ +#include <rpm/rpmlib.h>

+ +#include <rpm/rpmstring.h>

+ +

+ +#include "rpmplugin.h"

+ +

+ +struct measurestat {

+ +    /* We're counting psm not packages because packages often run psm_pre/post

+ +       more than once and we want to accumulate the time

+ +    */

+ +    unsigned int psm_count;

+ +    unsigned int scriptlet_count;

+ +    struct timespec plugin_start;

+ +    struct timespec psm_start;

+ +    struct timespec scriptlet_start;

+ +};

+ +

+ +static rpmRC push(const char *format, const char *value, const char *formatted)

+ +{

+ +    char *key = NULL;

+ +    rpmRC rc = RPMRC_FAIL;

+ +    if (formatted == NULL) {

+ +        /* yes we're okay with discarding const here */

+ +        key = (char *)format;

+ +    } else {

+ +        if (rasprintf(&key, format, formatted) == -1) {

+ +            rpmlog(

+ +                RPMLOG_ERR,

+ +                _("measure: Failed to allocate formatted key %s, %s\n"),

+ +                format,

+ +                formatted

+ +            );

+ +            goto exit;

+ +        }

+ +    }

+ +    if (rpmPushMacro(NULL, key, NULL, value, RMIL_GLOBAL)) {

+ +        rpmlog(RPMLOG_ERR, _("measure: Failed to set %s\n"), key);

+ +        goto exit;

+ +    }

+ +    rc = RPMRC_OK;

+ +exit:

+ +    if (formatted != NULL) {

+ +        free(key);

+ +    }

+ +    return rc;

+ +}

+ +

+ +static rpmRC diff_ms(char **ms, struct timespec *start, struct timespec *end)

+ +{

+ +    if (rasprintf(ms, "%ld", (

+ +        (end->tv_sec - start->tv_sec) * 1000 +

+ +        (end->tv_nsec - start->tv_nsec) / 1000000

+ +    )) == -1) {

+ +        rpmlog(RPMLOG_ERR, _("measure: Failed to allocate formatted ms\n"));

+ +        return RPMRC_FAIL;

+ +    }

+ +    return RPMRC_OK;

+ +}

+ +

+ +static rpmRC measure_init(rpmPlugin plugin, rpmts ts)

+ +{

+ +    rpmRC rc = RPMRC_FAIL;

+ +    struct measurestat *state = rcalloc(1, sizeof(*state));

+ +    if (clock_gettime(CLOCK_MONOTONIC, &state->plugin_start)) {

+ +        rpmlog(RPMLOG_ERR, _("measure: Failed to get plugin_start time\n"));

+ +        goto exit;

+ +    }

+ +    state->psm_count = 0;

+ +    state->scriptlet_count = 0;

+ +    rpmPluginSetData(plugin, state);

+ +    rc = RPMRC_OK;

+ +exit:

+ +    return rc;

+ +}

+ +

+ +static void measure_cleanup(rpmPlugin plugin)

+ +{

+ +    struct measurestat *state = rpmPluginGetData(plugin);

+ +    free(state);

+ +}

+ +

+ +static rpmRC measure_tsm_post(rpmPlugin plugin, rpmts ts, int res)

+ +{

+ +    struct measurestat *state = rpmPluginGetData(plugin);

+ +    char *psm_count = NULL, *scriptlet_count = NULL;

+ +    rpmRC rc = RPMRC_FAIL;

+ +

+ +    if (rasprintf(&psm_count, "%d", state->psm_count) == -1) {

+ +        rpmlog(RPMLOG_ERR, _("measure: Failed to allocate formatted psm_count\n"));

+ +        goto exit;

+ +    }

+ +    if (rasprintf(&scriptlet_count, "%d", state->scriptlet_count) == -1) {

+ +        rpmlog(RPMLOG_ERR, _("measure: Failed to allocate formatted scriptlet_count\n"));

+ +        goto exit;

+ +    }

+ +    if (push("_measure_plugin_psm_count", psm_count, NULL) != RPMRC_OK) {

+ +        goto exit;

+ +    }

+ +    if (push("_measure_plugin_scriptlet_count", scriptlet_count, NULL) != RPMRC_OK) {

+ +        goto exit;

+ +    }

+ +    rc = RPMRC_OK;

+ +exit:

+ +    free(psm_count);

+ +    free(scriptlet_count);

+ +    return rc;

+ +}

+ +

+ +static rpmRC measure_psm_pre(rpmPlugin plugin, rpmte te)

+ +{

+ +    struct measurestat *state = rpmPluginGetData(plugin);

+ +    rpmRC rc = RPMRC_FAIL;

+ +

+ +    if (clock_gettime(CLOCK_MONOTONIC, &state->psm_start)) {

+ +        rpmlog(RPMLOG_ERR, _("measure: Failed to get psm_start time\n"));

+ +        goto exit;

+ +    }

+ +    rc = RPMRC_OK;

+ +exit:

+ +    return rc;

+ +}

+ +

+ +static rpmRC measure_psm_post(rpmPlugin plugin, rpmte te, int res)

+ +{

+ +    struct measurestat *state = rpmPluginGetData(plugin);

+ +    struct timespec end;

+ +    char *offset = NULL, *duration = NULL, *prefix = NULL;

+ +    Header h = rpmteHeader(te);

+ +    rpmRC rc = RPMRC_FAIL;

+ +

+ +    if (clock_gettime(CLOCK_MONOTONIC, &end)) {

+ +        rpmlog(RPMLOG_ERR, _("measure: Failed to get psm end time\n"));

+ +        goto exit;

+ +    }

+ +    if (rasprintf(&prefix, "_measure_plugin_package_%u", state->psm_count) == -1) {

+ +        rpmlog(RPMLOG_ERR, _("measure: Failed to allocate prefix\n"));

+ +        goto exit;

+ +    }

+ +    if (diff_ms(&offset, &state->plugin_start, &state->psm_start) != RPMRC_OK) {

+ +        goto exit;

+ +    }

+ +    if (diff_ms(&duration, &state->psm_start, &end) != RPMRC_OK) {

+ +        goto exit;

+ +    }

+ +    if (push("%s_nevra", rpmteNEVRA(te), prefix) != RPMRC_OK) {

+ +        goto exit;

+ +    }

+ +    if (push("%s_compressor", headerGetString(h, RPMTAG_PAYLOADCOMPRESSOR), prefix) != RPMRC_OK) {

+ +        goto exit;

+ +    }

+ +    if (push("%s_offset", offset, prefix) != RPMRC_OK) {

+ +        goto exit;

+ +    }

+ +    if (push("%s_ms", duration, prefix) != RPMRC_OK) {

+ +        goto exit;

+ +    }

+ +    state->psm_count += 1;

+ +    rc = RPMRC_OK;

+ +exit:

+ +    headerFree(h);

+ +    free(prefix);

+ +    free(duration);

+ +    free(offset);

+ +    return rc;

+ +}

+ +

+ +static rpmRC measure_scriptlet_pre(rpmPlugin plugin,

+ +					const char *s_name, int type)

+ +{

+ +    struct measurestat *state = rpmPluginGetData(plugin);

+ +    if (clock_gettime(CLOCK_MONOTONIC, &state->scriptlet_start)) {

+ +        rpmlog(RPMLOG_ERR, _("measure: Failed to get scriptlet_start time\n"));

+ +        return RPMRC_FAIL;

+ +    }

+ +    return RPMRC_OK;

+ +}

+ +

+ +static rpmRC measure_scriptlet_post(rpmPlugin plugin,

+ +					const char *s_name, int type, int res)

+ +{

+ +    struct measurestat *state = rpmPluginGetData(plugin);

+ +    struct timespec end;

+ +    char *offset = NULL, *duration = NULL, *prefix = NULL;

+ +    rpmRC rc = RPMRC_FAIL;

+ +

+ +    if (clock_gettime(CLOCK_MONOTONIC, &end)) {

+ +        rpmlog(RPMLOG_ERR, _("measure: Failed to get end time\n"));

+ +        goto exit;

+ +    }

+ +

+ +    if (rasprintf(&prefix, "_measure_plugin_scriptlet_%d", state->scriptlet_count) == -1) {

+ +        rpmlog(RPMLOG_ERR, _("measure: Failed to allocate formatted prefix\n"));

+ +        goto exit;

+ +    }

+ +    if (diff_ms(&offset, &state->plugin_start, &state->scriptlet_start) != RPMRC_OK) {

+ +        goto exit;

+ +    }

+ +    if (diff_ms(&duration, &state->scriptlet_start, &end) != RPMRC_OK) {

+ +        goto exit;

+ +    }

+ +    if (push("%s_name", s_name, prefix) != RPMRC_OK) {

+ +        goto exit;

+ +    }

+ +    if (push("%s_offset", offset, prefix) != RPMRC_OK) {

+ +        goto exit;

+ +    }

+ +    if (push("%s_ms", duration, prefix) != RPMRC_OK) {

+ +        goto exit;

+ +    }

+ +    state->scriptlet_count += 1;

+ +    rc = RPMRC_OK;

+ +exit:

+ +    free(prefix);

+ +    free(duration);

+ +    free(offset);

+ +    return rc;

+ +}

+ +

+ +struct rpmPluginHooks_s measure_hooks = {

+ +    .init = measure_init,

+ +    .cleanup = measure_cleanup,

+ +    .tsm_post = measure_tsm_post,

+ +    .psm_pre = measure_psm_pre,

+ +    .psm_post = measure_psm_post,

+ +    .scriptlet_pre = measure_scriptlet_pre,

+ +    .scriptlet_post = measure_scriptlet_post,

+ +};

+ -- 

+ 2.47.1

+ 

The added file is too large to be shown here, see it at: 0001-RPM-with-Copy-on-Write.patch
file modified
+30 -1
@@ -27,7 +27,7 @@ 

  

  %global rpmver 4.19.1.1

  #global snapver rc1

- %global baserelease 9

+ %global baserelease 9.1

  %global sover 10

  

  %global srcver %{rpmver}%{?snapver:-%{snapver}}
@@ -149,6 +149,10 @@ 

  # These are not yet upstream

  rpm-4.7.1-geode-i686.patch

  

+ # CoW

+ 0001-RPM-with-Copy-on-Write.patch

+ 0001-Measure-plugin.patch

+ 

  %description

  The RPM Package Manager (RPM) is a powerful command line driven

  package management system capable of installing, uninstalling,
@@ -353,6 +357,20 @@ 

  subscribe to the signals to get notified when packages on the system

  change.

  

+ %package plugin-reflink

+ Summary: Rpm plugin for reflink functionality

+ Requires: rpm-libs%{_isa} = %{version}-%{release}

+ 

+ %description plugin-reflink

+ %{summary}.

+ 

+ %package plugin-measure

+ Summary: Rpm plugin for measure

+ Requires: rpm-libs%{_isa} = %{version}-%{release}

+ 

+ %description plugin-measure

+ Adds measure support

+ 

  # with plugins

  %endif

  
@@ -563,6 +581,14 @@ 

  %{_datadir}/dbus-1/system.d/org.rpm.conf

  %endif

  

+ %files plugin-reflink

+ %{rpmhome}/rpm2extents

+ %{rpmhome}/rpm2extents_dump

+ %{_libdir}/rpm-plugins/reflink.so

+ 

+ %files plugin-measure

+ %{_libdir}/rpm-plugins/measure.so

+ 

  %files build-libs

  %{_libdir}/librpmbuild.so.%{sover}

  %{_libdir}/librpmbuild.so.%{sover}.*
@@ -628,6 +654,9 @@ 

  %doc %{_defaultdocdir}/rpm/API/

  

  %changelog

+ * Thu Dec 05 2024 Matteo Croce <teknoraver@meta.com> - 4.19.1.1-9.1

+ - Port CoW and measure plugins to 4.19

+ 

  * Wed Dec 04 2024 Panu Matilainen <pmatilai@redhat.com> - 4.19.1.1-9

  - Revert the gnupg/sequoia sub-packages, too much headache

  - Ship sequoia-signing enablement macros as documentation instead

Port RPM CoW on top of latest C10s tree.
Port measure plugin as well.

Run test:

[root@localhost ~]# cat /etc/redhat-release
CentOS Stream release 10 (Coughlan)
[root@localhost ~]# rpm -q rpm rpm-plugin-reflink
rpm-4.19.1.1-9.1.hs.el10.aarch64
rpm-plugin-reflink-4.19.1.1-9.1.hs.el10.aarch64
[root@localhost ~]# strace -eioctl rpm -i zsh-5.9-15.el10.aarch64.rpme
ioctl(13, BTRFS_IOC_CLONE_RANGE or FICLONERANGE, {src_fd=9, src_offset=544768, src_length=4096, dest_offset=0}) = 0
ioctl(13, BTRFS_IOC_CLONE_RANGE or FICLONERANGE, {src_fd=9, src_offset=548864, src_length=4096, dest_offset=0}) = 0
ioctl(12, BTRFS_IOC_CLONE_RANGE or FICLONERANGE, {src_fd=9, src_offset=552960, src_length=4096, dest_offset=0}) = 0
ioctl(12, BTRFS_IOC_CLONE_RANGE or FICLONERANGE, {src_fd=9, src_offset=557056, src_length=4096, dest_offset=0}) = 0
ioctl(12, BTRFS_IOC_CLONE_RANGE or FICLONERANGE, {src_fd=9, src_offset=561152, src_length=4096, dest_offset=0}) = 0
ioctl(12, BTRFS_IOC_CLONE_RANGE or FICLONERANGE, {src_fd=9, src_offset=565248, src_length=4096, dest_offset=0}) = 0
[...]
[root@localhost ~]# rpm -V zsh
[root@localhost ~]# zsh --version
zsh 5.9 (aarch64-redhat-linux-gnu)

rebased onto 4783f44

a day ago

Pull-Request has been merged by dcavalca

a day ago