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:
parent
ef79dc012e
commit
1011d10a51
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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,
|
||||
|
Loading…
x
Reference in New Issue
Block a user