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

# Content
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 _doit (int dev, int server = 0)
34 CODE:
35 if (server)
36 for (server = 0; server < 4095; server++)
37 if (server != dev)
38 close (server);
39
40 ioctl (dev, NBD_DO_IT);
41
42 if (server)
43 _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 ioctl (dev, NBD_SET_SIZE, size);
69
70 void
71 _set_size_blocks (int dev, unsigned long nblocks)
72 CODE:
73 ioctl (dev, NBD_SET_SIZE_BLOCKS, nblocks);
74
75 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 MODULE = Linux::NBD PACKAGE = Linux::NBD::Server
86
87 void
88 _one_request (SV *obj, int fd)
89 CODE:
90 {
91 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 req.type = htonl (req.type);
98
99 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 }
122
123 SV *
124 _format_reply (SV *handle, unsigned int error = 0, SV *data = 0)
125 CODE:
126 {
127 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 }
143 OUTPUT:
144 RETVAL
145