mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-03-07 17:28:15 +00:00
Network: Add additional hosts internal infrastructure
Signed-off-by: Michal Novotny <minovotn@redhat.com>
This commit is contained in:
parent
60b9c69313
commit
91b7924eee
@ -194,6 +194,7 @@ virUnrefStream;
|
|||||||
|
|
||||||
# dnsmasq.h
|
# dnsmasq.h
|
||||||
dnsmasqAddDhcpHost;
|
dnsmasqAddDhcpHost;
|
||||||
|
dnsmasqAddHost;
|
||||||
dnsmasqContextFree;
|
dnsmasqContextFree;
|
||||||
dnsmasqContextNew;
|
dnsmasqContextNew;
|
||||||
dnsmasqDelete;
|
dnsmasqDelete;
|
||||||
|
@ -608,6 +608,9 @@ networkBuildDnsmasqArgv(virNetworkObjPtr network,
|
|||||||
if (dctx->hostsfile->nhosts)
|
if (dctx->hostsfile->nhosts)
|
||||||
virCommandAddArgPair(cmd, "--dhcp-hostsfile",
|
virCommandAddArgPair(cmd, "--dhcp-hostsfile",
|
||||||
dctx->hostsfile->path);
|
dctx->hostsfile->path);
|
||||||
|
if (dctx->addnhostsfile->nhosts)
|
||||||
|
virCommandAddArgPair(cmd, "--addn-hosts",
|
||||||
|
dctx->addnhostsfile->path);
|
||||||
|
|
||||||
dnsmasqContextFree(dctx);
|
dnsmasqContextFree(dctx);
|
||||||
}
|
}
|
||||||
|
@ -48,6 +48,7 @@
|
|||||||
|
|
||||||
#define VIR_FROM_THIS VIR_FROM_NETWORK
|
#define VIR_FROM_THIS VIR_FROM_NETWORK
|
||||||
#define DNSMASQ_HOSTSFILE_SUFFIX "hostsfile"
|
#define DNSMASQ_HOSTSFILE_SUFFIX "hostsfile"
|
||||||
|
#define DNSMASQ_ADDNHOSTSFILE_SUFFIX "addnhosts"
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dhcphostFree(dnsmasqDhcpHost *host)
|
dhcphostFree(dnsmasqDhcpHost *host)
|
||||||
@ -55,6 +56,235 @@ dhcphostFree(dnsmasqDhcpHost *host)
|
|||||||
VIR_FREE(host->host);
|
VIR_FREE(host->host);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
addnhostFree(dnsmasqAddnHost *host)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < host->nhostnames; i++)
|
||||||
|
VIR_FREE(host->hostnames[i]);
|
||||||
|
VIR_FREE(host->hostnames);
|
||||||
|
VIR_FREE(host->ip);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
addnhostsFree(dnsmasqAddnHostsfile *addnhostsfile)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
if (addnhostsfile->hosts) {
|
||||||
|
for (i = 0; i < addnhostsfile->nhosts; i++)
|
||||||
|
addnhostFree(&addnhostsfile->hosts[i]);
|
||||||
|
|
||||||
|
VIR_FREE(addnhostsfile->hosts);
|
||||||
|
|
||||||
|
addnhostsfile->nhosts = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
VIR_FREE(addnhostsfile->path);
|
||||||
|
|
||||||
|
VIR_FREE(addnhostsfile);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
addnhostsAdd(dnsmasqAddnHostsfile *addnhostsfile,
|
||||||
|
virSocketAddr *ip,
|
||||||
|
const char *name)
|
||||||
|
{
|
||||||
|
char *ipstr = NULL;
|
||||||
|
int idx = -1;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (!(ipstr = virSocketFormatAddr(ip)))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
for (i = 0; i < addnhostsfile->nhosts; i++) {
|
||||||
|
if (STREQ((const char *)addnhostsfile->hosts[i].ip, (const char *)ipstr)) {
|
||||||
|
idx = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (idx < 0) {
|
||||||
|
if (VIR_REALLOC_N(addnhostsfile->hosts, addnhostsfile->nhosts + 1) < 0)
|
||||||
|
goto alloc_error;
|
||||||
|
|
||||||
|
idx = addnhostsfile->nhosts;
|
||||||
|
if (VIR_ALLOC(addnhostsfile->hosts[idx].hostnames) < 0)
|
||||||
|
goto alloc_error;
|
||||||
|
|
||||||
|
if (virAsprintf(&addnhostsfile->hosts[idx].ip, "%s", ipstr) < 0)
|
||||||
|
goto alloc_error;
|
||||||
|
|
||||||
|
addnhostsfile->hosts[idx].nhostnames = 0;
|
||||||
|
addnhostsfile->nhosts++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (VIR_REALLOC_N(addnhostsfile->hosts[idx].hostnames, addnhostsfile->hosts[idx].nhostnames + 1) < 0)
|
||||||
|
goto alloc_error;
|
||||||
|
|
||||||
|
if (virAsprintf(&addnhostsfile->hosts[idx].hostnames[addnhostsfile->hosts[idx].nhostnames], "%s", name) < 0)
|
||||||
|
goto alloc_error;
|
||||||
|
|
||||||
|
VIR_FREE(ipstr);
|
||||||
|
|
||||||
|
addnhostsfile->hosts[idx].nhostnames++;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
alloc_error:
|
||||||
|
virReportOOMError();
|
||||||
|
VIR_FREE(ipstr);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static dnsmasqAddnHostsfile *
|
||||||
|
addnhostsNew(const char *name,
|
||||||
|
const char *config_dir)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
dnsmasqAddnHostsfile *addnhostsfile;
|
||||||
|
|
||||||
|
if (VIR_ALLOC(addnhostsfile) < 0) {
|
||||||
|
virReportOOMError();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
addnhostsfile->hosts = NULL;
|
||||||
|
addnhostsfile->nhosts = 0;
|
||||||
|
|
||||||
|
if (virAsprintf(&addnhostsfile->path, "%s/%s.%s", config_dir, name,
|
||||||
|
DNSMASQ_ADDNHOSTSFILE_SUFFIX) < 0) {
|
||||||
|
virReportOOMError();
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((err = virFileMakePath(config_dir))) {
|
||||||
|
virReportSystemError(err, _("cannot create config directory '%s'"),
|
||||||
|
config_dir);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
return addnhostsfile;
|
||||||
|
|
||||||
|
error:
|
||||||
|
addnhostsFree(addnhostsfile);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
addnhostsWrite(const char *path,
|
||||||
|
dnsmasqAddnHost *hosts,
|
||||||
|
unsigned int nhosts)
|
||||||
|
{
|
||||||
|
char *tmp;
|
||||||
|
FILE *f;
|
||||||
|
bool istmp = true;
|
||||||
|
unsigned int i, ii;
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
if (nhosts == 0)
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
if (virAsprintf(&tmp, "%s.new", path) < 0)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
if (!(f = fopen(tmp, "w"))) {
|
||||||
|
istmp = false;
|
||||||
|
if (!(f = fopen(path, "w"))) {
|
||||||
|
rc = errno;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < nhosts; i++) {
|
||||||
|
if (fputs(hosts[i].ip, f) == EOF || fputc('\t', f) == EOF) {
|
||||||
|
rc = errno;
|
||||||
|
VIR_FORCE_FCLOSE(f);
|
||||||
|
|
||||||
|
if (istmp)
|
||||||
|
unlink(tmp);
|
||||||
|
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (ii = 0; ii < hosts[i].nhostnames; ii++) {
|
||||||
|
if (fputs(hosts[i].hostnames[ii], f) == EOF || fputc('\t', f) == EOF) {
|
||||||
|
rc = errno;
|
||||||
|
VIR_FORCE_FCLOSE(f);
|
||||||
|
|
||||||
|
if (istmp)
|
||||||
|
unlink(tmp);
|
||||||
|
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fputc('\n', f) == EOF) {
|
||||||
|
rc = errno;
|
||||||
|
VIR_FORCE_FCLOSE(f);
|
||||||
|
|
||||||
|
if (istmp)
|
||||||
|
unlink(tmp);
|
||||||
|
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (VIR_FCLOSE(f) == EOF) {
|
||||||
|
rc = errno;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (istmp) {
|
||||||
|
if (rename(tmp, path) < 0) {
|
||||||
|
rc = errno;
|
||||||
|
unlink(tmp);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (unlink(tmp) < 0) {
|
||||||
|
rc = errno;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
VIR_FREE(tmp);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
addnhostsSave(dnsmasqAddnHostsfile *addnhostsfile)
|
||||||
|
{
|
||||||
|
int err = addnhostsWrite(addnhostsfile->path, addnhostsfile->hosts,
|
||||||
|
addnhostsfile->nhosts);
|
||||||
|
|
||||||
|
if (err < 0) {
|
||||||
|
virReportSystemError(err, _("cannot write config file '%s'"),
|
||||||
|
addnhostsfile->path);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
genericFileDelete(char *path)
|
||||||
|
{
|
||||||
|
if (!virFileExists(path))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (unlink(path) < 0) {
|
||||||
|
virReportSystemError(errno, _("cannot remove config file '%s'"),
|
||||||
|
path);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
hostsfileFree(dnsmasqHostsfile *hostsfile)
|
hostsfileFree(dnsmasqHostsfile *hostsfile)
|
||||||
{
|
{
|
||||||
@ -220,21 +450,6 @@ hostsfileSave(dnsmasqHostsfile *hostsfile)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
hostsfileDelete(dnsmasqHostsfile *hostsfile)
|
|
||||||
{
|
|
||||||
if (!virFileExists(hostsfile->path))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (unlink(hostsfile->path) < 0) {
|
|
||||||
virReportSystemError(errno, _("cannot remove config file '%s'"),
|
|
||||||
hostsfile->path);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* dnsmasqContextNew:
|
* dnsmasqContextNew:
|
||||||
*
|
*
|
||||||
@ -255,6 +470,8 @@ dnsmasqContextNew(const char *network_name,
|
|||||||
|
|
||||||
if (!(ctx->hostsfile = hostsfileNew(network_name, config_dir)))
|
if (!(ctx->hostsfile = hostsfileNew(network_name, config_dir)))
|
||||||
goto error;
|
goto error;
|
||||||
|
if (!(ctx->addnhostsfile = addnhostsNew(network_name, config_dir)))
|
||||||
|
goto error;
|
||||||
|
|
||||||
return ctx;
|
return ctx;
|
||||||
|
|
||||||
@ -277,6 +494,8 @@ dnsmasqContextFree(dnsmasqContext *ctx)
|
|||||||
|
|
||||||
if (ctx->hostsfile)
|
if (ctx->hostsfile)
|
||||||
hostsfileFree(ctx->hostsfile);
|
hostsfileFree(ctx->hostsfile);
|
||||||
|
if (ctx->addnhostsfile)
|
||||||
|
addnhostsFree(ctx->addnhostsfile);
|
||||||
|
|
||||||
VIR_FREE(ctx);
|
VIR_FREE(ctx);
|
||||||
}
|
}
|
||||||
@ -300,6 +519,24 @@ dnsmasqAddDhcpHost(dnsmasqContext *ctx,
|
|||||||
hostsfileAdd(ctx->hostsfile, mac, ip, name);
|
hostsfileAdd(ctx->hostsfile, mac, ip, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* dnsmasqAddHost:
|
||||||
|
* @ctx: pointer to the dnsmasq context for each network
|
||||||
|
* @ip: pointer to the socket address contains ip of the host
|
||||||
|
* @name: pointer to the string contains hostname of the host
|
||||||
|
*
|
||||||
|
* Add additional host entry.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
dnsmasqAddHost(dnsmasqContext *ctx,
|
||||||
|
virSocketAddr *ip,
|
||||||
|
const char *name)
|
||||||
|
{
|
||||||
|
if (ctx->addnhostsfile)
|
||||||
|
addnhostsAdd(ctx->addnhostsfile, ip, name);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* dnsmasqSave:
|
* dnsmasqSave:
|
||||||
* @ctx: pointer to the dnsmasq context for each network
|
* @ctx: pointer to the dnsmasq context for each network
|
||||||
@ -309,10 +546,16 @@ dnsmasqAddDhcpHost(dnsmasqContext *ctx,
|
|||||||
int
|
int
|
||||||
dnsmasqSave(const dnsmasqContext *ctx)
|
dnsmasqSave(const dnsmasqContext *ctx)
|
||||||
{
|
{
|
||||||
if (ctx->hostsfile)
|
int ret = 0;
|
||||||
return hostsfileSave(ctx->hostsfile);
|
|
||||||
|
|
||||||
return 0;
|
if (ctx->hostsfile)
|
||||||
|
ret = hostsfileSave(ctx->hostsfile);
|
||||||
|
if (ret == 0) {
|
||||||
|
if (ctx->addnhostsfile)
|
||||||
|
ret = addnhostsSave(ctx->addnhostsfile);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -325,10 +568,14 @@ dnsmasqSave(const dnsmasqContext *ctx)
|
|||||||
int
|
int
|
||||||
dnsmasqDelete(const dnsmasqContext *ctx)
|
dnsmasqDelete(const dnsmasqContext *ctx)
|
||||||
{
|
{
|
||||||
if (ctx->hostsfile)
|
int ret = 0;
|
||||||
return hostsfileDelete(ctx->hostsfile);
|
|
||||||
|
|
||||||
return 0;
|
if (ctx->hostsfile)
|
||||||
|
ret = genericFileDelete(ctx->hostsfile->path);
|
||||||
|
if (ctx->addnhostsfile)
|
||||||
|
ret = genericFileDelete(ctx->addnhostsfile->path);
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -42,9 +42,26 @@ typedef struct
|
|||||||
char *path; /* Absolute path of dnsmasq's hostsfile. */
|
char *path; /* Absolute path of dnsmasq's hostsfile. */
|
||||||
} dnsmasqHostsfile;
|
} dnsmasqHostsfile;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
unsigned int nhostnames;
|
||||||
|
char *ip;
|
||||||
|
char **hostnames;
|
||||||
|
|
||||||
|
} dnsmasqAddnHost;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
unsigned int nhosts;
|
||||||
|
dnsmasqAddnHost *hosts;
|
||||||
|
|
||||||
|
char *path; /* Absolute path of dnsmasq's hostsfile. */
|
||||||
|
} dnsmasqAddnHostsfile;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
dnsmasqHostsfile *hostsfile;
|
dnsmasqHostsfile *hostsfile;
|
||||||
|
dnsmasqAddnHostsfile *addnhostsfile;
|
||||||
} dnsmasqContext;
|
} dnsmasqContext;
|
||||||
|
|
||||||
dnsmasqContext * dnsmasqContextNew(const char *network_name,
|
dnsmasqContext * dnsmasqContextNew(const char *network_name,
|
||||||
@ -54,6 +71,9 @@ void dnsmasqAddDhcpHost(dnsmasqContext *ctx,
|
|||||||
const char *mac,
|
const char *mac,
|
||||||
virSocketAddr *ip,
|
virSocketAddr *ip,
|
||||||
const char *name);
|
const char *name);
|
||||||
|
void dnsmasqAddHost(dnsmasqContext *ctx,
|
||||||
|
virSocketAddr *ip,
|
||||||
|
const char *name);
|
||||||
int dnsmasqSave(const dnsmasqContext *ctx);
|
int dnsmasqSave(const dnsmasqContext *ctx);
|
||||||
int dnsmasqDelete(const dnsmasqContext *ctx);
|
int dnsmasqDelete(const dnsmasqContext *ctx);
|
||||||
int dnsmasqReload(pid_t pid);
|
int dnsmasqReload(pid_t pid);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user