mirror of
https://git.proxmox.com/git/mirror_lxc
synced 2025-08-14 09:47:06 +00:00
Added C++ compatibility, change to libtool, improve monitoring
This commit is contained in:
parent
187d3a35fa
commit
c2cc9f0a9b
@ -11,6 +11,7 @@ AC_CANONICAL_HOST
|
|||||||
AC_PROG_RANLIB
|
AC_PROG_RANLIB
|
||||||
AM_PROG_CC_C_O
|
AM_PROG_CC_C_O
|
||||||
AC_GNU_SOURCE
|
AC_GNU_SOURCE
|
||||||
|
AC_PROG_LIBTOOL
|
||||||
AC_CHECK_HEADERS([linux/netlink.h linux/genetlink.h],, AC_MSG_ERROR([netlink headers not found]), [[]])
|
AC_CHECK_HEADERS([linux/netlink.h linux/genetlink.h],, AC_MSG_ERROR([netlink headers not found]), [[]])
|
||||||
AC_PROG_GCC_TRADITIONAL
|
AC_PROG_GCC_TRADITIONAL
|
||||||
|
|
||||||
|
@ -82,6 +82,7 @@ rm -rf %{buildroot}
|
|||||||
%files
|
%files
|
||||||
%defattr(-,root,root)
|
%defattr(-,root,root)
|
||||||
%{_sysconfdir}/%{name}/*
|
%{_sysconfdir}/%{name}/*
|
||||||
|
%{_libdir}/*.so*
|
||||||
%{_bindir}/*
|
%{_bindir}/*
|
||||||
|
|
||||||
%files devel
|
%files devel
|
||||||
@ -89,6 +90,10 @@ rm -rf %{buildroot}
|
|||||||
%{_includedir}/%{name}/*
|
%{_includedir}/%{name}/*
|
||||||
%{_libdir}/*.a
|
%{_libdir}/*.a
|
||||||
|
|
||||||
|
%post devel
|
||||||
|
ln -sf %{_includedir}/%{name} %{_includedir}/liblxc
|
||||||
|
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
* Sun Aug 3 2008 Daniel Lezcano <dlezcano@fr.ibm.com>
|
* Sun Aug 3 2008 Daniel Lezcano <dlezcano@fr.ibm.com>
|
||||||
- Initial RPM release.
|
- Initial RPM release.
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
lib_LIBRARIES = liblxc.a
|
lib_LTLIBRARIES = liblxc.la
|
||||||
pkginclude_HEADERS = \
|
pkginclude_HEADERS = \
|
||||||
lxc.h \
|
lxc.h \
|
||||||
lxc_cgroup.h \
|
lxc_cgroup.h \
|
||||||
@ -10,16 +10,15 @@ pkginclude_HEADERS = \
|
|||||||
lxc_state.h \
|
lxc_state.h \
|
||||||
lxc_utils.h
|
lxc_utils.h
|
||||||
|
|
||||||
liblxc_a_SOURCES = \
|
liblxc_la_SOURCES = \
|
||||||
create.c \
|
create.c \
|
||||||
destroy.c \
|
destroy.c \
|
||||||
start.c \
|
start.c \
|
||||||
stop.c \
|
stop.c \
|
||||||
execute.c \
|
execute.c \
|
||||||
monitor.c \
|
monitor.c monitor.h \
|
||||||
kill.c \
|
kill.c \
|
||||||
freezer.c \
|
freezer.c \
|
||||||
lxc_state.c lxc_state.h \
|
|
||||||
lxc_cgroup.c lxc_cgroup.h \
|
lxc_cgroup.c lxc_cgroup.h \
|
||||||
lxc.h \
|
lxc.h \
|
||||||
lxc_utils.h \
|
lxc_utils.h \
|
||||||
@ -34,3 +33,5 @@ liblxc_a_SOURCES = \
|
|||||||
nl.c nl.h \
|
nl.c nl.h \
|
||||||
rtnl.c rtnl.h \
|
rtnl.c rtnl.h \
|
||||||
genl.c genl.h
|
genl.c genl.h
|
||||||
|
|
||||||
|
liblxc_la_LDFLAGS = -release @PACKAGE_VERSION@
|
@ -116,7 +116,7 @@ int lxc_create(const char *name, struct lxc_conf *conf)
|
|||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mkstate(name)) {
|
if (lxc_mkstate(name)) {
|
||||||
lxc_log_error("failed to create the state file for %s", name);
|
lxc_log_error("failed to create the state file for %s", name);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
@ -139,7 +139,7 @@ out:
|
|||||||
err_state:
|
err_state:
|
||||||
lxc_unconfigure(name);
|
lxc_unconfigure(name);
|
||||||
|
|
||||||
if (rmstate(name))
|
if (lxc_rmstate(name))
|
||||||
lxc_log_error("failed to remove state file for %s", name);
|
lxc_log_error("failed to remove state file for %s", name);
|
||||||
err:
|
err:
|
||||||
if (remove_lxc_directory(name))
|
if (remove_lxc_directory(name))
|
||||||
|
@ -94,10 +94,12 @@ int lxc_destroy(const char *name)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rmstate(name)) {
|
if (lxc_rmstate(name)) {
|
||||||
lxc_log_error("failed to remove state file for %s", name);
|
lxc_log_error("failed to remove state file for %s", name);
|
||||||
goto out_lock;
|
goto out_lock;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lxc_monitor_cleanup(name);
|
||||||
|
|
||||||
if (lxc_unconfigure(name)) {
|
if (lxc_unconfigure(name)) {
|
||||||
lxc_log_error("failed to cleanup %s", name);
|
lxc_log_error("failed to cleanup %s", name);
|
||||||
|
@ -64,10 +64,8 @@ int lxc_execute(const char *name, int argc, char *argv[],
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
fcntl(lock, F_SETFD, FD_CLOEXEC);
|
|
||||||
|
|
||||||
if (lxc_setstate(name, STARTING)) {
|
if (lxc_setstate(name, STARTING)) {
|
||||||
lxc_log_error("failed to set state %s", state2str(STARTING));
|
lxc_log_error("failed to set state %s", lxc_state2str(STARTING));
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -117,10 +115,12 @@ int lxc_execute(const char *name, int argc, char *argv[],
|
|||||||
lxc_log_error("failed to setup the container");
|
lxc_log_error("failed to setup the container");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mount("proc", "/proc", "proc", 0, NULL)) {
|
if (mount("proc", "/proc", "proc", 0, NULL)) {
|
||||||
lxc_log_error("failed to mount '/proc'");
|
lxc_log_syserror("failed to mount '/proc'");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mount("sysfs", "/sys", "sysfs", 0, NULL)) {
|
if (mount("sysfs", "/sys", "sysfs", 0, NULL)) {
|
||||||
lxc_log_syserror("failed to mount '/sys'");
|
lxc_log_syserror("failed to mount '/sys'");
|
||||||
/* continue: non fatal error until sysfs not per
|
/* continue: non fatal error until sysfs not per
|
||||||
@ -213,7 +213,7 @@ int lxc_execute(const char *name, int argc, char *argv[],
|
|||||||
lxc_log_warning("cgroupfs not found: cgroup disabled");
|
lxc_log_warning("cgroupfs not found: cgroup disabled");
|
||||||
|
|
||||||
if (lxc_setstate(name, RUNNING)) {
|
if (lxc_setstate(name, RUNNING)) {
|
||||||
lxc_log_error("failed to set state to %s", state2str(RUNNING));
|
lxc_log_error("failed to set state to %s", lxc_state2str(RUNNING));
|
||||||
goto err_state_failed;
|
goto err_state_failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -226,7 +226,7 @@ wait_again:
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (lxc_setstate(name, STOPPING))
|
if (lxc_setstate(name, STOPPING))
|
||||||
lxc_log_error("failed to set state %s", state2str(STOPPING));
|
lxc_log_error("failed to set state %s", lxc_state2str(STOPPING));
|
||||||
|
|
||||||
if (clone_flags & CLONE_NEWNET && conf_destroy_network(name))
|
if (clone_flags & CLONE_NEWNET && conf_destroy_network(name))
|
||||||
lxc_log_error("failed to destroy the network");
|
lxc_log_error("failed to destroy the network");
|
||||||
@ -234,7 +234,7 @@ wait_again:
|
|||||||
err = 0;
|
err = 0;
|
||||||
out:
|
out:
|
||||||
if (lxc_setstate(name, STOPPED))
|
if (lxc_setstate(name, STOPPED))
|
||||||
lxc_log_error("failed to set state %s", state2str(STOPPED));
|
lxc_log_error("failed to set state %s", lxc_state2str(STOPPED));
|
||||||
|
|
||||||
lxc_unlink_nsgroup(name);
|
lxc_unlink_nsgroup(name);
|
||||||
unlink(init);
|
unlink(init);
|
||||||
@ -257,7 +257,7 @@ err_pipe_read:
|
|||||||
err_open:
|
err_open:
|
||||||
err_waitpid_failed:
|
err_waitpid_failed:
|
||||||
if (lxc_setstate(name, ABORTING))
|
if (lxc_setstate(name, ABORTING))
|
||||||
lxc_log_error("failed to set state %s", state2str(STOPPED));
|
lxc_log_error("failed to set state %s", lxc_state2str(STOPPED));
|
||||||
|
|
||||||
kill(pid, SIGKILL);
|
kill(pid, SIGKILL);
|
||||||
err_fork_ns:
|
err_fork_ns:
|
||||||
|
@ -42,6 +42,8 @@ int lxc_get_lock(const char *name)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fcntl(fd, F_SETFD, FD_CLOEXEC);
|
||||||
|
|
||||||
if (flock(fd, LOCK_EX|LOCK_NB)) {
|
if (flock(fd, LOCK_EX|LOCK_NB)) {
|
||||||
ret = errno == EWOULDBLOCK ? 0 : -errno;
|
ret = errno == EWOULDBLOCK ? 0 : -errno;
|
||||||
close(fd);
|
close(fd);
|
||||||
|
@ -23,20 +23,24 @@
|
|||||||
#ifndef __lxc_h
|
#ifndef __lxc_h
|
||||||
#define __lxc_h
|
#define __lxc_h
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Following code is for liblxc.
|
Following code is for liblxc.
|
||||||
|
|
||||||
liblxc/lxc.h will contain exports of liblxc
|
liblxc/lxc.h will contain exports of liblxc
|
||||||
**/
|
**/
|
||||||
|
|
||||||
#include <lxc_state.h>
|
#include <liblxc/lxc_state.h>
|
||||||
#include <lxc_list.h>
|
#include <liblxc/lxc_list.h>
|
||||||
#include <lxc_conf.h>
|
#include <liblxc/lxc_conf.h>
|
||||||
#include <lxc_log.h>
|
#include <liblxc/lxc_log.h>
|
||||||
#include <lxc_lock.h>
|
#include <liblxc/lxc_lock.h>
|
||||||
#include <lxc_cgroup.h>
|
#include <liblxc/lxc_cgroup.h>
|
||||||
#include <lxc_namespace.h>
|
#include <liblxc/lxc_namespace.h>
|
||||||
#include <lxc_utils.h>
|
#include <liblxc/lxc_utils.h>
|
||||||
|
|
||||||
#define LXCPATH "/var/lxc"
|
#define LXCPATH "/var/lxc"
|
||||||
#define MAXPIDLEN 20
|
#define MAXPIDLEN 20
|
||||||
@ -104,12 +108,37 @@ extern int lxc_stop(const char *name);
|
|||||||
* is changed, a state data is send through a file descriptor passed to
|
* is changed, a state data is send through a file descriptor passed to
|
||||||
* the function with output_fd.
|
* the function with output_fd.
|
||||||
* The function will block until the container is destroyed.
|
* The function will block until the container is destroyed.
|
||||||
* @name : the name of the contaier
|
* @name : the name of the container
|
||||||
* @output_fd : the file descriptor where to send the states
|
* @output_fd : the file descriptor where to send the states
|
||||||
* Returns 0 on success, < 0 otherwise
|
* Returns 0 on success, < 0 otherwise
|
||||||
*/
|
*/
|
||||||
extern int lxc_monitor(const char *name, int output_fd);
|
extern int lxc_monitor(const char *name, int output_fd);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Open the monitoring mechanism for a specific container
|
||||||
|
* The function will return an fd corresponding to the events
|
||||||
|
* @name : the name of the container
|
||||||
|
* Returns a file descriptor on success, < 0 otherwise
|
||||||
|
*/
|
||||||
|
extern int lxc_monitor_open(const char *name);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Read the state of the container if this one has changed
|
||||||
|
* The function will block until there is an event available
|
||||||
|
* @fd : the file descriptor provided by lxc_monitor_open
|
||||||
|
* @state : the variable which will be filled with the state
|
||||||
|
* Returns 0 if the monitored container has exited, > 0 if
|
||||||
|
* data was readen, < 0 otherwise
|
||||||
|
*/
|
||||||
|
extern int lxc_monitor_read(int fd, lxc_state_t *state);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Close the fd associated with the monitoring
|
||||||
|
* @fd : the file descriptor provided by lxc_monitor_open
|
||||||
|
* Returns 0 on success, < 0 otherwise
|
||||||
|
*/
|
||||||
|
extern int lxc_monitor_close(int fd);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Show the console of the container.
|
* Show the console of the container.
|
||||||
* @name : the name of container
|
* @name : the name of container
|
||||||
@ -220,4 +249,8 @@ extern int lxc_cgroup_get_cpuset(const char *name, long *cpumask,
|
|||||||
*/
|
*/
|
||||||
extern int lxc_cgroup_get_cpu_usage(const char *name, long long *usage);
|
extern int lxc_cgroup_get_cpu_usage(const char *name, long long *usage);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -101,7 +101,7 @@ int lxc_unlink_nsgroup(const char *name)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int lxc_set_priority(const char *name, int priority)
|
int lxc_cgroup_set_priority(const char *name, int priority)
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
char *path = NULL, *prio = NULL;
|
char *path = NULL, *prio = NULL;
|
||||||
@ -129,7 +129,7 @@ out:
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int lxc_get_priority(const char *name, int *priority)
|
int lxc_cgroup_get_priority(const char *name, int *priority)
|
||||||
{
|
{
|
||||||
int fd, ret = -1;
|
int fd, ret = -1;
|
||||||
char *path, prio[MAXPRIOLEN];
|
char *path, prio[MAXPRIOLEN];
|
||||||
|
@ -35,13 +35,13 @@ static inline int lxc_list_empty(struct lxc_list *list)
|
|||||||
return list == list->next;
|
return list == list->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void lxc_list_add(struct lxc_list *list, struct lxc_list *new)
|
static inline void lxc_list_add(struct lxc_list *head, struct lxc_list *list)
|
||||||
{
|
{
|
||||||
struct lxc_list *next = list->next;
|
struct lxc_list *next = head->next;
|
||||||
next->prev = new;
|
next->prev = list;
|
||||||
new->next = next;
|
list->next = next;
|
||||||
new->prev = list;
|
list->prev = head;
|
||||||
list->next = new;
|
head->next = list;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void lxc_list_del(struct lxc_list *list)
|
static inline void lxc_list_del(struct lxc_list *list)
|
||||||
|
@ -32,20 +32,21 @@
|
|||||||
#include <sys/file.h>
|
#include <sys/file.h>
|
||||||
|
|
||||||
#include <lxc.h>
|
#include <lxc.h>
|
||||||
|
#include "monitor.h"
|
||||||
|
|
||||||
static char *strstate[] = {
|
static char *strstate[] = {
|
||||||
"STOPPED", "STARTING", "RUNNING", "STOPPING",
|
"STOPPED", "STARTING", "RUNNING", "STOPPING",
|
||||||
"ABORTING", "FREEZING", "FROZEN",
|
"ABORTING", "FREEZING", "FROZEN",
|
||||||
};
|
};
|
||||||
|
|
||||||
const char *state2str(lxc_state_t state)
|
const char *lxc_state2str(lxc_state_t state)
|
||||||
{
|
{
|
||||||
if (state < STOPPED || state > MAX_STATE - 1)
|
if (state < STOPPED || state > MAX_STATE - 1)
|
||||||
return NULL;
|
return NULL;
|
||||||
return strstate[state];
|
return strstate[state];
|
||||||
}
|
}
|
||||||
|
|
||||||
lxc_state_t str2state(const char *state)
|
lxc_state_t lxc_str2state(const char *state)
|
||||||
{
|
{
|
||||||
int i, len;
|
int i, len;
|
||||||
len = sizeof(strstate)/sizeof(strstate[0]);
|
len = sizeof(strstate)/sizeof(strstate[0]);
|
||||||
@ -59,7 +60,7 @@ int lxc_setstate(const char *name, lxc_state_t state)
|
|||||||
{
|
{
|
||||||
int fd, err;
|
int fd, err;
|
||||||
char file[MAXPATHLEN];
|
char file[MAXPATHLEN];
|
||||||
const char *str = state2str(state);
|
const char *str = lxc_state2str(state);
|
||||||
|
|
||||||
if (!str)
|
if (!str)
|
||||||
return -1;
|
return -1;
|
||||||
@ -91,6 +92,8 @@ int lxc_setstate(const char *name, lxc_state_t state)
|
|||||||
out:
|
out:
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
||||||
|
lxc_monitor_send_state(name, state);
|
||||||
|
|
||||||
/* let the event to be propagated, crappy but that works,
|
/* let the event to be propagated, crappy but that works,
|
||||||
* otherwise the events will be folded into only one event,
|
* otherwise the events will be folded into only one event,
|
||||||
* and I want to have them to be one by one in order
|
* and I want to have them to be one by one in order
|
||||||
@ -101,7 +104,7 @@ out:
|
|||||||
return -err;
|
return -err;
|
||||||
}
|
}
|
||||||
|
|
||||||
int mkstate(const char *name)
|
int lxc_mkstate(const char *name)
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
char file[MAXPATHLEN];
|
char file[MAXPATHLEN];
|
||||||
@ -116,7 +119,7 @@ int mkstate(const char *name)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int rmstate(const char *name)
|
int lxc_rmstate(const char *name)
|
||||||
{
|
{
|
||||||
char file[MAXPATHLEN];
|
char file[MAXPATHLEN];
|
||||||
snprintf(file, MAXPATHLEN, LXCPATH "/%s/state", name);
|
snprintf(file, MAXPATHLEN, LXCPATH "/%s/state", name);
|
||||||
@ -152,7 +155,7 @@ lxc_state_t lxc_getstate(const char *name)
|
|||||||
file[err] = '\0';
|
file[err] = '\0';
|
||||||
|
|
||||||
close(fd);
|
close(fd);
|
||||||
return str2state(file);
|
return lxc_str2state(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int freezer_state(const char *name)
|
static int freezer_state(const char *name)
|
||||||
@ -166,7 +169,7 @@ static int freezer_state(const char *name)
|
|||||||
LXCPATH "/%s/freezer.freeze", name);
|
LXCPATH "/%s/freezer.freeze", name);
|
||||||
|
|
||||||
file = fopen(freezer, "r");
|
file = fopen(freezer, "r");
|
||||||
if (file < 0) {
|
if (!file) {
|
||||||
lxc_log_syserror("failed to open %s", freezer);
|
lxc_log_syserror("failed to open %s", freezer);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -179,7 +182,7 @@ static int freezer_state(const char *name)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return str2state(status);
|
return lxc_str2state(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
lxc_state_t lxc_state(const char *name)
|
lxc_state_t lxc_state(const char *name)
|
||||||
|
@ -28,11 +28,12 @@ typedef enum {
|
|||||||
ABORTING, FREEZING, FROZEN, MAX_STATE,
|
ABORTING, FREEZING, FROZEN, MAX_STATE,
|
||||||
} lxc_state_t;
|
} lxc_state_t;
|
||||||
|
|
||||||
extern const char *state2str(lxc_state_t state);
|
extern int lxc_mkstate(const char *name);
|
||||||
extern lxc_state_t str2state(const char *state);
|
extern int lxc_rmstate(const char *name);
|
||||||
extern int mkstate(const char *name);
|
|
||||||
extern int rmstate(const char *name);
|
|
||||||
extern int lxc_setstate(const char *name, lxc_state_t state);
|
extern int lxc_setstate(const char *name, lxc_state_t state);
|
||||||
extern lxc_state_t lxc_getstate(const char *name);
|
extern lxc_state_t lxc_getstate(const char *name);
|
||||||
|
|
||||||
|
extern lxc_state_t lxc_str2state(const char *state);
|
||||||
|
extern const char *lxc_state2str(lxc_state_t state);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -24,16 +24,22 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/inotify.h>
|
#include <sys/inotify.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/un.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <net/if.h>
|
#include <net/if.h>
|
||||||
|
|
||||||
#include <lxc.h>
|
#include <lxc.h>
|
||||||
|
|
||||||
|
#ifndef UNIX_PATH_MAX
|
||||||
|
#define UNIX_PATH_MAX 108
|
||||||
|
#endif
|
||||||
|
|
||||||
int lxc_monitor(const char *name, int output_fd)
|
int lxc_monitor(const char *name, int output_fd)
|
||||||
{
|
{
|
||||||
char path[MAXPATHLEN];
|
char path[MAXPATHLEN];
|
||||||
@ -93,3 +99,72 @@ out:
|
|||||||
close(nfd);
|
close(nfd);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void lxc_monitor_send_state(const char *name, lxc_state_t state)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
struct sockaddr_un addr;
|
||||||
|
|
||||||
|
fd = socket(PF_UNIX, SOCK_DGRAM, 0);
|
||||||
|
if (fd < 0)
|
||||||
|
lxc_log_syserror("failed to create notification socket");
|
||||||
|
|
||||||
|
memset(&addr, 0, sizeof(addr));
|
||||||
|
addr.sun_family = AF_UNIX;
|
||||||
|
snprintf(addr.sun_path, UNIX_PATH_MAX, LXCPATH "/%s/notification", name);
|
||||||
|
|
||||||
|
sendto(fd, &state, sizeof(state), 0,
|
||||||
|
(const struct sockaddr *)&addr, sizeof(addr));
|
||||||
|
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
void lxc_monitor_cleanup(const char *name)
|
||||||
|
{
|
||||||
|
char path[UNIX_PATH_MAX];
|
||||||
|
snprintf(path, UNIX_PATH_MAX, LXCPATH "/%s/notification", name);
|
||||||
|
unlink(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
int lxc_monitor_open(const char *name)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
struct sockaddr_un addr;
|
||||||
|
|
||||||
|
fd = socket(PF_UNIX, SOCK_DGRAM, 0);
|
||||||
|
if (fd < 0) {
|
||||||
|
lxc_log_syserror("failed to create notification socket");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&addr, 0, sizeof(addr));
|
||||||
|
|
||||||
|
addr.sun_family = AF_UNIX;
|
||||||
|
snprintf(addr.sun_path, UNIX_PATH_MAX, LXCPATH "/%s/notification", name);
|
||||||
|
unlink(addr.sun_path);
|
||||||
|
|
||||||
|
if (bind(fd, (const struct sockaddr *)&addr, sizeof(addr))) {
|
||||||
|
lxc_log_syserror("failed to bind to '%s'", addr.sun_path);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lxc_monitor_read(int fd, lxc_state_t *state)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = recv(fd, state, sizeof(*state), 0);
|
||||||
|
if (ret < 0) {
|
||||||
|
lxc_log_syserror("failed to received state");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lxc_monitor_close(int fd)
|
||||||
|
{
|
||||||
|
return close(fd);
|
||||||
|
}
|
||||||
|
@ -69,7 +69,7 @@ int lxc_start(const char *name, int argc, char *argv[],
|
|||||||
|
|
||||||
/* Begin the set the state to STARTING*/
|
/* Begin the set the state to STARTING*/
|
||||||
if (lxc_setstate(name, STARTING)) {
|
if (lxc_setstate(name, STARTING)) {
|
||||||
lxc_log_error("failed to set state %s", state2str(STARTING));
|
lxc_log_error("failed to set state %s", lxc_state2str(STARTING));
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -195,7 +195,7 @@ int lxc_start(const char *name, int argc, char *argv[],
|
|||||||
lxc_log_warning("cgroupfs not found: cgroup disabled");
|
lxc_log_warning("cgroupfs not found: cgroup disabled");
|
||||||
|
|
||||||
if (lxc_setstate(name, RUNNING)) {
|
if (lxc_setstate(name, RUNNING)) {
|
||||||
lxc_log_error("failed to set state to %s", state2str(RUNNING));
|
lxc_log_error("failed to set state to %s", lxc_state2str(RUNNING));
|
||||||
goto err_state_failed;
|
goto err_state_failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -208,7 +208,7 @@ wait_again:
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (lxc_setstate(name, STOPPING))
|
if (lxc_setstate(name, STOPPING))
|
||||||
lxc_log_error("failed to set state %s", state2str(STOPPING));
|
lxc_log_error("failed to set state %s", lxc_state2str(STOPPING));
|
||||||
|
|
||||||
if (clone_flags & CLONE_NEWNET && conf_destroy_network(name))
|
if (clone_flags & CLONE_NEWNET && conf_destroy_network(name))
|
||||||
lxc_log_error("failed to destroy the network");
|
lxc_log_error("failed to destroy the network");
|
||||||
@ -216,7 +216,7 @@ wait_again:
|
|||||||
err = 0;
|
err = 0;
|
||||||
out:
|
out:
|
||||||
if (lxc_setstate(name, STOPPED))
|
if (lxc_setstate(name, STOPPED))
|
||||||
lxc_log_error("failed to set state %s", state2str(STOPPED));
|
lxc_log_error("failed to set state %s", lxc_state2str(STOPPED));
|
||||||
|
|
||||||
lxc_unlink_nsgroup(name);
|
lxc_unlink_nsgroup(name);
|
||||||
unlink(init);
|
unlink(init);
|
||||||
@ -239,7 +239,7 @@ err_create_network:
|
|||||||
err_pipe_read:
|
err_pipe_read:
|
||||||
err_waitpid_failed:
|
err_waitpid_failed:
|
||||||
if (lxc_setstate(name, ABORTING))
|
if (lxc_setstate(name, ABORTING))
|
||||||
lxc_log_error("failed to set state %s", state2str(STOPPED));
|
lxc_log_error("failed to set state %s", lxc_state2str(STOPPED));
|
||||||
|
|
||||||
kill(pid, SIGKILL);
|
kill(pid, SIGKILL);
|
||||||
err_fork_ns:
|
err_fork_ns:
|
||||||
|
@ -17,50 +17,50 @@ bin_PROGRAMS = \
|
|||||||
lxc-unfreeze \
|
lxc-unfreeze \
|
||||||
lxc-priority
|
lxc-priority
|
||||||
|
|
||||||
lxc_create_SOURCES = lxc_create.c config.c config.h
|
lxc_create_SOURCES = lxc_create.c lxc_config.c lxc_config.h
|
||||||
lxc_create_LDADD = \
|
lxc_create_LDADD = \
|
||||||
$(top_builddir)/src/liblxc/liblxc.a
|
$(top_builddir)/src/liblxc/liblxc.la
|
||||||
|
|
||||||
lxc_destroy_SOURCES = lxc_destroy.c
|
lxc_destroy_SOURCES = lxc_destroy.c
|
||||||
lxc_destroy_LDADD = \
|
lxc_destroy_LDADD = \
|
||||||
$(top_builddir)/src/liblxc/liblxc.a
|
$(top_builddir)/src/liblxc/liblxc.la
|
||||||
|
|
||||||
lxc_start_SOURCES = lxc_start.c
|
lxc_start_SOURCES = lxc_start.c
|
||||||
lxc_start_LDADD = \
|
lxc_start_LDADD = \
|
||||||
$(top_builddir)/src/liblxc/liblxc.a
|
$(top_builddir)/src/liblxc/liblxc.la
|
||||||
|
|
||||||
lxc_stop_SOURCES = lxc_stop.c
|
lxc_stop_SOURCES = lxc_stop.c
|
||||||
lxc_stop_LDADD = \
|
lxc_stop_LDADD = \
|
||||||
$(top_builddir)/src/liblxc/liblxc.a
|
$(top_builddir)/src/liblxc/liblxc.la
|
||||||
|
|
||||||
lxc_execute_SOURCES = lxc_execute.c config.c
|
lxc_execute_SOURCES = lxc_execute.c
|
||||||
lxc_execute_LDADD = \
|
lxc_execute_LDADD = \
|
||||||
$(top_builddir)/src/liblxc/liblxc.a
|
$(top_builddir)/src/liblxc/liblxc.la
|
||||||
|
|
||||||
lxc_monitor_SOURCES = lxc_monitor.c
|
lxc_monitor_SOURCES = lxc_monitor.c
|
||||||
lxc_monitor_LDADD = \
|
lxc_monitor_LDADD = \
|
||||||
$(top_builddir)/src/liblxc/liblxc.a
|
$(top_builddir)/src/liblxc/liblxc.la
|
||||||
|
|
||||||
lxc_console_SOURCES = lxc_console.c
|
lxc_console_SOURCES = lxc_console.c
|
||||||
lxc_console_LDADD = \
|
lxc_console_LDADD = \
|
||||||
$(top_builddir)/src/liblxc/liblxc.a
|
$(top_builddir)/src/liblxc/liblxc.la
|
||||||
|
|
||||||
lxc_state_SOURCES = lxc_state.c
|
lxc_state_SOURCES = lxc_state.c
|
||||||
lxc_state_LDADD = \
|
lxc_state_LDADD = \
|
||||||
$(top_builddir)/src/liblxc/liblxc.a
|
$(top_builddir)/src/liblxc/liblxc.la
|
||||||
|
|
||||||
lxc_kill_SOURCES = lxc_kill.c
|
lxc_kill_SOURCES = lxc_kill.c
|
||||||
lxc_kill_LDADD = \
|
lxc_kill_LDADD = \
|
||||||
$(top_builddir)/src/liblxc/liblxc.a
|
$(top_builddir)/src/liblxc/liblxc.la
|
||||||
|
|
||||||
lxc_freeze_SOURCES = lxc_freeze.c
|
lxc_freeze_SOURCES = lxc_freeze.c
|
||||||
lxc_freeze_LDADD = \
|
lxc_freeze_LDADD = \
|
||||||
$(top_builddir)/src/liblxc/liblxc.a
|
$(top_builddir)/src/liblxc/liblxc.la
|
||||||
|
|
||||||
lxc_unfreeze_SOURCES = lxc_unfreeze.c
|
lxc_unfreeze_SOURCES = lxc_unfreeze.c
|
||||||
lxc_unfreeze_LDADD = \
|
lxc_unfreeze_LDADD = \
|
||||||
$(top_builddir)/src/liblxc/liblxc.a
|
$(top_builddir)/src/liblxc/liblxc.la
|
||||||
|
|
||||||
lxc_priority_SOURCES = lxc_priority.c
|
lxc_priority_SOURCES = lxc_priority.c
|
||||||
lxc_priority_LDADD = \
|
lxc_priority_LDADD = \
|
||||||
$(top_builddir)/src/liblxc/liblxc.a
|
$(top_builddir)/src/liblxc/liblxc.la
|
||||||
|
546
src/lxc/lxc_config.c
Normal file
546
src/lxc/lxc_config.c
Normal file
@ -0,0 +1,546 @@
|
|||||||
|
/*
|
||||||
|
* lxc: linux Container library
|
||||||
|
*
|
||||||
|
* (C) Copyright IBM Corp. 2007, 2008
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Daniel Lezcano <dlezcano at fr.ibm.com>
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/param.h>
|
||||||
|
#include <sys/utsname.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <net/if.h>
|
||||||
|
|
||||||
|
#include <lxc.h>
|
||||||
|
|
||||||
|
typedef int (*file_cb)(char* buffer, void *data);
|
||||||
|
typedef int (*config_cb)(char *value, struct lxc_conf *lxc_conf);
|
||||||
|
|
||||||
|
static int config_mount(char *, struct lxc_conf *);
|
||||||
|
static int config_chroot(char *, struct lxc_conf *);
|
||||||
|
static int config_utsname(char *, struct lxc_conf *);
|
||||||
|
static int config_network_type(char *, struct lxc_conf *);
|
||||||
|
static int config_network_flags(char *, struct lxc_conf *);
|
||||||
|
static int config_network_link(char *, struct lxc_conf *);
|
||||||
|
static int config_network_name(char *, struct lxc_conf *);
|
||||||
|
static int config_network_hwaddr(char *, struct lxc_conf *);
|
||||||
|
static int config_network_ipv4(char *, struct lxc_conf *);
|
||||||
|
static int config_network_ipv6(char *, struct lxc_conf *);
|
||||||
|
|
||||||
|
struct config {
|
||||||
|
char *name;
|
||||||
|
int type;
|
||||||
|
config_cb cb;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum { MOUNT, CHROOT, UTSNAME, NETTYPE, NETFLAGS, NETLINK,
|
||||||
|
NETNAME, NETHWADDR, NETIPV4, NETIPV6 };
|
||||||
|
|
||||||
|
struct config config[] = {
|
||||||
|
{ "lxc.mount", MOUNT, config_mount },
|
||||||
|
{ "lxc.chroot", CHROOT, config_chroot },
|
||||||
|
{ "lxc.utsname", UTSNAME, config_utsname },
|
||||||
|
{ "lxc.network.type", NETTYPE, config_network_type },
|
||||||
|
{ "lxc.network.flags", NETFLAGS, config_network_flags },
|
||||||
|
{ "lxc.network.link", NETLINK, config_network_link },
|
||||||
|
{ "lxc.network.name", NETNAME, config_network_name },
|
||||||
|
{ "lxc.network.hwaddr", NETHWADDR, config_network_hwaddr },
|
||||||
|
{ "lxc.network.ipv4", NETIPV4, config_network_ipv4 },
|
||||||
|
{ "lxc.network.ipv6", NETIPV6, config_network_ipv6 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const size_t config_size = sizeof(config)/sizeof(struct config);
|
||||||
|
|
||||||
|
static struct config *getconfig(const char *key)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < config_size; i++)
|
||||||
|
if (!strncmp(config[i].name, key,
|
||||||
|
strlen(config[i].name)))
|
||||||
|
return &config[i];
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int is_line_empty(char *line)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
size_t len = strlen(line);
|
||||||
|
|
||||||
|
for (i = 0; i < len; i++)
|
||||||
|
if (line[i] != ' ' && line[i] != '\t' &&
|
||||||
|
line[i] != '\n' && line[i] != '\r' &&
|
||||||
|
line[i] != '\f' && line[i] != '\0')
|
||||||
|
return 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int char_left_gc(char *buffer, size_t len)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < len; i++) {
|
||||||
|
if (buffer[i] == ' ' ||
|
||||||
|
buffer[i] == '\t')
|
||||||
|
continue;
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int char_right_gc(char *buffer, size_t len)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = len - 1; i >= 0; i--) {
|
||||||
|
if (buffer[i] == ' ' ||
|
||||||
|
buffer[i] == '\t' ||
|
||||||
|
buffer[i] == '\n' ||
|
||||||
|
buffer[i] == '\0')
|
||||||
|
continue;
|
||||||
|
return i + 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int config_network_type(char *value, struct lxc_conf *lxc_conf)
|
||||||
|
{
|
||||||
|
struct lxc_list *networks = &lxc_conf->networks;
|
||||||
|
struct lxc_network *network;
|
||||||
|
struct lxc_netdev *netdev;
|
||||||
|
struct lxc_list *list;
|
||||||
|
struct lxc_list *ndlist;
|
||||||
|
|
||||||
|
network = malloc(sizeof(*network));
|
||||||
|
if (!network) {
|
||||||
|
lxc_log_syserror("failed to allocate memory");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
lxc_list_init(&network->netdev);
|
||||||
|
|
||||||
|
netdev = malloc(sizeof(*netdev));
|
||||||
|
if (!netdev) {
|
||||||
|
lxc_log_syserror("failed to allocate memory");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
lxc_list_init(&netdev->ipv4);
|
||||||
|
lxc_list_init(&netdev->ipv6);
|
||||||
|
lxc_list_init(&netdev->route4);
|
||||||
|
lxc_list_init(&netdev->route6);
|
||||||
|
|
||||||
|
ndlist = malloc(sizeof(*ndlist));
|
||||||
|
if (!ndlist) {
|
||||||
|
lxc_log_syserror("failed to allocate memory");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ndlist->elem = netdev;
|
||||||
|
|
||||||
|
lxc_list_add(&network->netdev, ndlist);
|
||||||
|
|
||||||
|
list = malloc(sizeof(*list));
|
||||||
|
if (!list) {
|
||||||
|
lxc_log_syserror("failed to allocate memory");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
lxc_list_init(list);
|
||||||
|
list->elem = network;
|
||||||
|
|
||||||
|
lxc_list_add(networks, list);
|
||||||
|
|
||||||
|
if (!strcmp(value, "veth"))
|
||||||
|
network->type = VETH;
|
||||||
|
else if (!strcmp(value, "macvlan"))
|
||||||
|
network->type = MACVLAN;
|
||||||
|
else if (!strcmp(value, "phys"))
|
||||||
|
network->type = PHYS;
|
||||||
|
else {
|
||||||
|
lxc_log_error("invalid network type %s", value);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int config_network_flags(char *value, struct lxc_conf *lxc_conf)
|
||||||
|
{
|
||||||
|
struct lxc_list *networks = &lxc_conf->networks;
|
||||||
|
struct lxc_network *network;
|
||||||
|
struct lxc_netdev *netdev;
|
||||||
|
|
||||||
|
if (lxc_list_empty(networks)) {
|
||||||
|
lxc_log_error("network is not created for '%s' option", value);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
network = lxc_list_first_elem(networks);
|
||||||
|
if (!network) {
|
||||||
|
lxc_log_error("no network defined for '%s' option", value);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
netdev = lxc_list_first_elem(&network->netdev);
|
||||||
|
netdev->flags |= IFF_UP;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int config_network_link(char *value, struct lxc_conf *lxc_conf)
|
||||||
|
{
|
||||||
|
struct lxc_list *networks = &lxc_conf->networks;
|
||||||
|
struct lxc_network *network;
|
||||||
|
struct lxc_netdev *netdev;
|
||||||
|
|
||||||
|
if (lxc_list_empty(networks)) {
|
||||||
|
lxc_log_error("network is not created for %s", value);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
network = lxc_list_first_elem(networks);
|
||||||
|
if (!network) {
|
||||||
|
lxc_log_error("no network defined for %s", value);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strlen(value) > IFNAMSIZ) {
|
||||||
|
lxc_log_error("invalid interface name: %s", value);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
netdev = lxc_list_first_elem(&network->netdev);
|
||||||
|
netdev->ifname = strdup(value);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int config_network_name(char *value, struct lxc_conf *lxc_conf)
|
||||||
|
{
|
||||||
|
struct lxc_list *networks = &lxc_conf->networks;
|
||||||
|
struct lxc_network *network;
|
||||||
|
struct lxc_netdev *netdev;
|
||||||
|
|
||||||
|
if (lxc_list_empty(networks)) {
|
||||||
|
lxc_log_error("network is not created for %s", value);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
network = lxc_list_first_elem(networks);
|
||||||
|
if (!network) {
|
||||||
|
lxc_log_error("no network defined for %s", value);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strlen(value) > IFNAMSIZ) {
|
||||||
|
lxc_log_error("invalid interface name: %s", value);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
netdev = lxc_list_first_elem(&network->netdev);
|
||||||
|
netdev->newname = strdup(value);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int config_network_hwaddr(char *value, struct lxc_conf *lxc_conf)
|
||||||
|
{
|
||||||
|
struct lxc_list *networks = &lxc_conf->networks;
|
||||||
|
struct lxc_network *network;
|
||||||
|
struct lxc_netdev *netdev;
|
||||||
|
|
||||||
|
if (lxc_list_empty(networks)) {
|
||||||
|
lxc_log_error("network is not created for %s", value);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
network = lxc_list_first_elem(networks);
|
||||||
|
if (!network) {
|
||||||
|
lxc_log_error("no network defined for %s", value);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
netdev = lxc_list_first_elem(&network->netdev);
|
||||||
|
netdev->hwaddr = strdup(value);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int config_network_ipv4(char *value, struct lxc_conf *lxc_conf)
|
||||||
|
{
|
||||||
|
struct lxc_list *networks = &lxc_conf->networks;
|
||||||
|
struct lxc_network *network;
|
||||||
|
struct lxc_inetdev *inetdev;
|
||||||
|
struct lxc_netdev *netdev;
|
||||||
|
struct lxc_list *list;
|
||||||
|
char *cursor, *slash, *addr = NULL, *bcast = NULL, *prefix = NULL;
|
||||||
|
|
||||||
|
if (lxc_list_empty(networks)) {
|
||||||
|
lxc_log_error("network is not created for '%s'", value);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
network = lxc_list_first_elem(networks);
|
||||||
|
if (!network) {
|
||||||
|
lxc_log_error("no network defined for '%s'", value);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
netdev = lxc_list_first_elem(&network->netdev);
|
||||||
|
if (!netdev) {
|
||||||
|
lxc_log_error("no netdev defined for '%s'", value);
|
||||||
|
}
|
||||||
|
|
||||||
|
inetdev = malloc(sizeof(*inetdev));
|
||||||
|
if (!inetdev) {
|
||||||
|
lxc_log_syserror("failed to allocate ipv4 address");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
memset(inetdev, 0, sizeof(*inetdev));
|
||||||
|
|
||||||
|
list = malloc(sizeof(*list));
|
||||||
|
if (!list) {
|
||||||
|
lxc_log_syserror("failed to allocate memory");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
lxc_list_init(list);
|
||||||
|
list->elem = inetdev;
|
||||||
|
|
||||||
|
addr = value;
|
||||||
|
|
||||||
|
cursor = strstr(addr, " ");
|
||||||
|
if (cursor) {
|
||||||
|
*cursor = '\0';
|
||||||
|
bcast = cursor + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
slash = strstr(addr, "/");
|
||||||
|
if (slash) {
|
||||||
|
*slash = '\0';
|
||||||
|
prefix = slash + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!addr) {
|
||||||
|
lxc_log_error("no address specified");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!inet_pton(AF_INET, addr, &inetdev->addr)) {
|
||||||
|
lxc_log_syserror("invalid ipv4 address: %s", value);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bcast)
|
||||||
|
if (!inet_pton(AF_INET, bcast, &inetdev->bcast)) {
|
||||||
|
lxc_log_syserror("invalid ipv4 address: %s", value);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (prefix)
|
||||||
|
inetdev->prefix = atoi(prefix);
|
||||||
|
|
||||||
|
lxc_list_add(&netdev->ipv4, list);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int config_network_ipv6(char *value, struct lxc_conf *lxc_conf)
|
||||||
|
{
|
||||||
|
struct lxc_list *networks = &lxc_conf->networks;
|
||||||
|
struct lxc_network *network;
|
||||||
|
struct lxc_netdev *netdev;
|
||||||
|
struct lxc_inet6dev *inet6dev;
|
||||||
|
struct lxc_list *list;
|
||||||
|
char *slash;
|
||||||
|
char *netmask;
|
||||||
|
|
||||||
|
if (lxc_list_empty(networks)) {
|
||||||
|
lxc_log_error("network is not created for %s", value);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
network = lxc_list_first_elem(networks);
|
||||||
|
if (!network) {
|
||||||
|
lxc_log_error("no network defined for %s", value);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
inet6dev = malloc(sizeof(*inet6dev));
|
||||||
|
if (!inet6dev) {
|
||||||
|
lxc_log_syserror("failed to allocate ipv6 address");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
memset(inet6dev, 0, sizeof(*inet6dev));
|
||||||
|
|
||||||
|
list = malloc(sizeof(*list));
|
||||||
|
if (!list) {
|
||||||
|
lxc_log_syserror("failed to allocate memory");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
lxc_list_init(list);
|
||||||
|
list->elem = inet6dev;
|
||||||
|
|
||||||
|
slash = strstr(value, "/");
|
||||||
|
if (slash) {
|
||||||
|
*slash = '\0';
|
||||||
|
netmask = slash + 1;
|
||||||
|
inet6dev->prefix = atoi(netmask);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!inet_pton(AF_INET6, value, &inet6dev->addr)) {
|
||||||
|
lxc_log_syserror("invalid ipv6 address: %s", value);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
netdev = lxc_list_first_elem(&network->netdev);
|
||||||
|
lxc_list_add(&netdev->ipv6, list);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int config_mount(char *value, struct lxc_conf *lxc_conf)
|
||||||
|
{
|
||||||
|
if (strlen(value) >= MAXPATHLEN) {
|
||||||
|
lxc_log_error("%s path is too long", value);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
lxc_conf->fstab = strdup(value);
|
||||||
|
if (!lxc_conf->fstab) {
|
||||||
|
lxc_log_syserror("failed to duplicate string %s", value);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int config_chroot(char *value, struct lxc_conf *lxc_conf)
|
||||||
|
{
|
||||||
|
if (strlen(value) >= MAXPATHLEN) {
|
||||||
|
lxc_log_error("%s path is too long", value);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
lxc_conf->chroot = strdup(value);
|
||||||
|
if (!lxc_conf->chroot) {
|
||||||
|
lxc_log_syserror("failed to duplicate string %s", value);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int config_utsname(char *value, struct lxc_conf *lxc_conf)
|
||||||
|
{
|
||||||
|
struct utsname *utsname;
|
||||||
|
|
||||||
|
utsname = malloc(sizeof(*utsname));
|
||||||
|
if (!utsname) {
|
||||||
|
lxc_log_syserror("failed to allocate memory");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strlen(value) >= sizeof(utsname->nodename)) {
|
||||||
|
lxc_log_error("node name '%s' is too long",
|
||||||
|
utsname->nodename);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
strcpy(utsname->nodename, value);
|
||||||
|
lxc_conf->utsname = utsname;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int parse_line(char *buffer, void *data)
|
||||||
|
{
|
||||||
|
struct config *config;
|
||||||
|
char *dot;
|
||||||
|
char *key;
|
||||||
|
char *value;
|
||||||
|
|
||||||
|
if (is_line_empty(buffer))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
buffer += char_left_gc(buffer, strlen(buffer));
|
||||||
|
if (buffer[0] == '#')
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
dot = strstr(buffer, "=");
|
||||||
|
if (!dot) {
|
||||||
|
lxc_log_error("invalid configuration line: %s", buffer);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
*dot = '\0';
|
||||||
|
value = dot + 1;
|
||||||
|
|
||||||
|
key = buffer;
|
||||||
|
key[char_right_gc(key, strlen(key))] = '\0';
|
||||||
|
|
||||||
|
value += char_left_gc(value, strlen(value));
|
||||||
|
value[char_right_gc(value, strlen(value))] = '\0';
|
||||||
|
|
||||||
|
config = getconfig(key);
|
||||||
|
if (!config) {
|
||||||
|
lxc_log_error("unknow key %s", key);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return config->cb(value, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int file_for_each_line(const char *file, file_cb callback, void *data)
|
||||||
|
{
|
||||||
|
char buffer[MAXPATHLEN];
|
||||||
|
size_t len = sizeof(buffer);
|
||||||
|
FILE *f;
|
||||||
|
int err = -1;
|
||||||
|
|
||||||
|
f = fopen(file, "r");
|
||||||
|
if (!f) {
|
||||||
|
lxc_log_syserror("failed to open %s", file);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (fgets(buffer, len, f))
|
||||||
|
if (callback(buffer, data))
|
||||||
|
goto out;
|
||||||
|
err = 0;
|
||||||
|
out:
|
||||||
|
fclose(f);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lxc_config_read(const char *file, struct lxc_conf *conf)
|
||||||
|
{
|
||||||
|
return file_for_each_line(file, parse_line, conf);
|
||||||
|
}
|
||||||
|
|
||||||
|
int lxc_config_init(struct lxc_conf *conf)
|
||||||
|
{
|
||||||
|
conf->chroot = NULL;
|
||||||
|
conf->fstab = NULL;
|
||||||
|
conf->utsname = NULL;
|
||||||
|
conf->cgroup = NULL;
|
||||||
|
lxc_list_init(&conf->networks);
|
||||||
|
return 0;
|
||||||
|
}
|
28
src/lxc/lxc_config.h
Normal file
28
src/lxc/lxc_config.h
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
/*
|
||||||
|
* lxc: linux Container library
|
||||||
|
*
|
||||||
|
* (C) Copyright IBM Corp. 2007, 2008
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Daniel Lezcano <dlezcano at fr.ibm.com>
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern int lxc_config_init(struct lxc_conf *conf);
|
||||||
|
extern int lxc_config_read(const char *file, struct lxc_conf *conf);
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -32,8 +32,7 @@
|
|||||||
#include <net/if.h>
|
#include <net/if.h>
|
||||||
|
|
||||||
#include <lxc.h>
|
#include <lxc.h>
|
||||||
|
#include "lxc_config.h"
|
||||||
#include "config.h"
|
|
||||||
|
|
||||||
void usage(char *cmd)
|
void usage(char *cmd)
|
||||||
{
|
{
|
||||||
@ -63,12 +62,12 @@ int main(int argc, char *argv[])
|
|||||||
if (!name || !file)
|
if (!name || !file)
|
||||||
usage(argv[0]);
|
usage(argv[0]);
|
||||||
|
|
||||||
if (config_init(&lxc_conf)) {
|
if (lxc_config_init(&lxc_conf)) {
|
||||||
fprintf(stderr, "failed to initialize the configuration\n");
|
fprintf(stderr, "failed to initialize the configuration\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config_read(file, &lxc_conf)) {
|
if (lxc_config_read(file, &lxc_conf)) {
|
||||||
fprintf(stderr, "invalid configuration file\n");
|
fprintf(stderr, "invalid configuration file\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -90,7 +90,7 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
printf("container has changed the state to %d - %s\n",
|
printf("container has changed the state to %d - %s\n",
|
||||||
state, state2str(state));
|
state, lxc_state2str(state));
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <libgen.h>
|
#include <libgen.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
#include <lxc.h>
|
#include <lxc.h>
|
||||||
@ -58,7 +59,7 @@ int main(int argc, char *argv[])
|
|||||||
usage(argv[0]);
|
usage(argv[0]);
|
||||||
|
|
||||||
if (!priority) {
|
if (!priority) {
|
||||||
if (lxc_get_priority(name, &prio)) {
|
if (lxc_cgroup_get_priority(name, &prio)) {
|
||||||
fprintf(stderr, "failed to retrieve the priority of '%s'\n", name);
|
fprintf(stderr, "failed to retrieve the priority of '%s'\n", name);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -68,7 +69,7 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
prio = atoi(priority);
|
prio = atoi(priority);
|
||||||
if (lxc_set_priority(name, prio)) {
|
if (lxc_cgroup_set_priority(name, prio)) {
|
||||||
fprintf(stderr, "failed to assign priority %d to of '%s'",
|
fprintf(stderr, "failed to assign priority %d to of '%s'",
|
||||||
prio, name);
|
prio, name);
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -59,7 +59,7 @@ int main(int argc, char *argv[])
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("'%s' is %s\n", name, state2str(state));
|
printf("'%s' is %s\n", name, lxc_state2str(state));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -18,74 +18,79 @@ noinst_PROGRAMS = \
|
|||||||
lxc_start \
|
lxc_start \
|
||||||
lxc_stop \
|
lxc_stop \
|
||||||
lxc_monitor \
|
lxc_monitor \
|
||||||
|
lxc_low_monitor \
|
||||||
lxc_state
|
lxc_state
|
||||||
|
|
||||||
|
|
||||||
tst_list_SOURCES = tst_list.c
|
tst_list_SOURCES = tst_list.c
|
||||||
tst_list_LDADD = \
|
tst_list_LDADD = \
|
||||||
$(top_builddir)/src/liblxc/liblxc.a
|
$(top_builddir)/src/liblxc/liblxc.la
|
||||||
|
|
||||||
confile_SOURCES = confile.c
|
confile_SOURCES = confile.c
|
||||||
confile_LDADD = \
|
confile_LDADD = \
|
||||||
$(top_builddir)/src/lxc/config.o \
|
$(top_builddir)/src/lxc/lxc_config.o \
|
||||||
$(top_builddir)/src/liblxc/liblxc.a
|
$(top_builddir)/src/liblxc/liblxc.la
|
||||||
|
|
||||||
conf_SOURCES = conf.c
|
conf_SOURCES = conf.c
|
||||||
conf_LDADD = \
|
conf_LDADD = \
|
||||||
$(top_builddir)/src/liblxc/liblxc.a
|
$(top_builddir)/src/liblxc/liblxc.la
|
||||||
|
|
||||||
movedev_SOURCES = movedev.c
|
movedev_SOURCES = movedev.c
|
||||||
movedev_LDADD = \
|
movedev_LDADD = \
|
||||||
$(top_builddir)/src/liblxc/liblxc.a
|
$(top_builddir)/src/liblxc/liblxc.la
|
||||||
|
|
||||||
dev_SOURCES = dev.c
|
dev_SOURCES = dev.c
|
||||||
dev_LDADD = \
|
dev_LDADD = \
|
||||||
$(top_builddir)/src/liblxc/liblxc.a
|
$(top_builddir)/src/liblxc/liblxc.la
|
||||||
|
|
||||||
forward_SOURCES = forward.c
|
forward_SOURCES = forward.c
|
||||||
forward_LDADD = \
|
forward_LDADD = \
|
||||||
$(top_builddir)/src/liblxc/liblxc.a
|
$(top_builddir)/src/liblxc/liblxc.la
|
||||||
|
|
||||||
proxy_SOURCES = proxy.c
|
proxy_SOURCES = proxy.c
|
||||||
proxy_LDADD = \
|
proxy_LDADD = \
|
||||||
$(top_builddir)/src/liblxc/liblxc.a
|
$(top_builddir)/src/liblxc/liblxc.la
|
||||||
|
|
||||||
veth_SOURCES = veth.c
|
veth_SOURCES = veth.c
|
||||||
veth_LDADD = \
|
veth_LDADD = \
|
||||||
$(top_builddir)/src/liblxc/liblxc.a
|
$(top_builddir)/src/liblxc/liblxc.la
|
||||||
|
|
||||||
macvlan_SOURCES = macvlan.c
|
macvlan_SOURCES = macvlan.c
|
||||||
macvlan_LDADD = \
|
macvlan_LDADD = \
|
||||||
$(top_builddir)/src/liblxc/liblxc.a
|
$(top_builddir)/src/liblxc/liblxc.la
|
||||||
|
|
||||||
ipv4_add_SOURCES = ipv4_add.c
|
ipv4_add_SOURCES = ipv4_add.c
|
||||||
ipv4_add_LDADD = \
|
ipv4_add_LDADD = \
|
||||||
$(top_builddir)/src/liblxc/liblxc.a
|
$(top_builddir)/src/liblxc/liblxc.la
|
||||||
|
|
||||||
ipv6_add_SOURCES = ipv6_add.c
|
ipv6_add_SOURCES = ipv6_add.c
|
||||||
ipv6_add_LDADD = \
|
ipv6_add_LDADD = \
|
||||||
$(top_builddir)/src/liblxc/liblxc.a
|
$(top_builddir)/src/liblxc/liblxc.la
|
||||||
|
|
||||||
lxc_create_SOURCES = lxc_create.c
|
lxc_create_SOURCES = lxc_create.c
|
||||||
lxc_create_LDADD = \
|
lxc_create_LDADD = \
|
||||||
$(top_builddir)/src/liblxc/liblxc.a
|
$(top_builddir)/src/liblxc/liblxc.la
|
||||||
|
|
||||||
lxc_destroy_SOURCES = lxc_destroy.c
|
lxc_destroy_SOURCES = lxc_destroy.c
|
||||||
lxc_destroy_LDADD = \
|
lxc_destroy_LDADD = \
|
||||||
$(top_builddir)/src/liblxc/liblxc.a
|
$(top_builddir)/src/liblxc/liblxc.la
|
||||||
|
|
||||||
lxc_start_SOURCES = lxc_start.c
|
lxc_start_SOURCES = lxc_start.c
|
||||||
lxc_start_LDADD = \
|
lxc_start_LDADD = \
|
||||||
$(top_builddir)/src/liblxc/liblxc.a
|
$(top_builddir)/src/liblxc/liblxc.la
|
||||||
|
|
||||||
lxc_stop_SOURCES = lxc_stop.c
|
lxc_stop_SOURCES = lxc_stop.c
|
||||||
lxc_stop_LDADD = \
|
lxc_stop_LDADD = \
|
||||||
$(top_builddir)/src/liblxc/liblxc.a
|
$(top_builddir)/src/liblxc/liblxc.la
|
||||||
|
|
||||||
lxc_monitor_SOURCES = lxc_monitor.c
|
lxc_monitor_SOURCES = lxc_monitor.c
|
||||||
lxc_monitor_LDADD = \
|
lxc_monitor_LDADD = \
|
||||||
$(top_builddir)/src/liblxc/liblxc.a
|
$(top_builddir)/src/liblxc/liblxc.la
|
||||||
|
|
||||||
|
lxc_low_monitor_SOURCES = lxc_low_monitor.c
|
||||||
|
lxc_low_monitor_LDADD = \
|
||||||
|
$(top_builddir)/src/liblxc/liblxc.la
|
||||||
|
|
||||||
lxc_state_SOURCES = lxc_state.c
|
lxc_state_SOURCES = lxc_state.c
|
||||||
lxc_state_LDADD = \
|
lxc_state_LDADD = \
|
||||||
$(top_builddir)/src/liblxc/liblxc.a
|
$(top_builddir)/src/liblxc/liblxc.la
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
|
|
||||||
#include <lxc.h>
|
#include <lxc.h>
|
||||||
|
|
||||||
#include "../src/lxc/config.h"
|
#include "../src/lxc/lxc_config.h"
|
||||||
|
|
||||||
static void usage(const char *cmd)
|
static void usage(const char *cmd)
|
||||||
{
|
{
|
||||||
@ -60,12 +60,12 @@ int main(int argc, char *argv[])
|
|||||||
if (!file || !name)
|
if (!file || !name)
|
||||||
usage(argv[0]);
|
usage(argv[0]);
|
||||||
|
|
||||||
if (config_init(&lxc_conf)) {
|
if (lxc_config_init(&lxc_conf)) {
|
||||||
fprintf(stderr, "failed to initialize configuration structure\n");
|
fprintf(stderr, "failed to initialize configuration structure\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config_read(file, &lxc_conf)) {
|
if (lxc_config_read(file, &lxc_conf)) {
|
||||||
fprintf(stderr, "failed to read configuration\n");
|
fprintf(stderr, "failed to read configuration\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
65
test/lxc_low_monitor.c
Normal file
65
test/lxc_low_monitor.c
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
/*
|
||||||
|
* lxc: linux Container library
|
||||||
|
*
|
||||||
|
* (C) Copyright IBM Corp. 2007, 2008
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Daniel Lezcano <dlezcano at fr.ibm.com>
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <libgen.h>
|
||||||
|
|
||||||
|
#include <lxc.h>
|
||||||
|
|
||||||
|
void usage(char *cmd)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "%s <command>\n", basename(cmd));
|
||||||
|
fprintf(stderr, "\t -n <name> : name of the container\n");
|
||||||
|
_exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
char opt;
|
||||||
|
char *name = NULL;
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
while ((opt = getopt(argc, argv, "n:")) != -1) {
|
||||||
|
switch (opt) {
|
||||||
|
case 'n':
|
||||||
|
name = optarg;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!name)
|
||||||
|
usage(argv[0]);
|
||||||
|
|
||||||
|
fd = lxc_monitor_open(name);
|
||||||
|
if (fd < 0) {
|
||||||
|
fprintf(stderr, "failed to open monitor\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
lxc_state_t state;
|
||||||
|
lxc_monitor_read(fd, &state);
|
||||||
|
printf("received changing state '%s'\n", lxc_state2str(state));
|
||||||
|
}
|
||||||
|
}
|
@ -92,7 +92,7 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
printf("container has changed the state to %d - %s\n",
|
printf("container has changed the state to %d - %s\n",
|
||||||
state, state2str(state));
|
state, lxc_state2str(state));
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -58,7 +58,7 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
printf("container has the state to %d - %s\n",
|
printf("container has the state to %d - %s\n",
|
||||||
state, state2str(state));
|
state, lxc_state2str(state));
|
||||||
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user