Hi Patrick, The attached program produces the output: 557b.main: lvb = 0xbffff4c0 [hello] 557c.main: lvb = 0xbffff4c0 [hello] 557c.my_ast: lvb = 0xbffff4c0 [] 557c.my_ast: lvb = 0xbffff4c0 [foobar] 557c.my_ast: lvb = 0xbffff4c0 [foobar] The [] looks like trouble, don't you think? This code never clears the lvb, yet the lvb ends up clear in the ast corresponding to acquiring the PW lock. Regards, Daniel
#include <stdlib.h> #include <unistd.h> #include <stdint.h> #include <errno.h> #include <string.h> #include <stdio.h> #include <signal.h> #include <libdlm.h> #define warn(string, args...) do { fprintf(stderr, "%x.%s: " string "\n", getpid(), __func__, ##args); } while (0) #define error(string, args...) do { warn(string, ##args); exit(1); } while (0) void my_ast(void *arg) { struct dlm_lksb *lksb = arg; warn("lvb = %p [%s]", lksb->sb_lvbptr, lksb->sb_lvbptr); } int main(void) { int fd, child; struct dlm_lksb lksb = { .sb_lvbptr = (char *)(char[32]){ "hello" } }; warn("lvb = %p [%s]", lksb.sb_lvbptr, lksb.sb_lvbptr); if ((fd = dlm_get_fd()) < 0) error("dlm error %i, %s", errno, strerror(errno)); switch (child = fork()) { case -1: error("fork error %i, %s", errno, strerror(errno)); case 0: warn("lvb = %p [%s]", lksb.sb_lvbptr, lksb.sb_lvbptr); while (1) dlm_dispatch(fd); } memcpy(lksb.sb_lvbptr, "foobar", 6); if (dlm_lock(LKM_PWMODE, &lksb, LKF_NOQUEUE | LKF_VALBLK, "fod", 3, 0, my_ast, &lksb, NULL, NULL) < 0) goto err; sleep(1); // let ast happen if (dlm_lock(LKM_CRMODE, &lksb, LKF_CONVERT | LKF_NOQUEUE | LKF_VALBLK, "fod", 3, 0, my_ast, &lksb, NULL, NULL) < 0) goto err; sleep(1); // let ast happen if (dlm_unlock(lksb.sb_lkid, 0, &lksb, &lksb) < 0) goto err; sleep(1); // let ast happen quit: kill(child, SIGTERM); return 0; err: warn("dlm error %i, %s", errno, strerror(errno)); goto quit; }