ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Linux-NBD/NBD.xs
Revision: 1.5
Committed: Mon Sep 20 11:14:25 2010 UTC (13 years, 8 months ago) by root
Branch: MAIN
Changes since 1.4: +11 -1 lines
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 root 1.1 #include "EXTERN.h"
2     #include "perl.h"
3     #include "XSUB.h"
4    
5     #include <inttypes.h>
6     #include <unistd.h>
7     #include <endian.h>
8    
9     #include <sys/ioctl.h>
10     #include <netinet/in.h>
11     #include <byteswap.h>
12    
13     typedef uint32_t u32;
14     typedef uint64_t u64;
15     #include <linux/nbd.h>
16    
17     #if __BYTE_ORDER == __BIG_ENDIAN
18     #define ntohll(netlong) (netlong)
19     #elif __BYTE_ORDER == __LITTLE_ENDIAN
20     #define ntohll(netlong) __bswap_64(netlong)
21     #else
22     error, you should not exist
23     #endif
24    
25     MODULE = Linux::NBD PACKAGE = Linux::NBD::Client
26    
27     void
28     _set_sock (int dev, int fd)
29     CODE:
30     ioctl (dev, NBD_SET_SOCK, (unsigned long)fd);
31    
32     void
33 root 1.2 _doit (int dev, int server = 0)
34 root 1.1 CODE:
35 root 1.2 if (server)
36     for (server = 0; server < 4095; server++)
37     if (server != dev)
38     close (server);
39    
40 root 1.1 ioctl (dev, NBD_DO_IT);
41 root 1.2
42     if (server)
43 root 1.1 _exit (0);
44    
45     void
46     _disconnect (int dev)
47     CODE:
48     ioctl (dev, NBD_DISCONNECT);
49    
50     void
51     _clear_sock (int dev)
52     CODE:
53     ioctl (dev, NBD_CLEAR_SOCK);
54    
55     void
56     _clear_que (int dev)
57     CODE:
58     ioctl (dev, NBD_CLEAR_QUE);
59    
60     void
61     _set_blksize (int dev, unsigned long blocksize)
62     CODE:
63     ioctl (dev, NBD_SET_BLKSIZE, blocksize);
64    
65     void
66     _set_size (int dev, unsigned long size)
67     CODE:
68 root 1.5 ioctl (dev, NBD_SET_SIZE, size);
69 root 1.1
70     void
71     _set_size_blocks (int dev, unsigned long nblocks)
72     CODE:
73     ioctl (dev, NBD_SET_SIZE_BLOCKS, nblocks);
74    
75 root 1.5 void
76     _set_timeout (int dev, unsigned long timeout)
77     CODE:
78     ioctl (dev, NBD_SET_TIMEOUT, timeout);
79    
80     void
81     _print_debug (int dev)
82     CODE:
83     ioctl (dev, NBD_PRINT_DEBUG, 0);
84    
85 root 1.1 MODULE = Linux::NBD PACKAGE = Linux::NBD::Server
86    
87     void
88     _one_request (SV *obj, int fd)
89     CODE:
90 root 1.3 {
91 root 1.1 struct nbd_request req;
92    
93     if (read (fd, &req, sizeof (req)) == sizeof (req))
94     {
95     if (req.magic == htonl (NBD_REQUEST_MAGIC))
96     {
97 root 1.4 req.type = htonl (req.type);
98    
99 root 1.1 if (req.type < 2)
100     {
101     u64 from = ntohll (req.from);
102    
103     PUSHMARK (SP);
104     EXTEND (SP, 3);
105     PUSHs (obj);
106     PUSHs (sv_2mortal (newSVpvn (req.handle, sizeof (req.handle))));
107     PUSHs (sv_2mortal (sizeof (UV) < 8 && from > (0xffffffffUL)
108     ? newSVnv (from)
109     : newSVuv (from)));
110     PUSHs (sv_2mortal (newSVuv (ntohl (req.len))));
111     PUTBACK;
112     call_method (req.type ? "req_write" : "req_read", G_DISCARD);
113     SPAGAIN;
114    
115     XSRETURN_NO;
116     }
117     }
118     }
119    
120     XSRETURN_YES;
121 root 1.3 }
122 root 1.1
123     SV *
124     _format_reply (SV *handle, unsigned int error = 0, SV *data = 0)
125     CODE:
126 root 1.3 {
127 root 1.1 struct nbd_reply rep;
128     STRLEN len;
129     char *h = SvPV (handle, len);
130    
131     if (len != sizeof (rep.handle))
132     croak ("format_reply: illegal handle (length %d, should be %d)", len, sizeof (rep.handle));
133    
134     rep.magic = htonl (NBD_REPLY_MAGIC);
135     rep.error = htonl (error);
136     memcpy (rep.handle, h, sizeof (rep.handle));
137    
138     RETVAL = newSVpvn ((char *)&rep, sizeof (rep));
139    
140     if (data && !error)
141     sv_catsv (RETVAL, data);
142 root 1.3 }
143 root 1.1 OUTPUT:
144     RETVAL
145