Treating share modes as advisory when set by Mac clients
Brian Campbell
lambda at editshare.com
Tue Mar 20 15:50:16 MDT 2012
On Wed, Mar 14, 2012 at 2:55 AM, Volker Lendecke
<Volker.Lendecke at sernet.de>wrote:
> On Tue, Mar 13, 2012 at 08:04:43PM +0100, Volker Lendecke wrote:
> > We need to fix "share modes = no" for you. It is highly
> > deprecated and will cause data corruption, but if it is
> > necessary to support OS/X, that's what you want. Probably
> > OS/X has its own secure mechanisms to protect against this
> > data corruption.
>
> To fix share modes = no, we need more information. In
> particular, it would be great to have a reproducer with
> stock OS/X Lion (which I have available).
Hi! Thanks for the offer to fix "share modes = no". Sorry it's taken me
some time to get back to you.
At the end of this message is a test program to reproduce this issue.
On a local filesystem, you can run from within one terminal:
# Open somefile with O_EXLOCK
open-test -l somefile
And in another terminal:
# Open somefile with no locks
open-test somefile
And both succeed in opening the file.
If you mount a Samba share on two machines, and do the above with a file in
the share, then the second open will fail; and it fails regardless of the
setting of "share modes = no".
If "share modes = no" were working, I would expect that the second open
would succeed whether or not we requested a lock in the second open.
Ideally, to match local filesystem semantics, there would be a way to make
share modes advisory (as I proposed in my initial message), not turn them
off entirely. If they are advisory, then you should be able to open the
file with a lock on one machine, and open it with no lock on another. But
the second open should fail if you try to open it with a lock on both
machines. Just fixing "share modes = no" will probably fix our problem, but
it won't be compatible with software that does depend on locks working when
both processes request a lock.
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
void err_exit(char *msg, ...) {
va_list ap;
va_start(ap, msg);
vfprintf(stderr, msg, ap);
va_end(ap);
exit(1);
}
void usage(char *name) {
err_exit("Usage: %s [-l] filename\n", name);
}
int main(int argc, char *argv[]) {
if (argc < 2 || argc > 3)
usage(argv[0]);
bool lock = false;
bool flag = false;
if (argc == 3) {
flag = true;
if (strcmp("-l", argv[1]))
usage(argv[0]);
else
lock = true;
}
char *name = flag ? argv[2] : argv[1];
int flags = O_WRONLY|O_CREAT|O_TRUNC|O_NONBLOCK;
if (lock) {
printf("Attempting to open %s with O_EXLOCK\n", name);
flags |= O_EXLOCK;
} else {
printf("Attempting to open %s with no locks\n", name);
}
int fd = open(name, flags, 0664);
if (fd < 0)
err_exit("Couldn't open %s\n", name);
printf("Opened %s. Press return to continue.\n", name);
char buffer[2];
fgets(buffer, sizeof(buffer), stdin);
if (close(fd) < 0)
err_exit("Couldn't close %s\n", name);
return 0;
}
-- Brian
More information about the samba-technical
mailing list