WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

[Xen-devel] [PATCH] Make vnet-module working on x86_64

To: xen-devel@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-devel] [PATCH] Make vnet-module working on x86_64
From: Robert Valentan <R.Valentan@xxxxxxxxxxxxx>
Date: Tue, 28 Mar 2006 17:27:02 +0200
Delivery-date: Tue, 28 Mar 2006 15:28:39 +0000
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
User-agent: Mozilla Thunderbird 1.0 (X11/20041206)
Replacing the kernelcall "socketcall" with a partly copy
from linux net/socket.c
This call ist not in x86_64, ia64 and some other. With
the patch the kernelcall is replaced.

An other way will be an export of the needed function
in net/socket.c...

If there is something wrong with my patch, please let
it me known, it's me first kernelmodule working ;-/

--
wbr
Robert Valentan
diff -r 2604abf98ede tools/vnet/vnet-module/varp_socket.c
--- a/tools/vnet/vnet-module/varp_socket.c      Tue Mar 28 09:09:44 2006
+++ b/tools/vnet/vnet-module/varp_socket.c      Tue Mar 28 17:10:53 2006
@@ -16,6 +16,9 @@
  * 59 Temple Place, suite 330, Boston, MA 02111-1307 USA
  *
  */
+
+static int errno;
+
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/version.h>
@@ -36,7 +39,6 @@
 
 /* Get macros needed to define system calls as functions in the kernel. */
 #define __KERNEL_SYSCALLS__
-static int errno;
 #include <linux/unistd.h>
 
 #define MODULE_NAME "VARP"
@@ -75,110 +77,254 @@
  * The parts we need anyway.
  */
 
-/* Define the socketcall() syscall.
- * Multiplexes all the socket-related calls.
- *
- * @param call socket call id
- * @param args arguments (upto 6)
- * @return call-dependent value
- */
-static inline _syscall2(int, socketcall,
-                        int, call,
-                        unsigned long *, args)
+/* the following code is copied from linux-kernel/net/socket.c
+ * As replacement of the __NR_socketcall, which exists not in x86_64 and
+ * same other systems.
+ * An alternate will be an export of the copied-functions in net/socket.c
+ */ 
+#define MAX_SOCK_ADDR 128
 
 int socket(int family, int type, int protocol){
-    unsigned long args[6];
-    
-    args[0] = (unsigned long)family;
-    args[1] = (unsigned long)type;
-    args[2] = (unsigned long)protocol;
-    return socketcall(SYS_SOCKET, args);
+
+       int retval;
+       struct socket *sock;
+       retval = sock_create(family, type, protocol, &sock);
+       if (retval < 0)
+               goto out;
+
+       retval = sock_map_fd(sock);
+       if (retval < 0)
+               goto out_release;
+
+out:
+       /* It may be already another descriptor 8) Not kernel problem. */
+       return retval;
+
+out_release:
+       sock_release(sock);
+       return retval;
 }
 
 int bind(int fd, struct sockaddr *umyaddr, int addrlen){
-    unsigned long args[6];
-    
-    args[0] = (unsigned long)fd;
-    args[1] = (unsigned long)umyaddr;
-    args[2] = (unsigned long)addrlen;
-    return socketcall(SYS_BIND, args);
+
+       struct socket *sock;
+       char address[MAX_SOCK_ADDR];
+       int err;
+
+       if((sock = sockfd_lookup(fd,&err))!=NULL)
+       {
+               if((err=move_addr_to_kernel(umyaddr,addrlen,address))>=0) {
+                       err = security_socket_bind(sock, (struct sockaddr 
*)address, addrlen);
+                       if (err) {
+                               sockfd_put(sock);
+                               return err;
+                       }
+                       err = sock->ops->bind(sock, (struct sockaddr *)address, 
addrlen);
+               }
+               sockfd_put(sock);
+       }                       
+       return err;
 }
 
 int connect(int fd, struct sockaddr *uservaddr, int addrlen){
-    unsigned long args[6];
-    
-    args[0] = (unsigned long)fd;
-    args[1] = (unsigned long)uservaddr;
-    args[2] = (unsigned long)addrlen;
-    return socketcall(SYS_CONNECT, args);
+
+       struct socket *sock;
+       char address[MAX_SOCK_ADDR];
+       int err;
+
+       sock = sockfd_lookup(fd, &err);
+       if (!sock)
+               goto out;
+       err = move_addr_to_kernel(uservaddr, addrlen, address);
+       if (err < 0)
+               goto out_put;
+
+       err = security_socket_connect(sock, (struct sockaddr *)address, 
addrlen);
+       if (err)
+               goto out_put;
+
+       err = sock->ops->connect(sock, (struct sockaddr *) address, addrlen,
+                                sock->file->f_flags);
+out_put:
+       sockfd_put(sock);
+out:
+       return err;
 }
 
 int sendto(int fd, void * buff, size_t len,
            unsigned flags, struct sockaddr *addr,
            int addr_len){
-    unsigned long args[6];
-    
-    args[0] = (unsigned long)fd;
-    args[1] = (unsigned long)buff;
-    args[2] = (unsigned long)len;
-    args[3] = (unsigned long)flags;
-    args[4] = (unsigned long)addr;
-    args[5] = (unsigned long)addr_len;
-    return socketcall(SYS_SENDTO, args);
+
+       struct socket *sock;
+       char address[MAX_SOCK_ADDR];
+       int err;
+       struct msghdr msg;
+       struct iovec iov;
+       
+       sock = sockfd_lookup(fd, &err);
+       if (!sock)
+               goto out;
+       iov.iov_base=buff;
+       iov.iov_len=len;
+       msg.msg_name=NULL;
+       msg.msg_iov=&iov;
+       msg.msg_iovlen=1;
+       msg.msg_control=NULL;
+       msg.msg_controllen=0;
+       msg.msg_namelen=0;
+       if(addr)
+       {
+               err = move_addr_to_kernel(addr, addr_len, address);
+               if (err < 0)
+                       goto out_put;
+               msg.msg_name=address;
+               msg.msg_namelen=addr_len;
+       }
+       if (sock->file->f_flags & O_NONBLOCK)
+               flags |= MSG_DONTWAIT;
+       msg.msg_flags = flags;
+       err = sock_sendmsg(sock, &msg, len);
+
+out_put:               
+       sockfd_put(sock);
+out:
+       return err;
 }
 
 int recvfrom(int fd, void * ubuf, size_t size,
              unsigned flags, struct sockaddr *addr,
              int *addr_len){
-    unsigned long args[6];
-    
-    args[0] = (unsigned long)fd;
-    args[1] = (unsigned long)ubuf;
-    args[2] = (unsigned long)size;
-    args[3] = (unsigned long)flags;
-    args[4] = (unsigned long)addr;
-    args[5] = (unsigned long)addr_len;
-    return socketcall(SYS_RECVFROM, args);
+
+       struct socket *sock;
+       struct iovec iov;
+       struct msghdr msg;
+       char address[MAX_SOCK_ADDR];
+       int err,err2;
+
+       sock = sockfd_lookup(fd, &err);
+       if (!sock)
+               goto out;
+
+       msg.msg_control=NULL;
+       msg.msg_controllen=0;
+       msg.msg_iovlen=1;
+       msg.msg_iov=&iov;
+       iov.iov_len=size;
+       iov.iov_base=ubuf;
+       msg.msg_name=address;
+       msg.msg_namelen=MAX_SOCK_ADDR;
+       if (sock->file->f_flags & O_NONBLOCK)
+               flags |= MSG_DONTWAIT;
+       err=sock_recvmsg(sock, &msg, size, flags);
+
+       if(err >= 0 && addr != NULL)
+       {
+               err2=move_addr_to_user(address, msg.msg_namelen, addr, 
addr_len);
+               if(err2<0)
+                       err=err2;
+       }
+       sockfd_put(sock);                       
+out:
+       return err;
 }
 
 int setsockopt(int fd, int level, int optname, void *optval, int optlen){
-    unsigned long args[6];
-    
-    args[0] = (unsigned long)fd;
-    args[1] = (unsigned long)level;
-    args[2] = (unsigned long)optname;
-    args[3] = (unsigned long)optval;
-    args[4] = (unsigned long)optlen;
-    return socketcall(SYS_SETSOCKOPT, args);
-}
-
+
+       int err;
+       struct socket *sock;
+
+       if (optlen < 0)
+               return -EINVAL;
+                       
+       if ((sock = sockfd_lookup(fd, &err))!=NULL)
+       {
+               err = security_socket_setsockopt(sock,level,optname);
+               if (err) {
+                       sockfd_put(sock);
+                       return err;
+               }
+
+               if (level == SOL_SOCKET)
+                       err=sock_setsockopt(sock,level,optname,optval,optlen);
+               else
+                       err=sock->ops->setsockopt(sock, level, optname, optval, 
optlen);
+               sockfd_put(sock);
+       }
+       return err;
+}
+
+/*  not possible, because sock_getsockopt is not exported ...
 int getsockopt(int fd, int level, int optname, void *optval, int *optlen){
-    unsigned long args[6];
-    
-    args[0] = (unsigned long)fd;
-    args[1] = (unsigned long)level;
-    args[2] = (unsigned long)optname;
-    args[3] = (unsigned long)optval;
-    args[4] = (unsigned long)optlen;
-    return socketcall(SYS_GETSOCKOPT, args);
-}
+
+       int err;
+       struct socket *sock;
+
+       if ((sock = sockfd_lookup(fd, &err))!=NULL)
+       {
+               err = security_socket_getsockopt(sock, level, optname);
+               if (err) {
+                       sockfd_put(sock);
+                       return err;
+               }
+
+               if (level == SOL_SOCKET)
+                       err=sock_getsockopt(sock,level,optname,optval,optlen);
+               else
+                       err=sock->ops->getsockopt(sock, level, optname, optval, 
optlen);
+               sockfd_put(sock);
+       }
+       return err;
+}
+*/
 
 int shutdown(int fd, int how){
-    unsigned long args[6];
-    
-    args[0] = (unsigned long)fd;
-    args[1] = (unsigned long)how;
-    return socketcall(SYS_SHUTDOWN, args);
+
+       int err;
+       struct socket *sock;
+
+       if ((sock = sockfd_lookup(fd, &err))!=NULL)
+       {
+               err = security_socket_shutdown(sock, how);
+               if (err) {
+                       sockfd_put(sock);
+                       return err;
+               }
+                               
+               err=sock->ops->shutdown(sock, how);
+               sockfd_put(sock);
+       }
+       return err;
 }
 
 int getsockname(int fd, struct sockaddr *usockaddr, int *usockaddr_len){
-    unsigned long args[6];
-    
-    args[0] = (unsigned long)fd;
-    args[1] = (unsigned long)usockaddr;
-    args[2] = (unsigned long)usockaddr_len;
-    return socketcall(SYS_GETSOCKNAME, args);
-}
+
+       struct socket *sock;
+       char address[MAX_SOCK_ADDR];
+       int len, err;
+       
+       sock = sockfd_lookup(fd, &err);
+       if (!sock)
+               goto out;
+
+       err = security_socket_getsockname(sock);
+       if (err)
+               goto out_put;
+
+       err = sock->ops->getname(sock, (struct sockaddr *)address, &len, 0);
+       if (err)
+               goto out_put;
+       err = move_addr_to_user(address, len, usockaddr, usockaddr_len);
+
+out_put:
+       sockfd_put(sock);
+out:
+       return err;
+}
+
+/**
+ * End of copy from net/socket.c
+ */
+
 
 
/*============================================================================*/
 /** Socket flags. */
@@ -577,7 +723,7 @@
     int err = 0;
     mm_segment_t oldfs;
 
-    dprintf("> mcaddr=%u.%u.%u.%u port=%u\n", NIPQUAD(mcaddr), ntohs(port));
+    iprintf("> mcaddr=%u.%u.%u.%u port=%u\n", NIPQUAD(mcaddr), ntohs(port));
     oldfs = change_fs(KERNEL_DS);
     err = varp_mcast_open(mcaddr, port, &varp_mcast_sock);
     if(err < 0 ) goto exit;
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
<Prev in Thread] Current Thread [Next in Thread>