It works as follows: Whenever a semaphore operation is performed, the
PID of the process is stored in the sempid field of the semaphore.
This PID can be obtained from a different process by calling semctl
with the GETPID command.
com_kill() first tries to acquire the lock by calling the new
mutex_try_lock() function of ipc.c. In contrast to mutex_lock(),
mutex_try_lock() only operates on the first semaphore in the semaphore
set, leaving the sempid field of the second semaphore unchanged. If
mutex_try_lock() succeeds, no running dss process is holding the lock
and the kill command fails. Otherwise, some dss process is running
whose PID can be obtained by calling semctl() on the second semaphore.
COMMAND(ls) \
COMMAND(create) \
COMMAND(prune) \
COMMAND(ls) \
COMMAND(create) \
COMMAND(prune) \
+ COMMAND(run) \
+ COMMAND(kill)
#define COMMAND(x) static int com_ ##x(void);
COMMANDS
#undef COMMAND
#define COMMAND(x) static int com_ ##x(void);
COMMANDS
#undef COMMAND
+static int com_kill(void)
+{
+ pid_t pid;
+ char *config_file = get_config_file_name();
+ int ret = get_dss_pid(config_file, &pid);
+
+ free(config_file);
+ if (ret < 0)
+ return ret;
+ if (conf.dry_run_given) {
+ dss_msg("%d\n", (int)pid);
+ return 0;
+ }
+ ret = kill(pid, SIGTERM);
+ if (ret < 0)
+ return -ERRNO_TO_DSS_ERROR(errno);
+ return 1;
+}
+
static void dss_get_snapshot_list(struct snapshot_list *sl)
{
get_snapshot_list(sl, conf.unit_interval_arg, conf.num_intervals_arg);
static void dss_get_snapshot_list(struct snapshot_list *sl)
{
get_snapshot_list(sl, conf.unit_interval_arg, conf.num_intervals_arg);
received. See also the --exit-hook option.
"
received. See also the --exit-hook option.
"
+groupoption "kill" K
+#~~~~~~~~~~~~~~~~~~~
+"Kill a running dss process"
+group="command"
+details="
+ This sends SIGTERM to the dss process that corresponds to the
+ given config file. If --dry-run is given, the PID of the dss
+ process is written to stdout, but no signal is sent.
+"
+
###############################
section "Rsync-related options"
###############################
###############################
section "Rsync-related options"
###############################
DSS_ERROR(SIGNAL_SIG_ERR, "signal() returned SIG_ERR") \
DSS_ERROR(SIGNAL, "caught terminating signal") \
DSS_ERROR(BUG, "values of beta might cause dom!") \
DSS_ERROR(SIGNAL_SIG_ERR, "signal() returned SIG_ERR") \
DSS_ERROR(SIGNAL, "caught terminating signal") \
DSS_ERROR(BUG, "values of beta might cause dom!") \
+ DSS_ERROR(NOT_RUNNING, "dss not running") \
+static int mutex_try_lock(int id)
+{
+ int ret;
+
+ DSS_DEBUG_LOG("trying to lock\n");
+ struct sembuf sops[2] = {
+ {
+ .sem_num = 0,
+ .sem_op = 0,
+ .sem_flg = SEM_UNDO | IPC_NOWAIT
+ },
+ {
+ .sem_num = 0,
+ .sem_op = 1,
+ .sem_flg = SEM_UNDO | IPC_NOWAIT
+ }
+ };
+ ret = do_semop(id, sops, 2);
+ if (ret < 0)
+ return -ERRNO_TO_DSS_ERROR(errno);
+ return 1;
+}
+
int lock_dss(char *config_file)
{
int ret, key = get_key_or_die(config_file);
int lock_dss(char *config_file)
{
int ret, key = get_key_or_die(config_file);
return ret;
return mutex_lock(ret);
}
return ret;
return mutex_lock(ret);
}
+
+int get_dss_pid(char *config_file, pid_t *pid)
+{
+ int ret, semid, key = get_key_or_die(config_file);
+
+ ret = mutex_get(key, 0);
+ if (ret < 0)
+ return ret;
+ semid = ret;
+ ret = semctl(semid, 1, GETPID);
+ if (ret < 0)
+ return -E_NOT_RUNNING;
+ *pid = ret;
+ ret = mutex_try_lock(semid);
+ if (ret >= 0)
+ return -E_NOT_RUNNING;
+ return 1;
+}
int lock_dss(char *config_file);
int lock_dss(char *config_file);
+int get_dss_pid(char *config_file, pid_t *pid);