RE: [PATCH v14 06/10] usbip: exporting devices: modifications to attach and detach

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello,

> > Refactoring to attach and detach operation to reuse common portion to
> > application(vhci)-side daemon.
> >
> > The new application(vhci)-side daemon executes same procedures as
> > attach and detach. Most of common code to access vhci has been
> > implemented in VHCI userspace wrapper(libsrc/vhci_driver.c) but left in
> > attach and detach. With this patch, an accessor of vhci driver and
> > tracking of vhci connections in attach and detach are moved to the VHCI
> > userspace wrapper.
> >
> > Functions to create and delete port status file also moved to the
> > wrapper. Timing to execute these function are corrected to keep
> > consistent with attached status of vhci.
> >
> > Here, attach, detach and application(vhci)-side daemon is EXISTING-5,
> > EXISTING-6 and NEW-1 respectively in diagram below.
> >
> > EXISTING) - invites devices from application(vhci)-side
> >          +------+
> +------------------+
> >  device--+ STUB |                               | application/VHCI |
> >          +------+
> +------------------+
> >          (server)                               (client)
> >  1) # usbipd ... start daemon
> >  = = =
> >  2) # usbip list --local
> >  3) # usbip bind
> >                   <--- list bound devices ---  4) # usbip list --remote
> >                   <--- import a device ------  5) # usbip attach
> >  = = =
> >                      X disconnected            6) # usbip detach
> >  7) usbip unbind
> >
> > NEW) - dedicates devices from device(stub)-side
> >          +------+
> +------------------+
> >  device--+ STUB |                               | application/VHCI |
> >          +------+
> +------------------+
> >          (client)                               (server)
> >                                             1) # usbipa ... start
> daemon
> >  = = =
> >  2) # usbip list --local
> >  3) # usbip connect    --- export a device ------>
> >  = = =
> >  4) # usbip disconnect --- un-export a device --->
> >
> >  Bind and unbind are done in connect and disconnect internally.
> >
> > Signed-off-by: Nobuo Iwata <nobuo.iwata@xxxxxxxxxxxxxxx>
> > ---
> >  tools/usb/usbip/libsrc/vhci_driver.c | 96
> +++++++++++++++++++++++----
> >  tools/usb/usbip/libsrc/vhci_driver.h |  3 +
> >  tools/usb/usbip/src/usbip_attach.c   | 99
> +++++++++-------------------
> >  tools/usb/usbip/src/usbip_detach.c   | 17 ++---
> >  4 files changed, 124 insertions(+), 91 deletions(-)
> >
> > diff --git a/tools/usb/usbip/libsrc/vhci_driver.c
> b/tools/usb/usbip/libsrc/vhci_driver.c
> > index ad92047..5843f43 100644
> > --- a/tools/usb/usbip/libsrc/vhci_driver.c
> > +++ b/tools/usb/usbip/libsrc/vhci_driver.c
> > @@ -7,6 +7,8 @@
> >  #include <limits.h>
> >  #include <netdb.h>
> >  #include <libudev.h>
> > +#include <fcntl.h>
> > +#include <errno.h>
> >  #include "sysfs_utils.h"
> >
> >  #undef  PROGNAME
> > @@ -215,6 +217,25 @@ static int read_record(int rhport, char *host,
> unsigned long host_len,
> >  	return 0;
> >  }
> >
> > +#define OPEN_HC_MODE_FIRST	0
> > +#define OPEN_HC_MODE_REOPEN	1
> > +
> > +static int open_hc_device(int mode)
> > +{
> > +	if (mode == OPEN_HC_MODE_REOPEN)
> > +		udev_device_unref(vhci_driver->hc_device);
> > +
> > +	vhci_driver->hc_device =
> > +
> 	udev_device_new_from_subsystem_sysname(udev_context,
> > +
> USBIP_VHCI_BUS_TYPE,
> > +
> USBIP_VHCI_DRV_NAME);
> > +	if (!vhci_driver->hc_device) {
> > +		err("udev_device_new_from_subsystem_sysname
> failed");
> > +		return -1;
> > +	}
> > +	return 0;
> > +}
> > +
> 
> Please let mi cite my previous email:
> 
> <<<<
> Could you please elaborate why this function takes an argument and why
> you are reopening vhci device while refreshing device list? there is
> nothing about this in commit msg.
> >>>>
> 
> could you please answer?

Sorry, I missed the comment.
For new usbipa daemon, vhci_driver->hc_device life cycle is here,
usbip_vhci_driver_open() : new
usbip_vhci_refresh_device_list() for each request: unref, new
usbip_vhci_driver_close() : unref

In vanilla, usbip_vhci_refresh_device_list() has been defined but not
 used. And it doesn't work because it doesn't have unref, new.

I refactored unref+new as open_hc_device(do_unref_flag) but I didn't
 create close_hc_device().

With your comment, I think it's better to make open_hc_device() as new,
 close_hc_device() as unref and usbip_vhci_refresh_device_list() calls
 close_hc_device() and open_hc_device().

> >  /*
> ----------------------------------------------------------------------
> */
> >
> >  int usbip_vhci_driver_open(void)
> > @@ -227,28 +248,21 @@ int usbip_vhci_driver_open(void)
> >
> >  	vhci_driver = calloc(1, sizeof(struct usbip_vhci_driver));
> >
> > -	/* will be freed in usbip_driver_close() */
> > -	vhci_driver->hc_device =
> > -
> 	udev_device_new_from_subsystem_sysname(udev_context,
> > -
> USBIP_VHCI_BUS_TYPE,
> > -
> USBIP_VHCI_DRV_NAME);
> > -	if (!vhci_driver->hc_device) {
> > -		err("udev_device_new_from_subsystem_sysname
> failed");
> > -		goto err;
> > -	}
> > +	if (open_hc_device(OPEN_HC_MODE_FIRST))
> > +		goto err_free_driver;
> >
> >  	vhci_driver->nports = get_nports();
> >
> >  	dbg("available ports: %d", vhci_driver->nports);
> >
> >  	if (refresh_imported_device_list())
> > -		goto err;
> > +		goto err_unref_device;
> >
> >  	return 0;
> >
> > -err:
> > +err_unref_device:
> >  	udev_device_unref(vhci_driver->hc_device);
> > -
> > +err_free_driver:
> >  	if (vhci_driver)
> >  		free(vhci_driver);
> >
> > @@ -277,7 +291,8 @@ void usbip_vhci_driver_close(void)
> >
> >  int usbip_vhci_refresh_device_list(void)
> >  {
> > -
> > +	if (open_hc_device(OPEN_HC_MODE_REOPEN))
> > +		goto err;
> 
> empty line
> 
> >  	if (refresh_imported_device_list())
> >  		goto err;
> >
> > @@ -409,3 +424,58 @@ int usbip_vhci_imported_device_dump(struct
> usbip_imported_device *idev)
> >
> >  	return 0;
> >  }
> > +
> > +#define MAX_BUFF 100
> > +int usbip_vhci_create_record(char *host, char *port, char *busid, int
> rhport)
> > +{
> > +	int fd;
> > +	char path[PATH_MAX+1];
> > +	char buff[MAX_BUFF+1];
> > +	int ret;
> > +
> > +	ret = mkdir(VHCI_STATE_PATH, 0700);
> > +	if (ret < 0) {
> > +		/* if VHCI_STATE_PATH exists, then it better be a
> directory */
> > +		if (errno == EEXIST) {
> > +			struct stat s;
> > +
> > +			ret = stat(VHCI_STATE_PATH, &s);
> > +			if (ret < 0)
> > +				return -1;
> > +			if (!(s.st_mode & S_IFDIR))
> > +				return -1;
> > +		} else
> > +			return -1;
> > +	}
> > +
> > +	snprintf(path, PATH_MAX, VHCI_STATE_PATH"/port%d", rhport);
> > +
> > +	fd = open(path, O_WRONLY|O_CREAT|O_TRUNC, 0700);
> > +	if (fd < 0)
> > +		return -1;
> > +
> > +	snprintf(buff, MAX_BUFF, "%s %s %s\n",
> > +			host, port, busid);
> 
> if you use snprintf() it would be nice to check the returned value

It's moved from usbip_attach.c: record_connection() but I will fix.

> > +
> > +	ret = write(fd, buff, strlen(buff));
> > +	if (ret != (ssize_t) strlen(buff)) {
> > +		close(fd);
> > +		return -1;
> > +	}
> > +
> > +	close(fd);
> > +
> > +	return 0;
> > +}
> > +
> > +int usbip_vhci_delete_record(int rhport)
> > +{
> > +	char path[PATH_MAX+1];
> > +
> > +	snprintf(path, PATH_MAX, VHCI_STATE_PATH"/port%d", rhport);
> > +
> > +	remove(path);
> > +	rmdir(VHCI_STATE_PATH);
> 
> it would be nice to add a comment here that you don't check the return
> value because it will succeed only when all files had been removed

OK. Thanks!

> > +
> > +	return 0;
> > +}
> > diff --git a/tools/usb/usbip/libsrc/vhci_driver.h
> b/tools/usb/usbip/libsrc/vhci_driver.h
> > index fa2316c..c85988c 100644
> > --- a/tools/usb/usbip/libsrc/vhci_driver.h
> > +++ b/tools/usb/usbip/libsrc/vhci_driver.h
> > @@ -54,6 +54,9 @@ int usbip_vhci_attach_device(uint8_t port, int
> sockfd, uint8_t busnum,
> >
> >  int usbip_vhci_detach_device(uint8_t port);
> >
> > +int usbip_vhci_create_record(char *host, char *port, char *busid, int
> rhport);
> > +int usbip_vhci_delete_record(int rhport);
> > +
> >  int usbip_vhci_imported_device_dump(struct usbip_imported_device
> *idev);
> >
> >  #endif /* __VHCI_DRIVER_H */
> > diff --git a/tools/usb/usbip/src/usbip_attach.c
> b/tools/usb/usbip/src/usbip_attach.c
> > index 695b2e5..17a84ea 100644
> > --- a/tools/usb/usbip/src/usbip_attach.c
> > +++ b/tools/usb/usbip/src/usbip_attach.c
> > @@ -4,6 +4,7 @@
> >   * Copyright (C) 2015-2016 Samsung Electronics
> >   *               Igor Kotrasinski <i.kotrasinsk@xxxxxxxxxxx>
> >   *               Krzysztof Opasiak <k.opasiak@xxxxxxxxxxx>
> > + * Copyright (C) 2015-2016 Nobuo Iwata
> <nobuo.iwata@xxxxxxxxxxxxxxx>
> >   *
> >   * This program is free software: you can redistribute it and/or modify
> >   * it under the terms of the GNU General Public License as published
> by
> > @@ -26,7 +27,6 @@
> >  #include <stdio.h>
> >  #include <string.h>
> >
> > -#include <fcntl.h>
> >  #include <getopt.h>
> >  #include <unistd.h>
> >  #include <errno.h>
> > @@ -47,83 +47,53 @@ void usbip_attach_usage(void)
> >  	printf("usage: %s", usbip_attach_usage_string);
> >  }
> >
> > -#define MAX_BUFF 100
> > -static int record_connection(char *host, char *port, char *busid, int
> rhport)
> > -{
> > -	int fd;
> > -	char path[PATH_MAX+1];
> > -	char buff[MAX_BUFF+1];
> > -	int ret;
> > -
> > -	ret = mkdir(VHCI_STATE_PATH, 0700);
> > -	if (ret < 0) {
> > -		/* if VHCI_STATE_PATH exists, then it better be a
> directory */
> > -		if (errno == EEXIST) {
> > -			struct stat s;
> > -
> > -			ret = stat(VHCI_STATE_PATH, &s);
> > -			if (ret < 0)
> > -				return -1;
> > -			if (!(s.st_mode & S_IFDIR))
> > -				return -1;
> > -		} else
> > -			return -1;
> > -	}
> > -
> > -	snprintf(path, PATH_MAX, VHCI_STATE_PATH"/port%d", rhport);
> > -
> > -	fd = open(path, O_WRONLY|O_CREAT|O_TRUNC, S_IRWXU);
> > -	if (fd < 0)
> > -		return -1;
> > -
> > -	snprintf(buff, MAX_BUFF, "%s %s %s\n",
> > -			host, port, busid);
> > -
> > -	ret = write(fd, buff, strlen(buff));
> > -	if (ret != (ssize_t) strlen(buff)) {
> > -		close(fd);
> > -		return -1;
> > -	}
> > -
> > -	close(fd);
> > -
> > -	return 0;
> > -}
> > -
> > -static int import_device(int sockfd, struct usbip_usb_device *udev)
> > +static int import_device(int sockfd, struct usbip_usb_device *udev,
> > +			 char *host, char *port, char *busid)
> >  {
> >  	int rc;
> > -	int port;
> > +	int rhport;
> >
> >  	rc = usbip_vhci_driver_open();
> >  	if (rc < 0) {
> >  		err("open vhci_driver");
> > -		return -1;
> > +		goto err_out;
> >  	}
> >
> >  	do {
> > -		port = usbip_vhci_get_free_port();
> > -		if (port < 0) {
> > +		rhport = usbip_vhci_get_free_port();
> > +		if (rhport < 0) {
> >  			err("no free port");
> > -			usbip_vhci_driver_close();
> > -			return -1;
> > +			goto err_driver_close;
> >  		}
> >
> > -		rc = usbip_vhci_attach_device(port, sockfd,
> udev->busnum,
> > +		rc = usbip_vhci_attach_device(rhport, sockfd,
> udev->busnum,
> >  					      udev->devnum,
> udev->speed);
> >  		if (rc < 0 && errno != EBUSY) {
> >  			err("import device");
> > -			usbip_vhci_driver_close();
> > +			goto err_driver_close;
> >  			return -1;
> 
> Am I missing sth or this return here is unreachable?

Sorry. I will fix 'usbip: auto retry for concurrent attach' patch.

> >  		}
> >  	} while (rc < 0);
> >
> > +	rc = usbip_vhci_create_record(host, port, busid, rhport);
> > +	if (rc < 0) {
> > +		err("record connection");
> > +		goto err_detach_device;
> > +	}
> > +
> >  	usbip_vhci_driver_close();
> >
> > -	return port;
> > +	return 0;
> > +
> > +err_detach_device:
> > +	usbip_vhci_detach_device(rhport);
> > +err_driver_close:
> > +	usbip_vhci_driver_close();
> > +err_out:
> > +	return -1;
> >  }
> >
> > -static int query_import_device(int sockfd, char *busid)
> > +static int query_import_device(int sockfd, char *host, char *port, char
> *busid)
> >  {
> >  	int rc;
> >  	struct op_import_request request;
> > @@ -171,15 +141,13 @@ static int query_import_device(int sockfd, char
> *busid)
> >  		return -1;
> >  	}
> >
> > -	/* import a device */
> > -	return import_device(sockfd, &reply.udev);
> > +	return import_device(sockfd, &reply.udev, host, port, busid);
> >  }
> >
> > -static int attach_device(char *host, char *busid)
> > +static int attach_device(char *host, char *port, char *busid)
> >  {
> >  	int sockfd;
> >  	int rc;
> > -	int rhport;
> >
> >  	sockfd = usbip_net_tcp_connect(host, usbip_port_string);
> >  	if (sockfd < 0) {
> > @@ -187,20 +155,15 @@ static int attach_device(char *host, char
> *busid)
> >  		return -1;
> >  	}
> >
> > -	rhport = query_import_device(sockfd, busid);
> > -	if (rhport < 0) {
> > +	rc = query_import_device(sockfd, host, port, busid);
> > +	if (rc < 0) {
> >  		err("query");
> > +		close(sockfd);
> >  		return -1;
> >  	}
> >
> >  	close(sockfd);
> 
> Once again the same pater:
> 	ret = func();
> 	if (cond(ret)) {
> 		do_stuff();
> 		do_other_stuff();
> 	}
> 
> 	do_stuff();
> 
> Why not just:
> 
> 	ret = fun();
> 	do_stuff();
> 	if (ret)
> 		do_other_stuff();
> 
> >
> > -	rc = record_connection(host, usbip_port_string, busid, rhport);
> > -	if (rc < 0) {
> > -		err("record connection");
> > -		return -1;
> > -	}
> > -
> >  	return 0;
> >  }
> 
> Why didn't you put this in a separate commit as we talked during
> previous revision?

Very sorry. I checked my sent e-mails and I missed to respond 06/10.
But I couldn't find about separation about this patch.
http://www.mail-archive.com/linux-usb@xxxxxxxxxxxxxxx/msg84077.html

We talked in 8/10 change to usbip_list.c.
http://www.mail-archive.com/linux-usb@xxxxxxxxxxxxxxx/msg84246.html
>> In addition I think that this patch should be send separately before
>> this whole series.
> After this set is re-arranged. I will remind it.
> I may include this patch because (it can be said that) this caused by
> introducing export request.

For 06/10, I will separate improvement to original code.
Modification for this patch set will be remained in this set.

For 08/10, it will be separated into two patches out of this series,
1) move close().
2) fix correction to wording inconsistency around import and export.

> Best regards,
> --
> Krzysztof Opasiak
> Samsung R&D Institute Poland
> Samsung Electronics

Sorry for my late response,

Nobuo Iwata
//
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux