[multipath and multipathd] remove the path cache file logic
authorroot <root@xa-s05.(none)>
Thu, 21 Jul 2005 15:58:45 +0000 (17:58 +0200)
committerroot <root@xa-s05.(none)>
Thu, 21 Jul 2005 15:58:45 +0000 (17:58 +0200)
Replace by an Unix socket communication with the daemon.

The daemon has its pathvec always up-to-date, thanks to its
event-driven model.

As a side-effect, people who care about early userspace have now
2 options :

1) No daemon in early userspace, and disable hotplug-triggered multipath.
   /sbin/multipath is ran once.

2) Start the daemon in early userspace, let multipath be hotplug-triggered

Comments welcome on dm-devel. It's not too late to revert the thing :/

libmultipath/cache.c
libmultipath/cache.h
multipath/main.c
multipathd/cli.c
multipathd/cli.h
multipathd/cli_handlers.c
multipathd/cli_handlers.h
multipathd/main.c
multipathd/main.h
multipathd/uxlsnr.c
multipathd/uxlsnr.h

index de5bb17..e49daca 100644 (file)
@@ -1,62 +1,40 @@
-#include <stdio.h>
 #include <unistd.h>
-#include <fcntl.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <string.h>
-#include <time.h>
 
+#include "memory.h"
 #include "vector.h"
 #include "structs.h"
 #include "debug.h"
 #include "cache.h"
+#include "uxsock.h"
 
 static void
 revoke_cache_info(struct path * pp)
 {
+       pp->checker_context = NULL;
        pp->fd = 0;
 }
 
-static int
-lock_fd (int fd, int flag)
-{
-       struct flock fl;
-
-       fl.l_type = flag;
-       fl.l_whence = 0;
-       fl.l_start = 0;
-       fl.l_len = 0;
-
-       alarm(MAX_WAIT);
-
-       if (fcntl(fd, F_SETLKW, &fl) == -1) {
-               condlog(0, "can't take a write lease on cache file\n");
-               return 1;
-       }
-       alarm(0);
-       return 0;
-}
-
 int
 cache_load (vector pathvec)
 {
+       char *reply;
+       size_t len;
        int fd;
-       int r = 1;
-       off_t record_len;
-       struct path record;
        struct path * pp;
+       int r = 1;
+       char * p;
 
-       fd = open(CACHE_FILE, O_RDONLY);
+        fd = ux_socket_connect(SOCKET_NAME);
 
-       if (fd < 0)
+       if (fd == -1) {
+               condlog(0, "ux_socket_connect error");
                return 1;
+       }
 
-       if (lock_fd(fd, F_RDLCK))
-               goto out;
-
-       record_len = sizeof(struct path);
+       send_packet(fd, "dump pathvec", 13);
+       recv_packet(fd, &reply, &len);
 
-       while (read(fd, &record, record_len)) {
+       for (p = reply; p < (reply + len); p += sizeof(struct path)) {
                pp = alloc_path();
 
                if (!pp)
@@ -67,63 +45,13 @@ cache_load (vector pathvec)
                        goto out;
                }
                vector_set_slot(pathvec, pp);
-               memcpy(pp, &record, record_len);
+               memcpy(pp, (void *)p, sizeof(struct path));
                revoke_cache_info(pp);
        }
-       r = 0;
-       lock_fd(fd, F_UNLCK);
-out:
-       close(fd);
-       return r;
-}
 
-int
-cache_dump (vector pathvec)
-{
-       int i;
-       int fd;
-       int r = 1;
-       off_t record_len;
-       struct path * pp;
-
-       fd = open(CACHE_TMPFILE, O_RDWR|O_CREAT, 0600);
-
-       if (fd < 0)
-               return 1;
-
-       if (lock_fd(fd, F_WRLCK))
-               goto out;
-
-       ftruncate(fd, 0); 
-       record_len = sizeof(struct path);
-
-       vector_foreach_slot (pathvec, pp, i) {
-               if (write(fd, pp, record_len) < record_len)
-                       goto out1;
-       }
-       rename(CACHE_TMPFILE, CACHE_FILE);
        r = 0;
-out1:
-       lock_fd(fd, F_UNLCK);
 out:
+       FREE(reply);
        close(fd);
        return r;
 }
-
-int
-cache_cold (int expire)
-{
-       time_t t;
-       struct stat s;
-
-       if (time(&t) < 0)
-               return 1;
-
-       if(stat(CACHE_FILE, &s))
-               return 1;
-
-       if ((t - s.st_mtime) < expire)
-               return 0;
-
-       return 1;
-}
index aafdb4c..737a50a 100644 (file)
@@ -1,8 +1 @@
-#define CACHE_FILE     "/var/cache/multipath/.multipath.cache"
-#define CACHE_TMPFILE  "/var/cache/multipath/.multipath.cache.tmp"
-#define CACHE_EXPIRE   5
-#define MAX_WAIT       5
-
 int cache_load (vector pathvec);
-int cache_dump (vector pathvec);
-int cache_cold (int expire);
index fc4718c..abd755e 100644 (file)
@@ -177,7 +177,7 @@ print_path (struct path * pp, int style)
                printf("%-7s ", pp->dev_t);
 
        if (conf->list > 1) {
-               len = pstate_snprintf(&buff, MAX_PSTATE_LEN, pp->state);
+               len = pstate_snprintf(&buff[0], MAX_PSTATE_LEN, pp->state);
 
                if (len) {
                        printf("[%s", buff);
@@ -971,9 +971,12 @@ main (int argc, char *argv[])
        if (conf->dev && blacklist(conf->blist, conf->dev))
                goto out;
        
-       if (!cache_cold(CACHE_EXPIRE)) {
-               condlog(3, "load path identifiers cache");
-               cache_load(pathvec);
+       condlog(3, "load path identifiers cache");
+       cache_load(pathvec);
+
+       if (conf->verbosity > 2) {
+               fprintf(stdout, "#\n# all paths in cache :\n#\n");
+               print_all_paths(pathvec);
        }
 
        /*
@@ -1005,7 +1008,6 @@ main (int argc, char *argv[])
        if (get_dm_mpvec(curmp, pathvec, refwwid))
                goto out;
 
-       cache_dump(pathvec);
        filter_pathvec(pathvec, refwwid);
 
        if (conf->list)
index c83fada..fadf096 100644 (file)
@@ -48,7 +48,7 @@ out:
 }
 
 int
-add_handler (int fp, char * (*fn)(void *, void *))
+add_handler (int fp, int (*fn)(void *, char **, int *, void *))
 {
        struct handler * h;
 
@@ -126,6 +126,8 @@ load_keys (void)
        r += add_key(keys, "path", PATH, 1);
        r += add_key(keys, "map", MAP, 1);
        r += add_key(keys, "group", GROUP, 1);
+       r += add_key(keys, "dump", DUMP, 0);
+       r += add_key(keys, "pathvec", PATHVEC, 0);
 
        if (r) {
                free_keys(keys);
@@ -143,7 +145,8 @@ find_key (char * str)
        struct key * kw = NULL;
 
        vector_foreach_slot (keys, kw, i)
-               if (!strncmp(kw->str, str, strlen(kw->str)))
+               if (strlen(str) == strlen(kw->str) &&
+                   !strcmp(kw->str, str))
                                return kw;
 
        return NULL;
@@ -298,28 +301,34 @@ genhelp_handler (void)
        return reply;
 }
 
-char *
-parse_cmd (char * cmd, void * data)
+int
+parse_cmd (char * cmd, char ** reply, int * len, void * data)
 {
-       char * reply;
+       int r;
        struct handler * h;
        vector cmdvec = get_cmdvec(cmd);
 
-       if (!cmdvec)
-               return genhelp_handler();
+       if (!cmdvec) {
+               *reply = genhelp_handler();
+               *len = strlen(*reply);
+               return 0;
+       }
 
        h = find_handler(fingerprint(cmdvec));
 
-       if (!h)
-               return genhelp_handler();
+       if (!h) {
+               *reply = genhelp_handler();
+               *len = strlen(*reply);
+               return 0;
+       }
 
        /*
         * execute handler
         */
-       reply = h->fn(cmdvec, data);
+       r = h->fn(cmdvec, reply, len, data);
        free_keys(cmdvec);
 
-       return reply;
+       return r;
 }
 
 char *
index 486ea39..0824f30 100644 (file)
@@ -7,6 +7,8 @@
 #define PATH   (1 << 6)
 #define MAP    (1 << 7)
 #define GROUP  (1 << 8)
+#define DUMP   (1 << 9)
+#define PATHVEC        (1 << 10)
 
 #define MAX_REPLY_LEN 1000
 
@@ -19,15 +21,15 @@ struct key {
 
 struct handler {
        int fingerprint;
-       char * (*fn)(void *, void *);
+       int (*fn)(void *, char **, int *, void *);
 };
 
 vector keys;
 vector handlers;
 
 int alloc_handlers (void);
-int add_handler (int fp, char * (*fn)(void *, void *));
-char * parse_cmd (char * cmd, void *);
+int add_handler (int fp, int (*fn)(void *, char **, int *, void *));
+int parse_cmd (char * cmd, char ** reply, int * len, void *);
 int load_keys (void);
 char * get_keyparam (vector v, int code);
 void free_keys (vector vec);
index 8526714..ffa3bea 100644 (file)
@@ -6,77 +6,71 @@
 #include "main.h"
 #include "cli.h"
 
-char *
-list_paths (void * v, void * data)
+int
+cli_list_paths (void * v, char ** reply, int * len, void * data)
 {
        struct paths * allpaths = (struct paths *)data;
 
-       return show_paths(allpaths);
+       return show_paths(reply, len, allpaths);
 }
 
-char *
-list_maps (void * v, void * data)
+int
+cli_list_maps (void * v, char ** reply, int * len, void * data)
 {
        struct paths * allpaths = (struct paths *)data;
 
-       return show_maps(allpaths);
+       return show_maps(reply, len, allpaths);
 }
 
-char *
-add_path (void * v, void * data)
+int
+cli_add_path (void * v, char ** reply, int * len, void * data)
 {
        struct paths * allpaths = (struct paths *)data;
        char * param = get_keyparam(v, PATH);
 
-       if (uev_add_path(param, allpaths))
-               return NULL;
-
-       return STRDUP("ok");
+       return uev_add_path(param, allpaths);
 }
 
-char *
-del_path (void * v, void * data)
+int
+cli_del_path (void * v, char ** reply, int * len, void * data)
 {
        struct paths * allpaths = (struct paths *)data;
        char * param = get_keyparam(v, PATH);
 
-       if (uev_remove_path(param, allpaths))
-               return NULL;
-
-       return STRDUP("ok");
+       return uev_remove_path(param, allpaths);
 }
 
-char *
-add_map (void * v, void * data)
+int
+cli_add_map (void * v, char ** reply, int * len, void * data)
 {
        struct paths * allpaths = (struct paths *)data;
        char * param = get_keyparam(v, MAP);
 
-       if (uev_add_map(param, allpaths))
-               return NULL;
-
-       return STRDUP("ok");
+       return uev_add_map(param, allpaths);
 }
 
-char *
-del_map (void * v, void * data)
+int
+cli_del_map (void * v, char ** reply, int * len, void * data)
 {
        struct paths * allpaths = (struct paths *)data;
        char * param = get_keyparam(v, MAP);
 
-       if (uev_remove_map(param, allpaths))
-               return NULL;
-
-       return STRDUP("ok");
+       return uev_remove_map(param, allpaths);
 }
 
-char *
-switch_group(void * v, void * data)
+int
+cli_switch_group(void * v, char ** reply, int * len, void * data)
 {
        char * mapname = get_keyparam(v, MAP);
        int groupnum = atoi(get_keyparam(v, GROUP));
        
-       dm_switchgroup(mapname, groupnum);
+       return dm_switchgroup(mapname, groupnum);
+}
 
-       return STRDUP("ok");
+int
+cli_dump_pathvec(void * v, char ** reply, int * len, void * data)
+{
+       struct paths * allpaths = (struct paths *)data;
+                       
+       return dump_pathvec(reply, len, allpaths);
 }
index 659441a..f856638 100644 (file)
@@ -1,7 +1,8 @@
-char * list_paths (void * v, void * data);
-char * list_maps (void * v, void * data);
-char * add_path (void * v, void * data);
-char * del_path (void * v, void * data);
-char * add_map (void * v, void * data);
-char * del_map (void * v, void * data);
-char * switch_group (void * v, void * data);
+int cli_list_paths (void * v, char ** reply, int * len, void * data);
+int cli_list_maps (void * v, char ** reply, int * len, void * data);
+int cli_add_path (void * v, char ** reply, int * len, void * data);
+int cli_del_path (void * v, char ** reply, int * len, void * data);
+int cli_add_map (void * v, char ** reply, int * len, void * data);
+int cli_del_map (void * v, char ** reply, int * len, void * data);
+int cli_switch_group(void * v, char ** reply, int * len, void * data);
+int cli_dump_pathvec(void * v, char ** reply, int * len, void * data);
index 2216f74..ed4067a 100644 (file)
@@ -671,8 +671,8 @@ uev_remove_path (char * devname, struct paths * allpaths)
        return 0;
 }
 
-char *
-show_paths (struct paths * allpaths)
+int
+show_paths (char ** r, int * len, struct paths * allpaths)
 {
        int i, j, k;
        struct path * pp;
@@ -682,7 +682,7 @@ show_paths (struct paths * allpaths)
        reply = MALLOC(MAX_REPLY_LEN);
 
        if (!reply)
-               return NULL;
+               return 1;
 
        c = reply;
        c += sprintf(c, "\n");
@@ -697,7 +697,7 @@ show_paths (struct paths * allpaths)
 
                if (MAX_REPLY_LEN - MAX_PSTATE_LEN < 0) {
                        FREE(reply);
-                       return NULL;
+                       return 1;
                }
 
                j = pstate_snprintf(c, MAX_PSTATE_LEN, pp->state);
@@ -721,12 +721,13 @@ show_paths (struct paths * allpaths)
                c += sprintf(c, "\n");
        }
 
-       reply[MAX_REPLY_LEN - 1] = 0;
-       return reply;
+       *r = reply;
+       *len = (int)(c - reply);
+       return 0;
 }
 
-char *
-show_maps (struct paths * allpaths)
+int
+show_maps (char ** r, int *len, struct paths * allpaths)
 {
        int i, j, k;
        struct multipath * mpp;
@@ -736,7 +737,7 @@ show_maps (struct paths * allpaths)
        reply = MALLOC(MAX_REPLY_LEN);
 
        if (!reply)
-               return NULL;
+               return 1;
 
        c = reply;
        c += sprintf(c, "\n");
@@ -763,32 +764,65 @@ show_maps (struct paths * allpaths)
                c += sprintf(c, "\n");
        }
 
-       reply[MAX_REPLY_LEN - 1] = 0;
-       return reply;
+       *r = reply;
+       *len = (int)(c - reply);
+       return 0;
 }
 
-char *
-uxsock_trigger (char * str, void * trigger_data)
+int
+dump_pathvec (char ** r, int * len, struct paths * allpaths)
 {
-       struct paths * allpaths;
-       char * reply = NULL;
+       int i;
+       struct path * pp;
+       char * reply;
+       char * p;
+
+       *len = VECTOR_SIZE(allpaths->pathvec) * sizeof(struct path);
+       reply = (char *)MALLOC(*len);
+       *r = reply;
+
+       if (!reply)
+               return 1;
 
+       p = reply;
+
+       vector_foreach_slot (allpaths->pathvec, pp, i) {
+               memcpy((void *)p, pp, sizeof(struct path));
+               p += sizeof(struct path);
+       }
+
+       return 0;
+}
+
+int
+uxsock_trigger (char * str, char ** reply, int * len, void * trigger_data)
+{
+       struct paths * allpaths;
+       int r;
+       
+       *reply = NULL;
+       *len = 0;
        allpaths = (struct paths *)trigger_data;
 
        pthread_cleanup_push(cleanup_lock, allpaths->lock);
        lock(allpaths->lock);
 
-       reply = parse_cmd(str, allpaths);
-
-       if (!reply)
-               reply = STRDUP("fail\n");
+       r = parse_cmd(str, reply, len, allpaths);
 
-       else if (strlen(reply) == 0)
-               reply = STRDUP("ok\n");
+       if (r) {
+               *reply = STRDUP("fail\n");
+               *len = strlen(*reply) + 1;
+               r = 1;
+       }
+       else if (*len == 0) {
+               *reply = STRDUP("ok\n");
+               *len = strlen(*reply) + 1;
+               r = 0;
+       }
 
        pthread_cleanup_pop(1);
 
-       return reply;
+       return r;
 }
 
 int 
@@ -862,13 +896,14 @@ uxlsnrloop (void * ap)
        if (alloc_handlers())
                return NULL;
 
-       add_handler(LIST+PATHS, list_paths);
-       add_handler(LIST+MAPS, list_maps);
-       add_handler(ADD+PATH, add_path);
-       add_handler(DEL+PATH, del_path);
-       add_handler(ADD+MAP, add_map);
-       add_handler(DEL+MAP, del_map);
-       add_handler(SWITCH+MAP+GROUP, switch_group);
+       add_handler(LIST+PATHS, cli_list_paths);
+       add_handler(LIST+MAPS, cli_list_maps);
+       add_handler(ADD+PATH, cli_add_path);
+       add_handler(DEL+PATH, cli_del_path);
+       add_handler(ADD+MAP, cli_add_map);
+       add_handler(DEL+MAP, cli_del_map);
+       add_handler(SWITCH+MAP+GROUP, cli_switch_group);
+       add_handler(DUMP+PATHVEC, cli_dump_pathvec);
 
        uxsock_listen(&uxsock_trigger, ap);
 
index 6a56bdd..f240ca2 100644 (file)
@@ -12,8 +12,9 @@ struct paths {
        vector mpvec;
 };
 
-char * show_paths (struct paths *);
-char * show_maps (struct paths *);
+int show_paths (char **, int *, struct paths *);
+int show_maps (char **, int *, struct paths *);
+int dump_pathvec (char **, int *, struct paths * allpaths);
 int uev_add_path (char *, struct paths *);
 int uev_remove_path (char *, struct paths *);
 int uev_add_map (char *, struct paths *);
index 44c2588..b4999b6 100644 (file)
@@ -76,11 +76,12 @@ void free_polls (void)
 /*
  * entry point
  */
-void * uxsock_listen(char * (*uxsock_trigger)(char *, void * trigger_data),
+void * uxsock_listen(int (*uxsock_trigger)(char *, char **, int *, void *),
                        void * trigger_data)
 {
        int ux_sock;
        size_t len;
+       int rlen;
        char *inbuf;
        char *reply;
 
@@ -129,16 +130,17 @@ void * uxsock_listen(char * (*uxsock_trigger)(char *, void * trigger_data),
                                        dead_client(c);
                                } else {
                                        inbuf[len - 1] = 0;
-                                       condlog(4, "Got request [s]", inbuf);
-                                       reply = uxsock_trigger(inbuf,
+                                       condlog(4, "Got request [%s]", inbuf);
+                                       uxsock_trigger(inbuf, &reply, &rlen,
                                                        trigger_data);
 
                                        if (reply) {
                                                if (send_packet(c->fd, reply,
-                                                    strlen(reply) + 1) != 0) {
+                                                    rlen) != 0) {
                                                        dead_client(c);
                                                }
                                                FREE(reply);
+                                               reply = NULL;
                                        }
                                        FREE(inbuf);
                                }
index 31fcbd5..00d98b0 100644 (file)
@@ -1,7 +1,7 @@
 struct pollfd *polls;
 
 void free_polls(void);
-void * uxsock_listen(char * (*uxsock_trigger)
-                       (char *, void * trigger_data),
+void * uxsock_listen(int (*uxsock_trigger)
+                       (char *, char **, int *, void *),
                        void * trigger_data);