[pacman-dev] FS#9424 : storing pid in db.lck

Nagy Gabor ngaba at bibl.u-szeged.hu
Tue Feb 19 11:26:00 EST 2008


> Quote from the feature request :
> > Pacman would be able to handle automatically lock file removal without
> user
> > interaction if db.lck was dead, but it would still be locked if it was
> > alive.
> 
> That looks interesting, and there is also a patch attached, that I am
> repasting here:
> 
> 
> diff -Naur pacman-3.1.1/lib/libalpm/alpm.h
> pacman-3.1.1.bak/lib/libalpm/alpm.h
> --- pacman-3.1.1/lib/libalpm/alpm.h	2008-01-20 20:14:45.000000000 +0100
> +++ pacman-3.1.1.bak/lib/libalpm/alpm.h	2008-02-03 03:58:03.000000000 +0100
> @@ -428,6 +428,7 @@
>  	PM_ERR_HANDLE_NULL,
>  	PM_ERR_HANDLE_NOT_NULL,
>  	PM_ERR_HANDLE_LOCK,
> +	PM_ERR_INSTANCE_RUNNING,
>  	/* Databases */
>  	PM_ERR_DB_OPEN,
>  	PM_ERR_DB_CREATE,
> diff -Naur pacman-3.1.1/lib/libalpm/error.c
> pacman-3.1.1.bak/lib/libalpm/error.c
> --- pacman-3.1.1/lib/libalpm/error.c	2008-01-20 20:14:45.000000000 +0100
> +++ pacman-3.1.1.bak/lib/libalpm/error.c	2008-02-03 03:58:03.000000000 +0100
> @@ -56,6 +56,8 @@
>  			return _("library already initialized");
>  		case PM_ERR_HANDLE_LOCK:
>  			return _("unable to lock database");
> +		case PM_ERR_INSTANCE_RUNNING:
> +			return _("another instance is running");
>  		/* Databases */
>  		case PM_ERR_DB_OPEN:
>  			return _("could not open database");
> diff -Naur pacman-3.1.1/lib/libalpm/trans.c
> pacman-3.1.1.bak/lib/libalpm/trans.c
> --- pacman-3.1.1/lib/libalpm/trans.c	2008-01-20 20:17:05.000000000 +0100
> +++ pacman-3.1.1.bak/lib/libalpm/trans.c	2008-02-03 03:58:03.000000000 +0100
> @@ -75,6 +75,8 @@
>  	handle->lckfd = _alpm_lckmk();
>  	if(handle->lckfd == -1) {
>  		RET_ERR(PM_ERR_HANDLE_LOCK, -1);
> +	} else if(handle->lckfd == -2) {
> +		RET_ERR(PM_ERR_INSTANCE_RUNNING, -1);
>  	}
>  
>  	handle->trans = _alpm_trans_new();
> diff -Naur pacman-3.1.1/lib/libalpm/util.c
> pacman-3.1.1.bak/lib/libalpm/util.c
> --- pacman-3.1.1/lib/libalpm/util.c	2008-01-20 20:17:05.000000000 +0100
> +++ pacman-3.1.1.bak/lib/libalpm/util.c	2008-02-03 17:49:53.000000000 +0100
> @@ -330,30 +330,64 @@
>  	return newstr;
>  }
>  
> -
>  /* Create a lock file */
>  int _alpm_lckmk()
>  {
> -	int fd, count = 0;
> +	/*
> +	* pid: string representing pacman pid
> +	* tmpfile: string containing the temporary file
> +	* sizeofpid: integer that stores sizeof(pid)
> +	*/
> +	char pid[7], tmpfile[19]="/tmp/pacman-lock-", existingpid[7],
> runningprocess[15]="/proc/";
> +	int fd, count, sizeofpid;
>  	char *dir, *ptr;
> -	const char *file = alpm_option_get_lockfile();
> -
> +	struct stat st;
> +	const char *lockfile = alpm_option_get_lockfile();
> +	
>  	/* create the dir of the lockfile first */
> -	dir = strdup(file);
> +	dir = strdup(lockfile);
>  	ptr = strrchr(dir, '/');
>  	if(ptr) {
>  		*ptr = '\0';
>  	}
>  	_alpm_makepath(dir);
> +	
> +	// fill with zeroes
> +	for (count=0; count<sizeof(existingpid); count++) {
> +		existingpid[count]='\0';
> +	}
>  
> -	while((fd = open(file, O_WRONLY | O_CREAT | O_EXCL, 0000)) == -1 && errno
> == EACCES) {
> +	/* check if there is another lock, and if so, check if its associated
> process is running */
> +	if ((fd = open(lockfile, O_RDONLY , 0000)) != -1) {
> +		read(fd, existingpid, sizeof(existingpid));
> +		int n = read(fd, existingpid, sizeof(existingpid));
> +		close(fd);
> +		existingpid[n] = '\0';
> +		strcat(runningprocess,existingpid);
> +		if (stat(runningprocess, &st) != -1 && S_ISDIR(st.st_mode)) {
> +			return -2;
> +		}
> +	}
> +	if (unlink(lockfile) == -1 && errno != ENOENT) {
> +		return -1;
> +	}
> +	
> +	sizeofpid = sprintf(pid, "%d", getpid());
> +	strcat(tmpfile,pid);
> +
> +	count=0;
> +	while((fd = open(tmpfile, O_WRONLY | O_CREAT | O_EXCL, 0444)) == -1 &&
> errno == EACCES) {
>  		if(++count < 1) {
>  			sleep(1);
> -		}	else {
> +		} else {
>  			return(-1);
>  		}
>  	}
>  
> +	write(fd, pid, sizeofpid);
> +	
> +	symlink(tmpfile, lockfile);
> +
>  	FREE(dir);
>  
>  	return(fd > 0 ? fd : -1);
> @@ -362,13 +396,23 @@
>  /* Remove a lock file */
>  int _alpm_lckrm()
>  {
> -	const char *file = alpm_option_get_lockfile();
> -	if(unlink(file) == -1 && errno != ENOENT) {
> +	char pid[7], tmpfile[19]="/tmp/pacman-lock-";
> +	const char *lockfile = alpm_option_get_lockfile();
> +	int unlinkstatus=0;
> +	
> +	sprintf(pid, "%d", getpid());
> +	strcat(tmpfile,pid);
> +	
> +	if(unlink(tmpfile) == -1 && errno != ENOENT) {
> +		unlinkstatus=-1;
> +	}
> +	if(unlink(lockfile) == -1 && errno != ENOENT) {
>  		return(-1);
>  	}
> -	return(0);
> +	return (unlinkstatus);
>  }
>  
> +
>  /* Compression functions */
>  
>  int _alpm_unpack(const char *archive, const char *prefix, const char *fn)
> 
> _______________________________________________
> pacman-dev mailing list
> pacman-dev at archlinux.org
> http://archlinux.org/mailman/listinfo/pacman-dev
> 
> 
Hi!
1. I don't really understand why this /tmp/* stuff is needed (and tmpfile
shouldn't be PACMAN specific). We could write the pid to the lockfile directly.
2. Just for safety we could compare our current pid and the lock-pid on lockfile
removal.

Bye


----------------------------------------------------
SZTE Egyetemi Könyvtár - http://www.bibl.u-szeged.hu
This mail sent through IMP: http://horde.org/imp/





More information about the pacman-dev mailing list