[libvirt] [PATCH]: Give /dev/disk/by-{id,path} a chance to exist

Daniel P. Berrange berrange at redhat.com
Wed Nov 26 10:24:08 UTC 2008


On Tue, Nov 25, 2008 at 04:15:05PM +0100, Chris Lalancette wrote:
> All,
>     When refreshing a storage pool (say, an iSCSI pool), one of the things it
> does is to generate the stable path for each of the LUNs via
> virStorageBackendStablePath.  That, in turn, has the following code:


> Index: src/storage_backend.c
> ===================================================================
> RCS file: /data/cvs/libvirt/src/storage_backend.c,v
> retrieving revision 1.29
> diff -u -r1.29 storage_backend.c
> --- a/src/storage_backend.c	17 Nov 2008 11:19:33 -0000	1.29
> +++ b/src/storage_backend.c	25 Nov 2008 15:14:20 -0000
> @@ -291,6 +291,7 @@
>      DIR *dh;
>      struct dirent *dent;
>      char *stablepath;
> +    int opentries;
>  
>      /* Short circuit if pool has no target, or if its /dev */
>      if (pool->def->target.path == NULL ||
> @@ -304,19 +305,33 @@
>      if (!STRPREFIX(pool->def->target.path, "/dev"))
>          goto ret_strdup;
>  
> -    /* The pool is pointing somewhere like /dev/disk/by-path
> -     * or /dev/disk/by-id, so we need to check all symlinks in
> -     * the target directory and figure out which one points
> -     * to this device node
> +    /* We loop here because /dev/disk/by-{id,path} may not have existed
> +     * before we started this operation, so we have to give it some time to
> +     * get created.
>       */
> -    if ((dh = opendir(pool->def->target.path)) == NULL) {
> +    dh = NULL;
> +    opentries = 0;
> +    while (opentries < 50) {
> +        if ((dh = opendir(pool->def->target.path)) != NULL)
> +            break;
> +
> +        usleep(100 * 1000);
> +        opentries++;
> +    }

Just as stylist thing - in most other places in storage code where we
retry operations we use a different code pattern - I'd prefer to keep
things consistent in this regard, so closer to this:

   reopen:
       if ((dh = opendir(pool->def->target.path) == NULL) {
           if (errno == ENOENT && opentries++ < 50)
                 usleep(100 * 1000);
                 goto reopen;
           }
           virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
                                _("cannot read dir %s: %s"),
                                pool->def->target.path,
                                strerror(errno));
          return NULL;
      }

Daniel
-- 
|: Red Hat, Engineering, London   -o-   http://people.redhat.com/berrange/ :|
|: http://libvirt.org  -o-  http://virt-manager.org  -o-  http://ovirt.org :|
|: http://autobuild.org       -o-         http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505  -o-  F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|




More information about the libvir-list mailing list