On Tue, Feb 23, 2021 at 07:07:34AM -0500, Ashton Fagg wrote:
> Claudio Jeker <[email protected]> writes:
>
> > Looking at the screenshot it seems there is a timing issue. The fsck -N
> > tries to run before the disk was actually attached. I guess the iscsid
> > startup script should wait to ensure the disks are ready.
> > You could probably add a 'sleep 5' to rc_start() in /etc/rc.d/iscsid and
> > see if that helps. Ideally iscsictl should actually do the wait or fail.
>
> I took a bit of a look through the code, and I've worked out an
> (untested, beyond building) patch. I'll be able to try it later today
> probably, but wondering if this looks reasonable?
>
> Unless I misunderstand, it looks like what's happening is that
> /dev/vscsi0 isn't ready when iscsid calls vscsi_open(). My proposed fix
> is to add a wait loop to this (try 3 times, waiting 5 seconds between
> each attempt).
>
> I'll try it tonight once I can reboot the machine.
>
I'm not sure. vscsi(4) is ready the moment the kernel starts init. So it
should not result in any problem for iscsid. What made you think this is
the issue?
My assumption is that the initial exchange to get the iscsi session going
with the target just takes a bit longer than the rc script takes to do the
fsck. Because of this I think a sleep may be a quick fix.
A proper fix would be to block iscsictl until the configured session is
up. The tricky bit is that at some point a timeout needs to trigger in
case the target is unavailable.
> diff --git a/usr.sbin/iscsid/vscsi.c b/usr.sbin/iscsid/vscsi.c
> index dc8d5ed67e0..25f3feba6ff 100644
> --- a/usr.sbin/iscsid/vscsi.c
> +++ b/usr.sbin/iscsid/vscsi.c
> @@ -29,6 +29,7 @@
> #include <fcntl.h>
> #include <stdlib.h>
> #include <string.h>
> +#include <unistd.h>
>
> #include "iscsid.h"
> #include "log.h"
> @@ -52,11 +53,30 @@ void vscsi_fail(void *arg);
> void vscsi_dataout(struct connection *, struct scsi_task *, u_int32_t,
> size_t, size_t);
>
> +#define VSCSI_OPEN_WAIT 5
> +#define VSCSI_OPEN_TRIES 3
> +
> void
> vscsi_open(char *dev)
> {
> - if ((v.fd = open(dev, O_RDWR)) == -1)
> - fatal("vscsi_open");
> + /* Sometimes, it seems we try to open before this is ready.
> + This builds in a little tolerance to that. */
> + int tries;
> +
> + for (tries = 1; tries <= VSCSI_OPEN_TRIES; ++tries) {
> + if ((v.fd = open(dev, O_RDWR)) == -1) {
> + /* We can't try again, so fail. */
> + if (tries == VSCSI_OPEN_TRIES)
> + fatal("vscsi_open");
> + log_debug("vscsi_open: waiting...");
> + sleep(VSCSI_OPEN_WAIT);
> + } else {
> + /* That worked, so we're good! */
> + log_debug("vscsci_open: successful");
> + break;
> + }
> + }
> +
>
> event_set(&v.ev, v.fd, EV_READ|EV_PERSIST, vscsi_dispatch, NULL);
> event_add(&v.ev, NULL);
--
:wq Claudio