[Libvir] [PATCH] Miscellaneous fixes to #includes
by Richard W.M. Jones
(1) #include <libvirt/*.h> ---> #include "libvirt/*.h"
(2) src/internal.h has become a dumping ground for all sorts of
includes. Removed the ones which are not actually used in this file
(ie. almost all of them) and moved them down into the two files which
actually needed them.
(3) Remove <ansidecl.h>, which is apparently some legacy thing.
(4) Add a comment that __func__ is from the C99 standard.
(5) xen_unified.c was defining a symbol called 'VERSION' which clashed
with the one from "config.h", so change it to HV_VERSION.
(6) <limits.h> / <sys/syslimits.h> / backup plan if neither exists -- is
done in src/internal.h, so remove explicit includes from other files.
Rich.
--
Emerging Technologies, Red Hat - http://et.redhat.com/~rjones/
Registered Address: Red Hat UK Ltd, Amberley Place, 107-111 Peascod
Street, Windsor, Berkshire, SL4 1TE, United Kingdom. Registered in
England and Wales under Company Registration No. 03798903
16 years, 11 months
[Libvir] Port forwarding
by Richard W.M. Jones
What do people think about adding port forwarding to network configurations?
At the moment it's unnecessarily difficult to connect to (eg.) sshd port
or remote desktop port on a virtual machine running under the virtual
network configuration. If those ports could be mapped to consecutive
ports on the public (eth0) interface then connecting would be simply a
matter of knowing the port number.
AFAICS this could be implemented by adding rules such as these to the
iptables:
iptables -t nat -A PREROUTING -i $EXTIF -p tcp --dport 80 \
-j DNAT --to-destination 192.168.122.5
iptables -A FORWARD -i $EXTIF -p tcp --dport 80 -j ACCEPT
iptables -t nat -A PREROUTING -i $INTIF -p tcp -d $EXTIP --dport 80 \
-j DNAT --to-destination 192.168.122.5
iptables -A FORWARD -i $INTIF -p tcp -d $EXTIP --dport 80 -j ACCEPT
(rules taken from
http://www.ma.utexas.edu/users/stirling/computergeek/server.html)
Rich.
PS. I'm assuming that this is _not_ what the current /network/forward
XML does? It seems to enable forwarding for a single privileged guest
as far as I can work out.
--
Emerging Technologies, Red Hat - http://et.redhat.com/~rjones/
Registered Address: Red Hat UK Ltd, Amberley Place, 107-111 Peascod
Street, Windsor, Berkshire, SL4 1TE, United Kingdom. Registered in
England and Wales under Company Registration No. 03798903
16 years, 11 months
[Libvir] [PATCH] Remove curses, don't require readline
by Richard W.M. Jones
This patch removes checking for curses/ncurses. It is never used.
It also allows libvirt to be compiled without readline support. If
readline support is not available then the only difference is that
'virsh' will be built without it -- in other words, command line editing
will not work in virsh.
Rich.
--
Emerging Technologies, Red Hat - http://et.redhat.com/~rjones/
Registered Address: Red Hat UK Ltd, Amberley Place, 107-111 Peascod
Street, Windsor, Berkshire, SL4 1TE, United Kingdom. Registered in
England and Wales under Company Registration No. 03798903
16 years, 11 months
[Libvir] [PATCH] No rpcgen at all
by Richard W.M. Jones
If there is no 'rpcgen' program at all then ./configure fails. It
should not, because rpcgen is not necessary to build libvirt.
Patch fixes.
Rich.
--
Emerging Technologies, Red Hat - http://et.redhat.com/~rjones/
Registered Address: Red Hat UK Ltd, Amberley Place, 107-111 Peascod
Street, Windsor, Berkshire, SL4 1TE, United Kingdom. Registered in
England and Wales under Company Registration No. 03798903
16 years, 11 months
[Libvir] PATCH: strip auto-generated VIF names from XML
by Daniel P. Berrange
For the QEMU / KVM driver, if the user doesn't specify an explicit name for
the TAP device associated with a virtual NIC, we auto-generate one with a
name vnetXXX. You can see this if you dump XML for a running QEMU guest.
Unfortunately if you dump XML, make a change and then feed it back in with
the define XML API, you have now persisted this auto-generated VIF name.
Do this for several domains at varying times and you'll eventually get
2 domains which have persisted the same auto-generated vnetXXX device
name. You can now not start both of these VMs at once.
The fix for this is simple - simply strip any TAP device name starting with
the string 'vnet' when defining a new VM. It will thus get assigned a new
automatically generate name which doesn't clash. The patch also strips out
hardcoded vnetXXX names when starting a VM to proactively deal with any
existing VMs whose config has been broken in this way.
Dan.
--
|=- Red Hat, Engineering, Emerging Technologies, Boston. +1 978 392 2496 -=|
|=- Perl modules: http://search.cpan.org/~danberr/ -=|
|=- Projects: http://freshmeat.net/~danielpb/ -=|
|=- GnuPG: 7D3B9505 F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 -=|
16 years, 11 months
[Libvir] [PATCH] Avoid compile failure when HAVE_AVAHI is not defined.
by Jim Meyering
Without this patch, building without HAVE_AVAHI fails due to an unguarded
use of mdns_name. Rather than adding yet another #ifdef..#endif (ugly
and less maintainable), I've chosen to un-ifdef the declarations and
a few uses. The more code that we compile and use unconditionally,
the fewer surprises we'll encounter down the road.
Mon Dec 3 14:24:20 CET 2007 Jim Meyering <meyering(a)redhat.com>
Avoid compile failure when HAVE_AVAHI is not defined.
* qemud/qemud.c (remoteReadConfigFile): Remove some of the
"#ifdef HAVE_AVAHI" guards around uses of mdns_name and mdns_adv.
diff --git a/qemud/qemud.c b/qemud/qemud.c
index 9904e4a..f88ed42 100644
--- a/qemud/qemud.c
+++ b/qemud/qemud.c
@@ -77,10 +77,8 @@ static gid_t unix_sock_gid = 0; /* Only root by default */
static int unix_sock_rw_mask = 0700; /* Allow user only */
static int unix_sock_ro_mask = 0777; /* Allow world */
-#ifdef HAVE_AVAHI
static int mdns_adv = 1;
static char *mdns_name = NULL;
-#endif
static int tls_no_verify_certificate = 0;
static int tls_no_verify_address = 0;
@@ -1696,10 +1694,8 @@ remoteReadConfigFile (const char *filename)
unix_sock_rw_perms = NULL;
}
-#ifdef HAVE_AVAHI
GET_CONF_INT (conf, filename, mdns_adv);
GET_CONF_STR (conf, filename, mdns_name);
-#endif
GET_CONF_INT (conf, filename, tls_no_verify_certificate);
GET_CONF_INT (conf, filename, tls_no_verify_address);
--
1.5.3.7.949.g2221a6
16 years, 12 months
[Libvir] PATCH: Pull generic I/O apis out of QEMU driver
by Daniel P. Berrange
The QEMU driver has a number of handy APIs which I want to use from the
storage driver:
- Read entire file in one go
- Check filename suffix
- Compare filename against name + suffix
- Check link destination
- Construct a filename from dir, name + suffix
- Recursively make a directory
This patch pulls all these methods out of the QEMU driver, gives them a
sensible name and adds them to the util.h file. No functional change, this
is a straight refactoring.
qemu_conf.c | 256 ++++------------------------------------------------------
qemu_conf.h | 1
qemu_driver.c | 6 -
util.c | 223 ++++++++++++++++++++++++++++++++++++++++++++++++++
util.h | 29 ++++++
5 files changed, 275 insertions(+), 240 deletions(-)
diff -r 41c9eb891349 src/qemu_conf.c
--- a/src/qemu_conf.c Sun Dec 02 13:30:44 2007 -0500
+++ b/src/qemu_conf.c Sun Dec 02 13:40:44 2007 -0500
@@ -48,6 +48,7 @@
#include "uuid.h"
#include "buf.h"
#include "conf.h"
+#include "util.h"
#define qemudLog(level, msg...) fprintf(stderr, msg)
@@ -227,55 +228,6 @@ void qemudFreeVM(struct qemud_vm *vm) {
free(vm);
}
-/* Build up a fully qualfiied path for a config file to be
- * associated with a persistent guest or network */
-static int
-qemudMakeConfigPath(const char *configDir,
- const char *name,
- const char *ext,
- char *buf,
- unsigned int buflen) {
- if ((strlen(configDir) + 1 + strlen(name) + (ext ? strlen(ext) : 0) + 1) > buflen)
- return -1;
-
- strcpy(buf, configDir);
- strcat(buf, "/");
- strcat(buf, name);
- if (ext)
- strcat(buf, ext);
- return 0;
-}
-
-int
-qemudEnsureDir(const char *path)
-{
- struct stat st;
- char parent[PATH_MAX];
- char *p;
- int err;
-
- if (stat(path, &st) >= 0)
- return 0;
-
- strncpy(parent, path, PATH_MAX);
- parent[PATH_MAX - 1] = '\0';
-
- if (!(p = strrchr(parent, '/')))
- return EINVAL;
-
- if (p == parent)
- return EPERM;
-
- *p = '\0';
-
- if ((err = qemudEnsureDir(parent)))
- return err;
-
- if (mkdir(path, 0777) < 0 && errno != EEXIST)
- return errno;
-
- return 0;
-}
/* The list of possible machine types for various architectures,
as supported by QEMU - taken from 'qemu -M ?' for each arch */
@@ -2075,22 +2027,22 @@ qemudSaveVMDef(virConnectPtr conn,
if (vm->configFile[0] == '\0') {
int err;
- if ((err = qemudEnsureDir(driver->configDir))) {
+ if ((err = virFileMakePath(driver->configDir))) {
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
"cannot create config directory %s: %s",
driver->configDir, strerror(err));
return -1;
}
- if (qemudMakeConfigPath(driver->configDir, def->name, ".xml",
- vm->configFile, PATH_MAX) < 0) {
+ if (virFileBuildPath(driver->configDir, def->name, ".xml",
+ vm->configFile, PATH_MAX) < 0) {
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
"cannot construct config file path");
return -1;
}
- if (qemudMakeConfigPath(driver->autostartDir, def->name, ".xml",
- vm->autostartLink, PATH_MAX) < 0) {
+ if (virFileBuildPath(driver->autostartDir, def->name, ".xml",
+ vm->autostartLink, PATH_MAX) < 0) {
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
"cannot construct autostart link path");
vm->configFile[0] = '\0';
@@ -2114,7 +2066,7 @@ static int qemudSaveNetworkConfig(virCon
return -1;
}
- if ((err = qemudEnsureDir(driver->networkConfigDir))) {
+ if ((err = virFileMakePath(driver->networkConfigDir))) {
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
"cannot create config directory %s: %s",
driver->networkConfigDir, strerror(err));
@@ -2521,22 +2473,22 @@ qemudSaveNetworkDef(virConnectPtr conn,
if (network->configFile[0] == '\0') {
int err;
- if ((err = qemudEnsureDir(driver->networkConfigDir))) {
+ if ((err = virFileMakePath(driver->networkConfigDir))) {
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
"cannot create config directory %s: %s",
driver->networkConfigDir, strerror(err));
return -1;
}
- if (qemudMakeConfigPath(driver->networkConfigDir, def->name, ".xml",
- network->configFile, PATH_MAX) < 0) {
+ if (virFileBuildPath(driver->networkConfigDir, def->name, ".xml",
+ network->configFile, PATH_MAX) < 0) {
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
"cannot construct config file path");
return -1;
}
- if (qemudMakeConfigPath(driver->networkAutostartDir, def->name, ".xml",
- network->autostartLink, PATH_MAX) < 0) {
+ if (virFileBuildPath(driver->networkAutostartDir, def->name, ".xml",
+ network->autostartLink, PATH_MAX) < 0) {
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
"cannot construct autostart link path");
network->configFile[0] = '\0';
@@ -2547,174 +2499,6 @@ qemudSaveNetworkDef(virConnectPtr conn,
return qemudSaveNetworkConfig(conn, driver, network, def);
}
-static int
-qemudReadFile(const char *path,
- char *buf,
- int maxlen) {
- FILE *fh;
- struct stat st;
- int ret = 0;
-
- if (!(fh = fopen(path, "r"))) {
- qemudLog(QEMUD_WARN, "Failed to open file '%s': %s",
- path, strerror(errno));
- goto error;
- }
-
- if (fstat(fileno(fh), &st) < 0) {
- qemudLog(QEMUD_WARN, "Failed to stat file '%s': %s",
- path, strerror(errno));
- goto error;
- }
-
- if (S_ISDIR(st.st_mode)) {
- qemudDebug("Ignoring directory '%s' - clearly not a config file", path);
- goto error;
- }
-
- if (st.st_size >= maxlen) {
- qemudLog(QEMUD_WARN, "File '%s' is too large", path);
- goto error;
- }
-
- if ((ret = fread(buf, st.st_size, 1, fh)) != 1) {
- qemudLog(QEMUD_WARN, "Failed to read config file '%s': %s",
- path, strerror(errno));
- goto error;
- }
-
- buf[st.st_size] = '\0';
-
- ret = 1;
-
- error:
- if (fh)
- fclose(fh);
-
- return ret;
-}
-
-static int
-compareFileToNameSuffix(const char *file,
- const char *name,
- const char *suffix) {
- int filelen = strlen(file);
- int namelen = strlen(name);
- int suffixlen = strlen(suffix);
-
- if (filelen == (namelen + suffixlen) &&
- !strncmp(file, name, namelen) &&
- !strncmp(file + namelen, suffix, suffixlen))
- return 1;
- else
- return 0;
-}
-
-static int
-hasSuffix(const char *str,
- const char *suffix)
-{
- int len = strlen(str);
- int suffixlen = strlen(suffix);
-
- if (len < suffixlen)
- return 0;
-
- return strcmp(str + len - suffixlen, suffix) == 0;
-}
-
-static int
-checkLinkPointsTo(const char *checkLink,
- const char *checkDest)
-{
- char dest[PATH_MAX];
- char real[PATH_MAX];
- char checkReal[PATH_MAX];
- int n;
- int passed = 0;
-
- /* read the link destination */
- if ((n = readlink(checkLink, dest, PATH_MAX)) < 0) {
- switch (errno) {
- case ENOENT:
- case ENOTDIR:
- break;
-
- case EINVAL:
- qemudLog(QEMUD_WARN, "Autostart file '%s' is not a symlink",
- checkLink);
- break;
-
- default:
- qemudLog(QEMUD_WARN, "Failed to read autostart symlink '%s': %s",
- checkLink, strerror(errno));
- break;
- }
-
- goto failed;
- } else if (n >= PATH_MAX) {
- qemudLog(QEMUD_WARN, "Symlink '%s' contents too long to fit in buffer",
- checkLink);
- goto failed;
- }
-
- dest[n] = '\0';
-
- /* make absolute */
- if (dest[0] != '/') {
- char dir[PATH_MAX];
- char tmp[PATH_MAX];
- char *p;
-
- strncpy(dir, checkLink, PATH_MAX);
- dir[PATH_MAX-1] = '\0';
-
- if (!(p = strrchr(dir, '/'))) {
- qemudLog(QEMUD_WARN, "Symlink path '%s' is not absolute", checkLink);
- goto failed;
- }
-
- if (p == dir) /* handle unlikely root dir case */
- p++;
-
- *p = '\0';
-
- if (qemudMakeConfigPath(dir, dest, NULL, tmp, PATH_MAX) < 0) {
- qemudLog(QEMUD_WARN, "Path '%s/%s' is too long", dir, dest);
- goto failed;
- }
-
- strncpy(dest, tmp, PATH_MAX);
- dest[PATH_MAX-1] = '\0';
- }
-
- /* canonicalize both paths */
- if (!realpath(dest, real)) {
- qemudLog(QEMUD_WARN, "Failed to expand path '%s' :%s",
- dest, strerror(errno));
- strncpy(real, dest, PATH_MAX);
- real[PATH_MAX-1] = '\0';
- }
-
- if (!realpath(checkDest, checkReal)) {
- qemudLog(QEMUD_WARN, "Failed to expand path '%s' :%s",
- checkDest, strerror(errno));
- strncpy(checkReal, checkDest, PATH_MAX);
- checkReal[PATH_MAX-1] = '\0';
- }
-
- /* compare */
- if (strcmp(checkReal, real) != 0) {
- qemudLog(QEMUD_WARN, "Autostart link '%s' is not a symlink to '%s', ignoring",
- checkLink, checkReal);
- goto failed;
- }
-
- passed = 1;
-
- failed:
- return passed;
-}
static struct qemud_vm *
qemudLoadConfig(struct qemud_driver *driver,
@@ -2732,7 +2516,7 @@ qemudLoadConfig(struct qemud_driver *dri
return NULL;
}
- if (!compareFileToNameSuffix(file, def->name, ".xml")) {
+ if (!virFileMatchesNameSuffix(file, def->name, ".xml")) {
qemudLog(QEMUD_WARN, "QEMU guest config filename '%s' does not match guest name '%s'",
path, def->name);
qemudFreeVMDef(def);
@@ -2751,7 +2535,7 @@ qemudLoadConfig(struct qemud_driver *dri
strncpy(vm->autostartLink, autostartLink, PATH_MAX);
vm->autostartLink[PATH_MAX-1] = '\0';
- vm->autostart = checkLinkPointsTo(vm->autostartLink, vm->configFile);
+ vm->autostart = virFileLinkPointsTo(vm->autostartLink, vm->configFile);
return vm;
}
@@ -2772,7 +2556,7 @@ qemudLoadNetworkConfig(struct qemud_driv
return NULL;
}
- if (!compareFileToNameSuffix(file, def->name, ".xml")) {
+ if (!virFileMatchesNameSuffix(file, def->name, ".xml")) {
qemudLog(QEMUD_WARN, "Network config filename '%s' does not match network name '%s'",
path, def->name);
qemudFreeNetworkDef(def);
@@ -2791,7 +2575,7 @@ qemudLoadNetworkConfig(struct qemud_driv
strncpy(network->autostartLink, autostartLink, PATH_MAX);
network->autostartLink[PATH_MAX-1] = '\0';
- network->autostart = checkLinkPointsTo(network->autostartLink, network->configFile);
+ network->autostart = virFileLinkPointsTo(network->autostartLink, network->configFile);
return network;
}
@@ -2820,22 +2604,22 @@ int qemudScanConfigDir(struct qemud_driv
if (entry->d_name[0] == '.')
continue;
- if (!hasSuffix(entry->d_name, ".xml"))
+ if (!virFileHasSuffix(entry->d_name, ".xml"))
continue;
- if (qemudMakeConfigPath(configDir, entry->d_name, NULL, path, PATH_MAX) < 0) {
+ if (virFileBuildPath(configDir, entry->d_name, NULL, path, PATH_MAX) < 0) {
qemudLog(QEMUD_WARN, "Config filename '%s/%s' is too long",
configDir, entry->d_name);
continue;
}
- if (qemudMakeConfigPath(autostartDir, entry->d_name, NULL, autostartLink, PATH_MAX) < 0) {
+ if (virFileBuildPath(autostartDir, entry->d_name, NULL, autostartLink, PATH_MAX) < 0) {
qemudLog(QEMUD_WARN, "Autostart link path '%s/%s' is too long",
autostartDir, entry->d_name);
continue;
}
- if (!qemudReadFile(path, xml, QEMUD_MAX_XML_LEN))
+ if (virFileReadAll(path, xml, QEMUD_MAX_XML_LEN) < 0)
continue;
if (isGuest)
diff -r 41c9eb891349 src/qemu_conf.h
--- a/src/qemu_conf.h Sun Dec 02 13:30:44 2007 -0500
+++ b/src/qemu_conf.h Sun Dec 02 13:40:44 2007 -0500
@@ -362,7 +362,6 @@ int qemudDeleteConfig
struct qemud_driver *driver,
const char *configFile,
const char *name);
-int qemudEnsureDir (const char *path);
void qemudFreeVMDef (struct qemud_vm_def *vm);
void qemudFreeVM (struct qemud_vm *vm);
diff -r 41c9eb891349 src/qemu_driver.c
--- a/src/qemu_driver.c Sun Dec 02 13:30:44 2007 -0500
+++ b/src/qemu_driver.c Sun Dec 02 13:40:44 2007 -0500
@@ -632,7 +632,7 @@ static int qemudStartVMDaemon(virConnect
strcat(logfile, vm->def->name);
strcat(logfile, ".log");
- if (qemudEnsureDir(driver->logDir) < 0) {
+ if (virFileMakePath(driver->logDir) < 0) {
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
"cannot create log directory %s: %s",
driver->logDir, strerror(errno));
@@ -2458,7 +2458,7 @@ static int qemudDomainSetAutostart(virDo
if (autostart) {
int err;
- if ((err = qemudEnsureDir(driver->autostartDir))) {
+ if ((err = virFileMakePath(driver->autostartDir))) {
qemudReportError(dom->conn, dom, NULL, VIR_ERR_INTERNAL_ERROR,
"cannot create autostart directory %s: %s",
driver->autostartDir, strerror(err));
@@ -2806,7 +2806,7 @@ static int qemudNetworkSetAutostart(virN
if (autostart) {
int err;
- if ((err = qemudEnsureDir(driver->networkAutostartDir))) {
+ if ((err = virFileMakePath(driver->networkAutostartDir))) {
qemudReportError(net->conn, NULL, net, VIR_ERR_INTERNAL_ERROR,
"cannot create autostart directory %s: %s",
driver->networkAutostartDir, strerror(err));
diff -r 41c9eb891349 src/util.c
--- a/src/util.c Sun Dec 02 13:30:44 2007 -0500
+++ b/src/util.c Sun Dec 02 13:40:44 2007 -0500
@@ -30,12 +30,16 @@
#include <fcntl.h>
#include <paths.h>
#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
#include <libvirt/virterror.h>
#include "event.h"
#include "buf.h"
#include "util.h"
#define MAX_ERROR_LEN 1024
+
+#define virLog(msg...) fprintf(stderr, msg)
static void
ReportError(virConnectPtr conn,
@@ -214,6 +218,7 @@ ssize_t safewrite(int fd, const void *bu
size_t nwritten = 0;
while (count > 0) {
int r = write(fd, buf, count);
+
if (r < 0 && errno == EINTR)
continue;
if (r < 0)
@@ -226,3 +231,221 @@ ssize_t safewrite(int fd, const void *bu
}
return nwritten;
}
+
+
+int virFileReadAll(const char *path,
+ char *buf,
+ unsigned int buflen)
+{
+ FILE *fh;
+ struct stat st;
+ int ret = -1;
+
+ if (!(fh = fopen(path, "r"))) {
+ virLog("Failed to open file '%s': %s",
+ path, strerror(errno));
+ goto error;
+ }
+
+ if (fstat(fileno(fh), &st) < 0) {
+ virLog("Failed to stat file '%s': %s",
+ path, strerror(errno));
+ goto error;
+ }
+
+ if (S_ISDIR(st.st_mode)) {
+ virLog("Ignoring directory '%s'", path);
+ goto error;
+ }
+
+ if (st.st_size >= (buflen-1)) {
+ virLog("File '%s' is too large", path);
+ goto error;
+ }
+
+ if ((ret = fread(buf, st.st_size, 1, fh)) != 1) {
+ virLog("Failed to read config file '%s': %s",
+ path, strerror(errno));
+ goto error;
+ }
+
+ buf[st.st_size] = '\0';
+
+ ret = 0;
+
+ error:
+ if (fh)
+ fclose(fh);
+
+ return ret;
+}
+
+int virFileMatchesNameSuffix(const char *file,
+ const char *name,
+ const char *suffix)
+{
+ int filelen = strlen(file);
+ int namelen = strlen(name);
+ int suffixlen = strlen(suffix);
+
+ if (filelen == (namelen + suffixlen) &&
+ !strncmp(file, name, namelen) &&
+ !strncmp(file + namelen, suffix, suffixlen))
+ return 1;
+ else
+ return 0;
+}
+
+int virFileHasSuffix(const char *str,
+ const char *suffix)
+{
+ int len = strlen(str);
+ int suffixlen = strlen(suffix);
+
+ if (len < suffixlen)
+ return 0;
+
+ return strcmp(str + len - suffixlen, suffix) == 0;
+}
+
+
+int virFileLinkPointsTo(const char *checkLink,
+ const char *checkDest)
+{
+ char dest[PATH_MAX];
+ char real[PATH_MAX];
+ char checkReal[PATH_MAX];
+ int n;
+
+ /* read the link destination */
+ if ((n = readlink(checkLink, dest, PATH_MAX)) < 0) {
+ switch (errno) {
+ case ENOENT:
+ case ENOTDIR:
+ return 0;
+
+ case EINVAL:
+ virLog("File '%s' is not a symlink",
+ checkLink);
+ return 0;
+
+ }
+ virLog("Failed to read symlink '%s': %s",
+ checkLink, strerror(errno));
+ return 0;
+ } else if (n >= PATH_MAX) {
+ virLog("Symlink '%s' contents too long to fit in buffer",
+ checkLink);
+ return 0;
+ }
+
+ dest[n] = '\0';
+
+ /* make absolute */
+ if (dest[0] != '/') {
+ char dir[PATH_MAX];
+ char tmp[PATH_MAX];
+ char *p;
+
+ strncpy(dir, checkLink, PATH_MAX);
+ dir[PATH_MAX-1] = '\0';
+
+ if (!(p = strrchr(dir, '/'))) {
+ virLog("Symlink path '%s' is not absolute", checkLink);
+ return 0;
+ }
+
+ if (p == dir) /* handle unlikely root dir case */
+ p++;
+
+ *p = '\0';
+
+ if (virFileBuildPath(dir, dest, NULL, tmp, PATH_MAX) < 0) {
+ virLog("Path '%s/%s' is too long", dir, dest);
+ return 0;
+ }
+
+ strncpy(dest, tmp, PATH_MAX);
+ dest[PATH_MAX-1] = '\0';
+ }
+
+ /* canonicalize both paths */
+ if (!realpath(dest, real)) {
+ virLog("Failed to expand path '%s' :%s", dest, strerror(errno));
+ strncpy(real, dest, PATH_MAX);
+ real[PATH_MAX-1] = '\0';
+ }
+
+ if (!realpath(checkDest, checkReal)) {
+ virLog("Failed to expand path '%s' :%s", checkDest, strerror(errno));
+ strncpy(checkReal, checkDest, PATH_MAX);
+ checkReal[PATH_MAX-1] = '\0';
+ }
+
+ /* compare */
+ if (strcmp(checkReal, real) != 0) {
+ virLog("Link '%s' does not point to '%s', ignoring",
+ checkLink, checkReal);
+ return 0;
+ }
+
+ return 1;
+}
+
+int virFileMakePath(const char *path)
+{
+ struct stat st;
+ char parent[PATH_MAX];
+ char *p;
+ int err;
+
+ if (stat(path, &st) >= 0)
+ return 0;
+
+ strncpy(parent, path, PATH_MAX);
+ parent[PATH_MAX - 1] = '\0';
+
+ if (!(p = strrchr(parent, '/')))
+ return EINVAL;
+
+ if (p == parent)
+ return EPERM;
+
+ *p = '\0';
+
+ if ((err = virFileMakePath(parent)))
+ return err;
+
+ if (mkdir(path, 0777) < 0 && errno != EEXIST)
+ return errno;
+
+ return 0;
+}
+
+/* Build up a fully qualfiied path for a config file to be
+ * associated with a persistent guest or network */
+int virFileBuildPath(const char *dir,
+ const char *name,
+ const char *ext,
+ char *buf,
+ unsigned int buflen)
+{
+ if ((strlen(dir) + 1 + strlen(name) + (ext ? strlen(ext) : 0) + 1) >= (buflen-1))
+ return -1;
+
+ strcpy(buf, dir);
+ strcat(buf, "/");
+ strcat(buf, name);
+ if (ext)
+ strcat(buf, ext);
+ return 0;
+}
+
+/*
+ * Local variables:
+ * indent-tabs-mode: nil
+ * c-indent-level: 4
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ */
diff -r 41c9eb891349 src/util.h
--- a/src/util.h Sun Dec 02 13:30:44 2007 -0500
+++ b/src/util.h Sun Dec 02 13:40:44 2007 -0500
@@ -21,8 +21,37 @@
* File created Jul 18, 2007 - Shuveb Hussain <shuveb(a)binarykarma.com>
*/
+#ifndef __VIR_UTIL_H__
+#define __VIR_UTIL_H__
+
+#include "internal.h"
+
int virExec(virConnectPtr conn, char **argv, int *retpid, int infd, int *outfd, int *errfd);
int virExecNonBlock(virConnectPtr conn, char **argv, int *retpid, int infd, int *outfd, int *errfd);
int saferead(int fd, void *buf, size_t count);
ssize_t safewrite(int fd, const void *buf, size_t count);
+
+int virFileReadAll(const char *path,
+ char *buf,
+ unsigned int buflen);
+
+int virFileMatchesNameSuffix(const char *file,
+ const char *name,
+ const char *suffix);
+
+int virFileHasSuffix(const char *str,
+ const char *suffix);
+
+int virFileLinkPointsTo(const char *checkLink,
+ const char *checkDest);
+int virFileMakePath(const char *path);
+
+int virFileBuildPath(const char *dir,
+ const char *name,
+ const char *ext,
+ char *buf,
+ unsigned int buflen);
+
+
+#endif /* __VIR_UTIL_H__ */
Dan.
--
|=- Red Hat, Engineering, Emerging Technologies, Boston. +1 978 392 2496 -=|
|=- Perl modules: http://search.cpan.org/~danberr/ -=|
|=- Projects: http://freshmeat.net/~danielpb/ -=|
|=- GnuPG: 7D3B9505 F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 -=|
16 years, 12 months
[Libvir] testing libvirtd: don't hard-code $HOME/.libvirt/libvirt-sock
by Jim Meyering
I've written a test to exercise libvirtd a little.
Unfortunately, if I'm already running libvirtd, that test fails
and I can't do anything about it:
$ ./libvirtd & ./libvirtd
Failed to bind socket to '@/j/.libvirt/libvirt-sock': Address already in use
[Exit 2]
Any objection to providing an option to libvirtd that specifies
that directory (also used to form server->logDir)?
It feels like it should come from the config file, but I haven't
looked at details yet.
16 years, 12 months
[Libvir] Semantic of xenUnifiedType()
by Daniel Veillard
It does the following:
static const char *
xenUnifiedType (virConnectPtr conn)
{
GET_PRIVATE(conn);
int i;
const char *ret;
for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
if (priv->opened[i] && drivers[i]->type) {
ret = drivers[i]->type (conn);
if (ret) return ret;
}
return NULL;
}
as a result if running as an user virConnectGetType() returns
"XenXM" because the XM file parser backend ended up being registered
first. I think that's bogus and we should change the function to
return "Xen" in any case and drop the virDrvGetType type from
struct xenUnifiedDriver and all associated functions in the various
back-ends.
Opinion ?
Daniel
--
Red Hat Virtualization group http://redhat.com/virtualization/
Daniel Veillard | virtualization library http://libvirt.org/
veillard(a)redhat.com | libxml GNOME XML XSLT toolkit http://xmlsoft.org/
http://veillard.com/ | Rpmfind RPM search engine http://rpmfind.net/
16 years, 12 months