hfsplus, hfsprogs, hfsplus-tools

What is needed to format SSD as hfsplus and to access (rw) hfsplus and fsck.hfsplus file system on an external usb3 connected SSD device (docking station)?

It seems that ‘yast2 partitioner’ doesn’t support hfsplus, but probably gparted can do it.

It seems that basic hfsplus support should be available in the kernel
https://www.kernel.org/doc/html/latest/filesystems/hfsplus.html

without specifying the kernel version?

Leap 15.3

uname -r
5.3.18-59.37-default

An automounted SSD in my case:

df -Th /dev/sdj1
Filesystem     Type     Size  Used Avail Use% Mounted on
/dev/sdj1      hfsplus  477G  387M  477G   1% /run/media/terje/untitled

The only ‘hfs’ packages I’ve found for Leap 15.3 is ‘hfsutils’ v. 3,2,6 and ‘xhfsutil’ (front-end), but it seems to be for the previous hfs file system and not for hfsplus?

What about 'hfsprogs, and ‘hfsplus-tools’ packages for Debian and Fedora, isn’t there available and need for a corresponding packages for Leap 15.3?

But, it doesn’t seem to be included in the current openSUSE Leap 15.3 kernel –

  • “cat /proc/filesystems” and upper/lowercase search for “hfs” – it ain’t there …
  • Ditto in the “filesystems” man page …

Wikipedia does supply some clues as to what is going on – <HFS Plus - Wikipedia; –

  • You may have to contact the Paragon Software Group for the commercial HFS Plus driver …

The output results I’ve got on Leap 15.3 looks confusing and not consistently as far as I understand:

This repeated df command say type ‘hfsplus’

df -Th /dev/sdj1 
Filesystem     Type     Size  Used Avail Use% Mounted on 
/dev/sdj1      hfsplus  477G  387M  477G   1% /run/media/terje/untitled

The mount man page contains no ‘hfsplus’, just ‘hfs’:

man mount | grep hfsplus 

man mount | grep hfs 
              ple  'fuse.sshfs'.  It's recommended to use subtype  notation rather than add any prefix  to  the  mount  source  (for 
              example 'sshfs#example.com' is deprecated). 
   Mount options for hfs 
              mksquashfs /etc /tmp/etc.squashfs 
              veritysetup format /tmp/etc.squashfs /tmp/etc.hash 
              verity.roothashsig=/tmp/etc.p7 /tmp/etc.squashfs /mnt 
       create  squashfs image from /etc directory, verity hash device  and mount verified filesystem image to /mnt.  The kernel will 
       option is used for filesystems with subtypes support (for  example /sbin/mount.fuse -t fuse.sshfs). 

And the mount command has had output ‘hfsplus’ with both (rw…) and (ro…)?

mount | grep hfs 
/dev/sdj1 on /run/media/terje/untitled type hfsplus  (rw,nosuid,nodev,relatime,umask=22,uid=1000,gid=100,nls=utf8,uhelper=udisks2)

mount | grep hfs 
/dev/sdj1 on /run/media/terje/untitled type hfsplus (ro,nosuid,nodev,relatime,umask=22,uid=1000,gid=100,nls=utf8,uhelper=udisks2)

** I was able to delete (rm) some visible ‘empty’ files on the hfs(plus) file system disk earlier to-day!**

/etc/filesystems contains ‘hfs’, not ‘hfsplus’

cat /etc/filesystems 
vfat 
hfs 
minix 
reiserfs 
exfat 
exfat_fuse 
* 

I guess you know it yourself - it is not.

need for a corresponding packages for Leap 15.3?

Personally I never needed to format HFS or HFS+, and I suspect I am now alone. As usual you have two options - find someone who is willing to do the job for you or try to compile it yourself. You can start with Show home:nuklly / hfsprogs - openSUSE Build Service and try to build it for Leap 15.3.

But I find ‘hfsplus’

cat /proc/filesystems | grep hfs
    hfsplus

Well, I formatted the actual SSD with Gparted in 2016 on openSUSE Leap 42.1
https://forums.opensuse.org/showthread.php/513850-HFS-and-exFAT-support-for-usb-SSDs-on-Leap-42-1

Now I will need several more SSD disks with hfsplus file systems to record uncompressed video, and where I want do post processing on Linux
https://download.opensuse.org/repositories/home:/nuklly/openSUSE_Tumbleweed/

fsck.hfsplus /dev/sdj1 
** /dev/sdj1 
** Checking HFS Plus volume. 
** Checking Extents Overflow file. 
** Checking Catalog file. 
** Checking Catalog hierarchy. 
** Checking Extended Attributes file. 
** Checking volume bitmap. 
** Checking volume information. 
** The volume untitled appears to be OK. 

You’re not wrong –


 > LANG=C ls -l /lib/modules/5.3.18-59.37-default/kernel/fs/hfsplus/
total 52
-rw-r--r-- 1 root root 52724 Nov 24 07:14 hfsplus.ko.xz
 > 

Maybe, someone has executed “modprobe hfsplus” on your system.

  • And, added “hfs
    ” to the ‘/etc/filesystems’ file supplied by the “util-linux” package … That’s OK – I add “exfat” to that file – and, try to remember that, I need to re-edit that file if and when the “util-linux” package changes …
    *=2]Your administrator should change the “hfs” entry in that file to “hfsplus” …

‘/etc/filesystems’ is read by “mount” if, the “-t” option isn’t present – if the last line (entry) in that file is the character “*”, “mount” then goes looking in ‘/proc/filesystems’ for the filesystem type …

  • The filesystems supported by any given Kernel are located in ‘/lib/modules/$(uname -r)/kernel/fs/’ …

This is on one of my home workstations, where I’m the admin myself. I had gparted and hfsutils installed already on Leap 42.1 in 2016. Later on there have been online upgrades or from dvd media; possibly I had to replace the root file system with a new installation somewhere for Leap 15.x.

Related packages installed on 15.3 now are:


zypper se -is hfs util-linux gparted
Loading repository data...
Reading installed packages...

S  | Name               | Type    | Version           | Arch   | Repository
---+--------------------+---------+-------------------+--------+-------------------------------------------------------------
i+ | gparted            | package | 0.31.0-bp153.1.17 | x86_64 | Main Repository
i+ | gparted-lang       | package | 0.31.0-bp153.1.17 | noarch | Main Repository
i+ | hfsutils           | package | 3.2.6-2.20        | x86_64 | Main Repository
i+ | sshfs              | package | 2.9-bp153.1.15    | x86_64 | Main Repository
i  | util-linux         | package | 2.36.2-4.5.1      | x86_64 | Update repository with updates from SUSE Linux Enterprise 15
i  | util-linux-lang    | package | 2.36.2-4.5.1      | noarch | Update repository with updates from SUSE Linux Enterprise 15
i  | util-linux-systemd | package | 2.36.2-4.5.1      | x86_64 | Update repository with updates from SUSE Linux Enterprise 15
i+ | xhfsutil           | package | 3.2.6-2.20        | x86_64 | Main Repository


zypper info --requires gparted | grep hfs
    hfsutils


zypper se -is --provides hfs
Loading repository data...
Reading installed packages...

S  | Name             | Type    | Version           | Arch   | Repository
---+------------------+---------+-------------------+--------+-------------------------------------------------------------
i+ | hfsutils         | package | 3.2.6-2.20        | x86_64 | Main Repository
i+ | kernel-default   | package | 5.3.18-59.37.2    | x86_64 | Update repository with updates from SUSE Linux Enterprise 15
i+ | openSUSE-release | package | 15.3-lp1532.157.1 | x86_64 | Hovedpakkebrønn for oppdateringer
i+ | sshfs            | package | 2.9-bp153.1.15    | x86_64 | Main Repository
i+ | xhfsutil         | package | 3.2.6-2.20        | x86_64 | Main Repository


zypper se -is --provides hfsplus
Loading repository data...
Reading installed packages...

S  | Name           | Type    | Version        | Arch   | Repository
---+----------------+---------+----------------+--------+-------------------------------------------------------------
i+ | kernel-default | package | 5.3.18-59.37.2 | x86_64 | Update repository with updates from SUSE Linux Enterprise 15

‘/etc/filesystems’ is read by “mount” if, the “-t” option isn’t present – if the last line (entry) in that file is the character “*”, “mount” then goes looking in ‘/proc/filesystems’ for the filesystem type …

  • The filesystems supported by any given Kernel are located in ‘/lib/modules/$(uname -r)/kernel/fs/’ …

OK, thanks.

But the hfsplus external SSD is automounted Read only and it seems like I cannot get it ReadWrite accessible longer either:
https://forums.opensuse.org/showthread.php/565363-hfsplus-hfsprogs-hfsplus-tools?p=3099970#post3099970

while I got it ReadWrite accessible previously on Leap 42.1:
https://forums.opensuse.org/showthread.php/513850-HFS-and-exFAT-support-for-usb-SSDs-on-Leap-42-1?p=2758790#post2758790

# df /dev/sdj1
Filesystem     1K-blocks   Used Available Use% Mounted on
/dev/sdj1      500106240 396200 499710040   1% /run/media/terje/untitled

# ls -la /run/media/terje/untitled
total 0
drwxr-xr-x  1 root root  3 Jan 18 00:58 .
drwxr-x---+ 4 root root 80 Jan 23 13:22 ..

# chgrp -R users /run/media/terje/untitled
chgrp: changing group of '/run/media/terje/untitled': Read-only file system

# chmod -R 775 /run/media/terje/untitled
chmod: changing permissions of '/run/media/terje/untitled': Read-only file system

# cd /run/media/terje/untitled
# touch test2
touch: cannot touch 'test2': Read-only file system

How can I get the hfsplus SSD mounted and preferably automounted with ReadWrite access?

Please first show** if** it is mounted ro.

mount | grep terje

Then check if there are any messages during mounting that explain why it is read-only. e/g/ by mounting from the terminal (it must be unmounted at that moment of course, either by the desktop or with the umount command).

mount | grep terje
/dev/sdd1 on /run/media/terje/Seagate_4TB_back type ext4 (rw,nosuid,nodev,relatime,stripe=8191,uhelper=udisks2)
/dev/sdj1 on /run/media/terje/untitled type hfsplus (ro,nosuid,nodev,relatime,umask=22,uid=1000,gid=100,nls=utf8,uhelper=udisks2)

mount | grep hfs 
/dev/sdj1 on /run/media/terje/untitled type hfsplus (ro,nosuid,nodev,relatime,umask=22,uid=1000,gid=100,nls=utf8,uhelper=udisks2)

Then check if there are any messages during mounting that explain why it is read-only. e/g/ by mounting from the terminal (it must be unmounted at that moment of course, either by the desktop or with the umount command).

I tried to force rw without success. No error messages. On Superuser.com some said Journaling had to be disabled, other said it was not possible. On Leap 42.1 it seemed diskdev_cmds had to be installed, diskdev_cmds isnt’t available for 15.3, but I tested it on Tumbleweed witthout success with regards to rw access on hfsplus.

# umount /dev/sdj1

# mount /dev/sdj1
mount: /dev/sdj1: can't find in /etc/fstab.

# mount /dev/sdj1 /mnt

# mount | grep hfs 
/dev/sdj1 on /mnt type hfsplus (ro,relatime,umask=22,uid=0,gid=0,nls=utf8)

# umount /dev/sdj1

# mount -t hfsplus -o force,rw /dev/sdj1 /mnt

# mount | grep hfs 
/dev/sdj1 on /mnt type hfsplus (ro,relatime,umask=22,uid=0,gid=0,nls=utf8)

# mount -t hfsplus -o remount,force,rw /dev/sdj1 /mnt

# mount | grep hfs 
/dev/sdj1 on /mnt type hfsplus (ro,relatime,umask=22,uid=0,gid=0,nls=utf8)

# df -h /mnt
Filesystem      Size  Used Avail Use% Mounted on
/dev/sdj1       477G  387M  477G   1% /mnt

# cd /mnt

localhost:/mnt # ls -ld
drwxr-xr-x 1 root root 3 Jan 18 00:58 .

# touch test2
touch: cannot touch 'test2': Read-only file system

It is ro indeed.

Again ro. But no message to be seen. Maybe you should trace the log.
In one terminal (as root) do

journalctl -f

this will show new log entries as they occur. Then in another terminal (as root) do the mount again.
The first terminal you can stop the program with Ctrl-C. Post the relevant logging lines.

I crossposted (edited) a few comments in my previous post.

The journaling log below. The first mount (similar automount) and unmount was executed with the Gnome file manager.
Then further commands as follows in a second terminal:

localhost:~ # mount -t hfsplus -o force,rw /dev/sdj1 /mnt
localhost:~ # mount | grep hfs 
/dev/sdj1 on /mnt type hfsplus (ro,relatime,umask=22,uid=0,gid=0,nls=utf8)
localhost:~ # 
localhost:~ # mount -t hfsplus -o remount,force,rw /dev/sdj1 /mnt
localhost:~ # mount | grep hfs 
/dev/sdj1 on /mnt type hfsplus (ro,relatime,umask=22,uid=0,gid=0,nls=utf8)
localhost:~ # journalctl -f
-- Logs begin at Sun 2022-01-23 13:22:08 CET. --
Jan 23 16:00:36 localhost.localdomain su[6837]: The gnome keyring socket is not owned with the same credentials as the user login: /run/user/1000/keyring/control
Jan 23 16:00:36 localhost.localdomain su[6837]: gkr-pam: couldn't unlock the login keyring.
Jan 23 16:00:36 localhost.localdomain su[6837]: (to root) terje on pts/1
Jan 23 16:00:36 localhost.localdomain systemd[1]: Started Timeline of Snapper Snapshots.
Jan 23 16:00:36 localhost.localdomain su[6837]: pam_unix(su-l:session): session opened for user root by (uid=1000)
Jan 23 16:00:36 localhost.localdomain dbus-daemon[908]: [system] Activating via systemd: service name='org.opensuse.Snapper' unit='snapperd.service' requested by ':1.148' (uid=0 pid=6840 comm="/usr/lib/snapper/systemd-helper --timeline ")
Jan 23 16:00:36 localhost.localdomain systemd[1]: Starting DBus interface for snapper...
Jan 23 16:00:36 localhost.localdomain dbus-daemon[908]: [system] Successfully activated service 'org.opensuse.Snapper'
Jan 23 16:00:36 localhost.localdomain systemd[1]: Started DBus interface for snapper.
Jan 23 16:00:36 localhost.localdomain systemd[1]: snapper-timeline.service: Succeeded.
Jan 23 16:00:43 localhost.localdomain /usr/lib/gdm/gdm-x-session[2041]: -2
Jan 23 16:00:52 localhost.localdomain /usr/lib/gdm/gdm-x-session[2041]: -2
Jan 23 16:01:00 localhost.localdomain /usr/lib/gdm/gdm-x-session[2041]: -2
Jan 23 16:01:11 localhost.localdomain kernel: hfsplus: Filesystem was not cleanly unmounted, running fsck.hfsplus is recommended.  mounting read-only.
Jan 23 16:01:11 localhost.localdomain udisksd[2225]: Mounted /dev/sdj1 at /run/media/terje/untitled on behalf of uid 1000
Jan 23 16:01:11 localhost.localdomain dbus-daemon[2049]: [session uid=1000 pid=2049] Activating via systemd: service name='org.freedesktop.Tracker1' unit='tracker-store.service' requested by ':1.47' (uid=1000 pid=2354 comm="/usr/lib/tracker-miner-fs ")
Jan 23 16:01:11 localhost.localdomain systemd[2021]: Starting Tracker metadata database store and lookup manager...
Jan 23 16:01:11 localhost.localdomain dbus-daemon[908]: [system] Activating via systemd: service name='org.freedesktop.hostname1' unit='dbus-org.freedesktop.hostname1.service' requested by ':1.50' (uid=1000 pid=2168 comm="/usr/bin/gnome-shell ")
Jan 23 16:01:11 localhost.localdomain systemd[1]: Starting Hostname Service...
Jan 23 16:01:11 localhost.localdomain dbus-daemon[2049]: [session uid=1000 pid=2049] Successfully activated service 'org.freedesktop.Tracker1'
Jan 23 16:01:11 localhost.localdomain systemd[2021]: Started Tracker metadata database store and lookup manager.
Jan 23 16:01:11 localhost.localdomain nautilus[4992]: gtk_widget_set_visible: assertion 'GTK_IS_WIDGET (widget)' failed
Jan 23 16:01:11 localhost.localdomain dbus-daemon[2049]: [session uid=1000 pid=2049] Activating service name='org.gnome.Shell.HotplugSniffer' requested by ':1.18' (uid=1000 pid=2168 comm="/usr/bin/gnome-shell ")
Jan 23 16:01:11 localhost.localdomain dbus-daemon[2049]: [session uid=1000 pid=2049] Successfully activated service 'org.gnome.Shell.HotplugSniffer'
Jan 23 16:01:11 localhost.localdomain tracker-store[6903]: tracker_writeback_transact: assertion 'private == NULL' failed
Jan 23 16:01:12 localhost.localdomain dbus-daemon[908]: [system] Successfully activated service 'org.freedesktop.hostname1'
Jan 23 16:01:12 localhost.localdomain systemd[1]: Started Hostname Service.
Jan 23 16:01:36 localhost.localdomain systemd[1]: snapperd.service: Succeeded.
Jan 23 16:01:41 localhost.localdomain tracker-store[6903]: OK
Jan 23 16:01:41 localhost.localdomain systemd[2021]: tracker-store.service: Succeeded.
Jan 23 16:01:42 localhost.localdomain systemd[1]: systemd-hostnamed.service: Succeeded.
Jan 23 16:01:52 localhost.localdomain dbus-daemon[2049]: [session uid=1000 pid=2049] Activating via systemd: service name='org.freedesktop.Tracker1' unit='tracker-store.service' requested by ':1.47' (uid=1000 pid=2354 comm="/usr/lib/tracker-miner-fs ")
Jan 23 16:01:52 localhost.localdomain systemd[2021]: Starting Tracker metadata database store and lookup manager...
Jan 23 16:01:52 localhost.localdomain systemd[2021]: run-media-terje-untitled.mount: Succeeded.
Jan 23 16:01:52 localhost.localdomain systemd[1]: run-media-terje-untitled.mount: Succeeded.
Jan 23 16:01:52 localhost.localdomain udisksd[2225]: Cleaning up mount point /run/media/terje/untitled (device 8:145 is not mounted)
Jan 23 16:01:52 localhost.localdomain udisksd[2225]: Unmounted /dev/sdj1 on behalf of uid 1000
Jan 23 16:01:52 localhost.localdomain dbus-daemon[908]: [system] Activating via systemd: service name='org.freedesktop.hostname1' unit='dbus-org.freedesktop.hostname1.service' requested by ':1.50' (uid=1000 pid=2168 comm="/usr/bin/gnome-shell ")
Jan 23 16:01:52 localhost.localdomain systemd[1]: Starting Hostname Service...
Jan 23 16:01:52 localhost.localdomain dbus-daemon[2049]: [session uid=1000 pid=2049] Successfully activated service 'org.freedesktop.Tracker1'
Jan 23 16:01:52 localhost.localdomain systemd[2021]: Started Tracker metadata database store and lookup manager.
Jan 23 16:01:52 localhost.localdomain tracker-store[6941]: tracker_writeback_transact: assertion 'private == NULL' failed
Jan 23 16:01:52 localhost.localdomain /usr/lib/gdm/gdm-x-session[2041]: -2
Jan 23 16:01:52 localhost.localdomain dbus-daemon[908]: [system] Successfully activated service 'org.freedesktop.hostname1'
Jan 23 16:01:52 localhost.localdomain systemd[1]: Started Hostname Service.
Jan 23 16:01:53 localhost.localdomain nautilus[4992]: Called "net usershare info" but it failed: 'net usershare' returned error 255: net usershare: usershares are currently disabled
Jan 23 16:02:19 localhost.localdomain systemd[2021]: Started Application launched by gnome-shell.
Jan 23 16:02:19 localhost.localdomain gnome-shell[6971]: # _g_io_module_get_default: Found default implementation dconf (DConfSettingsBackend) for ‘gsettings-backend’
Jan 23 16:02:19 localhost.localdomain gnome-shell[6971]: # watch_fast: "/com/canonical/unity-gtk-module/" (establishing: 0, active: 0)
Jan 23 16:02:19 localhost.localdomain gnome-shell[6971]: # unwatch_fast: "/com/canonical/unity-gtk-module/" (active: 0, establishing: 1)
Jan 23 16:02:19 localhost.localdomain gnome-shell[6971]: # watch_established: "/com/canonical/unity-gtk-module/" (establishing: 0)
Jan 23 16:02:19 localhost.localdomain gnome-shell[6971]: # _g_io_module_get_default: Found default implementation gvfs (GDaemonVfs) for ‘gio-vfs’
Jan 23 16:02:19 localhost.localdomain gnome-shell[6971]: # watch_fast: "/org/gnome/terminal/legacy/" (establishing: 0, active: 0)
Jan 23 16:02:19 localhost.localdomain gnome-shell[6971]: # unwatch_fast: "/org/gnome/terminal/legacy/" (active: 0, establishing: 1)
Jan 23 16:02:19 localhost.localdomain gnome-shell[6971]: # watch_established: "/org/gnome/terminal/legacy/" (establishing: 0)
Jan 23 16:02:19 localhost.localdomain systemd[2021]: gnome-launched-org.gnome.Terminal.desktop-6971.scope: Succeeded.
Jan 23 16:02:22 localhost.localdomain tracker-store[6941]: OK
Jan 23 16:02:22 localhost.localdomain systemd[2021]: tracker-store.service: Succeeded.
Jan 23 16:02:23 localhost.localdomain systemd[1]: systemd-hostnamed.service: Succeeded.
Jan 23 16:02:32 localhost.localdomain su[7011]: The gnome keyring socket is not owned with the same credentials as the user login: /run/user/1000/keyring/control
Jan 23 16:02:32 localhost.localdomain su[7011]: gkr-pam: couldn't unlock the login keyring.
Jan 23 16:02:32 localhost.localdomain su[7011]: (to root) terje on pts/2
Jan 23 16:02:32 localhost.localdomain su[7011]: pam_unix(su-l:session): session opened for user root by (uid=1000)
Jan 23 16:03:30 localhost.localdomain kernel: hfsplus: Filesystem was not cleanly unmounted, running fsck.hfsplus is recommended.  mounting read-only.
Jan 23 16:03:30 localhost.localdomain dbus-daemon[908]: [system] Activating via systemd: service name='org.freedesktop.hostname1' unit='dbus-org.freedesktop.hostname1.service' requested by ':1.50' (uid=1000 pid=2168 comm="/usr/bin/gnome-shell ")
Jan 23 16:03:30 localhost.localdomain systemd[1]: Starting Hostname Service...
Jan 23 16:03:30 localhost.localdomain dbus-daemon[908]: [system] Successfully activated service 'org.freedesktop.hostname1'
Jan 23 16:03:30 localhost.localdomain systemd[1]: Started Hostname Service.
Jan 23 16:04:00 localhost.localdomain systemd[1]: systemd-hostnamed.service: Succeeded.
Jan 23 16:04:03 localhost.localdomain kernel: hfsplus: filesystem was not cleanly unmounted, running fsck.hfsplus is recommended.  leaving read-only.

The recommended fsck.hfsplus is run from Tumbleweed because hfsprogs is not available for Leap 15.3:

# fsck.hfsplus /dev/sdj1
** /dev/sdj1
   Executing fsck_hfs (version 540.1-Linux).
** Checking non-journaled HFS Plus Volume.
   The volume name is untitled
** Checking extents overflow file.
** Checking catalog file.
** Checking multi-linked files.
** Checking catalog hierarchy.
** Checking extended attributes file.
** Checking volume bitmap.
** Checking volume information.
** The volume untitled appears to be OK.

Well, the reason why it is mounted ro is now clear. I do not know what you can not repair it. That might be a hfsplus specific problem, of which I do know nothing.

Possibly one reason is that I may have released the USB3 external mounted SSD from its docking station without unmounting it first with the File manager.

Therefore I would try to reformat the SSd with hfsplus with Gparted as previouly on Leap 42.1, but
It’s too bad that Leap 15.3 lacks ‘hfs+’ support (only ‘hfs’ in Gparted) due too the missing hfsprogs package (not the only missing OBS package for 15.3) :frowning:

Happily hfsprogs is available for Tumbleweed, where I reformatted the SSD with Gparted and hfs+ :wink:

And then the SSD disk again was (auto)mounted with RW access both on Tumbleweed and on Leap 15.3 :slight_smile:


ls -ld /run/media/terje/untitled
    drwxr-xr-x 1 terje users 3 jan.  23 20:15 /run/media/terje/untitled
    
 mount | grep hfs
    /dev/sdj1 on /run/media/terje/untitled type hfsplus (rw,nosuid,nodev,relatime,umask=22,uid=1000,gid=100,nls=utf8,uhelper=udisks2)
    

Well, while it is a bit of a disappointment that the tool isn’t available in 15.3, it is nice that you have a TW to circumvent that.