This section describes how to configure a Single Intel Westport NIC in the LLS-C1 T-GM mode using the PTP timing pod.

VMware PTP Timing Pod is published in the form of Helm Charts. You need to modify network function CSAR and add the Timing Pod Helm as a prerequisite to the DU/application Helm Chart.

Prerequisites

The following topology diagram illustrates an example configuration:

  • PF1 is connected to RU1

  • PF2 is connected to RU2

  • PF3 is connected to Midhual and serving as secondary source of PTP (optional)


LLS-C1 T-GM Configuration for Single Intel Westport NIC Using Timing Pod

Procedure

  1. Navigate to Catalog > Network Function in the Telco Cloud Automation UI.
  2. Select the Network Function you want to set up in the T-GM mode and click Edit.
  3. Click the Topology tab, and select and drag 'Helm' from Components to the workspace.
  4. Enter all the required details about VMware PTP Timing Pod:
    1. Properties:
      • Name: tca-timing-pod

      • Description: Description of the helm chart

      • Chart Name: Chart name of timing-pod. The value must be 'tca-timing-pod'.

      • Chart Version: tca-timing-pod helm version

      • Helm Version: tca-timing-pod helm version (v3)

    2. Helm Property Overrides (Optional): Add an entry for values.yaml file.
      • Property: values.yaml

      • Type: File

    3. Depends On (Optional): Select the timing pod helm chart and add it as a dependency to your DU Helm chart.

      Note: tca-timing-pod must start before any other pods that are part of the network function.


    Configure PTP Timing Pod
  5. Edit the network function helm charts to add the dependency on timing-pod.

    Add dependency to timing pod
  6. Save the changes.
  7. Click the Infrastructure Requirements tab.
  8. Add a PTP device for each port that is connected to RU.

    Add PTP devices

    Secondary PTP source: If a secondary source of PTP is available, tca-timing-pod can sync DU to the secondary source when GNSS is down. Add a PTP device for the secondary PTP source, but is optional.

    Caution:
    • To sync PTP Hardware Clock (PHC) from GNSS, PTP device from PF0 is also required.

    • PF0 can also be used for other purposes such as connecting to a RU or secondary source of PTP.

  9. Instantiate the Network function.

    Namespace for tca-timing-pod helm: For tca-timing-pod helm charts, do not use 'tca-system' namespace. Use the same namespace where the DU application will be installed.

    In the below screenshot, 'testnf' namespace is used for both DU application and tca-timing-pod.


    Instantiate NF

    values.yaml for tca-timing-pod:

    • In the below sample file, the value of GNSSHoldoverTimeout is set to 14400s (=4 hours) based on Intel recommendation of Holdover period for Intel Westport NICs. You can change this value.

    • Modify other fields such as SecondaryPTPSource, interface names in Synce4lNic1GmConf, Synce4lNic1BcConf, Ptp4lNic1GmConf, and Ptp4lNic1BcConf based on the set up in use.

    • The name of the PTP device from the first port must be 'ptp'.

    Notes:

    • Use 'tca-system' as namespace in the tca-timing-pod values.yaml.

    • Use 3 as the ProfileId for Single WPC.

    Example: values.yaml for tca-timing-pod

    ProfileId: "3" # 1: T-TSC, 2: T-BC, 3: T-GM, 4: Dual WPC
     
    # GNSS state Polling interval in seconds
    GnssStatePollInterval: "2"
    # When timing pod is stated with ProfileId 3 (T-GM), once GNSS disconnection
    # is detected it goes into HOLDOVER state and continue operating in T-GM mode.
    # At the end of Holdover period, if secondary PTP source is available, it switches
    # to Boundary Clock Mode. If secondary PTP source is not available it transitions to
    # FREERUN state
    GnssHolderoverTimeout: "14400" # In seconds
    # If SecondaryPTPSource is provided,
    # then PTP source will be switched when GNSS status is offline
    # Interface name on worker node VM where PTP packets are received from secondary source
    SecondaryPTPSource: "nic1-eth4"
     
    namespace: tca-system
     
    nodeSelector: {
          key: value
    }
     
    Containers:
      TimingController:
        name: timing-controller
        image: vmwaresaas.jfrog.io/registry/tca-timing-controller:3.0.7
      MessageQueue:
        name: rabbitmq
        image: vmwaresaas.jfrog.io/registry/rabbitmq:3.12-management
      Monitor:
        name: monitor
        image: vmwaresaas.jfrog.io/registry/ptp-ocloud-notifications-monitor:3.0.7
     
    # tsp2hc config for 1st NIC (with GNSS module)
    Ts2phcNic1Conf: |
      [global]
      use_syslog              1
      verbose                 0
      logging_level           6
      ts2phc.pulsewidth       100000000
      ts2phc.nmea_serialport  /dev/ttyGNSS_0300
      message_tag             ts2phc_nic1
     
      [ptp]
      ts2phc.extts_polarity   rising
     
    # tsp2hc cmdline options for 1st NIC (with GNSS module)
    Ts2phcNic1Opts: |
      -m -s nmea
    # synce4l config for 1st NIC, when operating in T-GM Mode
    Synce4lNic1GmConf: |
      [global]
      logging_level 7
      use_syslog 0
      verbose 1
      message_tag [synce4l_nic1]
     
      [<synce1>]
      input_mode external
      network_option 1
      external_input_QL 1
      external_input_ext_QL 33
      extended_tlv 1
      recover_time 20
      eec_get_state_cmd cat /sys/class/net/ptp/device/dpll_0_state
      eec_holdover_value 4
      eec_locked_ho_value 3
      eec_locked_value 2
      eec_freerun_value 1
      eec_invalid_value 0
     
      # interface connected to RU
      [nic1-eth2]
      tx_heartbeat_msec 1000
      rx_heartbeat_msec 500
      recover_clock_enable_cmd echo 1 0 > /sys/class/net/nic1-eth2/device/phy/synce
      recover_clock_disable_cmd echo 0 0 > /sys/class/net/nic1-eth2/device/phy/synce
     
      # interface connected to RU
      [nic1-eth2]
      tx_heartbeat_msec 1000
      rx_heartbeat_msec 500
      recover_clock_enable_cmd echo 1 0 > /sys/class/net/nic1-eth3/device/phy/synce
      recover_clock_disable_cmd echo 0 0 > /sys/class/net/nic1-eth3/device/phy/synce
     
    # synce4l config for 1st NIC, when operating in T-BC Mode
    Synce4lNic1BcConf: |
      [global]
      logging_level 7
      use_syslog 0
      verbose 1
      message_tag [synce4l]
     
      [<synce1>]
      input_mode line
      network_option 1
      extended_tlv 1
      recover_time 20
      eec_get_state_cmd cat /sys/class/net/ptp/device/dpll_0_state
      eec_holdover_value 4
      eec_locked_ho_value 3
      eec_locked_value 2
      eec_freerun_value 1
      eec_invalid_value 0
     
      # interface connected to RU
      [nic1-eth2]
      tx_heartbeat_msec 1000
      rx_heartbeat_msec 500
      recover_clock_enable_cmd echo 1 0 > /sys/class/net/nic1-eth2/device/phy/synce
      recover_clock_disable_cmd echo 0 0 > /sys/class/net/nic1-eth2/device/phy/synce
     
      # interface connected to RU
      [nic1-eth3]
      tx_heartbeat_msec 1000
      rx_heartbeat_msec 500
      recover_clock_enable_cmd echo 1 0 > /sys/class/net/nic1-eth3/device/phy/synce
      recover_clock_disable_cmd echo 0 0 > /sys/class/net/nic1-eth3/device/phy/synce
     
      # interface connected to secondary PTP source
      [nic1-eth4]
      tx_heartbeat_msec 1000
      rx_heartbeat_msec 500
      recover_clock_enable_cmd echo 1 0 > /sys/class/net/nic1-eth4/device/phy/synce
      recover_clock_disable_cmd echo 0 0 > /sys/class/net/nic1-eth4/device/phy/synce
     
    # ptp4l config for 1st WPC when operating in T-GM mode
    Ptp4lNic1GmConf: |
      [global]
      #
      # Default Data Set
      #
      twoStepFlag       1
      clientOnly        0
      socket_priority       0
      priority1     128
      priority2     128
      domainNumber      24
      utc_offset        37
      clockClass        6
      clockAccuracy     0x21
      offsetScaledLogVariance   0xFFFF
      free_running      0
      freq_est_interval 1
      dscp_event        0
      dscp_general      0
      dataset_comparison    G.8275.x
      G.8275.defaultDS.localPriority    128
      maxStepsRemoved       255
      #
      # Port Data Set
      #
      logAnnounceInterval   -3
      logSyncInterval       -4
      operLogSyncInterval   0
      logMinDelayReqInterval    -4
      logMinPdelayReqInterval   0
      operLogPdelayReqInterval 0
      announceReceiptTimeout    3
      syncReceiptTimeout    0
      delayAsymmetry        0
      fault_reset_interval  4
      neighborPropDelayThresh   20000000
      serverOnly        0
      G.8275.portDS.localPriority   128
      asCapable               auto
      BMCA                    ptp
      inhibit_announce        0
      inhibit_delay_req       0
      ignore_source_id        0
      #
      # Run time options
      #
      assume_two_step       0
      logging_level     6
      path_trace_enabled    0
      follow_up_info        0
      hybrid_e2e        0
      inhibit_multicast_service 0
      net_sync_monitor  0
      tc_spanning_tree  0
      tx_timestamp_timeout  300
      unicast_listen        0
      unicast_master_table  0
      unicast_req_duration  3600
      use_syslog        1
      verbose           0
      summary_interval  0
      kernel_leap       1
      check_fup_sync        0
      #
      # Servo Options
      #
      pi_proportional_const 0.0
      pi_integral_const 0.0
      pi_proportional_scale 0.0
      pi_proportional_exponent  -0.3
      pi_proportional_norm_max  0.7
      pi_integral_scale 0.0
      pi_integral_exponent  0.4
      pi_integral_norm_max  0.3
      step_threshold        0.0
      first_step_threshold  0.00002
      max_frequency     900000000
      clock_servo       pi
      sanity_freq_limit 200000000
      ntpshm_segment        0
      msg_interval_request  0
      servo_num_offset_values 10
      servo_offset_threshold  0
      write_phase_mode  0
      #
      # Transport options
      #
      transportSpecific 0x0
      ptp_dst_mac       01:1B:19:00:00:00
      p2p_dst_mac       01:80:C2:00:00:0E
      udp_ttl           1
      udp6_scope        0x0E
      uds_address       /var/run/ptp4l_nic1
      uds_ro_address    /var/run/ptp4lro_nic1
      #
      # Default interface options
      #
      clock_type        OC
      network_transport L2
      delay_mechanism       E2E
      time_stamping     hardware
      tsproc_mode       filter
      delay_filter      moving_median
      delay_filter_length   10
      egressLatency     0
      ingressLatency        0
      boundary_clock_jbod   1
      #
      # Clock description
      #
      productDescription    ;;
      revisionData      ;;
      manufacturerIdentity  00:00:00
      userDescription       ;
      timeSource        0x20
      clock_class_threshold 7
     
      # interface's connected to RUs
      [ptp]
      serverOnly 1
      [nic1-eth2]
      serverOnly 1
    # ptp4l config for 1st WPC when operating in T-BC mode
    Ptp4lNic1BcConf: |
      [global]
      #
      # Default Data Set
      #
      twoStepFlag       1
      clientOnly        0
      socket_priority       0
      priority1     128
      priority2     128
      domainNumber      24
      utc_offset        37
      clockClass        248
      clockAccuracy     0x21
      offsetScaledLogVariance   0xFFFF
      free_running      0
      freq_est_interval 1
      dscp_event        0
      dscp_general      0
      dataset_comparison    G.8275.x
      G.8275.defaultDS.localPriority    128
      maxStepsRemoved       255
      #
      # Port Data Set
      #
      logAnnounceInterval   -3
      logSyncInterval       -4
      operLogSyncInterval   0
      logMinDelayReqInterval    -4
      logMinPdelayReqInterval   0
      operLogPdelayReqInterval 0
      announceReceiptTimeout    3
      syncReceiptTimeout    0
      delayAsymmetry        0
      fault_reset_interval  4
      neighborPropDelayThresh   20000000
      serverOnly        0
      G.8275.portDS.localPriority   128
      asCapable               auto
      BMCA                    ptp
      inhibit_announce        0
      inhibit_delay_req       0
      ignore_source_id        0
      #
      # Run time options
      #
      assume_two_step       0
      logging_level     6
      path_trace_enabled    0
      follow_up_info        0
      hybrid_e2e        0
      inhibit_multicast_service 0
      net_sync_monitor  0
      tc_spanning_tree  0
      tx_timestamp_timeout  300
      unicast_listen        0
      unicast_master_table  0
      unicast_req_duration  3600
      use_syslog        1
      verbose           0
      summary_interval  0
      kernel_leap       1
      check_fup_sync        0
      #
      # Servo Options
      #
      pi_proportional_const 0.0
      pi_integral_const 0.0
      pi_proportional_scale 0.0
      pi_proportional_exponent  -0.3
      pi_proportional_norm_max  0.7
      pi_integral_scale 0.0
      pi_integral_exponent  0.4
      pi_integral_norm_max  0.3
      step_threshold        0.0
      first_step_threshold  0.00002
      max_frequency     900000000
      clock_servo       pi
      sanity_freq_limit 200000000
      ntpshm_segment        0
      msg_interval_request  0
      servo_num_offset_values 10
      servo_offset_threshold  0
      write_phase_mode  0
      #
      # Transport options
      #
      transportSpecific 0x0
      ptp_dst_mac       01:1B:19:00:00:00
      p2p_dst_mac       01:80:C2:00:00:0E
      udp_ttl           1
      udp6_scope        0x0E
      uds_address       /var/run/ptp4l_nic1
      uds_ro_address    /var/run/ptp4lro_nic1
      #
      # Default interface options
      #
      clock_type        BC
      network_transport L2
      delay_mechanism       E2E
      time_stamping     hardware
      tsproc_mode       filter
      delay_filter      moving_median
      delay_filter_length   10
      egressLatency     0
      ingressLatency        0
      boundary_clock_jbod   1
      #
      # Clock description
      #
      productDescription    ;;
      revisionData      ;;
      manufacturerIdentity  00:00:00
      userDescription       ;
      timeSource        0x20
       
      # Name of the interface which is getting
      # PTP packets from the network.
      [nic1-eth3]
      serverOnly 0
      # interface's connected to RUs
      [ptp]
      serverOnly 1
      [nic1-eth2]
      serverOnly 1
     
    Phc2sysOpts: |
      -s ptp -c CLOCK_REALTIME -O -37 -m -R 16 -u 16
    LeapSeconds: |
      #
      # In the following text, the symbol '#' introduces
      # a comment, which continues from that symbol until
      # the end of the line. A plain comment line has a
      # whitespace character following the comment indicator.
      # There are also special comment lines defined below.
      # A special comment will always have a non-whitespace
      # character in column 2.
      #
      # A blank line should be ignored.
      #
      # The following table shows the corrections that must
      # be applied to compute International Atomic Time (TAI)
      # from the Coordinated Universal Time (UTC) values that
      # are transmitted by almost all time services.
      #
      # The first column shows an epoch as a number of seconds
      # since 1 January 1900, 00:00:00 (1900.0 is also used to
      # indicate the same epoch.) Both of these time stamp formats
      # ignore the complexities of the time scales that were
      # used before the current definition of UTC at the start
      # of 1972. (See note 3 below.)
      # The second column shows the number of seconds that
      # must be added to UTC to compute TAI for any timestamp
      # at or after that epoch. The value on each line is
      # valid from the indicated initial instant until the
      # epoch given on the next one or indefinitely into the
      # future if there is no next line.
      # (The comment on each line shows the representation of
      # the corresponding initial epoch in the usual
      # day-month-year format. The epoch always begins at
      # 00:00:00 UTC on the indicated day. See Note 5 below.)
      #
      # Important notes:
      #
      # 1. Coordinated Universal Time (UTC) is often referred to
      # as Greenwich Mean Time (GMT). The GMT time scale is no
      # longer used, and the use of GMT to designate UTC is
      # discouraged.
      #
      # 2. The UTC time scale is realized by many national
      # laboratories and timing centers. Each laboratory
      # identifies its realization with its name: Thus
      # UTC(NIST), UTC(USNO), etc. The differences among
      # these different realizations are typically on the
      # order of a few nanoseconds (i.e., 0.000 000 00x s)
      # and can be ignored for many purposes. These differences
      # are tabulated in Circular T, which is published monthly
      # by the International Bureau of Weights and Measures
      # (BIPM). See www.bipm.org for more information.
      #
      # 3. The current definition of the relationship between UTC
      # and TAI dates from 1 January 1972. A number of different
      # time scales were in use before that epoch, and it can be
      # quite difficult to compute precise timestamps and time
      # intervals in those "prehistoric" days. For more information,
      # consult:
      #
      #     The Explanatory Supplement to the Astronomical
      #     Ephemeris.
      # or
      #     Terry Quinn, "The BIPM and the Accurate Measurement
      #     of Time," Proc. of the IEEE, Vol. 79, pp. 894-905,
      #     July, 1991. <http://dx.doi.org/10.1109/5.84965>
      #     reprinted in:
      #        Christine Hackman and Donald B Sullivan (eds.)
      #        Time and Frequency Measurement
      #        American Association of Physics Teachers (1996)
      #        <http://tf.nist.gov/general/pdf/1168.pdf>, pp. 75-86
      #
      # 4. The decision to insert a leap second into UTC is currently
      # the responsibility of the International Earth Rotation and
      # Reference Systems Service. (The name was changed from the
      # International Earth Rotation Service, but the acronym IERS
      # is still used.)
      #
      # Leap seconds are announced by the IERS in its Bulletin C.
      #
      # See www.iers.org for more details.
      #
      # Every national laboratory and timing center uses the
      # data from the BIPM and the IERS to construct UTC(lab),
      # their local realization of UTC.
      #
      # Although the definition also includes the possibility
      # of dropping seconds ("negative" leap seconds), this has
      # never been done and is unlikely to be necessary in the
      # foreseeable future.
      #
      # 5. If your system keeps time as the number of seconds since
      # some epoch (e.g., NTP timestamps), then the algorithm for
      # assigning a UTC time stamp to an event that happens during a positive
      # leap second is not well defined. The official name of that leap
      # second is 23:59:60, but there is no way of representing that time
      # in these systems.
      # Many systems of this type effectively stop the system clock for
      # one second during the leap second and use a time that is equivalent
      # to 23:59:59 UTC twice. For these systems, the corresponding TAI
      # timestamp would be obtained by advancing to the next entry in the
      # following table when the time equivalent to 23:59:59 UTC
      # is used for the second time. Thus the leap second which
      # occurred on 30 June 1972 at 23:59:59 UTC would have TAI
      # timestamps computed as follows:
      #
      # ...
      # 30 June 1972 23:59:59 (2287785599, first time): TAI= UTC + 10 seconds
      # 30 June 1972 23:59:60 (2287785599,second time): TAI= UTC + 11 seconds
      # 1  July 1972 00:00:00 (2287785600)      TAI= UTC + 11 seconds
      # ...
      #
      # If your system realizes the leap second by repeating 00:00:00 UTC twice
      # (this is possible but not usual), then the advance to the next entry
      # in the table must occur the second time that a time equivalent to
      # 00:00:00 UTC is used. Thus, using the same example as above:
      #
      # ...
      #       30 June 1972 23:59:59 (2287785599):       TAI= UTC + 10 seconds
      #       30 June 1972 23:59:60 (2287785600, first time):   TAI= UTC + 10 seconds
      #       1  July 1972 00:00:00 (2287785600,second time):   TAI= UTC + 11 seconds
      # ...
      #
      # in both cases the use of timestamps based on TAI produces a smooth
      # time scale with no discontinuity in the time interval. However,
      # although the long-term behavior of the time scale is correct in both
      # methods, the second method is technically not correct because it adds
      # the extra second to the wrong day.
      #
      # This complexity would not be needed for negative leap seconds (if they
      # are ever used). The UTC time would skip 23:59:59 and advance from
      # 23:59:58 to 00:00:00 in that case. The TAI offset would decrease by
      # 1 second at the same instant. This is a much easier situation to deal
      # with, since the difficulty of unambiguously representing the epoch
      # during the leap second does not arise.
      #
      # Some systems implement leap seconds by amortizing the leap second
      # over the last few minutes of the day. The frequency of the local
      # clock is decreased (or increased) to realize the positive (or
      # negative) leap second. This method removes the time step described
      # above. Although the long-term behavior of the time scale is correct
      # in this case, this method introduces an error during the adjustment
      # period both in time and in frequency with respect to the official
      # definition of UTC.
      #
      # Questions or comments to:
      #     Judah Levine
      #     Time and Frequency Division
      #     NIST
      #     Boulder, Colorado
      #     [email protected]
      #
      # Last Update of leap second values:   8 July 2016
      #
      # The following line shows this last update date in NTP timestamp
      # format. This is the date on which the most recent change to
      # the leap second data was added to the file. This line can
      # be identified by the unique pair of characters in the first two
      # columns as shown below.
      #
      #$     3676924800
      #
      # The NTP timestamps are in units of seconds since the NTP epoch,
      # which is 1 January 1900, 00:00:00. The Modified Julian Day number
      # corresponding to the NTP time stamp, X, can be computed as
      #
      # X/86400 + 15020
      #
      # where the first term converts seconds to days and the second
      # term adds the MJD corresponding to the time origin defined above.
      # The integer portion of the result is the integer MJD for that
      # day, and any remainder is the time of day, expressed as the
      # fraction of the day since 0 hours UTC. The conversion from day
      # fraction to seconds or to hours, minutes, and seconds may involve
      # rounding or truncation, depending on the method used in the
      # computation.
      #
      # The data in this file will be updated periodically as new leap
      # seconds are announced. In addition to being entered on the line
      # above, the update time (in NTP format) will be added to the basic
      # file name leap-seconds to form the name leap-seconds.<NTP TIME>.
      # In addition, the generic name leap-seconds.list will always point to
      # the most recent version of the file.
      #
      # This update procedure will be performed only when a new leap second
      # is announced.
      #
      # The following entry specifies the expiration date of the data
      # in this file in units of seconds since the origin at the instant
      # 1 January 1900, 00:00:00. This expiration date will be changed
      # at least twice per year whether or not a new leap second is
      # announced. These semi-annual changes will be made no later
      # than 1 June and 1 December of each year to indicate what
      # action (if any) is to be taken on 30 June and 31 December,
      # respectively. (These are the customary effective dates for new
      # leap seconds.) This expiration date will be identified by a
      # unique pair of characters in columns 1 and 2 as shown below.
      # In the unlikely event that a leap second is announced with an
      # effective date other than 30 June or 31 December, then this
      # file will be edited to include that leap second as soon as it is
      # announced or at least one month before the effective date
      # (whichever is later).
      # If an announcement by the IERS specifies that no leap second is
      # scheduled, then only the expiration date of the file will
      # be advanced to show that the information in the file is still
      # current -- the update time stamp, the data and the name of the file
      # will not change.
      #
      # Updated through IERS Bulletin C65
      # File expires on:  28 December 2023
      #
      #@    3912710400
      #
      2272060800    10  # 1 Jan 1972
      2287785600    11  # 1 Jul 1972
      2303683200    12  # 1 Jan 1973
      2335219200    13  # 1 Jan 1974
      2366755200    14  # 1 Jan 1975
      2398291200    15  # 1 Jan 1976
      2429913600    16  # 1 Jan 1977
      2461449600    17  # 1 Jan 1978
      2492985600    18  # 1 Jan 1979
      2524521600    19  # 1 Jan 1980
      2571782400    20  # 1 Jul 1981
      2603318400    21  # 1 Jul 1982
      2634854400    22  # 1 Jul 1983
      2698012800    23  # 1 Jul 1985
      2776982400    24  # 1 Jan 1988
      2840140800    25  # 1 Jan 1990
      2871676800    26  # 1 Jan 1991
      2918937600    27  # 1 Jul 1992
      2950473600    28  # 1 Jul 1993
      2982009600    29  # 1 Jul 1994
      3029443200    30  # 1 Jan 1996
      3076704000    31  # 1 Jul 1997
      3124137600    32  # 1 Jan 1999
      3345062400    33  # 1 Jan 2006
      3439756800    34  # 1 Jan 2009
      3550089600    35  # 1 Jul 2012
      3644697600    36  # 1 Jul 2015
      3692217600    37  # 1 Jan 2017
      #
      # the following special comment contains the
      # hash value of the data in this file computed
      # use the secure hash algorithm as specified
      # by FIPS 180-1. See the files in ~/pub/sha for
      # the details of how this hash value is
      # computed. Note that the hash computation
      # ignores comments and whitespace characters
      # in data lines. It includes the NTP values
      # of both the last modification time and the
      # expiration time of the file, but not the
      # white space on those lines.
      # the hash line is also ignored in the
      # computation.
      #
      #h    e76a99dc 65f15cc7 e613e040 f5078b5e b23834fe