<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<!DOCTYPE bugzilla SYSTEM "https://bugzilla.yoctoproject.org/page.cgi?id=bugzilla.dtd">

<bugzilla version="5.0.6"
          urlbase="https://bugzilla.yoctoproject.org/"
          
          maintainer="it-coreprojects-helpdesk@linuxfoundation.org"
>

    <bug>
          <bug_id>11016</bug_id>
          
          <creation_ts>2017-02-06 10:49:08 +0000</creation_ts>
          <short_desc>First boot postinst actions</short_desc>
          <delta_ts>2017-02-14 08:06:22 +0000</delta_ts>
          <reporter_accessible>1</reporter_accessible>
          <cclist_accessible>1</cclist_accessible>
          <classification_id>9</classification_id>
          <classification>Documentation</classification>
          <product>Development Manual</product>
          <component>development</component>
          <version>unspecified</version>
          <rep_platform>All</rep_platform>
          <op_sys>Multiple</op_sys>
          <bug_status>RESOLVED</bug_status>
          <resolution>NOTABUG</resolution>
          
          
          <bug_file_loc></bug_file_loc>
          <status_whiteboard>13 Feb 2017: Set the doc flag to &quot;done.&quot;</status_whiteboard>
          <keywords></keywords>
          <priority>Undecided</priority>
          <bug_severity>normal</bug_severity>
          <target_milestone>---</target_milestone>
          
          
          <everconfirmed>1</everconfirmed>
          <reporter name="Xabier">xabier.marquiegui</reporter>
          <assigned_to name="Xabier">xabier.marquiegui</assigned_to>
          <cc>alex.kanavin</cc>
    
    <cc>bluelightning</cc>
    
    <cc>srifenbark</cc>
          
          
          <cf_os>---</cf_os>
          <cf_regression_type>---</cf_regression_type>
          
          <cf_docchange>No (bug/feature does not impact docs)</cf_docchange>

      

      

      

          <comment_sort_order>oldest_to_newest</comment_sort_order>  
          <long_desc isprivate="0" >
    <commentid>70443</commentid>
    <comment_count>0</comment_count>
    <who name="Xabier">xabier.marquiegui</who>
    <bug_when>2017-02-06 10:49:08 +0000</bug_when>
    <thetext>I have found that in cases where you inherit from systemd, you cannot really use the pkg_postinst_${PN} function in your recipes if you want to run code on first boot

I think it&apos;s because  the postinst actions of systemd return 0

An easy fix is to change the documentation of the mega-manual

where you say this:

     pkg_postinst_PACKAGENAME() {
     if [ x&quot;$D&quot; = &quot;x&quot; ]; then
          # Actions to carry out on the device go here
     else
          exit 1
     fi
     }

you could say this:
     pkg_postinst_PACKAGENAME() {
     if [ x&quot;$D&quot; = &quot;x&quot; ]; then
          # Actions to carry out on the device go here
     else
          trap &quot;exit 1&quot; EXIT
     fi
     }

by using

trap &quot;exit 1&quot; EXIT

instead of using

exit 1

you ensure that the code needed to run on first boot will get run</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>70444</commentid>
    <comment_count>1</comment_count>
    <who name="Xabier">xabier.marquiegui</who>
    <bug_when>2017-02-06 10:51:57 +0000</bug_when>
    <thetext>I&apos;m sorry, I should also mention that the code mentioned above should be included in the pkg_postinst_${PN}_prepend() function when inheriting from systemd.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>70445</commentid>
    <comment_count>2</comment_count>
    <who name="Alexander Kanavin">alex.kanavin</who>
    <bug_when>2017-02-06 11:50:05 +0000</bug_when>
    <thetext>The things that systemd appends to existing postinst scripts are designed so that they can run both during cross-install and on first boot. The existing solution will simply postpone everything to first boot - where your specific action will run first, then the systemd actions. 

Your solution has the effect of making the systemd specific things run at cross-install. (and then they will run again at first boot after your custom action). 

What is the improvement here, why is this better or necessary?</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>70493</commentid>
    <comment_count>3</comment_count>
    <who name="Xabier">xabier.marquiegui</who>
    <bug_when>2017-02-07 16:01:40 +0000</bug_when>
    <thetext>Well... I have dedicated a few minutes today to analyzing the problem, and I have a few more observations to throw into this matter.

I might be looking at something the wrong way, but let me describe what I am seeing.

Let&apos;s start with a description of the components I am using for my tests:

yocto 2.1 krogoth
systemd 229
Linux amos 4.8.6-fslc+g8d6e2d5 #1 SMP PREEMPT Mon Dec 19 17:12:40 UTC 2016 armv7l GNU/Linux

Test A: Following yocto development manual, I write a recipe with the following content:

...
inherit allarch systemd
...
SYSTEMD_SERVICE_${PN} = &quot;myservice.service&quot;
...
pkg_postinst_${PN}() {
#!/bin/sh

if [ x&quot;$D&quot; = &quot;x&quot; ] ; then
    # Native postinst code
    echo &quot;HELLO THERE!&quot;
else
    exit 1
fi
}

RESULT: System gets stuck on boot showing this message:

[***   ] (1 of 2) A start job is running for... postinsts (2min 12s / no limit)

Test B: Using trap, and adding exit 0 on the other condition (I forgot to put that in my original message as well), my recipe ends up looking like this:

...
inherit allarch systemd
...
SYSTEMD_SERVICE_${PN} = &quot;myservice.service&quot;
...
pkg_postinst_${PN}() {
#!/bin/sh

if [ x&quot;$D&quot; = &quot;x&quot; ] ; then
    # Native postinst code
    echo &quot;HELLO THERE!&quot;
    exit 0
else
    trap &quot;exit 1&quot; EXIT
fi
}

RESULT: System boots just fine, and myservice.service is correctly enabled.

With the added exit 0 systemd specific things only run at compile time.

I have also observed that using pkg_postinst_PACKAGENAME_append, or _prepend has no effect on the relative position of my code. Systemd always positions its postinst code after my recipe´s code.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>70505</commentid>
    <comment_count>4</comment_count>
    <who name="Scott Rifenbark">srifenbark</who>
    <bug_when>2017-02-07 17:42:08 +0000</bug_when>
    <thetext>Hi, 

I will monitor this and see if your solution is final.  When so, I will update the manual to reflect the change.

Scott</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>70534</commentid>
    <comment_count>5</comment_count>
    <who name="Alexander Kanavin">alex.kanavin</who>
    <bug_when>2017-02-08 09:34:34 +0000</bug_when>
    <thetext>The issue here is that your service gets enabled by systemd correctly during cross-install on the host machine, but for some reason the same enabling sequence gets stuck if it gets executed on the target. I still believe there&apos;s nothing to be fixed in the manual.

Specifically:

a)

if [ x&quot;$D&quot; = &quot;x&quot; ] ; then
    # Native postinst code
    echo &quot;HELLO THERE!&quot;
else
    exit 1
fi

exit 1 means defer the whole script to first boot, where it gets stuck on execution. You need to investigate this situation further. You can find the actual script that is executed on first boot in /etc/rpm-postinsts and work your way from there.

b)

if [ x&quot;$D&quot; = &quot;x&quot; ] ; then
    # Native postinst code
    echo &quot;HELLO THERE!&quot;
    exit 0
else
    trap &quot;exit 1&quot; EXIT
fi

The trap line means &quot;execute &apos;exit 1&apos; when the script finishes&quot;. This really means the script continues to execute during cross-install beyond the &apos;trap&apos; line, and so systemd service gets enabled at that time. The script is also deferred to first boot, but is a no-op, because you put an &apos;exit 0&apos; in there.

What happens if you remove the pkg_postinst() segment altogether from the recipe?</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>70535</commentid>
    <comment_count>6</comment_count>
    <who name="Xabier">xabier.marquiegui</who>
    <bug_when>2017-02-08 10:28:16 +0000</bug_when>
    <thetext>I am using opkg as the package manager.

( #v and #^ are just for better readability, I have not placed those lines in my code )

With this on my recipe (almost like b),

#vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv

pkg_postinst_${PN}() {
#!/bin/sh

if [ x&quot;$D&quot; = &quot;x&quot; ] ; then
    # Native postinst code
    echo &quot;HELLO THERE!&quot;
    exit 0
else
    trap &quot;exit 1&quot; EXIT
fi
}

#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

, I get this in /var/lib/opkg/info/mypackage.postinst:

#vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv

#!/bin/sh

if [ x&quot;$D&quot; = &quot;x&quot; ] ; then
    # Native postinst code
    echo &quot;HELLO THERE!&quot;
    exit 0
else
    trap &quot;exit 1&quot; EXIT
fi
OPTS=&quot;&quot;

if [ -n &quot;$D&quot; ]; then
    OPTS=&quot;--root=$D&quot;
fi

if type systemctl &gt;/dev/null 2&gt;/dev/null; then
        systemctl $OPTS enable myservice.service

        if [ -z &quot;$D&quot; -a &quot;enable&quot; = &quot;enable&quot; ]; then
                systemctl restart myservice.service
        fi
fi

#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

, and the system boots just fine.

If I remove pkg_postinst_${PN}() from the recipe I get this in /var/lib/opkg/info/mypackage.postinst:

#vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv

#!/bin/sh
OPTS=&quot;&quot;

if [ -n &quot;$D&quot; ]; then
    OPTS=&quot;--root=$D&quot;
fi

if type systemctl &gt;/dev/null 2&gt;/dev/null; then
        systemctl $OPTS enable myservice.service

        if [ -z &quot;$D&quot; -a &quot;enable&quot; = &quot;enable&quot; ]; then
                systemctl restart myservice.service
        fi
fi

#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

, and the system boots just fine.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>70536</commentid>
    <comment_count>7</comment_count>
    <who name="Alexander Kanavin">alex.kanavin</who>
    <bug_when>2017-02-08 10:34:27 +0000</bug_when>
    <thetext>Now type these two in the command line on the target:

systemctl enable myservice.service
systemctl restart myservice.service

I strongly suspect one of them will hang.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>70537</commentid>
    <comment_count>8</comment_count>
    <who name="Xabier">xabier.marquiegui</who>
    <bug_when>2017-02-08 10:38:18 +0000</bug_when>
    <thetext>I have issued both commands, and they both have returned in a few miliseconds, with a return value of 0.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>70538</commentid>
    <comment_count>9</comment_count>
    <who name="Xabier">xabier.marquiegui</who>
    <bug_when>2017-02-08 10:40:40 +0000</bug_when>
    <thetext>Some more information about my system:

BusyBox v1.24.1 (2016-12-12 20:05:45 UTC) multi-call binary.
opkg version 0.3.0</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>70539</commentid>
    <comment_count>10</comment_count>
    <who name="Alexander Kanavin">alex.kanavin</who>
    <bug_when>2017-02-08 10:41:04 +0000</bug_when>
    <thetext>Then something else gets in the way during boot - the issue is that executing the postinst script on first boot is causing a freeze somewhere, and your suggested fix merely moves the execution to cross-install time. Please do investigate that.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>70540</commentid>
    <comment_count>11</comment_count>
    <who name="Xabier">xabier.marquiegui</who>
    <bug_when>2017-02-08 10:50:45 +0000</bug_when>
    <thetext>I am also new to systemd, but here&apos;s my guess:
myservice does live in a custom target mytarget that comes after multi-user target. And my system&apos;s default target IS mytarget.

Is it possible that postinst gets executed in multi-user target, and if you ask systemd to restart a service that lives in a target that has not been reached, it gets stuck until the system reaches that target?

If that is true, if postinst is waiting for systemd to restart the service, and systemd is waiting for postinst to get to the next target, we have a deadlock situation caused by the way postinst is implemented.

Does it make any sense?</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>70541</commentid>
    <comment_count>12</comment_count>
    <who name="Alexander Kanavin">alex.kanavin</who>
    <bug_when>2017-02-08 10:56:47 +0000</bug_when>
    <thetext>I have no idea either. You can add additional logging to the postinst bits in system class, and see where precisely it gets stuck. Also, I guess systemctl itself has a verbose or debugging mode which you should enable.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>70542</commentid>
    <comment_count>13</comment_count>
    <who name="Xabier">xabier.marquiegui</who>
    <bug_when>2017-02-08 11:26:37 +0000</bug_when>
    <thetext>You are right, what I have been proposing until now is not the right solution. If I were to install this package in a running system that didn&apos;t have myservice enabled and running, it would never get automatically enabled, and that is not right.

On the other hand, I&apos;m pretty sure my theory is right. Boot gets stuck in:

systemctl restart myservice.service

If I manually generate a postinst script with the following content, everything works like a charm:

#vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv

#!/bin/sh

if [ x&quot;$D&quot; = &quot;x&quot; ] ; then
    # Native postinst code
    echo &quot;HELLO THERE!&quot;
else
    exit 1
fi
OPTS=&quot;&quot;

if [ -n &quot;$D&quot; ]; then
    OPTS=&quot;--root=$D&quot;
fi

if type systemctl &gt;/dev/null 2&gt;/dev/null; then
        systemctl $OPTS enable myservice.service

        if [ -z &quot;$D&quot; -a &quot;enable&quot; = &quot;enable&quot; ]; then
                systemctl try-restart myservice.service
        fi
fi


#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

So, changing systemctl restart with systemcl try-restart seems to be the right solution (which is code added by systemd bbclass)

How should I preceed? Should I close this bugzilla entry and open a new one for the systemd bbclass?</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>70543</commentid>
    <comment_count>14</comment_count>
    <who name="Alexander Kanavin">alex.kanavin</who>
    <bug_when>2017-02-08 11:36:04 +0000</bug_when>
    <thetext>Yes please. I&apos;m not exactly sure why &apos;restart&apos; is even needed there - if a unit is enabled, I&apos;d think system will start it when all pre conditions are satisfied.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>70544</commentid>
    <comment_count>15</comment_count>
    <who name="Xabier">xabier.marquiegui</who>
    <bug_when>2017-02-08 11:42:39 +0000</bug_when>
    <thetext>I just update the bug to mark it as resolved / not a bug, since it&apos;s not a documentation problem, but one in systemd.bbclass.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>70545</commentid>
    <comment_count>16</comment_count>
    <who name="Alexander Kanavin">alex.kanavin</who>
    <bug_when>2017-02-08 11:49:50 +0000</bug_when>
    <thetext>By the way, the systemd issue is resolved in poky master 2965ccfcdb5a5aefb94e6ec8e24832471f47239f

No need to file another bug.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>70546</commentid>
    <comment_count>17</comment_count>
    <who name="Xabier">xabier.marquiegui</who>
    <bug_when>2017-02-08 11:51:26 +0000</bug_when>
    <thetext>Yes, thank you. I have just seen that it&apos;s resolved in some branches. Is there any way I can ask for it to be backported to Yocto Krogoth?</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>70547</commentid>
    <comment_count>18</comment_count>
    <who name="Alexander Kanavin">alex.kanavin</who>
    <bug_when>2017-02-08 11:53:07 +0000</bug_when>
    <thetext>Yes, sure. Send a patch to the oe-core mailing list (look in list archives for how backports should be annotated).</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>70678</commentid>
    <comment_count>19</comment_count>
    <who name="Scott Rifenbark">srifenbark</who>
    <bug_when>2017-02-14 02:57:45 +0000</bug_when>
    <thetext>Hi, 

I know I don&apos;t own this bug but I see it was marked as NOT A BUG.  I went ahead and set the doc flag to &quot;no&quot;.

Thanks,
Scott</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>70680</commentid>
    <comment_count>20</comment_count>
    <who name="Xabier">xabier.marquiegui</who>
    <bug_when>2017-02-14 08:06:22 +0000</bug_when>
    <thetext>That&apos;s OK, I didn&apos;t know I had to mark that flag. Thank you. :)</thetext>
  </long_desc>
      
      

    </bug>

</bugzilla>