static int sync_lock(struct gfs2_sbd *sdp, int mode, uint32_t flags,
		     unsigned int num, struct dlm_lksb *lksb, char *name)
{
	struct lm_lockstruct *ls = &sdp->sd_lockstruct;
	char strname[GDLM_STRNAME_BYTES];
	int error, status;

	memset(strname, 0, GDLM_STRNAME_BYTES);
	snprintf(strname, GDLM_STRNAME_BYTES, "%8x%16x", LM_TYPE_NONDISK, num);

	error = dlm_lock(ls->ls_dlm, mode, lksb, flags,
			 strname, GDLM_STRNAME_BYTES - 1,
			 0, sync_wait_cb, ls, NULL);
	if (error) {
		fs_err(sdp, "%s lkid %x flags %x mode %d error %d\n",
		       name, lksb->sb_lkid, flags, mode, error);
		return error;
	}

	wait_for_completion(&ls->ls_sync_wait);

	status = lksb->sb_status;

	if (status && status != -EAGAIN) {
		fs_err(sdp, "%s lkid %x flags %x mode %d status %d\n",
		       name, lksb->sb_lkid, flags, mode, status);
	}

	return status;
}
示例#2
0
/*
 * An variation of dlm_lock_sync, which make lock request could
 * be interrupted
 */
static int dlm_lock_sync_interruptible(struct dlm_lock_resource *res, int mode,
				       struct mddev *mddev)
{
	int ret = 0;

	ret = dlm_lock(res->ls, mode, &res->lksb,
			res->flags, res->name, strlen(res->name),
			0, sync_ast, res, res->bast);
	if (ret)
		return ret;

	wait_event(res->sync_locking, res->sync_locking_done
				      || kthread_should_stop()
				      || test_bit(MD_CLOSING, &mddev->flags));
	if (!res->sync_locking_done) {
		/*
		 * the convert queue contains the lock request when request is
		 * interrupted, and sync_ast could still be run, so need to
		 * cancel the request and reset completion
		 */
		ret = dlm_unlock(res->ls, res->lksb.sb_lkid, DLM_LKF_CANCEL,
			&res->lksb, res);
		res->sync_locking_done = false;
		if (unlikely(ret != 0))
			pr_info("failed to cancel previous lock request "
				 "%s return %d\n", res->name, ret);
		return -EPERM;
	} else
		res->sync_locking_done = false;
	if (res->lksb.sb_status == 0)
		res->mode = mode;
	return res->lksb.sb_status;
}
static int gdlm_lock(struct gfs2_glock *gl, unsigned int req_state,
		     unsigned int flags)
{
	struct lm_lockstruct *ls = &gl->gl_sbd->sd_lockstruct;
	int req;
	u32 lkf;
	char strname[GDLM_STRNAME_BYTES] = "";

	req = make_mode(req_state);
	lkf = make_flags(gl, flags, req);
	gfs2_glstats_inc(gl, GFS2_LKS_DCOUNT);
	gfs2_sbstats_inc(gl, GFS2_LKS_DCOUNT);
	if (gl->gl_lksb.sb_lkid) {
		gfs2_update_request_times(gl);
	} else {
		memset(strname, ' ', GDLM_STRNAME_BYTES - 1);
		strname[GDLM_STRNAME_BYTES - 1] = '\0';
		gfs2_reverse_hex(strname + 7, gl->gl_name.ln_type);
		gfs2_reverse_hex(strname + 23, gl->gl_name.ln_number);
		gl->gl_dstamp = ktime_get_real();
	}
	/*
	 * Submit the actual lock request.
	 */

	return dlm_lock(ls->ls_dlm, req, &gl->gl_lksb, lkf, strname,
			GDLM_STRNAME_BYTES - 1, 0, gdlm_ast, gl, gdlm_bast);
}
示例#4
0
文件: pingtest.c 项目: beekhof/dlm
static int convert_lock(int mode)
{
    int status;

    printf("pinglock: convert to %d starting\n", mode);
    status = dlm_lock( mode,
		       &our_lksb,
		       LKF_VALBLK | LKF_CONVERT,
		       NULL,
		       0,
		       0,
		       compast_routine,
		       &our_lksb,
		       blockast_routine,
		       NULL);
    if (status != 0)
    {
	perror("pinglock: convert failed");
    }
    else
    {
	cur_mode = mode;
	printf("pinglock: convert to %d started\n", mode);
    }
    return status;
}
示例#5
0
文件: libdlm.c 项目: beekhof/dlm
/* lock_resource & unlock_resource
 * are the simplified, synchronous API.
 * Aways uses the default lockspace.
 */
int lock_resource(const char *resource, int mode, int flags, int *lockid)
{
    int status;
    struct lock_wait lwait;

    if (default_ls == NULL)
    {
	if (dlm_pthread_init())
	{
	    return -1;
	}
    }

    if (!lockid)
    {
	errno = EINVAL;
	return -1;
    }

    /* Conversions need the lockid in the LKSB */
    if (flags & LKF_CONVERT)
	lwait.lksb.sb_lkid = *lockid;

    pthread_cond_init(&lwait.cond, NULL);
    pthread_mutex_init(&lwait.mutex, NULL);
    pthread_mutex_lock(&lwait.mutex);

    status = dlm_lock(mode,
		      &lwait.lksb,
		      flags,
		      resource,
		      strlen(resource),
		      0,
		      sync_ast_routine,
		      &lwait,
		      NULL,
		      NULL);
    if (status)
	return status;

    /* Wait for it to complete */
    pthread_cond_wait(&lwait.cond, &lwait.mutex);
    pthread_mutex_unlock(&lwait.mutex);

    *lockid = lwait.lksb.sb_lkid;

    errno = lwait.lksb.sb_status;
    if (lwait.lksb.sb_status)
	return -1;
    else
	return 0;
}
示例#6
0
static int dlm_lock_sync(struct dlm_lock_resource *res, int mode)
{
	int ret = 0;

	init_completion(&res->completion);
	ret = dlm_lock(res->ls, mode, &res->lksb,
			res->flags, res->name, strlen(res->name),
			0, sync_ast, res, res->bast);
	if (ret)
		return ret;
	wait_for_completion(&res->completion);
	return res->lksb.sb_status;
}
示例#7
0
static int dlm_lock_sync(struct dlm_lock_resource *res, int mode)
{
	int ret = 0;

	ret = dlm_lock(res->ls, mode, &res->lksb,
			res->flags, res->name, strlen(res->name),
			0, sync_ast, res, res->bast);
	if (ret)
		return ret;
	wait_event(res->sync_locking, res->sync_locking_done);
	res->sync_locking_done = false;
	if (res->lksb.sb_status == 0)
		res->mode = mode;
	return res->lksb.sb_status;
}
示例#8
0
static int gdlm_lock(struct gfs2_glock *gl, unsigned int req_state,
		     unsigned int flags)
{
	struct lm_lockstruct *ls = &gl->gl_sbd->sd_lockstruct;
	int req;
	u32 lkf;

	req = make_mode(req_state);
	lkf = make_flags(gl->gl_lksb.sb_lkid, flags, req);

	/*
	 * Submit the actual lock request.
	 */

	return dlm_lock(ls->ls_dlm, req, &gl->gl_lksb, lkf, gl->gl_strname,
			GDLM_STRNAME_BYTES - 1, 0, gdlm_ast, gl, gdlm_bast);
}
示例#9
0
文件: pingtest.c 项目: beekhof/dlm
static void start_lock(void)
{
    int status;
    cur_mode = LKM_EXMODE;

    *lvb_int = us-1;

    printf("pinglock: starting\n");
    status = dlm_lock( cur_mode,
		       &our_lksb,
		       LKF_VALBLK,
		       lockname,
		       strlen(lockname)+1, /* include trailing NUL for ease of following */
		       0, /* Parent */
		       compast_routine,
		       &our_lksb,
		       blockast_routine,
		       NULL);
    if (status != 0)
	perror("pinglock: lock failed");
}
示例#10
0
static unsigned int gdlm_lock(struct gfs2_glock *gl,
                              unsigned int req_state, unsigned int flags)
{
    struct lm_lockstruct *ls = &gl->gl_sbd->sd_lockstruct;
    int error;
    int req;
    u32 lkf;

    gl->gl_req = req_state;
    req = make_mode(req_state);
    lkf = make_flags(gl->gl_lksb.sb_lkid, flags, req);

    /*
     * Submit the actual lock request.
     */

    error = dlm_lock(ls->ls_dlm, req, &gl->gl_lksb, lkf, gl->gl_strname,
                     GDLM_STRNAME_BYTES - 1, 0, gdlm_ast, gl, gdlm_bast);
    if (error == -EAGAIN)
        return 0;
    if (error)
        return LM_OUT_ERROR;
    return LM_OUT_ASYNC;
}
示例#11
0
文件: asttest.c 项目: smintz/cluster
int main(int argc, char *argv[])
{
    const char *resource = "LOCK-NAME";
    int  flags = 0;
    int  delay = 0;
    int  status;
    int  mode = LKM_EXMODE;
    int  convmode = -1;
    int  do_unlock = 1;
    int  do_crash = 0;
    signed char opt;

    /* Deal with command-line arguments */
    opterr = 0;
    optind = 0;
    while ((opt=getopt(argc,argv,"?m:nqupc:d:CvV")) != EOF)
    {
	switch(opt)
	{
	case 'h':
	    usage(argv[0], stdout);
	    exit(0);

	case '?':
	    usage(argv[0], stderr);
	    exit(0);

	case 'm':
	    mode = modetonum(optarg);
	    break;

	case 'c':
	    convmode = modetonum(optarg);
	    break;

        case 'p':
            use_threads++;
            break;

	case 'n':
	    flags |= LKF_NOQUEUE;
	    break;

        case 'q':
            quiet = 1;
            break;

        case 'u':
            do_unlock = 0;
            break;

	case 'C':
	    do_crash = 1;
	    break;

	case 'd':
	    delay = atoi(optarg);	
	    break;

	case 'V':
	    printf("\nasttest version 0.1\n\n");
	    exit(1);
	    break;
	}
    }

    if (argv[optind])
	resource = argv[optind];

    if (!quiet)
    fprintf(stderr, "locking %s %s %s...", resource,
	    numtomode(mode),
	    (flags&LKF_NOQUEUE?"(NOQUEUE)":""));

    fflush(stderr);

    if (use_threads)
    {
	pthread_cond_init(&cond, NULL);
	pthread_mutex_init(&mutex, NULL);
	pthread_mutex_lock(&mutex);

	dlm_pthread_init();
    }

    status = dlm_lock(mode,
		      &lksb,
		      flags,
		      resource,
		      strlen(resource),
		      0, // Parent,
		      ast_routine,
		      &lksb,
		      bast_routine,
		      NULL); // Range
    if (status == -1)
    {
	if (!quiet) fprintf(stderr, "\n");
	perror("lock");

	return -1;
    }
    printf("(lkid=%x)", lksb.sb_lkid);

    if (do_crash)
	*(int *)0 = 0xdeadbeef;

    /* Wait */
    if (use_threads)
	pthread_cond_wait(&cond, &mutex);
    else
	poll_for_ast();

    if (delay)
        sleep(delay);

    if (!quiet)
    {
        fprintf(stderr, "unlocking %s...", resource);
        fflush(stderr);
    }

    if (do_unlock)
    {
	status = dlm_unlock(lksb.sb_lkid,
			    0, // flags
			    &lksb,
			    &lksb); // AST args
	if (status == -1)
	{
	    if (!quiet) fprintf(stderr, "\n");
	    perror("unlock");
	    return -1;
	}

	/* Wait */
	if (use_threads)
	    pthread_cond_wait(&cond, &mutex);
	else
	    poll_for_ast();
    }

    return 0;
}
示例#12
0
文件: flood.c 项目: smintz/cluster
int main(int argc, char *argv[])
{
    int  flags = 0;
    int  lockops = 0;
    int  maxlocks = 100000;
    int  rescount = 10;
    int  increment = 1000;
    int  quiet = 0;
    int  status;
    int  i;
    int  mode = LKM_CRMODE;
    int  lksbnum = 0;
    signed char opt;
    char **resources;
    struct dlm_lksb *lksbs;

    /* Deal with command-line arguments */
    opterr = 0;
    optind = 0;
    while ((opt=getopt(argc,argv,"?m:i:qn:vV")) != EOF)
    {
	switch(opt)
	{
	case 'h':
	    usage(argv[0], stdout);
	    exit(0);

	case '?':
	    usage(argv[0], stderr);
	    exit(0);

	case 'm':
	    maxlocks = atoi(optarg);
	    break;

	case 'i':
	    increment = atoi(optarg);
	    break;

	case 'n':
	    rescount = atoi(optarg);
	    break;

	case 'q':
	    quiet = 1;
	    break;

	case 'V':
	    printf("\nflood version 0.3\n\n");
	    exit(1);
	    break;
	}
    }

    if ((resources = malloc(sizeof(char*) * rescount)) == NULL)
    {
	    perror("exhausted virtual memory");
	    return 1;
    }
    for (i=0; i < rescount; i++) {
	    char resname[256];
	    sprintf(resname, "TESTLOCK%d", i);
	    resources[i] = strdup(resname);
    }

    lksbs = malloc(sizeof(struct dlm_lksb) * maxlocks);
    if (!lksbs)
    {
	    perror("cannot allocate lksbs");
	    return 1;
    }

    pthread_cond_init(&cond, NULL);
    pthread_mutex_init(&mutex, NULL);
    pthread_mutex_lock(&mutex);

    dlm_pthread_init();

    while (1) {
	    char *resource = resources[rand() % rescount];

	    status = dlm_lock(mode,
			      &lksbs[lksbnum],
			      flags,
			      resource,
			      strlen(resource),
			      0, // Parent,
			      ast_routine,
			      &lksbs[lksbnum],
			      NULL, // bast_routine,
			      NULL); // Range
	    if (status == -1)
	    {
		    perror("lock failed");
		    return -1;
	    }

	    count++;
	    lockops++;
	    if ((lockops % increment) == 0 && !quiet)
		    fprintf(stderr, "%d lockops, %d locks\n", lockops, count);

	    while (count > maxlocks) {
		    sleep(1);
	    }
	    lksbnum = (lksbnum+1)%maxlocks;
    }

    return 0;
}