Hello community,

here is the log from the commit of package conmon for openSUSE:Factory checked 
in at 2020-03-08 22:23:44
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/conmon (Old)
 and      /work/SRC/openSUSE:Factory/.conmon.new.26092 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "conmon"

Sun Mar  8 22:23:44 2020 rev:9 rq:781862 version:2.0.11

Changes:
--------
--- /work/SRC/openSUSE:Factory/conmon/conmon.changes    2020-02-21 
16:40:28.817807938 +0100
+++ /work/SRC/openSUSE:Factory/.conmon.new.26092/conmon.changes 2020-03-08 
22:24:01.532073320 +0100
@@ -1,0 +2,11 @@
+Thu Mar  5 08:06:24 UTC 2020 - Sascha Grunert <sgrun...@suse.com>
+
+- Update to v2.0.11
+  - log: reject --log-tag with k8s-file
+  - chmod std files pipes
+  - adjust score to -1000 to prevent conmon from ever being OOM
+    killed
+  - container OOM: verify cgroup hasn't been cleaned up before
+    reporting OOM
+
+-------------------------------------------------------------------

Old:
----
  conmon-2.0.10.tar.xz

New:
----
  conmon-2.0.11.tar.xz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ conmon.spec ++++++
--- /var/tmp/diff_new_pack.8SUZcB/_old  2020-03-08 22:24:02.296073791 +0100
+++ /var/tmp/diff_new_pack.8SUZcB/_new  2020-03-08 22:24:02.300073794 +0100
@@ -17,7 +17,7 @@
 
 
 Name:           conmon
-Version:        2.0.10
+Version:        2.0.11
 Release:        0
 Summary:        An OCI container runtime monitor
 License:        Apache-2.0

++++++ _service ++++++
--- /var/tmp/diff_new_pack.8SUZcB/_old  2020-03-08 22:24:02.336073816 +0100
+++ /var/tmp/diff_new_pack.8SUZcB/_new  2020-03-08 22:24:02.336073816 +0100
@@ -2,8 +2,8 @@
 <service name="tar_scm" mode="disabled">
 <param name="url">https://github.com/containers/conmon</param>
 <param name="scm">git</param>
-<param name="versionformat">2.0.10</param>
-<param name="revision">v2.0.10</param>
+<param name="versionformat">2.0.11</param>
+<param name="revision">v2.0.11</param>
 </service>
 <service name="recompress" mode="disabled">
 <param name="file">conmon-*.tar</param>

++++++ conmon-2.0.10.tar.xz -> conmon-2.0.11.tar.xz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/conmon-2.0.10/.cirrus.yml 
new/conmon-2.0.11/.cirrus.yml
--- old/conmon-2.0.10/.cirrus.yml       2020-01-07 22:53:52.000000000 +0100
+++ new/conmon-2.0.11/.cirrus.yml       2020-03-04 19:07:40.000000000 +0100
@@ -7,15 +7,19 @@
     ####
     # File to update in home-dir with task-specific env. var values
     ENVLIB: ".bash_profile"
+    GOPATH: "/var/tmp/go"
+    PATH: "${PATH}:${GOPATH}"
+    CRIO_REPO: "https://github.com/cri-o/cri-o.git";
+    CRIO_SLUG: "github.com/cri-o/cri-o"
+    CONMON_SLUG: "github.com/containers/conmon"
+
     # Overrides default location (/tmp/cirrus) for repo clone (will become 
$SRC)
-    CIRRUS_WORKING_DIR: "/tmp/conmon"
+    CIRRUS_WORKING_DIR: "${GOPATH}/src/${CONMON_SLUG}"
     # Required so $ENVLIB gets loaded and /bin/sh is not used
     CIRRUS_SHELL: "/bin/bash"
     # Save a little typing (path relative to $CIRRUS_WORKING_DIR)
     SCRIPT_BASE: "./contrib/cirrus"
     PACKER_BASE: "./contrib/cirrus/packer"
-    CRIO_REPO: "https://github.com/cri-o/cri-o.git";
-    CRIO_SLUG: "github.com/cri-o/cri-o"
     # Spoof self as travis, as cirrus has the same test issues as travis does
     TRAVIS: "true"
 
@@ -63,10 +67,11 @@
 # Every *_task runs in parallel in separate VMs. The name prefix only for 
reference
 # in WebUI, and will be followed by matrix details.  This task runs the 
integration
 # testing for every platform
-integration_task:
+cri-o_integration_task:
 
     depends_on:
         - 'config'
+        - 'fmt'
 
     gce_instance:
         # Generate multiple parallel tasks, covering all possible
@@ -81,6 +86,20 @@
             TEST_USERNS: 1
 
     setup_environment_script: '$SCRIPT_BASE/setup_environment.sh'
+    integration_test_script: '$SCRIPT_BASE/cri-o_test.sh'
+
+# this task runs the conmon integration tests
+integration_task:
+
+    depends_on:
+        - 'config'
+        - 'fmt'
+
+    gce_instance:
+        matrix:
+            # Images are generated separately, from build_images_task (below)
+            image_name: "${FEDORA_CACHE_IMAGE_NAME}"
+
     integration_test_script: '$SCRIPT_BASE/integration_test.sh'
 
 
@@ -108,8 +127,6 @@
 
 # Verify calls to bin/config were saved
 config_task:
-    env:
-        GOSRC: $CIRRUS_WORKING_DIR
     # Runs within Cirrus's "community cluster"
     container:
         matrix:
@@ -121,12 +138,30 @@
         memory: 12
 
     script:
-        - dnf install -y make glib2-devel git gcc rpm-build golang
+        - dnf install -y make glib2-devel git gcc golang
         - cd $CIRRUS_WORKING_DIR
         - GO111MODULE=on go mod init github.com/containers/conmon
         - make config
         - ./hack/tree_status.sh
 
+# Verify code was fmt'ed properly
+fmt_task:
+    # Runs within Cirrus's "community cluster"
+    container:
+        matrix:
+               # fedora:28 doesn't have go mod by default
+               # and we should only need one check to make sure
+               # config changes were synced
+            image: "${FEDORA_CONTAINER_FQIN}"
+        cpu: 4
+        memory: 12
+
+    script:
+        - dnf install -y make glib2-devel git gcc rpm-build clang golang
+        - cd $CIRRUS_WORKING_DIR
+        - make fmt
+        - ./hack/tree_status.sh
+
 # Test building of new cache-images for future PR testing, in this PR.
 # Output images will be stored only for a very short time, then automatically 
deleted.
 test_cache_images_task:
@@ -193,6 +228,7 @@
 static_binary_task:
     depends_on:
         - 'config'
+        - 'fmt'
     gce_instance:
         image_name: "${FEDORA_BASE_IMAGE}"
         cpu: 4
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/conmon-2.0.10/CODE-OF-CONDUCT.md 
new/conmon-2.0.11/CODE-OF-CONDUCT.md
--- old/conmon-2.0.10/CODE-OF-CONDUCT.md        1970-01-01 01:00:00.000000000 
+0100
+++ new/conmon-2.0.11/CODE-OF-CONDUCT.md        2020-03-04 19:07:40.000000000 
+0100
@@ -0,0 +1,3 @@
+## The conmon Project Community Code of Conduct
+
+The conmon Project follows the [Containers Community Code of 
Conduct](https://github.com/containers/common/blob/master/CODE-OF-CONDUCT.md).
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/conmon-2.0.10/Makefile new/conmon-2.0.11/Makefile
--- old/conmon-2.0.10/Makefile  2020-01-07 22:53:52.000000000 +0100
+++ new/conmon-2.0.11/Makefile  2020-03-04 19:07:40.000000000 +0100
@@ -72,6 +72,9 @@
        $(GO) build $(LDFLAGS) -tags "$(BUILDTAGS)" -o bin/config 
$(PROJECT)/cmd/conmon-config
                ( cd src && $(CURDIR)/bin/config )
 
+test: git-vars runner/conmon_test/*.go runner/conmon/*.go
+       $(GO) test $(LDFLAGS) -tags "$(BUILDTAGS)" 
$(PROJECT)/runner/conmon_test/
+
 src/cmsg.o: src/cmsg.c src/cmsg.h
 
 src/utils.o: src/utils.c src/utils.h
@@ -83,6 +86,14 @@
 bin:
        mkdir -p bin
 
+vendor:
+       export GO111MODULE=on \
+               $(GO) mod tidy && \
+               $(GO) mod vendor && \
+               $(GO) mod verify
+
+.PHONY: vendor
+
 .PHONY: clean
 clean:
        rm -rf bin/ src/*.o
@@ -105,5 +116,6 @@
 
 .PHONY: fmt
 fmt:
-       find . '(' -name '*.h' -o -name '*.c' ')'  -exec clang-format -i {} \+
+       find . '(' -name '*.h' -o -name '*.c' ! -path './vendor/*' ')'  -exec 
clang-format -i {} \+
+       find . -name '*.go' ! -path './vendor/*' -exec gofmt -s -w {} \+
        git diff --exit-code
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/conmon-2.0.10/VERSION new/conmon-2.0.11/VERSION
--- old/conmon-2.0.10/VERSION   2020-01-07 22:53:52.000000000 +0100
+++ new/conmon-2.0.11/VERSION   2020-03-04 19:07:40.000000000 +0100
@@ -1 +1 @@
-2.0.10
+2.0.11
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/conmon-2.0.10/contrib/cirrus/cri-o_test.sh 
new/conmon-2.0.11/contrib/cirrus/cri-o_test.sh
--- old/conmon-2.0.10/contrib/cirrus/cri-o_test.sh      1970-01-01 
01:00:00.000000000 +0100
+++ new/conmon-2.0.11/contrib/cirrus/cri-o_test.sh      2020-03-04 
19:07:40.000000000 +0100
@@ -0,0 +1,33 @@
+#!/bin/bash
+
+set -e
+source $(dirname $0)/lib.sh
+
+req_env_var "
+SRC $SRC
+CRIO_SRC $CRIO_SRC
+OS_RELEASE_ID $OS_RELEASE_ID
+OS_RELEASE_VER $OS_RELEASE_VER
+"
+
+cd "$CRIO_SRC"
+case "$OS_REL_VER" in
+    fedora-29)
+        PATCH="$SRC/$SCRIPT_BASE/network_bats.patch"
+        cd "$CRIO_SRC"
+        echo "WARNING: Applying $PATCH"
+        git apply --index --apply --ignore-space-change --recount "$PATCH"
+        ;;
+    *) bad_os_id_ver ;;
+esac
+
+# Assume cri-o and all dependencies are installed from packages
+# and conmon installed using build_and_replace_conmon()
+export CRIO_BINARY=/usr/bin/crio
+export CONMON_BINARY=/usr/libexec/crio/conmon
+export PAUSE_BINARY=/usr/libexec/crio/pause
+export CRIO_CNI_PLUGIN=/usr/libexec/cni
+
+echo "Executing cri-o integration tests (typical 10 - 20 min)"
+cd "$CRIO_SRC"
+timeout --foreground --kill-after=5m 60m ./test/test_runner.sh
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/conmon-2.0.10/contrib/cirrus/integration_test.sh 
new/conmon-2.0.11/contrib/cirrus/integration_test.sh
--- old/conmon-2.0.10/contrib/cirrus/integration_test.sh        2020-01-07 
22:53:52.000000000 +0100
+++ new/conmon-2.0.11/contrib/cirrus/integration_test.sh        2020-03-04 
19:07:40.000000000 +0100
@@ -4,30 +4,17 @@
 source $(dirname $0)/lib.sh
 
 req_env_var "
-SRC $SRC
-GOSRC $GOSRC
-OS_RELEASE_ID $OS_RELEASE_ID
-OS_RELEASE_VER $OS_RELEASE_VER
+       CRIO_REPO $CRIO_REPO
+       CRIO_SLUG $CRIO_SLUG
+       CONMON_SLUG $CONMON_SLUG
+       CIRRUS_WORKING_DIR $CIRRUS_WORKING_DIR
+       GOPATH $GOPATH
 "
 
-cd "$GOSRC"
-case "$OS_REL_VER" in
-    fedora-29)
-        PATCH="$SRC/$SCRIPT_BASE/network_bats.patch"
-        cd "$GOSRC"
-        echo "WARNING: Applying $PATCH"
-        git apply --index --apply --ignore-space-change --recount "$PATCH"
-        ;;
-    *) bad_os_id_ver ;;
-esac
-
-# Assume cri-o and all dependencies are installed from packages
-# and conmon installed using build_and_replace_conmon()
-export CRIO_BINARY=/usr/bin/crio
-export CONMON_BINARY=/usr/libexec/crio/conmon
-export PAUSE_BINARY=/usr/libexec/crio/pause
-export CRIO_CNI_PLUGIN=/usr/libexec/cni
-
-echo "Executing cri-o integration tests (typical 10 - 20 min)"
-cd "$GOSRC"
-timeout --foreground --kill-after=5m 60m ./test/test_runner.sh
+dnf install -y make glib2-devel git gcc golang
+setup_gopath
+cd $CIRRUS_WORKING_DIR
+make
+make install PREFIX=/usr # currently, the conmon location is hardcoded to 
/usr/bin/conmon
+GOCACHE=/tmp/go-build make vendor
+make test
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/conmon-2.0.10/contrib/cirrus/lib.sh 
new/conmon-2.0.11/contrib/cirrus/lib.sh
--- old/conmon-2.0.10/contrib/cirrus/lib.sh     2020-01-07 22:53:52.000000000 
+0100
+++ new/conmon-2.0.11/contrib/cirrus/lib.sh     2020-03-04 19:07:40.000000000 
+0100
@@ -166,32 +166,42 @@
     req_env_var "
         CRIO_REPO $CRIO_REPO
         CRIO_SLUG $CRIO_SLUG
+        CONMON_SLUG $CONMON_SLUG
     "
     echo "Configuring persistent Go environment for all users"
     sudo mkdir -p /var/tmp/go/src
     sudo chown -R $USER:$USER /var/tmp/go
     sudo chmod g=rws /var/tmp/go
     ENVLIB=/etc/profile.d/go.sh
+       # configure GOPATH if not set
     if ! grep -q GOPATH $ENVLIB
     then
         sudo tee "$ENVLIB" << EOF
 export GOPATH=/var/tmp/go
-export GOSRC=\$GOPATH/src/$CRIO_SLUG
 export PATH=\$PATH:\$GOPATH/bin
 EOF
     source $ENVLIB
     fi
+
+       # configure CRIO_SRC if not set
+    if ! grep -q CRIO_SRC $ENVLIB
+    then
+        sudo tee "$ENVLIB" << EOF
+export CRIO_SRC=\$GOPATH/src/$CRIO_SLUG
+EOF
+    source $ENVLIB
+    fi
 }
 
 install_crio_repo() {
     req_env_var "
         GOPATH $GOPATH
-        GOSRC $GOSRC
+        CRIO_SRC $CRIO_SRC
         CRIO_REPO $CRIO_REPO
     "
     echo "Cloning current CRI-O Source for faster access later"
-    sudo rm -rf "$GOSRC"  # just in case
-    ooe.sh git clone $CRIO_REPO $GOSRC
+    sudo rm -rf "$CRIO_SRC"  # just in case
+    ooe.sh git clone $CRIO_REPO $CRIO_SRC
 
     # Install CRI-O
     cd crio
@@ -202,7 +212,7 @@
 install_testing_deps() {
     req_env_var "
         GOPATH $GOPATH
-        GOSRC $GOSRC
+        CRIO_SRC $CRIO_SRC
     "
 
     echo "Installing required go packages into \$GOPATH"
@@ -226,7 +236,7 @@
     rm -rf /tmp/bats
 
     echo "Installing helper script for CNI plugin test"
-    cd "$GOSRC"
+    cd "$CRIO_SRC"
     sudo mkdir -p /opt/cni/bin/
     # Search path for helper is difficult to control
     ooe.sh sudo install -D -m 0755 test/cni_plugin_helper.bash 
/usr/libexec/cni/
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/conmon-2.0.10/contrib/cirrus/setup_environment.sh 
new/conmon-2.0.11/contrib/cirrus/setup_environment.sh
--- old/conmon-2.0.10/contrib/cirrus/setup_environment.sh       2020-01-07 
22:53:52.000000000 +0100
+++ new/conmon-2.0.11/contrib/cirrus/setup_environment.sh       2020-03-04 
19:07:40.000000000 +0100
@@ -68,7 +68,7 @@
             install_testing_deps
             build_and_replace_conmon
 
-            cd "$GOSRC"  # cri-o source
+            cd "$CRIO_SRC"  # cri-o source
             echo "Building binaries required for testing"
             ooe.sh make test-binaries
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/conmon-2.0.10/go.sum new/conmon-2.0.11/go.sum
--- old/conmon-2.0.10/go.sum    1970-01-01 01:00:00.000000000 +0100
+++ new/conmon-2.0.11/go.sum    2020-03-04 19:07:40.000000000 +0100
@@ -0,0 +1,31 @@
+github.com/fsnotify/fsnotify v1.4.7 
h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
+github.com/fsnotify/fsnotify v1.4.7/go.mod 
h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
+github.com/golang/protobuf v1.2.0 
h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
+github.com/golang/protobuf v1.2.0/go.mod 
h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
+github.com/hpcloud/tail v1.0.0/go.mod 
h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
+github.com/onsi/ginkgo v1.6.0/go.mod 
h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
+github.com/onsi/ginkgo v1.11.0 h1:JAKSXpt1YjtLA7YpPiqO9ss6sNXEsPfSGdwN0UHqzrw=
+github.com/onsi/ginkgo v1.11.0/go.mod 
h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
+github.com/onsi/gomega v1.8.1 h1:C5Dqfs/LeauYDX0jJXIe2SWmwCbGzx9yF8C8xy3Lh34=
+github.com/onsi/gomega v1.8.1/go.mod 
h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA=
+github.com/pkg/errors v0.9.0 h1:J8lpUdobwIeCI7OiSxHqEwJUKvJwicL5+3v1oe2Yb4k=
+github.com/pkg/errors v0.9.0/go.mod 
h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+golang.org/x/net v0.0.0-20180906233101-161cd47e91fd 
h1:nTDtHvHSdCn1m6ITfMRqtOd/9+7a3s8RBNOZ3eYZzJA=
+golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod 
h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f 
h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA=
+golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod 
h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e 
h1:o3PsSEY8E4eXWkXrIP9YJALUkVZqzHJT5DOasTyn8Vs=
+golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod 
h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7 
h1:9zdDQZ7Thm29KFXgAX/+yaf3eVbP7djjWp/dXAppNCc=
+golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod 
h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 
h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod 
h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
+gopkg.in/fsnotify.v1 v1.4.7/go.mod 
h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
+gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 
h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
+gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod 
h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
+gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=
+gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/conmon-2.0.10/runner/conmon/conmon.go 
new/conmon-2.0.11/runner/conmon/conmon.go
--- old/conmon-2.0.10/runner/conmon/conmon.go   1970-01-01 01:00:00.000000000 
+0100
+++ new/conmon-2.0.11/runner/conmon/conmon.go   2020-03-04 19:07:40.000000000 
+0100
@@ -0,0 +1,78 @@
+package conmon
+
+import (
+       "errors"
+       "io"
+       "os/exec"
+)
+
+var (
+       ErrConmonNotStarted = errors.New("conmon instance is not started")
+)
+
+type ConmonInstance struct {
+       args    []string
+       cmd     *exec.Cmd
+       started bool
+       path    string
+       stdout  io.Writer
+       stderr  io.Writer
+}
+
+func NewConmonInstance(options ...ConmonOption) (*ConmonInstance, error) {
+       ci := &ConmonInstance{
+               args: make([]string, 0),
+       }
+       for _, option := range options {
+               if err := option(ci); err != nil {
+                       return nil, err
+               }
+       }
+
+       // TODO verify path more
+       if ci.path == "" {
+               return nil, errors.New("conmon path not specified")
+       }
+
+       ci.cmd = exec.Command(ci.path, ci.args...)
+
+       ci.cmd.Stdout = ci.stdout
+       ci.cmd.Stderr = ci.stderr
+       return ci, nil
+}
+
+func (ci *ConmonInstance) Start() error {
+       ci.started = true
+       return ci.cmd.Start()
+}
+
+func (ci *ConmonInstance) Wait() error {
+       if !ci.started {
+               return ErrConmonNotStarted
+       }
+       return ci.cmd.Wait()
+}
+
+func (ci *ConmonInstance) Stdout() (io.Writer, error) {
+       if !ci.started {
+               return nil, ErrConmonNotStarted
+       }
+       return ci.cmd.Stdout, nil
+}
+
+func (ci *ConmonInstance) Stderr() (io.Writer, error) {
+       if !ci.started {
+               return nil, errors.New("conmon instance is not started")
+       }
+       return ci.cmd.Stderr, nil
+}
+
+func CreateAndExecConmon(options ...ConmonOption) (*ConmonInstance, error) {
+       ci, err := NewConmonInstance(options...)
+       if err != nil {
+               return nil, err
+       }
+
+       ci.Start()
+       return ci, nil
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/conmon-2.0.10/runner/conmon/options.go 
new/conmon-2.0.11/runner/conmon/options.go
--- old/conmon-2.0.10/runner/conmon/options.go  1970-01-01 01:00:00.000000000 
+0100
+++ new/conmon-2.0.11/runner/conmon/options.go  2020-03-04 19:07:40.000000000 
+0100
@@ -0,0 +1,68 @@
+package conmon
+
+import (
+       "fmt"
+       "io"
+)
+
+type ConmonOption func(*ConmonInstance) error
+
+func WithVersion() ConmonOption {
+       return func(ci *ConmonInstance) error {
+               return ci.addArgs("--version")
+       }
+}
+
+func WithStdout(stdout io.Writer) ConmonOption {
+       return func(ci *ConmonInstance) error {
+               ci.stdout = stdout
+               return nil
+       }
+}
+
+func WithStderr(stderr io.Writer) ConmonOption {
+       return func(ci *ConmonInstance) error {
+               ci.stderr = stderr
+               return nil
+       }
+}
+
+func WithPath(path string) ConmonOption {
+       return func(ci *ConmonInstance) error {
+               ci.path = path
+               return nil
+       }
+}
+
+func WithContainerID(ctrID string) ConmonOption {
+       return func(ci *ConmonInstance) error {
+               return ci.addArgs("--cid", ctrID)
+       }
+}
+
+func WithContainerUUID(ctrUUID string) ConmonOption {
+       return func(ci *ConmonInstance) error {
+               return ci.addArgs("--cuuid", ctrUUID)
+       }
+}
+
+func WithRuntimePath(path string) ConmonOption {
+       return func(ci *ConmonInstance) error {
+               return ci.addArgs("--runtime", path)
+       }
+}
+
+func WithLogDriver(driver, path string) ConmonOption {
+       return func(ci *ConmonInstance) error {
+               fullDriver := path
+               if driver != "" {
+                       fullDriver = fmt.Sprintf("%s:%s", driver, path)
+               }
+               return ci.addArgs("--log-path", fullDriver)
+       }
+}
+
+func (ci *ConmonInstance) addArgs(args ...string) error {
+       ci.args = append(ci.args, args...)
+       return nil
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/conmon-2.0.10/runner/conmon_test/conmon_test.go 
new/conmon-2.0.11/runner/conmon_test/conmon_test.go
--- old/conmon-2.0.10/runner/conmon_test/conmon_test.go 1970-01-01 
01:00:00.000000000 +0100
+++ new/conmon-2.0.11/runner/conmon_test/conmon_test.go 2020-03-04 
19:07:40.000000000 +0100
@@ -0,0 +1,200 @@
+package conmon_test
+
+import (
+       "bytes"
+       "fmt"
+       "io/ioutil"
+       "os"
+       "path/filepath"
+
+       "github.com/containers/conmon/runner/conmon"
+       . "github.com/onsi/ginkgo"
+       . "github.com/onsi/gomega"
+)
+
+var (
+       conmonPath  = "/usr/bin/conmon"
+       ctrID       = "abcdefghijklm"
+       validPath   = "/tmp"
+       invalidPath = "/not/a/path"
+)
+
+func getConmonOutputGivenOptions(options ...conmon.ConmonOption) (string, 
string) {
+       var stdout bytes.Buffer
+       var stderr bytes.Buffer
+
+       options = append(options, conmon.WithStdout(&stdout), 
conmon.WithStderr(&stderr))
+
+       ci, err := conmon.CreateAndExecConmon(options...)
+       Expect(err).To(BeNil())
+
+       ci.Wait()
+
+       return stdout.String(), stderr.String()
+}
+
+var _ = Describe("conmon", func() {
+       Describe("version", func() {
+               It("Should return conmon version", func() {
+                       out, _ := getConmonOutputGivenOptions(
+                               conmon.WithVersion(),
+                               conmon.WithPath(conmonPath),
+                       )
+                       Expect(out).To(ContainSubstring("conmon version"))
+                       Expect(out).To(ContainSubstring("commit"))
+               })
+       })
+       Describe("no container ID", func() {
+               It("should fail", func() {
+                       _, err := getConmonOutputGivenOptions(
+                               conmon.WithPath(conmonPath),
+                       )
+                       Expect(err).To(ContainSubstring("conmon: Container ID 
not provided. Use --cid"))
+               })
+       })
+       Describe("no container UUID", func() {
+               It("should fail", func() {
+                       _, err := getConmonOutputGivenOptions(
+                               conmon.WithPath(conmonPath),
+                               conmon.WithContainerID(ctrID),
+                       )
+                       Expect(err).To(ContainSubstring("Container UUID not 
provided. Use --cuuid"))
+               })
+       })
+       Describe("runtime path", func() {
+               It("no path should fail", func() {
+                       _, err := getConmonOutputGivenOptions(
+                               conmon.WithPath(conmonPath),
+                               conmon.WithContainerID(ctrID),
+                               conmon.WithContainerUUID(ctrID),
+                       )
+                       Expect(err).To(ContainSubstring("Runtime path not 
provided. Use --runtime"))
+               })
+               It("invalid path should fail", func() {
+                       _, err := getConmonOutputGivenOptions(
+                               conmon.WithPath(conmonPath),
+                               conmon.WithContainerID(ctrID),
+                               conmon.WithContainerUUID(ctrID),
+                               conmon.WithRuntimePath(invalidPath),
+                       )
+                       Expect(err).To(ContainSubstring(fmt.Sprintf("Runtime 
path %s is not valid", invalidPath)))
+               })
+       })
+       Describe("ctr logs", func() {
+               var tmpDir string
+               var tmpLogPath string
+               BeforeEach(func() {
+                       d, err := ioutil.TempDir(os.TempDir(), "conmon-")
+                       Expect(err).To(BeNil())
+                       tmpDir = d
+                       tmpLogPath = filepath.Join(tmpDir, "log")
+               })
+               AfterEach(func() {
+                       Expect(os.RemoveAll(tmpDir)).To(BeNil())
+               })
+               It("no log driver should fail", func() {
+                       _, stderr := getConmonOutputGivenOptions(
+                               conmon.WithPath(conmonPath),
+                               conmon.WithContainerID(ctrID),
+                               conmon.WithContainerUUID(ctrID),
+                               conmon.WithRuntimePath(validPath),
+                       )
+                       Expect(stderr).To(ContainSubstring("Log driver not 
provided. Use --log-path"))
+               })
+               It("log driver as path should pass", func() {
+                       _, stderr := getConmonOutputGivenOptions(
+                               conmon.WithPath(conmonPath),
+                               conmon.WithContainerID(ctrID),
+                               conmon.WithContainerUUID(ctrID),
+                               conmon.WithRuntimePath(validPath),
+                               conmon.WithLogDriver("", tmpLogPath),
+                       )
+                       Expect(stderr).To(BeEmpty())
+
+                       _, err := os.Stat(tmpLogPath)
+                       Expect(err).To(BeNil())
+               })
+               It("log driver as journald should pass", func() {
+                       _, stderr := getConmonOutputGivenOptions(
+                               conmon.WithPath(conmonPath),
+                               conmon.WithContainerID(ctrID),
+                               conmon.WithContainerUUID(ctrID),
+                               conmon.WithRuntimePath(validPath),
+                               conmon.WithLogDriver("journald", ""),
+                       )
+                       Expect(stderr).To(BeEmpty())
+               })
+               It("log driver as journald with short cid should fail", func() {
+                       // conmon requires a cid of len > 12
+                       shortCtrID := "abcdefghijkl"
+                       _, stderr := getConmonOutputGivenOptions(
+                               conmon.WithPath(conmonPath),
+                               conmon.WithContainerID(shortCtrID),
+                               conmon.WithContainerUUID(shortCtrID),
+                               conmon.WithRuntimePath(validPath),
+                               conmon.WithLogDriver("journald", ""),
+                       )
+                       Expect(stderr).To(ContainSubstring("Container ID must 
be longer than 12 characters"))
+               })
+               It("log driver as k8s-file with path should pass", func() {
+                       _, stderr := getConmonOutputGivenOptions(
+                               conmon.WithPath(conmonPath),
+                               conmon.WithContainerID(ctrID),
+                               conmon.WithContainerUUID(ctrID),
+                               conmon.WithRuntimePath(validPath),
+                               conmon.WithLogDriver("k8s-file", tmpLogPath),
+                       )
+                       Expect(stderr).To(BeEmpty())
+
+                       _, err := os.Stat(tmpLogPath)
+                       Expect(err).To(BeNil())
+               })
+               It("log driver as k8s-file with invalid path should fail", 
func() {
+                       _, stderr := getConmonOutputGivenOptions(
+                               conmon.WithPath(conmonPath),
+                               conmon.WithContainerID(ctrID),
+                               conmon.WithContainerUUID(ctrID),
+                               conmon.WithRuntimePath(validPath),
+                               conmon.WithLogDriver("k8s-file", invalidPath),
+                       )
+                       Expect(stderr).To(ContainSubstring("Failed to open log 
file"))
+               })
+               It("log driver as invalid driver should fail", func() {
+                       invalidLogDriver := "invalid"
+                       _, stderr := getConmonOutputGivenOptions(
+                               conmon.WithPath(conmonPath),
+                               conmon.WithContainerID(ctrID),
+                               conmon.WithContainerUUID(ctrID),
+                               conmon.WithRuntimePath(validPath),
+                               conmon.WithLogDriver("invalid", tmpLogPath),
+                       )
+                       Expect(stderr).To(ContainSubstring("No such log driver 
" + invalidLogDriver))
+               })
+               It("multiple log drivers should pass", func() {
+                       _, stderr := getConmonOutputGivenOptions(
+                               conmon.WithPath(conmonPath),
+                               conmon.WithContainerID(ctrID),
+                               conmon.WithContainerUUID(ctrID),
+                               conmon.WithRuntimePath(validPath),
+                               conmon.WithLogDriver("k8s-file", tmpLogPath),
+                               conmon.WithLogDriver("journald", ""),
+                       )
+                       Expect(stderr).To(BeEmpty())
+
+                       _, err := os.Stat(tmpLogPath)
+                       Expect(err).To(BeNil())
+               })
+               It("multiple log drivers with one invalid should fail", func() {
+                       invalidLogDriver := "invalid"
+                       _, stderr := getConmonOutputGivenOptions(
+                               conmon.WithPath(conmonPath),
+                               conmon.WithContainerID(ctrID),
+                               conmon.WithContainerUUID(ctrID),
+                               conmon.WithRuntimePath(validPath),
+                               conmon.WithLogDriver("k8s-file", tmpLogPath),
+                               conmon.WithLogDriver("invalid", tmpLogPath),
+                       )
+                       Expect(stderr).To(ContainSubstring("No such log driver 
" + invalidLogDriver))
+               })
+       })
+})
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/conmon-2.0.10/runner/conmon_test/suite_test.go 
new/conmon-2.0.11/runner/conmon_test/suite_test.go
--- old/conmon-2.0.10/runner/conmon_test/suite_test.go  1970-01-01 
01:00:00.000000000 +0100
+++ new/conmon-2.0.11/runner/conmon_test/suite_test.go  2020-03-04 
19:07:40.000000000 +0100
@@ -0,0 +1,13 @@
+package conmon_test
+
+import (
+       "testing"
+
+       . "github.com/onsi/ginkgo"
+       . "github.com/onsi/gomega"
+)
+
+func TestConmon(t *testing.T) {
+       RegisterFailHandler(Fail)
+       RunSpecs(t, "Conmon Suite")
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/conmon-2.0.10/src/conmon.c 
new/conmon-2.0.11/src/conmon.c
--- old/conmon-2.0.10/src/conmon.c      2020-01-07 22:53:52.000000000 +0100
+++ new/conmon-2.0.11/src/conmon.c      2020-03-04 19:07:40.000000000 +0100
@@ -100,7 +100,8 @@
        {"no-pivot", 0, 0, G_OPTION_ARG_NONE, &opt_no_pivot, "Do not use 
pivot_root", NULL},
        {"replace-listen-pid", 0, 0, G_OPTION_ARG_NONE, 
&opt_replace_listen_pid, "Replace listen pid if set for oci-runtime pid", NULL},
        {"bundle", 'b', 0, G_OPTION_ARG_STRING, &opt_bundle_path, "Bundle 
path", NULL},
-       {"persist-dir", '0', 0, G_OPTION_ARG_STRING, &opt_persist_path, 
"Persistent directory for a container that can be used for storing container 
data", NULL},
+       {"persist-dir", '0', 0, G_OPTION_ARG_STRING, &opt_persist_path,
+        "Persistent directory for a container that can be used for storing 
container data", NULL},
        {"pidfile", 0, 0, G_OPTION_ARG_STRING, &opt_container_pid_file, "PID 
file (DEPRECATED)", NULL},
        {"container-pidfile", 'p', 0, G_OPTION_ARG_STRING, 
&opt_container_pid_file, "Container PID file", NULL},
        {"conmon-pidfile", 'P', 0, G_OPTION_ARG_STRING, &opt_conmon_pid_file, 
"Conmon daemon PID file", NULL},
@@ -124,7 +125,7 @@
        {NULL, 0, 0, 0, NULL, NULL, NULL}};
 
 #define CGROUP_ROOT "/sys/fs/cgroup"
-#define OOM_SCORE "-999"
+#define OOM_SCORE "-1000"
 
 static ssize_t write_all(int fd, const void *buf, size_t count)
 {
@@ -514,7 +515,8 @@
  * this can be used for v1 and v2 OOMS
  * returns 0 on success, negative value on failure
  */
-static int write_oom_files() {
+static int write_oom_files()
+{
        _cleanup_close_ int oom_fd = -1;
        ninfo("OOM received");
        if (opt_persist_path) {
@@ -532,31 +534,63 @@
        return oom_fd >= 0 ? 0 : -1;
 }
 
-static gboolean oom_cb_cgroup_v1(int fd, GIOCondition condition, G_GNUC_UNUSED 
gpointer user_data)
+/* user_data is expected to be the container's cgroup.event_control file,
+ * used to verify the cgroup hasn't been cleaned up */
+static gboolean oom_cb_cgroup_v1(int fd, GIOCondition condition, gpointer 
user_data)
 {
-       uint64_t oom_event;
+       char *cgroup_event_control_path = (char *)user_data;
+       uint64_t event_count;
        ssize_t num_read = 0;
 
-       if ((condition & G_IO_IN) != 0) {
-               num_read = read(fd, &oom_event, sizeof(uint64_t));
-               if (num_read < 0) {
-                       nwarn("Failed to read oom event from eventfd");
-                       return G_SOURCE_CONTINUE;
-               }
+       if ((condition & G_IO_IN) == 0) {
+               /* End of input */
+               close(fd);
+               oom_event_fd = -1;
+               free(cgroup_event_control_path);
+               return G_SOURCE_REMOVE;
+       }
 
-               if (num_read > 0) {
-                       if (num_read != sizeof(uint64_t))
-                               nwarn("Failed to read full oom event from 
eventfd");
-                       write_oom_files();
+       num_read = read(fd, &event_count, sizeof(uint64_t));
+       if (num_read < 0) {
+               nwarn("Failed to read oom event from eventfd");
+               return G_SOURCE_CONTINUE;
+       }
+
+       if (num_read == 0) {
+               close(fd);
+               oom_event_fd = -1;
+               free(cgroup_event_control_path);
+               return G_SOURCE_REMOVE;
+       }
 
+       if (num_read != sizeof(uint64_t)) {
+               nwarn("Failed to read full oom event from eventfd");
+               return G_SOURCE_CONTINUE;
+       }
+
+       ndebugf("Memory cgroup event count: %ld", (long)event_count);
+       if (event_count == 0) {
+               nwarn("Unexpected event count (zero)");
+               return G_SOURCE_CONTINUE;
+       }
+       /* attempt to read the container's cgroup path.
+        * if we can't, the cgroup has probably been cleaned up.
+        * In all likelihood, this means we received an event on the eventfd
+        * because the memory.oom_control file was removed, not because of an 
OOM
+        */
+       if (access(cgroup_event_control_path, F_OK) < 0) {
+               ndebugf("Memory cgroup removal event received");
+               /* if event_count == 1, we know the only event triggered was a 
cgroup removal
+                * if it was greater than 1, we know the cgroup oomed, and then 
was cleaned up.
+                */
+               if (event_count == 1)
                        return G_SOURCE_CONTINUE;
-               }
        }
 
-       /* End of input */
-       close(fd);
-       oom_event_fd = -1;
-       return G_SOURCE_REMOVE;
+       ninfo("OOM event received");
+       write_oom_files();
+
+       return G_SOURCE_CONTINUE;
 }
 
 
@@ -718,7 +752,7 @@
  * line_process_func should return TRUE if it succeeds, and FALSE if it fails
  * to process the line.
  */
-static gboolean read_from_ctrl_buffer(int fd, 
gboolean(*line_process_func)(char*))
+static gboolean read_from_ctrl_buffer(int fd, gboolean 
(*line_process_func)(char *))
 {
        static char ctlbuf[CTLBUFSZ];
        static int readsz = CTLBUFSZ - 1;
@@ -777,7 +811,7 @@
  * and either writes to the winsz fd (to handle terminal resize events)
  * or reopens log files.
  */
-static gboolean process_terminal_ctrl_line(char* line)
+static gboolean process_terminal_ctrl_line(char *line)
 {
        int ctl_msg_type, height, width, ret = -1;
        _cleanup_free_ char *hw_str = NULL;
@@ -822,7 +856,7 @@
  * after the terminal_ctrl fd receives a winsz event.
  * It reads a height and length, and resizes the pty with it.
  */
-static gboolean process_winsz_ctrl_line(char * line)
+static gboolean process_winsz_ctrl_line(char *line)
 {
        int height, width, ret = -1;
        ret = sscanf(line, "%d %d\n", &height, &width);
@@ -1062,7 +1096,8 @@
        return attach_symlink_dir_path;
 }
 
-static void setup_fifo(int *fifo_r, int *fifo_w, char * filename, char* 
error_var_name) {
+static void setup_fifo(int *fifo_r, int *fifo_w, char *filename, char 
*error_var_name)
+{
        _cleanup_free_ char *fifo_path = g_build_filename(opt_bundle_path, 
filename, NULL);
 
        if (!fifo_r || !fifo_w)
@@ -1078,7 +1113,8 @@
                pexitf("Failed to open %s write half", error_var_name);
 }
 
-static void setup_console_fifo() {
+static void setup_console_fifo()
+{
        setup_fifo(&winsz_fd_r, &winsz_fd_w, "winsz", "window resize control 
fifo");
        ninfof("winsz read side: %d, winsz write side: %d", winsz_fd_r, 
winsz_fd_r);
 }
@@ -1140,7 +1176,8 @@
                return;
        }
 
-       _cleanup_free_ char *memory_cgroup_file_path = 
g_build_filename(memory_cgroup_path, "cgroup.event_control", NULL);
+       /* this will be cleaned up in oom_cb_cgroup_v1 */
+       char *memory_cgroup_file_path = g_build_filename(memory_cgroup_path, 
"cgroup.event_control", NULL);
 
        if ((cfd = open(memory_cgroup_file_path, O_WRONLY | O_CLOEXEC)) == -1) {
                nwarnf("Failed to open %s", memory_cgroup_file_path);
@@ -1158,7 +1195,7 @@
        if (write_all(cfd, data, strlen(data)) < 0)
                pexit("Failed to write to cgroup.event_control");
 
-       g_unix_fd_add(oom_event_fd, G_IO_IN, oom_cb_cgroup_v1, NULL);
+       g_unix_fd_add(oom_event_fd, G_IO_IN, oom_cb_cgroup_v1, 
memory_cgroup_file_path);
 }
 
 static void setup_oom_handling(int pid)
@@ -1547,16 +1584,22 @@
                        slavefd_stdin = dev_null_r;
                if (dup2(slavefd_stdin, STDIN_FILENO) < 0)
                        pexit("Failed to dup over stdin");
+               if (fchmod(STDIN_FILENO, 0777) < 0)
+                       nwarn("Failed to chown stdin");
 
                if (slavefd_stdout < 0)
                        slavefd_stdout = dev_null_w;
                if (dup2(slavefd_stdout, STDOUT_FILENO) < 0)
                        pexit("Failed to dup over stdout");
+               if (fchmod(STDOUT_FILENO, 0777) < 0)
+                       nwarn("Failed to chown stdout");
 
                if (slavefd_stderr < 0)
                        slavefd_stderr = slavefd_stdout;
                if (dup2(slavefd_stderr, STDERR_FILENO) < 0)
                        pexit("Failed to dup over stderr");
+               if (fchmod(STDERR_FILENO, 0777) < 0)
+                       nwarn("Failed to chown stderr");
 
                /* If LISTEN_PID env is set, we need to set the LISTEN_PID
                   it to the new child process */
@@ -1743,7 +1786,11 @@
        int exit_status = -1;
        const char *exit_message = NULL;
 
-       if (timed_out) {
+       /*
+        * If timed_out is TRUE but container_pid is -1, the process must have 
died before
+        * the timer elapsed. Ignore the timeout and treat it like a normal 
container exit.
+        */
+       if (timed_out && container_pid > 0) {
                pid_t process_group = getpgid(container_pid);
 
                if (process_group > 0)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/conmon-2.0.10/src/ctr_logging.c 
new/conmon-2.0.11/src/ctr_logging.c
--- old/conmon-2.0.10/src/ctr_logging.c 2020-01-07 22:53:52.000000000 +0100
+++ new/conmon-2.0.11/src/ctr_logging.c 2020-03-04 19:07:40.000000000 +0100
@@ -83,6 +83,9 @@
                k8s_log_fd = open(k8s_log_path, O_WRONLY | O_APPEND | O_CREAT | 
O_CLOEXEC, 0600);
                if (k8s_log_fd < 0)
                        pexit("Failed to open log file");
+
+               if (!use_journald_logging && tag)
+                       nexit("k8s-file doesn't support --log-tag");
        }
 
        if (use_journald_logging) {
@@ -106,7 +109,7 @@
                container_id = g_strdup_printf("CONTAINER_ID=%s", short_cuuid);
                if (tag) {
                        container_tag = g_strdup_printf("CONTAINER_TAG=%s", 
tag);
-                       container_tag_len = strlen (container_tag);
+                       container_tag_len = strlen(container_tag);
                }
 
                /* To maintain backwards compatibility with older versions of 
conmon, we need to skip setting
@@ -430,7 +433,7 @@
        struct timespec ts;
        char off_sign = '+';
        int off, len, err = -1;
-        
+
        if (clock_gettime(CLOCK_REALTIME, &ts) < 0) {
                /* If CLOCK_REALTIME is not supported, we set nano seconds to 0 
*/
                if (errno == EINVAL) {


Reply via email to