Re: pflogd write /var/run/mypflogdinstance.pid?

2020-12-06 Thread Theo de Raadt
Harald Dunkel  wrote:

> Hi folks,
> 
> I have to run several pflogd in parallel. To make pkill (i.e.
> newsyslog) work it seems to be necessary to create hard links
> pflogd1, pflogd2 etc., pointing to /sbin/pflogd. Soft links
> don't work, because they don't show up in the process table.
> This introduces new problems on the next upgrade of pflogd.
> Its unreliable and error-prone. (I lost 2 weeks of logfiles
> due to this.)
> 
> Would it be possible for pflogd to support a command line
> option -p /var/run/mypflogdinstance.pid, as common for other
> daemons? Without "-p" no pid file has to be written, as it is
> now.
> 
> I know this flag was present in ancient OpenBSD versions,
> but I never understood why such a reliable feature had
> been dropped in advance of the undependable pkill.

pid files don't really work any better than pkill, so we've removed
support all over the place.

pid files are a flawed mechanism.  Use of a stale pid file can impact
another process which has reused the pid, which is not that different
from pkill identifing the wrong program.  At least with pkill, you can
aim more carefully.

We've put some work into making programs not damage their argv.  If you
provide a strong set of arguments to the programs you start, you may be
able to pkill with a more fullsize pattern, increasing the accuracy.

It is all quite unsatisfying.  It would be better if a a parent
kept reference to the child, but that can also be unsatisfactory
when it creates too much process closeness.



pflogd write /var/run/mypflogdinstance.pid?

2020-12-06 Thread Harald Dunkel

Hi folks,

I have to run several pflogd in parallel. To make pkill (i.e.
newsyslog) work it seems to be necessary to create hard links
pflogd1, pflogd2 etc., pointing to /sbin/pflogd. Soft links
don't work, because they don't show up in the process table.
This introduces new problems on the next upgrade of pflogd.
Its unreliable and error-prone. (I lost 2 weeks of logfiles
due to this.)

Would it be possible for pflogd to support a command line
option -p /var/run/mypflogdinstance.pid, as common for other
daemons? Without "-p" no pid file has to be written, as it is
now.

I know this flag was present in ancient OpenBSD versions,
but I never understood why such a reliable feature had
been dropped in advance of the undependable pkill.


Thanx in advance
Harri



Re: Any insight on drm resetting chip for stopped heartbeat error

2020-12-06 Thread Joseph Olatt
On Mon, Dec 07, 2020 at 12:44:09PM +1100, Jonathan Gray wrote:
> On Sun, Dec 06, 2020 at 11:44:11AM -0800, Joseph Olatt wrote:
> > Hi,
> > 
> > I've started seeing the following error on my laptop along with
> > associated temporary freezing of the system:
> > 
> >   drm:pid90783:intel_gt_reset *NOTICE* Resetting chip for stopped
> >   heartbeat on rcs0
> >   drm:pid90783:mark_guilty *NOTICE* Xorg[83345] context reset due to GPU
> >   hang
> >   i915_vma_coredump_create: stub
> >   i915_vma_coredump_create: stub
> >   i915_vma_coredump_create: stub
> >   i915_vma_coredump_create: stub
> >   i915_vma_coredump_create: stub
> >   i915_vma_coredump_create: stub
> >   i915_vma_coredump_create: stub
> >   i915_vma_coredump_create: stub
> >   i915_vma_coredump_create: stub
> >   pool_fini: stub
> >   err_free_sgl: stub
> 
> This is inteldrm after it noticed a gpu hang.  Was there something in
> particular that was running at that point?

Thank you for responding.

Almost always, the hang happens when I'm running Firefox or Iridium.


> This diff against -current should help for some haswell problems,
> but perhaps not the one you are seeing.
> 
> https://patchwork.freedesktop.org/patch/395580/?series=82783&rev=1
> https://gitlab.freedesktop.org/drm/intel/-/issues/2024
> 
> Index: sys/dev/pci/drm/i915/gt/gen7_renderclear.c
> ===
> RCS file: /cvs/src/sys/dev/pci/drm/i915/gt/gen7_renderclear.c,v
> retrieving revision 1.1
> diff -u -p -r1.1 gen7_renderclear.c
> --- sys/dev/pci/drm/i915/gt/gen7_renderclear.c8 Jun 2020 04:48:13 
> -   1.1
> +++ sys/dev/pci/drm/i915/gt/gen7_renderclear.c28 Nov 2020 02:50:26 
> -
> @@ -7,8 +7,6 @@
>  #include "i915_drv.h"
>  #include "intel_gpu_commands.h"
>  
> -#define MAX_URB_ENTRIES 64
> -#define STATE_SIZE (4 * 1024)
>  #define GT3_INLINE_DATA_DELAYS 0x1E00
>  #define batch_advance(Y, CS) GEM_BUG_ON((Y)->end != (CS))
>  
> @@ -34,8 +32,7 @@ struct batch_chunk {
>  };
>  
>  struct batch_vals {
> - u32 max_primitives;
> - u32 max_urb_entries;
> + u32 max_primitives; /* == number of VFE threads */
>   u32 cmd_size;
>   u32 state_size;
>   u32 state_start;
> @@ -50,18 +47,35 @@ static void
>  batch_get_defaults(struct drm_i915_private *i915, struct batch_vals *bv)
>  {
>   if (IS_HASWELL(i915)) {
> - bv->max_primitives = 280;
> - bv->max_urb_entries = MAX_URB_ENTRIES;
> + switch (INTEL_INFO(i915)->gt) {
> + default:
> + case 1:
> + bv->max_primitives = 70;
> + break;
> + case 2:
> + bv->max_primitives = 140;
> + break;
> + case 3:
> + bv->max_primitives = 280;
> + break;
> + }
>   bv->surface_height = 16 * 16;
>   bv->surface_width = 32 * 2 * 16;
>   } else {
> - bv->max_primitives = 128;
> - bv->max_urb_entries = MAX_URB_ENTRIES / 2;
> + switch (INTEL_INFO(i915)->gt) {
> + default:
> + case 1: /* including vlv */
> + bv->max_primitives = 36;
> + break;
> + case 2:
> + bv->max_primitives = 128;
> + break;
> + }
>   bv->surface_height = 16 * 8;
>   bv->surface_width = 32 * 16;
>   }
>   bv->cmd_size = bv->max_primitives * 4096;
> - bv->state_size = STATE_SIZE;
> + bv->state_size = SZ_4K;
>   bv->state_start = bv->cmd_size;
>   bv->batch_size = bv->cmd_size + bv->state_size;
>   bv->scratch_size = bv->surface_height * bv->surface_width;
> @@ -244,7 +258,6 @@ gen7_emit_vfe_state(struct batch_chunk *
>   u32 urb_size, u32 curbe_size,
>   u32 mode)
>  {
> - u32 urb_entries = bv->max_urb_entries;
>   u32 threads = bv->max_primitives - 1;
>   u32 *cs = batch_alloc_items(batch, 32, 8);
>  
> @@ -254,7 +267,7 @@ gen7_emit_vfe_state(struct batch_chunk *
>   *cs++ = 0;
>  
>   /* number of threads & urb entries for GPGPU vs Media Mode */
> - *cs++ = threads << 16 | urb_entries << 8 | mode << 2;
> + *cs++ = threads << 16 | 1 << 8 | mode << 2;
>  
>   *cs++ = 0;
>  


I could try updating to a snapshot and see if it makes a difference. 

Once again, thank you for responding.



Another potential ksh bug?

2020-12-06 Thread Jordan Geoghegan

Hello again,

I was playing around with ksh array syntax and its behaviour when set as 
read-only. In my testing I noticed that ksh will allow you to overwrite 
the first element of a read-only array. Example snippet:


#!/bin/ksh
arr[0]=val1
arr[1]=val2
readonly arr
echo "${arr[@]}"
arr=yikes
echo "${arr[@]}"

I tested a few other shells, and this bug does exists in the original 
pdksh and is also present in zsh. This bug is not present in ksh93, mksh 
or bash, where they abort when trying to modify the read-only array.


I don't have access to a proper ksh88 shell, but it would be nice if 
someone could confirm its behaviour.


I was just hoping someone could confirm if this is intended behaviour, 
or if it's a bug.


Regards,

Jordan



Re: Seeking help creating an OpenBSD/OpenIKED alternative to the Algo VPN

2020-12-06 Thread Matthew Ernisse
On Sun, Dec 06, 2020 at 05:31:13PM +, Kyle Jensen said unto me:
> I am not an OpenBSD/OpenIKED pro and I'd very much appreciate collaborating
> with willing souls who, like me, could use an OpenBSD-based road warrior
> VPN.

OpenBSD and OpenIKED are really quite easy to understand if you take some time
to read the really quite well maintained man pages.  OpenIKED is in the base
system so there is literally nothing you need to do beyond install the system
and configure it for your application.  I've written a little bit about how
I achieve a road warrior configuration with OpenIKED for my macOS and iOS
devices.

https://www.going-flying.com/blog/protecting-my-macos-and-ios-devices-with-an-openbsd-vpn.html

That being said, iked.conf(5) and iked(8) have most of what you need.

--Matt

-- 
Matthew Ernisse
m...@going-flying.com
https://www.going-flying.com/



Re: Any insight on drm resetting chip for stopped heartbeat error

2020-12-06 Thread Jonathan Gray
On Sun, Dec 06, 2020 at 11:44:11AM -0800, Joseph Olatt wrote:
> Hi,
> 
> I've started seeing the following error on my laptop along with
> associated temporary freezing of the system:
> 
>   drm:pid90783:intel_gt_reset *NOTICE* Resetting chip for stopped
>   heartbeat on rcs0
>   drm:pid90783:mark_guilty *NOTICE* Xorg[83345] context reset due to GPU
>   hang
>   i915_vma_coredump_create: stub
>   i915_vma_coredump_create: stub
>   i915_vma_coredump_create: stub
>   i915_vma_coredump_create: stub
>   i915_vma_coredump_create: stub
>   i915_vma_coredump_create: stub
>   i915_vma_coredump_create: stub
>   i915_vma_coredump_create: stub
>   i915_vma_coredump_create: stub
>   pool_fini: stub
>   err_free_sgl: stub

This is inteldrm after it noticed a gpu hang.  Was there something in
particular that was running at that point?

This diff against -current should help for some haswell problems,
but perhaps not the one you are seeing.

https://patchwork.freedesktop.org/patch/395580/?series=82783&rev=1
https://gitlab.freedesktop.org/drm/intel/-/issues/2024

Index: sys/dev/pci/drm/i915/gt/gen7_renderclear.c
===
RCS file: /cvs/src/sys/dev/pci/drm/i915/gt/gen7_renderclear.c,v
retrieving revision 1.1
diff -u -p -r1.1 gen7_renderclear.c
--- sys/dev/pci/drm/i915/gt/gen7_renderclear.c  8 Jun 2020 04:48:13 -   
1.1
+++ sys/dev/pci/drm/i915/gt/gen7_renderclear.c  28 Nov 2020 02:50:26 -
@@ -7,8 +7,6 @@
 #include "i915_drv.h"
 #include "intel_gpu_commands.h"
 
-#define MAX_URB_ENTRIES 64
-#define STATE_SIZE (4 * 1024)
 #define GT3_INLINE_DATA_DELAYS 0x1E00
 #define batch_advance(Y, CS) GEM_BUG_ON((Y)->end != (CS))
 
@@ -34,8 +32,7 @@ struct batch_chunk {
 };
 
 struct batch_vals {
-   u32 max_primitives;
-   u32 max_urb_entries;
+   u32 max_primitives; /* == number of VFE threads */
u32 cmd_size;
u32 state_size;
u32 state_start;
@@ -50,18 +47,35 @@ static void
 batch_get_defaults(struct drm_i915_private *i915, struct batch_vals *bv)
 {
if (IS_HASWELL(i915)) {
-   bv->max_primitives = 280;
-   bv->max_urb_entries = MAX_URB_ENTRIES;
+   switch (INTEL_INFO(i915)->gt) {
+   default:
+   case 1:
+   bv->max_primitives = 70;
+   break;
+   case 2:
+   bv->max_primitives = 140;
+   break;
+   case 3:
+   bv->max_primitives = 280;
+   break;
+   }
bv->surface_height = 16 * 16;
bv->surface_width = 32 * 2 * 16;
} else {
-   bv->max_primitives = 128;
-   bv->max_urb_entries = MAX_URB_ENTRIES / 2;
+   switch (INTEL_INFO(i915)->gt) {
+   default:
+   case 1: /* including vlv */
+   bv->max_primitives = 36;
+   break;
+   case 2:
+   bv->max_primitives = 128;
+   break;
+   }
bv->surface_height = 16 * 8;
bv->surface_width = 32 * 16;
}
bv->cmd_size = bv->max_primitives * 4096;
-   bv->state_size = STATE_SIZE;
+   bv->state_size = SZ_4K;
bv->state_start = bv->cmd_size;
bv->batch_size = bv->cmd_size + bv->state_size;
bv->scratch_size = bv->surface_height * bv->surface_width;
@@ -244,7 +258,6 @@ gen7_emit_vfe_state(struct batch_chunk *
u32 urb_size, u32 curbe_size,
u32 mode)
 {
-   u32 urb_entries = bv->max_urb_entries;
u32 threads = bv->max_primitives - 1;
u32 *cs = batch_alloc_items(batch, 32, 8);
 
@@ -254,7 +267,7 @@ gen7_emit_vfe_state(struct batch_chunk *
*cs++ = 0;
 
/* number of threads & urb entries for GPGPU vs Media Mode */
-   *cs++ = threads << 16 | urb_entries << 8 | mode << 2;
+   *cs++ = threads << 16 | 1 << 8 | mode << 2;
 
*cs++ = 0;
 



Any insight on drm resetting chip for stopped heartbeat error

2020-12-06 Thread Joseph Olatt
Hi,

I've started seeing the following error on my laptop along with
associated temporary freezing of the system:

  drm:pid90783:intel_gt_reset *NOTICE* Resetting chip for stopped
  heartbeat on rcs0
  drm:pid90783:mark_guilty *NOTICE* Xorg[83345] context reset due to GPU
  hang
  i915_vma_coredump_create: stub
  i915_vma_coredump_create: stub
  i915_vma_coredump_create: stub
  i915_vma_coredump_create: stub
  i915_vma_coredump_create: stub
  i915_vma_coredump_create: stub
  i915_vma_coredump_create: stub
  i915_vma_coredump_create: stub
  i915_vma_coredump_create: stub
  pool_fini: stub
  err_free_sgl: stub


Seems like I started seeing them after upgrade to OpenBSD 6.8. But, I'm
not sure. It could be simply a coincidence.

It could be simply failing hardware. 

Any insight or advice would be greatly appreciated.

Some context follows:

Output of uname -a:

  OpenBSD puffy 6.8 GENERIC.MP#1 amd64


Output of fw_update -i:

  Installed: vmm-firmware-1.11.0p3 inteldrm-firmware-20200421 
uvideo-firmware-1.2p3 intel-firmware-20200616v0


/var/run/dmesg.boot:
  OpenBSD 6.8 (GENERIC.MP) #1: Tue Nov  3 09:06:04 MST 2020
  
r...@syspatch-68-amd64.openbsd.org:/usr/src/sys/arch/amd64/compile/GENERIC.MP
  real mem = 8491147264 (8097MB)
  avail mem = 8218771456 (7838MB)
  random: good seed from bootblocks
  mpath0 at root
  scsibus0 at mpath0: 256 targets
  mainbus0 at root
  bios0 at mainbus0: SMBIOS rev. 2.7 @ 0xecb60 (88 entries)
  bios0: vendor Dell Inc. version "A09" date 07/06/2015
  bios0: Dell Inc. Latitude 3340
  acpi0 at bios0: ACPI 5.0
  acpi0: sleep states S0 S3 S4 S5
  acpi0: tables DSDT FACP APIC FPDT ASF! SLIC LPIT SSDT SSDT SSDT SSDT HPET 
SSDT MCFG MSDM
  acpi0: wakeup devices RP01(S4) PXSX(S4) RP02(S4) PXSX(S4) PXSX(S4) RP04(S4) 
PXSX(S4) PXSX(S4) PXSX(S4) PXSX(S4) PXSX(S4) GLAN(S4) EHC1(S0) EHC2(S0) 
XHC_(S0) HDEF(S4) [...]
  acpitimer0 at acpi0: 3579545 Hz, 24 bits
  acpimadt0 at acpi0 addr 0xfee0: PC-AT compat
  cpu0 at mainbus0: apid 0 (boot processor)
  cpu0: Intel(R) Celeron(R) 2957U @ 1.40GHz, 1397.04 MHz, 06-45-01
  cpu0: 
FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,DS,ACPI,MMX,FXSR,SSE,SSE2,SS,HTT,TM,PBE,SSE3,PCLMUL,DTES64,MWAIT,DS-CPL,VMX,EST,TM2,SSSE3,SDBG,CX16,xTPR,PDCM,PCID,SSE4.1,SSE4.2,MOVBE,POPCNT,DEADLINE,XSAVE,RDRAND,NXE,PAGE1GB,RDTSCP,LONG,LAHF,ABM,PERF,ITSC,FSGSBASE,TSC_ADJUST,ERMS,INVPCID,SRBDS_CTRL,MD_CLEAR,IBRS,IBPB,STIBP,L1DF,SSBD,SENSOR,ARAT,XSAVEOPT,MELTDOWN
  cpu0: 256KB 64b/line 8-way L2 cache
  cpu0: smt 0, core 0, package 0
  mtrr: Pentium Pro MTRR support, 10 var ranges, 88 fixed ranges
  cpu0: apic clock running at 99MHz
  cpu0: mwait min=64, max=64, C-substates=0.2.1.2.4.1.1.1, IBE
  cpu1 at mainbus0: apid 2 (application processor)
  cpu1: Intel(R) Celeron(R) 2957U @ 1.40GHz, 1396.78 MHz, 06-45-01
  cpu1: 
FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,DS,ACPI,MMX,FXSR,SSE,SSE2,SS,HTT,TM,PBE,SSE3,PCLMUL,DTES64,MWAIT,DS-CPL,VMX,EST,TM2,SSSE3,SDBG,CX16,xTPR,PDCM,PCID,SSE4.1,SSE4.2,MOVBE,POPCNT,DEADLINE,XSAVE,RDRAND,NXE,PAGE1GB,RDTSCP,LONG,LAHF,ABM,PERF,ITSC,FSGSBASE,TSC_ADJUST,ERMS,INVPCID,SRBDS_CTRL,MD_CLEAR,IBRS,IBPB,STIBP,L1DF,SSBD,SENSOR,ARAT,XSAVEOPT,MELTDOWN
  cpu1: 256KB 64b/line 8-way L2 cache
  cpu1: smt 0, core 1, package 0
  ioapic0 at mainbus0: apid 8 pa 0xfec0, version 20, 40 pins
  acpihpet0 at acpi0: 14318179 Hz
  acpimcfg0 at acpi0
  acpimcfg0: addr 0xf800, bus 0-63
  acpiprt0 at acpi0: bus 0 (PCI0)
  acpiprt1 at acpi0: bus 1 (RP01)
  acpiprt2 at acpi0: bus 2 (RP02)
  acpiprt3 at acpi0: bus 3 (RP04)
  acpiprt4 at acpi0: bus -1 (PEG0)
  acpiprt5 at acpi0: bus -1 (PEG1)
  acpiprt6 at acpi0: bus -1 (PEG2)
  acpiec0 at acpi0
  acpipci0 at acpi0 PCI0: 0x0010 0x0011 0x
  acpicmos0 at acpi0
  "INT33D7" at acpi0 not configured
  "SMO8810" at acpi0 not configured
  "*pnp0c14" at acpi0 not configured
  acpibtn0 at acpi0: LID0
  acpibtn1 at acpi0: PBTN
  acpibtn2 at acpi0: SBTN
  acpiac0 at acpi0: AC unit offline
  acpibat0 at acpi0: BAT0 model "DELL H2F7D53" serial 584 type LION oem "SMP"
  "DELLABCE" at acpi0 not configured
  acpicpu0 at acpi0: C3(200@506 mwait.1@0x60), C2(200@148 mwait.1@0x33), 
C1(1000@1 mwait.1), PSS
  acpicpu1 at acpi0: C3(200@506 mwait.1@0x60), C2(200@148 mwait.1@0x33), 
C1(1000@1 mwait.1), PSS
  acpipwrres0 at acpi0: PAUD, resource for HDEF
  acpitz0 at acpi0: critical temperature is 107 degC
  acpivideo0 at acpi0: GFX0
  acpivout0 at acpivideo0: LCD_
  cpu0: using VERW MDS workaround (except on vmm entry)
  cpu0: Enhanced SpeedStep 1397 MHz: speeds: 1400, 1300, 1200, 1100, 1000, 900, 
800 MHz
  pci0 at mainbus0 bus 0
  pchb0 at pci0 dev 0 function 0 "Intel Core 4G Host" rev 0x0b
  inteldrm0 at pci0 dev 2 function 0 "Intel HD Graphics" rev 0x0b
  drm0 at inteldrm0
  inteldrm0: msi, HASWELL, gen 7
  azalia0 at pci0 dev 3 function 0 "Intel Core 4G HD Audio" rev 0x0b: msi
  azalia0: No codecs found
  xhci0 at pci0 dev 20 function 0 "Intel 8 Seri

Re: clock not set on boot

2020-12-06 Thread andygoblins



On December 6, 2020 7:44:01 AM UTC, Otto Moerbeek  wrote: 

>> Ah, I see the info is already there in another post. This edgerouter
>> is a slow machine. You can try what I suggested, e.g. by putting a
>> sleep after unbound starts in /etc/rc.
>> 
>> But an easier solution is not to rely on a single resolved and add
>> another one in /etc/resolve.conf
>
>Sorry about the typos. *resolver and */etc/resolv.conf

No worries; I knew what you meant. I added some fallback servers and my date is 
set correctly now. I should have added redundancy to my resolv.conf a long time 
ago. Oh well. Now my problem is...resolved



Re: subscribe misc

2020-12-06 Thread ben
welcome to the club



Seeking help creating an OpenBSD/OpenIKED alternative to the Algo VPN

2020-12-06 Thread Kyle Jensen
Hi, I'm working on an Ansible role to help me provision road-warrior style
IKEv2 VPNs using OpenIKED and OpenBSD. I'd like this to be similar to Algo
https://github.com/trailofbits/algo. You can see what I started here:
https://github.com/kljensen/hetun-vpn

My progress thus far is as follows. I can use that Ansible role to
provision a fresh 6.8 machine (usually on Vultr). The provisioning process
creates .mobileconfig files for importing on iOS and Mac OS so that I can
connect to OpenIKED, routing all my network traffic through the vpn. The
role also includes optional ad-blocking using unbound (though, perhaps it
shouldn't).

I am not an OpenBSD/OpenIKED pro and I'd very much appreciate collaborating
with willing souls who, like me, could use an OpenBSD-based road warrior
VPN.

Sincerely, Kyle


subscribe misc

2020-12-06 Thread Kyle Jensen
subscribe misc


ntpd and no RTC

2020-12-06 Thread Otto Moerbeek
Hi,

As seen in another thread there are some questionms on how ntpd works
if no relatime clock is available or it's battery is dead. This poses
problems since ntpd needs DNS and if the time is not right, DNSSEC
validation might fail.

The goals it to work in as mancy cass as possible , but also stop
attempts quickly if ntpd sees it's not going to work out, to avoid
unneeded delays booting: ntpd only backgrounds if it succeeds in
setting the time or realises it is not going to work.

So the hardest case is a machine without proper RTC that only uses a
resolver running on itself.


It goes more or less like this:

1. ntpd check if DNS is working by doing a probe
2. if that fails it does a CD (Checking Disabled) probe. This disables
DNSSEC for that query and should get an answer even if the time is wrong.
3. If that failes it gives up.
4. Otherwise is resolves the needed names (potentially with CD flag)
and gets the time via constraints and NTP packets.
5. If the time is to be moved forward, it does so.
6. In all other cases it does not set the time and backgrounds.
7. After the time is synced, it wil no longer do CD queries and
re-query names.

I (and others) spend quite some time in getting that right and it
works in many cases. But there are some machines that might not work,
especially slow machines.  I consider RTC-less machines broken, so we
are not going to introduce extra delays to comfort those and hinder
other cases. You might get such a slow machine to work by introducing
a sleep in specific places, e.g. after network startup or resolver
starting.

But in many cases it is much easier to just add an extra resolver (not
runing on the machine in question) to resolv.conf.

-Otto