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]

 




On 12/26/2016 08:08 AM, Nobuo Iwata wrote:
> 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?

>  /* ---------------------------------------------------------------------- */
>  
>  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

> +
> +	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

> +
> +	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?

>  		}
>  	} 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?

Best regards,
-- 
Krzysztof Opasiak
Samsung R&D Institute Poland
Samsung Electronics
--
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