1
0
mirror of https://github.com/samba-team/samba.git synced 2025-02-02 09:47:23 +03:00

common: Add routines to get process and lock information

Currently these functions are implemented only for Linux.

Signed-off-by: Amitay Isaacs <amitay@gmail.com>

(This used to be ctdb commit be4051326b0c6a0fd301561af10fd15a0e90023b)
This commit is contained in:
Amitay Isaacs 2012-06-06 11:50:25 +10:00
parent ef79dc012e
commit 1011d10a51
6 changed files with 262 additions and 0 deletions

View File

@ -373,3 +373,20 @@ int ctdb_get_peer_pid(const int fd, pid_t *peer_pid)
return ret;
}
char *ctdb_get_process_name(pid_t pid)
{
/* FIXME: not implemented */
return NULL;
}
bool ctdb_get_lock_info(pid_t req_pid, struct ctdb_lock_info *lock_info)
{
/* FIXME: not implemented */
return false;
}
bool ctdb_get_blocker_pid(struct ctdb_lock_info *reqlock, pid_t *blocker_pid)
{
/* FIXME: not implemented */
return false;
}

View File

@ -368,3 +368,21 @@ int ctdb_get_peer_pid(const int fd, pid_t *peer_pid)
/* FIXME not implemented */
return 1;
}
char *ctdb_get_process_name(pid_t pid)
{
/* FIXME: not implemented */
return NULL;
}
bool ctdb_get_lock_info(pid_t req_pid, struct ctdb_lock_info *lock_info)
{
/* FIXME: not implemented */
return false;
}
bool ctdb_get_blocker_pid(struct ctdb_lock_info *reqlock, pid_t *blocker_pid)
{
/* FIXME: not implemented */
return false;
}

View File

@ -361,3 +361,21 @@ int ctdb_get_peer_pid(const int fd, pid_t *peer_pid)
/* FIXME not implemented */
return 1;
}
char *ctdb_get_process_name(pid_t pid)
{
/* FIXME: not implemented */
return NULL;
}
bool ctdb_get_lock_info(pid_t req_pid, struct ctdb_lock_info *lock_info)
{
/* FIXME: not implemented */
return false;
}
bool ctdb_get_blocker_pid(struct ctdb_lock_info *reqlock, pid_t *blocker_pid)
{
/* FIXME: not implemented */
return false;
}

View File

@ -361,3 +361,21 @@ int ctdb_get_peer_pid(const int fd, pid_t *peer_pid)
/* FIXME not implemented */
return 1;
}
char *ctdb_get_process_name(pid_t pid)
{
/* FIXME: not implemented */
return NULL;
}
bool ctdb_get_lock_info(pid_t req_pid, struct ctdb_lock_info *lock_info)
{
/* FIXME: not implemented */
return false;
}
bool ctdb_get_blocker_pid(struct ctdb_lock_info *reqlock, pid_t *blocker_pid)
{
/* FIXME: not implemented */
return false;
}

View File

@ -574,3 +574,182 @@ int ctdb_get_peer_pid(const int fd, pid_t *peer_pid)
return ret;
}
/*
* Find the process name from process ID
*/
char *ctdb_get_process_name(pid_t pid)
{
char path[32];
char buf[PATH_MAX];
char *ptr;
int n;
snprintf(path, sizeof(path), "/proc/%d/exe", pid);
n = readlink(path, buf, sizeof(buf));
if (n < 0) {
return NULL;
}
/* Remove any extra fields */
buf[n] = '\0';
ptr = strtok(buf, " ");
return strdup(ptr);
}
/*
* Parsing a line from /proc/locks,
*/
static bool parse_proc_locks_line(char *line, pid_t *pid,
struct ctdb_lock_info *curlock)
{
char *ptr, *saveptr;
/* output of /proc/locks
*
* lock assigned
* 1: POSIX ADVISORY WRITE 25945 fd:00:6424820 212 212
*
* lock waiting
* 1: -> POSIX ADVISORY WRITE 25946 fd:00:6424820 212 212
*/
/* Id: */
ptr = strtok_r(line, " ", &saveptr);
if (ptr == NULL) return false;
/* -> */
ptr = strtok_r(NULL, " ", &saveptr);
if (ptr == NULL) return false;
if (strcmp(ptr, "->") == 0) {
curlock->waiting = true;
ptr = strtok_r(NULL, " ", &saveptr);
} else {
curlock->waiting = false;
}
/* POSIX */
if (ptr == NULL || strcmp(ptr, "POSIX") != 0) {
return false;
}
/* ADVISORY */
ptr = strtok_r(NULL, " ", &saveptr);
if (ptr == NULL) return false;
/* WRITE */
ptr = strtok_r(NULL, " ", &saveptr);
if (ptr == NULL) return false;
if (strcmp(ptr, "READ") == 0) {
curlock->read_only = true;
} else if (strcmp(ptr, "WRITE") == 0) {
curlock->read_only = false;
} else {
return false;
}
/* PID */
ptr = strtok_r(NULL, " ", &saveptr);
if (ptr == NULL) return false;
*pid = atoi(ptr);
/* MAJOR:MINOR:INODE */
ptr = strtok_r(NULL, " :", &saveptr);
if (ptr == NULL) return false;
ptr = strtok_r(NULL, " :", &saveptr);
if (ptr == NULL) return false;
ptr = strtok_r(NULL, " :", &saveptr);
if (ptr == NULL) return false;
curlock->inode = atol(ptr);
/* START OFFSET */
ptr = strtok_r(NULL, " ", &saveptr);
if (ptr == NULL) return false;
curlock->start = atol(ptr);
/* END OFFSET */
ptr = strtok_r(NULL, " ", &saveptr);
if (ptr == NULL) return false;
if (strncmp(ptr, "EOF", 3) == 0) {
curlock->end = (off_t)-1;
} else {
curlock->end = atol(ptr);
}
return true;
}
/*
* Find information of lock being waited on for given process ID
*/
bool ctdb_get_lock_info(pid_t req_pid, struct ctdb_lock_info *lock_info)
{
FILE *fp;
struct ctdb_lock_info curlock;
pid_t pid;
char buf[1024];
char *ptr;
bool status = false;
if ((fp = fopen("/proc/locks", "r")) == NULL) {
DEBUG(DEBUG_ERR, ("Failed to read locks information"));
return false;
}
while ((ptr = fgets(buf, sizeof(buf), fp)) != NULL) {
if (! parse_proc_locks_line(buf, &pid, &curlock)) {
continue;
}
if (pid == req_pid && curlock.waiting) {
*lock_info = curlock;
status = true;
break;
}
}
fclose(fp);
return status;
}
/*
* Find process ID which holds an overlapping byte lock for required
* inode and byte range.
*/
bool ctdb_get_blocker_pid(struct ctdb_lock_info *reqlock, pid_t *blocker_pid)
{
FILE *fp;
struct ctdb_lock_info curlock;
pid_t pid;
char buf[1024];
char *ptr;
bool status = false;
if ((fp = fopen("/proc/locks", "r")) == NULL) {
DEBUG(DEBUG_ERR, ("Failed to read locks information"));
return false;
}
while ((ptr = fgets(buf, sizeof(buf), fp)) != NULL) {
if (! parse_proc_locks_line(buf, &pid, &curlock)) {
continue;
}
if (curlock.waiting) {
continue;
}
if (curlock.inode != reqlock->inode) {
continue;
}
if (curlock.start > reqlock->end ||
curlock.end < reqlock->start) {
/* Outside the required range */
continue;
}
*blocker_pid = pid;
status = true;
break;
}
fclose(fp);
return status;
}

View File

@ -1182,6 +1182,18 @@ int ctdb_sys_send_tcp(const ctdb_sock_addr *dest,
const ctdb_sock_addr *src,
uint32_t seq, uint32_t ack, int rst);
/* Details of a byte range lock */
struct ctdb_lock_info {
ino_t inode;
off_t start, end;
bool waiting;
bool read_only;
};
char *ctdb_get_process_name(pid_t pid);
bool ctdb_get_lock_info(pid_t req_pid, struct ctdb_lock_info *lock_info);
bool ctdb_get_blocker_pid(struct ctdb_lock_info *reqlock, pid_t *blocker_pid);
int ctdb_set_public_addresses(struct ctdb_context *ctdb, bool check_addresses);
int ctdb_set_single_public_ip(struct ctdb_context *ctdb,
const char *iface,