upgrading PHP 7.4 to PHP 8 on FreeBSD

What, a technical post? It happens. Rarely. Usually, I’m focused on the tech that goes into a book, but sometimes the real world intervenes.

Like PHP. PHP is very much the real world. My site has been running PHP 7.4 for a while, which goes end of life on 28 November. I put this off as long as possible, but it’s time to update.

I run my e-bookstore on Woocommerce, which is built on WordPress, which is built on PHP. What started as a silly experiment has become the center of my business. I need to minimize downtime, which means I must check everything before upgrading. It’s PHP, which means it’s a maze of twisty little modules that all look alike. PHP has this annoying habit of adding, removing, splitting, and changing modules. Running PHP applications on FreeBSD is all about finding the module your application needs, so I want to identify all possible problems before changing.

First, let’s see what packages need upgrading.

# pkg info -x php
mod_php74-7.4.32_1
php74-7.4.32
php74-ctype-7.4.32
php74-curl-7.4.32
php74-dom-7.4.32
php74-exif-7.4.32
php74-fileinfo-7.4.32
php74-filter-7.4.32
php74-gd-7.4.32
php74-iconv-7.4.32
php74-intl-7.4.32
php74-json-7.4.32
php74-mbstring-7.4.32
php74-mysqli-7.4.32
php74-openssl-7.4.32
php74-pcntl-7.4.32
php74-pdo-7.4.32
php74-pdo_mysql-7.4.32
php74-pecl-imagick-im7-3.5.1_1
php74-phar-7.4.32
php74-posix-7.4.32
php74-session-7.4.32
php74-simplexml-7.4.32
php74-soap-7.4.32
php74-tokenizer-7.4.32
php74-xml-7.4.32
php74-xmlreader-7.4.32
php74-xmlrpc-7.4.32
php74-xmlwriter-7.4.32
php74-zip-7.4.32_1
php74-zlib-7.4.32

31 packages. Software like Tiny Tiny RSS and WordPress depend on PHP, but if the underlying PHP software has all the necessary libraries then they should just work. Should. But PHP modules sometimes disappear, get replaced, or get renamed. I want a list of all the modules I need before running any commands. So, what would the PHP 8.0 version of these packages be named? I have to iterate through sed a couple times to trim out excess version information and wind up with this.

# pkg info -x php | sed s/74/80/g | sed s/-7.4.32//g | sed s/_1//g

mod_php80
php80
php80-ctype
php80-curl
php80-dom
php80-exif
php80-fileinfo
php80-filter
...

Those look sensible. Now check to see if the packages exist.

I could automate this by checking the exit code of each command, but the list is short enough that I can process it by hand. I run one package search at a time, letting xargs prompt me for each one so I can eyeball the results.

# pkg info -x php | sed s/74/80/g | sed s/-7.4.32//g | sed s/_1//g | xargs -L1 -p pkg search
pkg search mod_php80?…y
mod_php80-8.0.25 PHP Scripting Language
pkg search php80?…y

This particular search will spew a couple hundred lines of output, but I’m confident the base PHP 8.0 package is in there.

...
php80-intl-8.0.25 The intl shared extension for php
pkg search php80-json?...y
pkg search php80-mbstring?...

Ooops! Pay attention here. There is no package for PHP 8.0’s JSON module! Make a note of that.

At the end, I have problems with three packages: php80-json, php80-openssl, and php80-xmlrpc. Freshports tells me that the JSON and OpenSSL modules were added into the default PHP 8.0 package, so I can cross those off my list.

The XML-RPC module is another tale. PHP 8.0 no longer has an XML module. Fortunately, that same bug lists a replacement pecl-xmlrpc. There’s a related php80-pecl-xmlrpc module.

I have a list of modules to install. For a last check, I’ll look for anything that depends on PHP 7.4.

# pkg info -dx php74
The list looks different, but contains the same modules. I’m as prepared as I can be.

One last check. Make a list of the packages to install. Eyeball it to make sure it looks right.

# pkg info -x php | sed s/74/80/g | sed s/-7.4.32//g | sed s/_1//g > php8.pkg

Create a boot environment, and do a dry run. If I remove all packages with PHP in their name, what will get pulled? Using -n tells me what the command would do, but doesn’t actually change anything.

# bectl create 12.3-p7-lastbeforePHP
# pkg remove -nx php74

That list looks sensible. Now remove the packages, and install everything on our list.

# pkg remove -x php74
# cat php8.pkg | xargs -L1 -p pkg install -y

The -p argument to xargs prompts me for confirmation, so I can use -y on the pkg command. The install fails on the nonexistent JSON, OpenSSL, and XMLRPC modules, but that’s expected.

At the end, I manually install php80-pecl-xmlrpc.

Reboot.

Test, test, test. Run a test purchase. It works.

Everything looks okay? I guess I can turn it over to the Crowdsourced Monitoring System, aka “y’all,” and go make some paying words.

New Test System

Now that “DNSSEC Mastery 2/e” is ready for copyedit, I can turn my attention to “OpenBSD Storage Mastery.”

Back in 2014, I bought a machine for writing the ZFS books. Ten hard drives. 32 GB memory. Enough power supply to heat my office during a Michigan winter, which was great during Michigan winters and not so great in the summer. Fan noise that belonged in a datacenter. That machine’s now in the basement, ready for me to test things that require large amounts of storage.

As of today I have a more modern system on my desk, running a current OpenBSD snapshot. Clean and simple, the way God and Dennis Ritchie intended.

By unpopular request, here’s the details. It’s clean out of the box, I don’t even have tcsh installed yet, let alone my .cwmrc copied over.


OpenBSD 7.0-current (GENERIC.MP) #132: Mon Nov 29 08:51:58 MST 2021
deraadt@amd64.openbsd.org:/usr/src/sys/arch/amd64/compile/GENERIC.MP
real mem = 33592328192 (32036MB)
avail mem = 32558276608 (31049MB)
random: good seed from bootblocks
mpath0 at root
scsibus0 at mpath0: 256 targets
mainbus0 at root
bios0 at mainbus0: SMBIOS rev. 3.3 @ 0xc6a02000 (72 entries)
bios0: vendor American Megatrends Inc. version "2423" date 08/10/2021
bios0: ASUS ROG STRIX B550-F GAMING
acpi0 at bios0: ACPI 6.0
acpi0: sleep states S0 S3 S4 S5
acpi0: tables DSDT FACP IVRS SSDT SSDT SSDT FIDT FPDT MCFG HPET VFCT BGRT WPBT TPM2 SSDT CRAT CDIT SSDT SSDT SSDT WSMT APIC SSDT SSDT
acpi0: wakeup devices X162(S4) GP17(S4) XHC0(S4) XHC1(S4) X161(S4) PTXH(S4) X1_1(S4) X1_2(S4) X1_3(S4) I225(S4) X162(S4) M2_2(S4)
acpitimer0 at acpi0: 3579545 Hz, 32 bits
acpimcfg0 at acpi0
acpimcfg0: addr 0xf0000000, bus 0-127
acpihpet0 at acpi0: 14318180 Hz
acpimadt0 at acpi0 addr 0xfee00000: PC-AT compat
cpu0 at mainbus0: apid 0 (boot processor)
cpu0: AMD Ryzen 5 5600G with Radeon Graphics, 3893.28 MHz, 19-50-00
cpu0: FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,MMX,FXSR,SSE,SSE2,HTT,SSE3,PCLMUL,MWAIT,SSSE3,FMA3,CX16,SSE4.1,SSE4.2,MOVBE,POPCNT,AES,XSAVE,AVX,F16C,RDRAND,NXE,MMXX,FFXSR,PAGE1GB,RDTSCP,LONG,LAHF,CMPLEG,SVM,EAPICSP,AMCR8,ABM,SSE4A,MASSE,3DNOWP,OSVW,IBS,SKINIT,TCE,TOPEXT,CPCTR,DBKP,PCTRL3,MWAITX,ITSC,FSGSBASE,BMI1,AVX2,SMEP,BMI2,ERMS,INVPCID,PQM,RDSEED,ADX,SMAP,CLFLUSHOPT,CLWB,SHA,UMIP,PKU,IBPB,IBRS,STIBP,SSBD,XSAVEOPT,XSAVEC,XGETBV1,XSAVES
cpu0: 32KB 64b/line 8-way I-cache, 32KB 64b/line 8-way D-cache, 512KB 64b/line 8-way L2 cache
cpu0: ITLB 64 4KB entries fully associative, 64 4MB entries fully associative
cpu0: DTLB 64 4KB entries fully associative, 64 4MB entries fully associative
cpu0: smt 0, core 0, package 0
mtrr: Pentium Pro MTRR support, 8 var ranges, 88 fixed ranges
cpu0: apic clock running at 99MHz
cpu0: mwait min=64, max=64, C-substates=1.1, IBE
cpu1 at mainbus0: apid 2 (application processor)
cpu1: AMD Ryzen 5 5600G with Radeon Graphics, 3892.69 MHz, 19-50-00
cpu1: FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,MMX,FXSR,SSE,SSE2,HTT,SSE3,PCLMUL,MWAIT,SSSE3,FMA3,CX16,SSE4.1,SSE4.2,MOVBE,POPCNT,AES,XSAVE,AVX,F16C,RDRAND,NXE,MMXX,FFXSR,PAGE1GB,RDTSCP,LONG,LAHF,CMPLEG,SVM,EAPICSP,AMCR8,ABM,SSE4A,MASSE,3DNOWP,OSVW,IBS,SKINIT,TCE,TOPEXT,CPCTR,DBKP,PCTRL3,MWAITX,ITSC,FSGSBASE,BMI1,AVX2,SMEP,BMI2,ERMS,INVPCID,PQM,RDSEED,ADX,SMAP,CLFLUSHOPT,CLWB,SHA,UMIP,PKU,IBPB,IBRS,STIBP,SSBD,XSAVEOPT,XSAVEC,XGETBV1,XSAVES
cpu1: 32KB 64b/line 8-way I-cache, 32KB 64b/line 8-way D-cache, 512KB 64b/line 8-way L2 cache
cpu1: ITLB 64 4KB entries fully associative, 64 4MB entries fully associative
cpu1: DTLB 64 4KB entries fully associative, 64 4MB entries fully associative
cpu1: smt 0, core 1, package 0
cpu2 at mainbus0: apid 4 (application processor)
cpu2: AMD Ryzen 5 5600G with Radeon Graphics, 3892.70 MHz, 19-50-00
cpu2: FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,MMX,FXSR,SSE,SSE2,HTT,SSE3,PCLMUL,MWAIT,SSSE3,FMA3,CX16,SSE4.1,SSE4.2,MOVBE,POPCNT,AES,XSAVE,AVX,F16C,RDRAND,NXE,MMXX,FFXSR,PAGE1GB,RDTSCP,LONG,LAHF,CMPLEG,SVM,EAPICSP,AMCR8,ABM,SSE4A,MASSE,3DNOWP,OSVW,IBS,SKINIT,TCE,TOPEXT,CPCTR,DBKP,PCTRL3,MWAITX,ITSC,FSGSBASE,BMI1,AVX2,SMEP,BMI2,ERMS,INVPCID,PQM,RDSEED,ADX,SMAP,CLFLUSHOPT,CLWB,SHA,UMIP,PKU,IBPB,IBRS,STIBP,SSBD,XSAVEOPT,XSAVEC,XGETBV1,XSAVES
cpu2: 32KB 64b/line 8-way I-cache, 32KB 64b/line 8-way D-cache, 512KB 64b/line 8-way L2 cache
cpu2: ITLB 64 4KB entries fully associative, 64 4MB entries fully associative
cpu2: DTLB 64 4KB entries fully associative, 64 4MB entries fully associative
cpu2: smt 0, core 2, package 0
cpu3 at mainbus0: apid 6 (application processor)
cpu3: AMD Ryzen 5 5600G with Radeon Graphics, 3892.69 MHz, 19-50-00
cpu3: FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,MMX,FXSR,SSE,SSE2,HTT,SSE3,PCLMUL,MWAIT,SSSE3,FMA3,CX16,SSE4.1,SSE4.2,MOVBE,POPCNT,AES,XSAVE,AVX,F16C,RDRAND,NXE,MMXX,FFXSR,PAGE1GB,RDTSCP,LONG,LAHF,CMPLEG,SVM,EAPICSP,AMCR8,ABM,SSE4A,MASSE,3DNOWP,OSVW,IBS,SKINIT,TCE,TOPEXT,CPCTR,DBKP,PCTRL3,MWAITX,ITSC,FSGSBASE,BMI1,AVX2,SMEP,BMI2,ERMS,INVPCID,PQM,RDSEED,ADX,SMAP,CLFLUSHOPT,CLWB,SHA,UMIP,PKU,IBPB,IBRS,STIBP,SSBD,XSAVEOPT,XSAVEC,XGETBV1,XSAVES
cpu3: 32KB 64b/line 8-way I-cache, 32KB 64b/line 8-way D-cache, 512KB 64b/line 8-way L2 cache
cpu3: ITLB 64 4KB entries fully associative, 64 4MB entries fully associative
cpu3: DTLB 64 4KB entries fully associative, 64 4MB entries fully associative
cpu3: smt 0, core 3, package 0
cpu4 at mainbus0: apid 8 (application processor)
cpu4: AMD Ryzen 5 5600G with Radeon Graphics, 3892.69 MHz, 19-50-00
cpu4: FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,MMX,FXSR,SSE,SSE2,HTT,SSE3,PCLMUL,MWAIT,SSSE3,FMA3,CX16,SSE4.1,SSE4.2,MOVBE,POPCNT,AES,XSAVE,AVX,F16C,RDRAND,NXE,MMXX,FFXSR,PAGE1GB,RDTSCP,LONG,LAHF,CMPLEG,SVM,EAPICSP,AMCR8,ABM,SSE4A,MASSE,3DNOWP,OSVW,IBS,SKINIT,TCE,TOPEXT,CPCTR,DBKP,PCTRL3,MWAITX,ITSC,FSGSBASE,BMI1,AVX2,SMEP,BMI2,ERMS,INVPCID,PQM,RDSEED,ADX,SMAP,CLFLUSHOPT,CLWB,SHA,UMIP,PKU,IBPB,IBRS,STIBP,SSBD,XSAVEOPT,XSAVEC,XGETBV1,XSAVES
cpu4: 32KB 64b/line 8-way I-cache, 32KB 64b/line 8-way D-cache, 512KB 64b/line 8-way L2 cache
cpu4: ITLB 64 4KB entries fully associative, 64 4MB entries fully associative
cpu4: DTLB 64 4KB entries fully associative, 64 4MB entries fully associative
cpu4: smt 0, core 4, package 0
cpu5 at mainbus0: apid 10 (application processor)
cpu5: AMD Ryzen 5 5600G with Radeon Graphics, 3892.69 MHz, 19-50-00
cpu5: FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,MMX,FXSR,SSE,SSE2,HTT,SSE3,PCLMUL,MWAIT,SSSE3,FMA3,CX16,SSE4.1,SSE4.2,MOVBE,POPCNT,AES,XSAVE,AVX,F16C,RDRAND,NXE,MMXX,FFXSR,PAGE1GB,RDTSCP,LONG,LAHF,CMPLEG,SVM,EAPICSP,AMCR8,ABM,SSE4A,MASSE,3DNOWP,OSVW,IBS,SKINIT,TCE,TOPEXT,CPCTR,DBKP,PCTRL3,MWAITX,ITSC,FSGSBASE,BMI1,AVX2,SMEP,BMI2,ERMS,INVPCID,PQM,RDSEED,ADX,SMAP,CLFLUSHOPT,CLWB,SHA,UMIP,PKU,IBPB,IBRS,STIBP,SSBD,XSAVEOPT,XSAVEC,XGETBV1,XSAVES
cpu5: 32KB 64b/line 8-way I-cache, 32KB 64b/line 8-way D-cache, 512KB 64b/line 8-way L2 cache
cpu5: ITLB 64 4KB entries fully associative, 64 4MB entries fully associative
cpu5: DTLB 64 4KB entries fully associative, 64 4MB entries fully associative
cpu5: smt 0, core 5, package 0
cpu6 at mainbus0: apid 1 (application processor)
cpu6: AMD Ryzen 5 5600G with Radeon Graphics, 3892.69 MHz, 19-50-00
cpu6: FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,MMX,FXSR,SSE,SSE2,HTT,SSE3,PCLMUL,MWAIT,SSSE3,FMA3,CX16,SSE4.1,SSE4.2,MOVBE,POPCNT,AES,XSAVE,AVX,F16C,RDRAND,NXE,MMXX,FFXSR,PAGE1GB,RDTSCP,LONG,LAHF,CMPLEG,SVM,EAPICSP,AMCR8,ABM,SSE4A,MASSE,3DNOWP,OSVW,IBS,SKINIT,TCE,TOPEXT,CPCTR,DBKP,PCTRL3,MWAITX,ITSC,FSGSBASE,BMI1,AVX2,SMEP,BMI2,ERMS,INVPCID,PQM,RDSEED,ADX,SMAP,CLFLUSHOPT,CLWB,SHA,UMIP,PKU,IBPB,IBRS,STIBP,SSBD,XSAVEOPT,XSAVEC,XGETBV1,XSAVES
cpu6: 32KB 64b/line 8-way I-cache, 32KB 64b/line 8-way D-cache, 512KB 64b/line 8-way L2 cache
cpu6: ITLB 64 4KB entries fully associative, 64 4MB entries fully associative
cpu6: DTLB 64 4KB entries fully associative, 64 4MB entries fully associative
cpu6: smt 1, core 0, package 0
cpu7 at mainbus0: apid 3 (application processor)
cpu7: AMD Ryzen 5 5600G with Radeon Graphics, 3892.69 MHz, 19-50-00
cpu7: FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,MMX,FXSR,SSE,SSE2,HTT,SSE3,PCLMUL,MWAIT,SSSE3,FMA3,CX16,SSE4.1,SSE4.2,MOVBE,POPCNT,AES,XSAVE,AVX,F16C,RDRAND,NXE,MMXX,FFXSR,PAGE1GB,RDTSCP,LONG,LAHF,CMPLEG,SVM,EAPICSP,AMCR8,ABM,SSE4A,MASSE,3DNOWP,OSVW,IBS,SKINIT,TCE,TOPEXT,CPCTR,DBKP,PCTRL3,MWAITX,ITSC,FSGSBASE,BMI1,AVX2,SMEP,BMI2,ERMS,INVPCID,PQM,RDSEED,ADX,SMAP,CLFLUSHOPT,CLWB,SHA,UMIP,PKU,IBPB,IBRS,STIBP,SSBD,XSAVEOPT,XSAVEC,XGETBV1,XSAVES
cpu7: 32KB 64b/line 8-way I-cache, 32KB 64b/line 8-way D-cache, 512KB 64b/line 8-way L2 cache
cpu7: ITLB 64 4KB entries fully associative, 64 4MB entries fully associative
cpu7: DTLB 64 4KB entries fully associative, 64 4MB entries fully associative
cpu7: smt 1, core 1, package 0
cpu8 at mainbus0: apid 5 (application processor)
cpu8: AMD Ryzen 5 5600G with Radeon Graphics, 3892.69 MHz, 19-50-00
cpu8: FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,MMX,FXSR,SSE,SSE2,HTT,SSE3,PCLMUL,MWAIT,SSSE3,FMA3,CX16,SSE4.1,SSE4.2,MOVBE,POPCNT,AES,XSAVE,AVX,F16C,RDRAND,NXE,MMXX,FFXSR,PAGE1GB,RDTSCP,LONG,LAHF,CMPLEG,SVM,EAPICSP,AMCR8,ABM,SSE4A,MASSE,3DNOWP,OSVW,IBS,SKINIT,TCE,TOPEXT,CPCTR,DBKP,PCTRL3,MWAITX,ITSC,FSGSBASE,BMI1,AVX2,SMEP,BMI2,ERMS,INVPCID,PQM,RDSEED,ADX,SMAP,CLFLUSHOPT,CLWB,SHA,UMIP,PKU,IBPB,IBRS,STIBP,SSBD,XSAVEOPT,XSAVEC,XGETBV1,XSAVES
cpu8: 32KB 64b/line 8-way I-cache, 32KB 64b/line 8-way D-cache, 512KB 64b/line 8-way L2 cache
cpu8: ITLB 64 4KB entries fully associative, 64 4MB entries fully associative
cpu8: DTLB 64 4KB entries fully associative, 64 4MB entries fully associative
cpu8: smt 1, core 2, package 0
cpu9 at mainbus0: apid 7 (application processor)
cpu9: AMD Ryzen 5 5600G with Radeon Graphics, 3892.69 MHz, 19-50-00
cpu9: FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,MMX,FXSR,SSE,SSE2,HTT,SSE3,PCLMUL,MWAIT,SSSE3,FMA3,CX16,SSE4.1,SSE4.2,MOVBE,POPCNT,AES,XSAVE,AVX,F16C,RDRAND,NXE,MMXX,FFXSR,PAGE1GB,RDTSCP,LONG,LAHF,CMPLEG,SVM,EAPICSP,AMCR8,ABM,SSE4A,MASSE,3DNOWP,OSVW,IBS,SKINIT,TCE,TOPEXT,CPCTR,DBKP,PCTRL3,MWAITX,ITSC,FSGSBASE,BMI1,AVX2,SMEP,BMI2,ERMS,INVPCID,PQM,RDSEED,ADX,SMAP,CLFLUSHOPT,CLWB,SHA,UMIP,PKU,IBPB,IBRS,STIBP,SSBD,XSAVEOPT,XSAVEC,XGETBV1,XSAVES
cpu9: 32KB 64b/line 8-way I-cache, 32KB 64b/line 8-way D-cache, 512KB 64b/line 8-way L2 cache
cpu9: ITLB 64 4KB entries fully associative, 64 4MB entries fully associative
cpu9: DTLB 64 4KB entries fully associative, 64 4MB entries fully associative
cpu9: smt 1, core 3, package 0
cpu10 at mainbus0: apid 9 (application processor)
cpu10: AMD Ryzen 5 5600G with Radeon Graphics, 3892.69 MHz, 19-50-00
cpu10: FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,MMX,FXSR,SSE,SSE2,HTT,SSE3,PCLMUL,MWAIT,SSSE3,FMA3,CX16,SSE4.1,SSE4.2,MOVBE,POPCNT,AES,XSAVE,AVX,F16C,RDRAND,NXE,MMXX,FFXSR,PAGE1GB,RDTSCP,LONG,LAHF,CMPLEG,SVM,EAPICSP,AMCR8,ABM,SSE4A,MASSE,3DNOWP,OSVW,IBS,SKINIT,TCE,TOPEXT,CPCTR,DBKP,PCTRL3,MWAITX,ITSC,FSGSBASE,BMI1,AVX2,SMEP,BMI2,ERMS,INVPCID,PQM,RDSEED,ADX,SMAP,CLFLUSHOPT,CLWB,SHA,UMIP,PKU,IBPB,IBRS,STIBP,SSBD,XSAVEOPT,XSAVEC,XGETBV1,XSAVES
cpu10: 32KB 64b/line 8-way I-cache, 32KB 64b/line 8-way D-cache, 512KB 64b/line 8-way L2 cache
cpu10: ITLB 64 4KB entries fully associative, 64 4MB entries fully associative
cpu10: DTLB 64 4KB entries fully associative, 64 4MB entries fully associative
cpu10: smt 1, core 4, package 0
cpu11 at mainbus0: apid 11 (application processor)
cpu11: AMD Ryzen 5 5600G with Radeon Graphics, 3892.69 MHz, 19-50-00
cpu11: FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,MMX,FXSR,SSE,SSE2,HTT,SSE3,PCLMUL,MWAIT,SSSE3,FMA3,CX16,SSE4.1,SSE4.2,MOVBE,POPCNT,AES,XSAVE,AVX,F16C,RDRAND,NXE,MMXX,FFXSR,PAGE1GB,RDTSCP,LONG,LAHF,CMPLEG,SVM,EAPICSP,AMCR8,ABM,SSE4A,MASSE,3DNOWP,OSVW,IBS,SKINIT,TCE,TOPEXT,CPCTR,DBKP,PCTRL3,MWAITX,ITSC,FSGSBASE,BMI1,AVX2,SMEP,BMI2,ERMS,INVPCID,PQM,RDSEED,ADX,SMAP,CLFLUSHOPT,CLWB,SHA,UMIP,PKU,IBPB,IBRS,STIBP,SSBD,XSAVEOPT,XSAVEC,XGETBV1,XSAVES
cpu11: 32KB 64b/line 8-way I-cache, 32KB 64b/line 8-way D-cache, 512KB 64b/line 8-way L2 cache
cpu11: ITLB 64 4KB entries fully associative, 64 4MB entries fully associative
cpu11: DTLB 64 4KB entries fully associative, 64 4MB entries fully associative
cpu11: smt 1, core 5, package 0
ioapic0 at mainbus0: apid 13 pa 0xfec00000, version 21, 24 pins
ioapic1 at mainbus0: apid 14 pa 0xfec01000, version 21, 32 pins
acpiprt0 at acpi0: bus 0 (PCI0)
acpiprt1 at acpi0: bus -1 (GPP6)
acpiprt2 at acpi0: bus -1 (GPP7)
acpiprt3 at acpi0: bus -1 (GPP8)
acpiprt4 at acpi0: bus -1 (GPP9)
acpiprt5 at acpi0: bus 8 (GP17)
acpiprt6 at acpi0: bus -1 (GPP0)
acpiprt7 at acpi0: bus -1 (GP18)
acpiprt8 at acpi0: bus 7 (GPP4)
acpiprt9 at acpi0: bus -1 (GPP5)
acpiprt10 at acpi0: bus 1 (GPP3)
acpipci0 at acpi0 PCI0: 0x00000010 0x00000011 0x00000000
acpicmos0 at acpi0
acpibtn0 at acpi0: PWRB
amdgpio0 at acpi0 GPIO uid 0 addr 0xfed81500/0x400 irq 7, 184 pins
tpm0 at acpi0 TPM_: unsupported TPM2 start method
"ACPI0010" at acpi0 not configured
acpicpu0 at acpi0: C3(0@350 io@0x415), C2(0@18 io@0x414), C1(0@1 mwait), PSS
acpicpu1 at acpi0: C3(0@350 io@0x415), C2(0@18 io@0x414), C1(0@1 mwait), PSS
acpicpu2 at acpi0: C3(0@350 io@0x415), C2(0@18 io@0x414), C1(0@1 mwait), PSS
acpicpu3 at acpi0: C3(0@350 io@0x415), C2(0@18 io@0x414), C1(0@1 mwait), PSS
acpicpu4 at acpi0: C3(0@350 io@0x415), C2(0@18 io@0x414), C1(0@1 mwait), PSS
acpicpu5 at acpi0: C3(0@350 io@0x415), C2(0@18 io@0x414), C1(0@1 mwait), PSS
acpicpu6 at acpi0: C3(0@350 io@0x415), C2(0@18 io@0x414), C1(0@1 mwait), PSS
acpicpu7 at acpi0: C3(0@350 io@0x415), C2(0@18 io@0x414), C1(0@1 mwait), PSS
acpicpu8 at acpi0: C3(0@350 io@0x415), C2(0@18 io@0x414), C1(0@1 mwait), PSS
acpicpu9 at acpi0: C3(0@350 io@0x415), C2(0@18 io@0x414), C1(0@1 mwait), PSS
acpicpu10 at acpi0: C3(0@350 io@0x415), C2(0@18 io@0x414), C1(0@1 mwait), PSS
acpicpu11 at acpi0: C3(0@350 io@0x415), C2(0@18 io@0x414), C1(0@1 mwait), PSS
"AMDIF030" at acpi0 not configured
"PNP0C14" at acpi0 not configured
"PNP0C14" at acpi0 not configured
"PNP0C14" at acpi0 not configured
"PNP0C14" at acpi0 not configured
"PNP0C14" at acpi0 not configured
cpu0: 3893 MHz: speeds: 3900 1700 1400 MHz
pci0 at mainbus0 bus 0
ksmn0 at pci0 dev 0 function 0 "AMD 17h/6xh Root Complex" rev 0x00
"AMD 17h/6xh IOMMU" rev 0x00 at pci0 dev 0 function 2 not configured
pchb0 at pci0 dev 1 function 0 "AMD 17h/6xh Host" rev 0x00
pchb1 at pci0 dev 2 function 0 "AMD 17h/6xh Host" rev 0x00
ppb0 at pci0 dev 2 function 1 "AMD 17h/6xh PCIE" rev 0x00: msi
pci1 at ppb0 bus 1
xhci0 at pci1 dev 0 function 0 "AMD 500 Series xHCI" rev 0x00: msi, xHCI 1.10
usb0 at xhci0: USB revision 3.0
uhub0 at usb0 configuration 1 interface 0 "AMD xHCI root hub" rev 3.00/1.00 addr 1
ahci0 at pci1 dev 0 function 1 "AMD 500 Series AHCI" rev 0x00: msi, AHCI 1.3.1
ahci0: port busy after first PMP probe FIS
ahci0: port busy after first PMP probe FIS
ahci0: port 1: 6.0Gb/s
scsibus1 at ahci0: 32 targets
sd0 at scsibus1 targ 1 lun 0: naa.5002538fc16090b3
sd0: 953869MB, 512 bytes/sector, 1953525168 sectors, thin
ppb1 at pci1 dev 0 function 2 "AMD 500 Series PCIE" rev 0x00
pci2 at ppb1 bus 2
ppb2 at pci2 dev 0 function 0 "AMD 500 Series PCIE" rev 0x00: msi
pci3 at ppb2 bus 3
ppb3 at pci2 dev 4 function 0 "AMD 500 Series PCIE" rev 0x00: msi
pci4 at ppb3 bus 4
nvme0 at pci4 dev 0 function 0 "SanDisk WD Black NVMe" rev 0x00: msix, NVMe 1.3
nvme0: WDBRPG0010BNC-WRSN, firmware 111130WD, serial 213733803989
scsibus2 at nvme0: 2 targets, initiator 0
sd1 at scsibus2 targ 1 lun 0:
sd1: 953869MB, 512 bytes/sector, 1953525168 sectors
ppb4 at pci2 dev 8 function 0 "AMD 500 Series PCIE" rev 0x00: msi
pci5 at ppb4 bus 5
ppb5 at pci2 dev 9 function 0 "AMD 500 Series PCIE" rev 0x00: msi
pci6 at ppb5 bus 6
igc0 at pci6 dev 0 function 0 "Intel I225-V" rev 0x03, msix, 4 queues, address 7c:10:c9:45:b2:d1
ppb6 at pci0 dev 2 function 2 "AMD 17h/6xh PCIE" rev 0x00: msi
pci7 at ppb6 bus 7
nvme1 at pci7 dev 0 function 0 "SanDisk WD Black NVMe" rev 0x00: msix, NVMe 1.3
nvme1: WDBRPG0010BNC-WRSN, firmware 111130WD, serial 213733806541
scsibus3 at nvme1: 2 targets, initiator 0
sd2 at scsibus3 targ 1 lun 0:
sd2: 953869MB, 512 bytes/sector, 1953525168 sectors
pchb2 at pci0 dev 8 function 0 "AMD 17h/6xh Host" rev 0x00
ppb7 at pci0 dev 8 function 1 "AMD 17h/6xh PCIE" rev 0x00
pci8 at ppb7 bus 8
amdgpu0 at pci8 dev 0 function 0 "ATI Cezanne" rev 0xc9
drm0 at amdgpu0
amdgpu0: msi
azalia0 at pci8 dev 0 function 1 "ATI Renoir HD Audio" rev 0x00: msi
azalia0: no supported codecs
ccp0 at pci8 dev 0 function 2 "AMD 17h/1xh Crypto" rev 0x00
xhci1 at pci8 dev 0 function 3 "AMD 17h/6xh xHCI" rev 0x00: msi, xHCI 1.10
usb1 at xhci1: USB revision 3.0
uhub1 at usb1 configuration 1 interface 0 "AMD xHCI root hub" rev 3.00/1.00 addr 1
xhci2 at pci8 dev 0 function 4 "AMD 17h/6xh xHCI" rev 0x00: msi, xHCI 1.10
usb2 at xhci2: USB revision 3.0
uhub2 at usb2 configuration 1 interface 0 "AMD xHCI root hub" rev 3.00/1.00 addr 1
azalia1 at pci8 dev 0 function 6 "AMD 17h/1xh HD Audio" rev 0x00: apic 14 int 12
azalia1: codecs: Realtek ALC1220
audio0 at azalia1
piixpm0 at pci0 dev 20 function 0 "AMD FCH SMBus" rev 0x51: polling
iic0 at piixpm0
iic1 at piixpm0
pcib0 at pci0 dev 20 function 3 "AMD FCH LPC" rev 0x51
pchb3 at pci0 dev 24 function 0 "AMD 19h/5xh Data Fabric" rev 0x00
pchb4 at pci0 dev 24 function 1 "AMD 19h/5xh Data Fabric" rev 0x00
pchb5 at pci0 dev 24 function 2 "AMD 19h/5xh Data Fabric" rev 0x00
pchb6 at pci0 dev 24 function 3 "AMD 19h/5xh Data Fabric" rev 0x00
pchb7 at pci0 dev 24 function 4 "AMD 19h/5xh Data Fabric" rev 0x00
pchb8 at pci0 dev 24 function 5 "AMD 19h/5xh Data Fabric" rev 0x00
pchb9 at pci0 dev 24 function 6 "AMD 19h/5xh Data Fabric" rev 0x00
pchb10 at pci0 dev 24 function 7 "AMD 19h/5xh Data Fabric" rev 0x00
isa0 at pcib0
isadma0 at isa0
com0 at isa0 port 0x3f8/8 irq 4: ns16550a, 16 byte fifo
pckbc0 at isa0 port 0x60/5 irq 1 irq 12
pckbd0 at pckbc0 (kbd slot)
wskbd0 at pckbd0: console keyboard
pcppi0 at isa0 port 0x61
spkr0 at pcppi0
efifb at mainbus0 not configured
dt: 451 probes
uhidev0 at uhub0 port 10 configuration 1 interface 2 "AsusTek Computer Inc. AURA LED Controller" rev 2.00/1.00 addr 2
uhidev0: iclass 3/0, 236 report ids
uhid0 at uhidev0 reportid 236: input=64, output=64, feature=0
ugen0 at uhub0 port 10 configuration 1 "AsusTek Computer Inc. AURA LED Controller" rev 2.00/1.00 addr 2
uhub3 at uhub0 port 11 configuration 1 interface 0 "Genesys Logic USB2.0 Hub" rev 2.00/60.90 addr 3
uhidev1 at uhub0 port 13 configuration 1 interface 0 "Unicomp Endura Pro Keyboard" rev 1.10/43.34 addr 4
uhidev1: iclass 3/1
ukbd0 at uhidev1: 8 variable keys, 6 key codes
wskbd1 at ukbd0 mux 1
uhidev2 at uhub0 port 13 configuration 1 interface 1 "Unicomp Endura Pro Keyboard" rev 1.10/43.34 addr 4
uhidev2: iclass 3/1, 3 report ids
ums0 at uhidev2 reportid 1: 3 buttons, Z dir
wsmouse0 at ums0 mux 0
ucc0 at uhidev2 reportid 2: 573 usages, 18 keys, array
wskbd2 at ucc0 mux 1
uhid1 at uhidev2 reportid 3: input=1, output=0, feature=0
ugen1 at uhub1 port 2 "Realtek USB3.0 802.11ac 1200M Adapter" rev 2.10/2.10 addr 2
urtwn0 at uhub2 port 2 configuration 1 interface 0 "Realtek 802.11n NIC" rev 2.10/2.00 addr 2
urtwn0: MAC/BB RTL8192EU, RF 6052 2T2R, address 98:de:d0:0f:c9:62
vscsi0 at root
scsibus4 at vscsi0: 256 targets
softraid0 at root
scsibus5 at softraid0: 256 targets
root on sd0a (d25c4224901b9485.a) swap on sd0b dump on sd0b
[drm] *ERROR* sdma_v4_0: Failed to load firmware "amdgpu/green_sardine_sdma.bin"
[drm] *ERROR* Failed to load sdma firmware!
drm:pid0:psp_init_asd_microcode *ERROR* fail to initialize asd microcode
[drm] *ERROR* Failed to load psp firmware!
[drm] *ERROR* sw_init of IP block failed -2
drm:pid0:amdgpu_device_init *ERROR* amdgpu_device_ip_init failed
drm:pid0:amdgpu_attachhook *ERROR* Fatal error during GPU init
efifb0 at mainbus0: 1920x1080, 32bpp
wsdisplay0 at efifb0 mux 1: console (std, vt100 emulation), using wskbd0
wskbd1: connecting to wsdisplay0
wskbd2: connecting to wsdisplay0
wsdisplay0: screen 1-5 added (std, vt100 emulation)

Dang, that’s a whole mess of CPUs. Maybe I should have replaced my desktop earlier?

Pretty sure this will spark questions, so:

  • Yes, I’m writing an OpenBSD storage book next.
  • No, I have no date on its release, or on a release of a third edition of Absolute OpenBSD.
  • Sponsorships will open once I ship the DNSSEC sponsor gifts.
  • No, I don’t have a hashtag yet.
  • I have no answer to any questions about any related topics.

Thank you for understanding.

Public Online TLS Talk

I’ll be talking about TLS at mug.org on 13 July 2021. I get more than an hour, so there’ll be time for an energetic discussion afterwards. Their web site is not yet updated, because I just now sent them the talk abstract.

This is an online meeting. All are welcome.

Online meetings are getting more common, and I’m getting more requests to present. While online talks don’t have travel time, they do take a kind of energy I call “people juice.” People juice is scarce and not easily renewed. Video calls are even more exhausting than regular ones. I haven’t made this an official policy yet, but I’ve pretty much set a limit of “not more than one presentation a month, and maybe zero depending on what else is going on.”

TLS Mastery Release, Sponsor Gifts, and Acknowledgements

As if 2020 wasn’t sufficiently rough, I spent it writing about TLS.

Now, I’m done.

TLS Mastery has escaped.

TLS Mastery Beastie Edition
Beastie Edition
TLS Mastery cover
Tux Edition

Transport Layer Security, or TLS, makes ecommerce and online banking possible. It protects your passwords and your privacy. Let’s Encrypt transformed TLS from an expensive tool to a free one. TLS understanding and debugging is an essential sysadmin skill you must have.

TLS Mastery takes you through:

  • How TLS works
  • What TLS provides, and what it doesn’t
  • Wrapping unencrypted connections inside TLS
  • Assessing TLS configurations
  • The Automated Certificate Management Environment (ACME) protocol
  • Using Let’s Encrypt to automatically maintain TLS certificates
  • Online Certificate Status Protocol
  • Certificate Revocation
  • CAA, HSTS, and Certificate Transparency
  • Why you shouldn’t run your own CA, and how to do it anyway
  • and more!

Stop wandering blindly around TLS. Master the protocol with TLS Mastery!

Available in the Beastie Edition and the Tux Edition. The only difference is the cover. Hardcover has both covers.

Get the two-cover hardcover at any of the print bookstores below, or direct from my bookstore.

Get the combined editions at:

Get the Beastie edition at:

Get the Tux edition at:


If you’re a sponsor: your gifts are on order. I have enough on hand for my Patronizers, so I’ll be shipping those first. As soon as yours arrive, I’ll get them to you.

This was a rough book to write, so I want to share the acknowledgements.

TLS is perhaps the most complicated topic I’ve ever written about. Writing this book would have been impossible without outside help.

This book would not exist if the Internet Security Research Group hadn’t deployed ACME and organized Let’s Encrypt. TLS certificates are not only free for most people, their maintenance and renewal is highly automatable. They’ve changed the whole Internet, and deserve our thanks for that.

It doesn’t matter how many RFCs I study and how many technical mailing list archives I read: I lack the expertise and context to best illuminate an arcane topic like TLS. The folks who read this manuscript’s early stages and pointed out my innumerable errors deserve special thanks. James Allen, Xavier Belanger, Trix Farrar, Loganaden Velvindron, Jan-Piet Mens, Mike O’Connor, Fred Schlechter, Grant Taylor, Gordon Tetlow, and Fraser Tweedale, here’s to you.

Lilith Saintcrow convinced me that The Princess Bride could be a useful motif for a serious technology book. This book was written during the 2020 pandemic, so I must also thank The Princess Bride for providing me a desperately needed sense of hope.

Dan Langille gracefully submitted to the pillaging of his blog for useful hints and guidance. I am grateful that JP Mens, Evan Hunt, and John-Mark Gurney provoked him into updating that blog and saving me a bunch of work.

I am unsure if I should profusely thank Bob Beck for his time and patience in revealing the innards of TLS, or profoundly curse him and his spawn unto the seventh generation. I must acknowledge the usefulness of “Happy Bob’s Test CA,” however, so I’ll raise a glass to that while waffling over whether or not the bottle of fair-to-middlin’ wine I owe him should be laced with iocane powder.

For Liz.

Again, to all the tech reviewers and Patronizers and sponsors: thank you. This book would not exist without you.

Online SNMP Talk Tomorrow Night

Late notice, but I have a brain like a stainless steel sponge.

Tomorrow night, 9 June 2020, I’ll be giving an SNMP talk at the mug.org meeting. The meeting starts at 6:30EDT or 22:30UTC, but they have to get through their usual meeting work before they unleash me.

The talk is, of course, based on SNMP Mastery. Or the Networknomicon. Whichever.

Put on your pajamas. Show up. Listen to the my frenetic babble. There will not be prizes, because I can’t throw them at people.

Restore Woocommerce Users from Backup

(This post is for sysadmins. If you use WooCommerce but aren’t a sysadmin, it won’t help you. I can’t help you either. Sorry.)

I use WooCommerce on my bookstore. It’s built on top of WordPress and, as such, attracts spam users. About 40,000 of them since I opened it. The last time I investigated performance problems, I installed Bulk WP Delete to get rid of them. From everything I saw, it would only remove the spam users and leave the customers unaffected.

I was wrong. A small percentage of customers lost their accounts.

I took a backup of the database before purging the spam users, because I’m not a complete idiot. And I kept it close at hand.

If you accidentally blow away user accounts you need, and want to restore them without touching the rest of your database, you can. I used the command line. You can probably do the same using whatever pointy-clicky tool you like, but don’t ask me for help–I don’t know how to use them. Talk to your sysadmin.

The first step is to take a backup of your database. Make sure it’s a good backup, and keep it close at hand. If you screw up, you’ll need it.

I created a VM on my desktop, installed MariaDB, and restored the pre-purge database on that VM. Check the name of your Woocommerce database. Mine is named rapacity, because that’s why I run my own bookstore.

When a user tells you that their account is missing, get the email address they used to create their account. My example user is joe@bucketsofmoney.com.

On your VM, extract the user’s account information to a file.

# mysqldump --user=root -p rapacity wp_users --where='user_email="joe@bucketsofmoney.com"' --skip-add-drop-table --no-create-info > bucketsofmoney.wp_users

Go into the file and look for the user description.

INSERT INTO `wp_users` VALUES (3185...

The first number is user ID. Grab that user’s metadata.

# mysqldump --user=root -p rapacity wp_usermeta --where='user_id=3185' --skip-add-drop-table --no-create-info > bucketsofmoney.wp_usermeta

Copy these two files to your web server. Log into the web server,

MariaDB [(none)]> use rapacity;
MariaDB [rapacity]> source bucketsofmoney.wp_users;
MariaDB [rapacity]> source bucketsofmoney.wp_usermeta;

Now log into the WooCommerce interface and go to Users. Search for that account. Switch the user’s role to Customer.

The user now exists, but their existing orders are disassociated from their account. Go to the Woocommerce page, then Reports, and hit the Customers report. Under the “All Customers” tab, search for the restored account. Over on the right side, one of the buttons will give the option to reconnect previous orders to the account. That button doesn’t appear unless there are previous orders. Hit it.

The account is now restored.

If you screw up and fry the existing database, restore from backup:

# mysql -u root -p --one-database rapacity < mysql-backup-2019-03-23

As you might guess, this blog is mostly for my own later reference.

And the next time I have to delete spam users, I plan to just go into the database and drop every user who has never ordered anything. Forget plugins.

How did I solve the performance issues? My new web site has more images per page, especially the fancy new front page. Installing “WP Super Cache” dramatically improved everything.

MS Word auto-recovery files and Dictation

Today, I learned about Microsoft Word auto-recovery files.

If Microsoft Word crashes and can’t auto-recover the document, find the autosave file. The location is given in File->Options->Save. Sort the directory by date, and your autosave should be at or near the top. The file name ends in .asd. Copy that file elsewhere and open it in Wordpad.

Your text will be therein, stripped of all formatting but present.

In related news: I’m trying dictation. I know several authors who produce several thousand words per hour with dictation. I would like to produce several thousand words per hour.

Seemingly unrelated fact: I habitually hit the “save” button after typing every sentence. Note the key word: typing.

In more related news: installing Dragon 15 has made Microsoft Word lock up three times today. The third time, it couldn’t auto-recover the lost text.

And I hadn’t even thought about saving. Because I automatically hit “save” every sentence.

Beware your habits. They will cause you pain when you change.

Also: computers are terrible. I need a stenographer. Who understands MS Word styles.

Penguicon 2017 Schedule

Next weekend, April 28-30 2017, I’ll be at Penguicon. Two weekends after that (12-14 May), I’ll be at Kansas LinuxFest. But we’re on Penguicon right now.

Here’s my events and the description for each. Each is 1 hour unless specified otherwise. And I’m asking your help for some of these events. (Updated to add the LN2 events, which I’m not running but a guy has to eat sometime.)

Friday:
8PM: LN2 Ice Cream
9PM: The OpenBSD Web Stack – OpenBSD is best known for security and networking. But they also have a highly secure web server and load balancer. This talk will take you through the OpenBSD web stack, presenting its strengths and disadvantages. We’ll cover the httpd web server, free globally valid SSL certificates through ACME, the Common Address Redundancy Protocol for two-server clusters, and the relayd load balancer. Many of the security issues common on web servers are simply not an issue on OpenBSD. Come find out why!

Saturday:
9 AM: Writers and Traditional Publishing – So you want to sell a book to a publisher. How do you do that? What should you expect? How do you optimize your chances of getting not just a deal, but the deal you want? What gets some people into traditional publishing, and keeps others out? Come hear authors discuss the good and bad of the publishing biz!

10-11:45AM: Author Meet & Read, Vol. 1 – A big room with Clif Flynt, Mary Lynne Gibbs, Jen Haeger, Christian Klaver, James Frederick Leach, David Erik Nelson, John Scalzi, Clarence Young, and myself, all showing off our books, talking to our readers, and signing books. I will have my books still in print for sale. I’m expecting that the others will all have long lines and I’ll be there alone, so this is your chance to heckle me in person.

10:54-11:03AM: reading from git commit murder – Readings are tightly scheduled, so I expect this to begin and end sharply on time.

1PM: self publishing in 2017 – Self-publishing is an increasingly important channel for authors to reach their readers. It also changes constantly, with new tools and distributors opening daily and existing platforms changing. This panel brings together veteran self-publishers to share their experiences, discuss the changes of the last year, and give new authors an edge in the business.

2PM: 90 second reads – Join a handful of Penguicon authors as they read 90-second passages from their novels. The selections will be thematically linked based on keywords, such as sorrow, fury, funny, love, etc. Timing is crucial! After, there will be a Q&A with the authors.

3PM: LN2 ice cream

5PM: Writing High-Performance Nonfiction – Writing nonfiction is not merely reciting facts. It’s a specialized form of storytelling, very different from your college essays and book reports. Whether you’re writing memoirs or computer texts, using storytelling techniques transforms your work for the better. This talk takes you through making your nonfiction not only readable, but memorable.

7PM: BSD Operating Systems in 2017 – I’ll be discussing the current options in BSD-based operating systems, the big news from recent projects, new developments, and where we’re going from here.

8-10PM: LN2 ice cream

Sunday:

10AM: breakfast – LN2 ice cream

11AM: Senior Sysadmin Panel – Storage – The years know things that the days and weeks never know. We’ve gathered half a dozen people who’ve been sysadmins for over 20 years to talk about the one of the most dreaded and annoying topics in computing: storage.

12PM: Self-Promotion for Creatives – Independent creators are their own PR departments. We have to not only make all the things, we have to spread the word about all the things. Here we have a bunch of artists and writer types who successfully spread their work across the world. What works? What doesn’t? How can you be shamelessly self-promoting without being a jerk? Come find out!

Where could I use help?

In the 90 second reads panel, I get a few 90 second periods to read a selection from my fiction. Each read should have a theme. Our group has four themes: Betrayal, Heartbreaking, Scary, Funny.

For those of you who have read my fiction: I could use suggestions for parts of my books that you thought fit these themes. I have a few thoughts, but what I think fits a theme is probably not what struck you lot as fitting that theme.

So: if you’ve read my fiction, what of mine would you suggest for a brief reading in any or all of those themes?