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 <[email protected]>
> ---
> 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 <[email protected]>
> * Krzysztof Opasiak <[email protected]>
> + * Copyright (C) 2015-2016 Nobuo Iwata <[email protected]>
> *
> * 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 [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html