projects
/
nbd.git
/ commitdiff
summary
|
shortlog
|
log
|
commit
| commitdiff |
tree
raw
|
patch
|
inline
| side by side (parent:
98c49cb
)
r274: Patch by Corey Minyard to set a device read-only at negotiate time
author
yoe <yoe>
Tue, 14 Aug 2007 06:14:09 +0000
(06:14 +0000)
committer
yoe <yoe>
Tue, 14 Aug 2007 06:14:09 +0000
(06:14 +0000)
cliserv.h
patch
|
blob
|
history
nbd-client.c
patch
|
blob
|
history
nbd-server.c
patch
|
blob
|
history
diff --git
a/cliserv.h
b/cliserv.h
index
4ccff22
..
1d8ecae
100644
(file)
--- a/
cliserv.h
+++ b/
cliserv.h
@@
-124,3
+124,7
@@
u64 ntohll(u64 a) {
}
#endif
#define htonll ntohll
}
#endif
#define htonll ntohll
+
+/* Flags used between the client and server */
+#define NBD_FLAG_HAS_FLAGS (1 << 0) /* Flags are there */
+#define NBD_FLAG_READ_ONLY (1 << 1) /* Device is read-only */
diff --git
a/nbd-client.c
b/nbd-client.c
index
1adf96a
..
f4836c5
100644
(file)
--- a/
nbd-client.c
+++ b/
nbd-client.c
@@
-27,6
+27,7
@@
#include <fcntl.h>
#include <syslog.h>
#include <stdlib.h>
#include <fcntl.h>
#include <syslog.h>
#include <stdlib.h>
+#include <sys/mount.h>
#ifndef __GNUC__
#error I need GCC to work
#ifndef __GNUC__
#error I need GCC to work
@@
-59,7
+60,7
@@
int opennet(char *name, int port) {
return sock;
}
return sock;
}
-u64 negotiate(int sock, int blocksize) {
+void negotiate(int sock, u64 *rsize64, u32 *flags) {
u64 magic, size64;
char buf[256] = "\0\0\0\0\0\0\0\0\0";
u64 magic, size64;
char buf[256] = "\0\0\0\0\0\0\0\0\0";
@@
-96,15
+97,20
@@
u64 negotiate(int sock, int blocksize) {
printf("size = %lu", (unsigned long)(size64));
#endif
printf("size = %lu", (unsigned long)(size64));
#endif
- if (read(sock, &buf, 128) < 0)
+ if (read(sock, flags, sizeof(*flags)) < 0)
err("Failed/4: %m\n");
err("Failed/4: %m\n");
+ *flags = ntohl(*flags);
+
+ if (read(sock, &buf, 124) < 0)
+ err("Failed/5: %m\n");
printf("\n");
printf("\n");
- return size64;
+ *rsize64 = size64;
}
}
-void setsizes(int nbd, u64 size64, int blocksize) {
+void setsizes(int nbd, u64 size64, int blocksize, u32 flags) {
unsigned long size;
unsigned long size;
+ int read_only = (flags & NBD_FLAG_READ_ONLY) ? 1 : 0;
#ifdef NBD_SET_SIZE_BLOCKS
if (size64/blocksize > (~0UL >> 1))
#ifdef NBD_SET_SIZE_BLOCKS
if (size64/blocksize > (~0UL >> 1))
@@
-129,6
+135,9
@@
void setsizes(int nbd, u64 size64, int blocksize) {
#endif
ioctl(nbd, NBD_CLEAR_SOCK);
#endif
ioctl(nbd, NBD_CLEAR_SOCK);
+
+ if (ioctl(nbd, BLKROSET, (unsigned long) &read_only) < 0)
+ err("Unable to set read-only attribute for device");
}
void finish_sock(int sock, int nbd, int swap) {
}
void finish_sock(int sock, int nbd, int swap) {
@@
-152,6
+161,7
@@
int main(int argc, char *argv[]) {
int swap=0;
int cont=0;
u64 size64;
int swap=0;
int cont=0;
u64 size64;
+ u32 flags;
logging();
logging();
@@
-227,8
+237,8
@@
int main(int argc, char *argv[]) {
}
argv=NULL; argc=0; /* don't use it later suddenly */
}
argv=NULL; argc=0; /* don't use it later suddenly */
- size64 = negotiate(sock, blocksize);
- setsizes(nbd, size64, blocksize);
+ negotiate(sock, &size64, &flags);
+ setsizes(nbd, size64, blocksize, flags);
finish_sock(sock, nbd, swap);
/* Go daemon */
finish_sock(sock, nbd, swap);
/* Go daemon */
@@
-248,14
+258,20
@@
int main(int argc, char *argv[]) {
cont=0;
} else {
if(cont) {
cont=0;
} else {
if(cont) {
+ u64 new_size;
+ u32 new_flags;
+
fprintf(stderr, " Reconnecting\n");
close(sock); close(nbd);
sock = opennet(hostname, port);
nbd = open(nbddev, O_RDWR);
fprintf(stderr, " Reconnecting\n");
close(sock); close(nbd);
sock = opennet(hostname, port);
nbd = open(nbddev, O_RDWR);
- if(size64!=negotiate(sock,blocksize)) {
+ negotiate(sock, &new_size, &new_flags);
+ if (size64 != new_size) {
err("Size of the device changed. Bye");
}
err("Size of the device changed. Bye");
}
- setsizes(nbd, size64, blocksize);
+ setsizes(nbd, size64, blocksize,
+ new_flags);
+
finish_sock(sock,nbd,swap);
}
}
finish_sock(sock,nbd,swap);
}
}
diff --git
a/nbd-server.c
b/nbd-server.c
index
26c8f59
..
09a5256
100644
(file)
--- a/
nbd-server.c
+++ b/
nbd-server.c
@@
-1027,10
+1027,11
@@
int expwrite(off_t a, char *buf, size_t len, CLIENT *client) {
* @param client The client we're negotiating with.
**/
void negotiate(CLIENT *client) {
* @param client The client we're negotiating with.
**/
void negotiate(CLIENT *client) {
- char zeros[300];
+ char zeros[128];
u64 size_host;
u64 size_host;
+ u32 flags = NBD_FLAG_HAS_FLAGS;
- memset(zeros, '\0', 290);
+ memset(zeros, '\0', sizeof(zeros));
if (write(client->net, INIT_PASSWD, 8) < 0)
err("Negotiation failed: %m");
cliserv_magic = htonll(cliserv_magic);
if (write(client->net, INIT_PASSWD, 8) < 0)
err("Negotiation failed: %m");
cliserv_magic = htonll(cliserv_magic);
@@
-1039,7
+1040,12
@@
void negotiate(CLIENT *client) {
size_host = htonll((u64)(client->exportsize));
if (write(client->net, &size_host, 8) < 0)
err("Negotiation failed: %m");
size_host = htonll((u64)(client->exportsize));
if (write(client->net, &size_host, 8) < 0)
err("Negotiation failed: %m");
- if (write(client->net, zeros, 128) < 0)
+ if (client->server->flags & F_READONLY)
+ flags |= NBD_FLAG_READ_ONLY;
+ flags = htonl(flags);
+ if (write(client->net, &flags, 4) < 0)
+ err("Negotiation failed: %m");
+ if (write(client->net, zeros, 124) < 0)
err("Negotiation failed: %m");
}
err("Negotiation failed: %m");
}