]> git.proxmox.com Git - pve-cluster.git/blobdiff - data/src/pmxcfs.c
add pmxcfs restart detection heuristic for IPCC
[pve-cluster.git] / data / src / pmxcfs.c
index 1b6cbcc3a72049d8848d6e42f730d36d446f03e5..6047ad05aa13604dd66153dd65a836f2256d4f1a 100644 (file)
@@ -58,6 +58,7 @@
 
 #define DBFILENAME VARLIBDIR "/config.db"
 #define LOCKFILE VARLIBDIR "/.pmxcfs.lockfile"
+#define RESTART_FLAG_FILE RUNDIR "/cfs-restart-flag"
 
 #define CFSDIR "/etc/pve"
 
@@ -186,6 +187,41 @@ ret:
        return ret;
 }
 
+static int cfs_fuse_chmod(const char *path, mode_t mode)
+{
+       int ret = -EPERM;
+
+       cfs_debug("enter cfs_fuse_chmod %s", path);
+
+       mode_t allowed_mode = (S_IRUSR | S_IWUSR);
+       if (!path_is_private(path))
+               allowed_mode |= (S_IRGRP);
+
+       // allow only setting our supported modes (0600 for priv, 0640 for rest)
+       // mode has additional bits set, which we ignore; see stat(2)
+       if ((mode & ALLPERMS) == allowed_mode)
+               ret = 0;
+
+       cfs_debug("leave cfs_fuse_chmod %s (%d) mode: %o", path, ret, (int)mode);
+
+       return ret;
+}
+
+static int cfs_fuse_chown(const char *path, uid_t user, gid_t group)
+{
+       int ret = -EPERM;
+
+       cfs_debug("enter cfs_fuse_chown %s", path);
+
+       // we get -1 if no change should be made
+       if ((user == 0 || user == -1) && (group == cfs.gid || group == -1))
+               ret = 0;
+
+       cfs_debug("leave cfs_fuse_chown %s (%d) (uid: %d; gid: %d)", path, ret, user, group);
+
+       return ret;
+}
+
 static int cfs_fuse_mkdir(const char *path, mode_t mode)
 {
        cfs_debug("enter cfs_fuse_mkdir %s", path);
@@ -488,7 +524,9 @@ static struct fuse_operations fuse_ops = {
        .readlink = cfs_fuse_readlink,
        .utimens = cfs_fuse_utimens,
        .statfs = cfs_fuse_statfs,
-       .init = cfs_fuse_init
+       .init = cfs_fuse_init,
+       .chown = cfs_fuse_chown,
+       .chmod = cfs_fuse_chmod
 };
 
 static char *
@@ -823,6 +861,7 @@ int main(int argc, char *argv[])
        umask(027);
 
        mkdir(VARLIBDIR, 0755);
+       mkdir(RUNDIR, 0755);
 
        if ((lockfd = open(LOCKFILE, O_RDWR|O_CREAT|O_APPEND, 0600)) == -1) {
                cfs_critical("unable to create lock '%s': %s", LOCKFILE, strerror (errno));
@@ -872,7 +911,7 @@ int main(int argc, char *argv[])
        int len = memdb_read(memdb, "corosync.conf", &conf_data);
        if (len >= 0) {
                if (force_local_mode) {
-                       cfs_message("forcing local mode (althought corosync.conf exists)");
+                       cfs_message("forcing local mode (although corosync.conf exists)");
                        cfs_set_quorate(1, TRUE);
                } else {
                        if (!(dcdb = dcdb_new(memdb)))
@@ -981,8 +1020,12 @@ int main(int argc, char *argv[])
 
        server_start(memdb);
 
+       unlink(RESTART_FLAG_FILE);
+
        ret = fuse_loop_mt(fuse);
 
+       open(RESTART_FLAG_FILE, O_CREAT|O_NOCTTY|O_NONBLOCK);
+
        cfs_message("teardown filesystem");
 
        server_stop();
@@ -1011,7 +1054,6 @@ int main(int argc, char *argv[])
        if (service_status)
                service_dfsm_destroy(service_status);
 
-       sleep(1); /* do not restart too fast */
  ret:
 
        if (status_fsm)