On Wed, Mar 11, 2009 at 05:42:20PM +0100, Florian Vichot wrote:
Hi everyone,
This patch is to allow using the "mount" type in the "filesystem" tag
for OpenVZ domains.
Example:
...
<filesystem type='mount'>
<source dir='/path/to/filesystem/directory/' />
<target dir='/path/to/pivot/root/' />
</filesystem>
...
This is my first patch to an external project, so don't spare me if I
got things wrong :)
Also, I'm curious for suggestions as to how I could allow for the target
not to be specified in the XML. Because in this case OpenVZ just makes a
temporary pivot root in "/var/lib/vz/root/" and that is probably
sufficient for most people, who might not want to have to explicitly
create a pivot root somewhere, just for mounting the filesystem while
it's running.
Actually the <target dir="..."> means something a little different. This
refers to the mount point *within* the container. So for the root filesystem
of the container it will be <target dir='/' />.
I believe OpenVZ only allows you to setup the root filesystem within the
container, so effectively you'd never need worry about anything other
than the one <target dir='/' />. IMHO there is no need to include the
temporary pivot root location in the XML, just leave it on default.
As an example, of why we have this, the LXC container driver, allows for
specifying multiple filesystems for containers. So you could setup lots
of containers each with their own private root fileystem, and then give
them all the same /home,
eg, in guest 1 you'd have
<filesystem type='mount'>
<source dir='/path/to/root/filesystem/guest1/' />
<target dir='/' />
</filesystem>
<filesystem type='mount'>
<source dir='/path/to/shared/home' />
<target dir='/home' />
</filesystem>
While in guest 2 you'd have
<filesystem type='mount'>
<source dir='/path/to/root/filesystem/guest2/' />
<target dir='/' />
</filesystem>
<filesystem type='mount'>
<source dir='/path/to/shared/home' />
<target dir='/home' />
</filesystem>
diff --git a/src/openvz_conf.c b/src/openvz_conf.c
index ff3d607..33fb259 100644
--- a/src/openvz_conf.c
+++ b/src/openvz_conf.c
@@ -314,6 +314,41 @@ error:
}
+/* utility function to replace 'from' by 'to' in 'str' */
+static char*
+openvz_replace(const char* str,
+ const char* from,
+ int to) {
+ char tmp[4096];
+ char* offset = tmp;
+ int len = strlen(str);
+ int fromLen = strlen(from);
+ int r,i,maxcmp,left = sizeof(tmp);
+
+ if(!from)
+ return NULL;
+
+ for(i = 0; i < len && left; ++i) {
+ /* compare first caracters to limit useless full comparisons */
+ if(*from == str[i]) {
+ maxcmp = (fromLen > len-i) ? len-i : fromLen;
+ if(strncmp(from, str+i, maxcmp) == 0) {
+ r = snprintf(offset, left, "%d", to);
+ offset += r;
+ i += fromLen - 1;
+ continue;
+ }
+ }
+ *offset++ = str[i];
+ left = sizeof(tmp) - (offset-tmp);
+ }
+
+ tmp[sizeof(tmp)-left] = '\0';
+
+ return strdup(tmp);
+}
In this function, can you use STREQLEN(from, str+i, maxcmp) instead
of strncmp == 0.
Also, I think it'd be clearer to avoid using the pre-declared 'char
tmp[4096]'
and instead make use of our automatic grow-on-demand string buffer code.
Just add
#include "buf.h"
Declare it with:
virBuffer buf = VIR_BUFFER_INITIALIZER;
And then use virBufferAdd to append to it
When you're all done, use virBufferError() to check if there was an OOM
condition and return an error. If OK,then use virBufferContentAndReset()
to get the internal char * - no need to strdup() that - you own the
pointer at that point.
@@ -343,7 +378,42 @@ openvzReadFSConf(virConnectPtr conn,
goto no_memory;
def->fss[def->nfss++] = fs;
fs = NULL;
+ } else {
+ /* OSTEMPLATE was not found, VE was booted from a private dir directly */
+ ret = openvzReadConfigParam(veid, "VE_PRIVATE", temp, sizeof(temp));
+ if (ret <= 0) {
+ openvzError(conn, VIR_ERR_INTERNAL_ERROR,
+ _("Cound not read 'VE_PRIVATE' from config for
container %d"),
+ veid);
+ goto error;
+ }
+
+ if (VIR_ALLOC(fs) < 0)
+ goto no_memory;
+
+ fs->type = VIR_DOMAIN_FS_TYPE_MOUNT;
+ fs->src = openvz_replace(temp, "$VEID", veid);
+
+ if (fs->src == NULL)
+ goto no_memory;
+
+ ret = openvzReadConfigParam(veid, "VE_ROOT", temp, sizeof(temp));
+ if (ret <= 0) {
+ openvzError(conn, VIR_ERR_INTERNAL_ERROR,
+ _("Cound not read 'VE_ROOT' from config for
container %d"),
+ veid);
+ goto error;
+ }
+
+ fs->dst = openvz_replace(temp, "$VEID", veid);
+ if (fs->dst == NULL)
+ goto no_memory;
+
+ if (VIR_REALLOC_N(def->fss, def->nfss + 1) < 0)
+ goto no_memory;
+ def->fss[def->nfss++] = fs;
+ fs = NULL;
}
return 0;
@@ -597,6 +667,81 @@ openvzReadConfigParam(int vpsid ,const char * param, char *value,
int maxlen)
return ret ;
}
+static int
+openvz_copyfile(char* from_path, char* to_path)
+{
+ char line[PATH_MAX];
+ int fd, copy_fd;
+ int bytes_read;
+
+ fd = open(from_path, O_RDONLY);
+ if (fd == -1)
+ return -1;
+ copy_fd = open(to_path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
+ if (copy_fd == -1) {
+ close(fd);
+ return -1;
+ }
+
+ while(1) {
+ if (openvz_readline(fd, line, sizeof(line)) <= 0)
+ break;
+
+ bytes_read = strlen(line);
+ if (safewrite(copy_fd, line, bytes_read) != bytes_read)
+ goto error;
+ }
+
+ if (close(fd) < 0)
+ goto error;
+ fd = -1;
+ if (close(copy_fd) < 0)
+ goto error;
+ copy_fd = -1;
+
+ return 0;
+
+error:
+ if (fd != -1)
+ close(fd);
+ if (copy_fd != -1)
+ close(copy_fd);
+ return -1;
+}
+
+/*
+* Copy the default config to the VE conf file
+* return: -1 - error
+* 0 - OK
+*/
+int
+openvzCopyDefaultConfig(int vpsid)
+{
+ char * confdir;
+ char default_conf_file[PATH_MAX], conf_file[PATH_MAX];
+
+ confdir = openvzLocateConfDir();
+ if (confdir == NULL)
+ return -1;
+
+ if (snprintf(default_conf_file, PATH_MAX, "%s/%s",
+ confdir, VZ_DEFAULT_CONF_FILE) >= PATH_MAX)
+ {
+ VIR_FREE(confdir);
+ return -1;
+ }
Could you make use of virAsprintf() here instead of statically declaring
a variable with PATH_MAX. I know we use PATH_MXA all over the place in
libvirt already, but we need to try to get out of that habit where
practical, to avoid wasting too much stack.
+
+ VIR_FREE(confdir);
+
+ if (openvzLocateConfFile(vpsid, conf_file, PATH_MAX, "conf")<0)
+ return -1;
+
+ if (openvz_copyfile(default_conf_file, conf_file)<0)
+ return -1;
+
+ return 0;
+}
+
/* Locate config file of container
Regards,
Daniel
--
|: Red Hat, Engineering, London -o-
http://people.redhat.com/berrange/ :|
|:
http://libvirt.org -o-
http://virt-manager.org -o-
http://ovirt.org :|
|:
http://autobuild.org -o-
http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|