]> git.proxmox.com Git - mirror_lxc.git/commitdiff
Add clone_update_unexp_ovl_paths() function
authorChristian Brauner <christianvanbrauner@gmail.com>
Mon, 2 Nov 2015 22:20:35 +0000 (23:20 +0100)
committerStéphane Graber <stgraber@ubuntu.com>
Fri, 6 Nov 2015 18:28:23 +0000 (13:28 -0500)
This functions updates absolute paths for overlay upper- and workdirs so users
can simply clone and start new containers without worrying about absolute paths
in lxc.mount.entry overlay entries.

Signed-off-by: Christian Brauner <christianvanbrauner@gmail.com>
Acked-by: Serge E. Hallyn <serge.hallyn@ubuntu.com>
src/lxc/confile.c
src/lxc/confile.h

index f7d68140025b72ebfda048a9974a8d84f90991b8..d5849643469ac1f0f780554f8cc731f11d43589d 100644 (file)
@@ -2598,6 +2598,102 @@ void clear_unexp_config_line(struct lxc_conf *conf, const char *key, bool rm_sub
        }
 }
 
+bool clone_update_unexp_ovl_paths(struct lxc_conf *conf, const char *oldpath,
+                                 const char *newpath, const char *oldname,
+                                 const char *newname, const char *ovldir)
+{
+       const char *key = "lxc.mount.entry";
+       int ret;
+       char *lstart = conf->unexpanded_config;
+       char *lend;
+       char *p;
+       char *q;
+       size_t newdirlen = strlen(ovldir) + strlen(newpath) + strlen(newname) + 2;
+       size_t olddirlen = strlen(ovldir) + strlen(oldpath) + strlen(oldname) + 2;
+       char *olddir = alloca(olddirlen + 1);
+       char *newdir = alloca(newdirlen + 1);
+
+       ret = snprintf(olddir, olddirlen + 1, "%s=%s/%s", ovldir, oldpath, oldname);
+       if (ret < 0 || ret >= olddirlen + 1) {
+               ERROR("Bug in %s", __func__);
+               return false;
+       }
+       ret = snprintf(newdir, newdirlen + 1, "%s=%s/%s", ovldir, newpath, newname);
+       if (ret < 0 || ret >= newdirlen + 1) {
+               ERROR("Bug in %s", __func__);
+               return false;
+       }
+       if (!conf->unexpanded_config)
+               return true;
+       while (*lstart) {
+               lend = strchr(lstart, '\n');
+               if (!lend)
+                       lend = lstart + strlen(lstart);
+               else
+                       lend++;
+               if (strncmp(lstart, key, strlen(key)) != 0)
+                        goto next;
+               p = strchr(lstart + strlen(key), '=');
+               if (!p)
+                        goto next;
+               p++;
+               while (isblank(*p))
+                       p++;
+               if (p >= lend)
+                        goto next;
+                /* Whenever an lxc.mount.entry entry is found in a line we check
+                *  if the substring " overlay" or the substring " aufs" is
+                *  present before doing any further work. We check for "
+                *  overlay" and " aufs" since both substrings need to have at
+                *  least one space before them in a valid overlay
+                *  lxc.mount.entry (/A B overlay).  When the space before is
+                *  missing it is very likely that these substrings are part of a
+                *  path or something else. (Checking q >= lend ensures that we
+                *  only count matches in the current line.) */
+               if ((!(q = strstr(p, " overlay")) || q >= lend) && (!(q = strstr(p, " aufs")) || q >= lend))
+                        goto next;
+               if (!(q = strstr(p, olddir)) || (q >= lend))
+                        goto next;
+
+               /* replace the olddir with newdir */
+               if (olddirlen >= newdirlen) {
+                       size_t diff = olddirlen - newdirlen;
+                       memcpy(q, newdir, newdirlen);
+                       if (olddirlen != newdirlen) {
+                               memmove(q + newdirlen, q + newdirlen + diff,
+                                       strlen(q) - newdirlen - diff + 1);
+                               lend -= diff;
+                               conf->unexpanded_len -= diff;
+                       }
+               } else {
+                       char *new;
+                       size_t diff = newdirlen - olddirlen;
+                       size_t oldlen = conf->unexpanded_len;
+                       size_t newlen = oldlen + diff;
+                       size_t poffset = q - conf->unexpanded_config;
+                       new = realloc(conf->unexpanded_config, newlen + 1);
+                       if (!new) {
+                               ERROR("Out of memory");
+                               return false;
+                       }
+                       conf->unexpanded_len = newlen;
+                       conf->unexpanded_alloced = newlen + 1;
+                       new[newlen - 1] = '\0';
+                       lend = new + (lend - conf->unexpanded_config);
+                       /* move over the remainder to make room for the newdir */
+                       memmove(new + poffset + newdirlen,
+                               new + poffset + olddirlen,
+                               oldlen - poffset - olddirlen + 1);
+                       conf->unexpanded_config = new;
+                       memcpy(new + poffset, newdir, newdirlen);
+                       lend += diff;
+               }
+next:
+                       lstart = lend;
+       }
+       return true;
+}
+
 bool clone_update_unexp_hooks(struct lxc_conf *conf, const char *oldpath,
        const char *newpath, const char *oldname, const char *newname)
 {
index 8da3699078af806d775470bceec0d52c9bb0417b..12ffd3c50259cd4a16c5731222a41b3912a3ab2c 100644 (file)
@@ -61,5 +61,8 @@ extern bool do_append_unexp_config_line(struct lxc_conf *conf, const char *key,
 extern void clear_unexp_config_line(struct lxc_conf *conf, const char *key, bool rm_subkeys);
 extern bool clone_update_unexp_hooks(struct lxc_conf *conf, const char *oldpath,
        const char *newpath, const char *oldname, const char *newmame);
+bool clone_update_unexp_ovl_paths(struct lxc_conf *conf, const char *oldpath,
+                                 const char *newpath, const char *oldname,
+                                 const char *newname, const char *ovldir);
 extern bool network_new_hwaddrs(struct lxc_conf *conf);
 #endif