Bamvor Jian Zhang
2012-Jun-06 07:09 UTC
[PATCH] [v4] libxl: Add API to retrieve domain console tty
This api retrieve domain console from xenstore. With this new api, it is easy to implement "virsh console" command in libvirt libxl driver. Signed-off-by: Bamvor Jian Zhang <bjzhang@suse.com> Changes since v3: * leave variable uninitialised at the top of the function in order to avoid hiding the useful compiler warnings. * using libxl__strdup instead of strdup in libxl_console_get_tty. benefit from the error handling behavior. libxl__strdup(0, tty) should be replaced by libxl__strdup(NOGC, tty) after Ian Jackson commit his patch: "Do not pass NULL as gc_opt; introduce NOGC." diff -r 6bea63e6c780 -r 2586692a6d74 tools/libxl/libxl.c --- a/tools/libxl/libxl.c Sat Jun 02 08:39:45 2012 +0100 +++ b/tools/libxl/libxl.c Wed Jun 06 14:35:01 2012 +0800 @@ -1217,7 +1217,8 @@ out: return rc; } -int libxl_console_exec(libxl_ctx *ctx, uint32_t domid, int cons_num, libxl_console_type type) +int libxl_console_exec(libxl_ctx *ctx, uint32_t domid, int cons_num, + libxl_console_type type) { GC_INIT(ctx); char *p = libxl__sprintf(gc, "%s/xenconsole", libxl__private_bindir_path()); @@ -1243,34 +1244,116 @@ out: return ERROR_FAIL; } -int libxl_primary_console_exec(libxl_ctx *ctx, uint32_t domid_vm) +int libxl_console_get_tty(libxl_ctx *ctx, uint32_t domid, int cons_num, + libxl_console_type type, char **path) +{ + GC_INIT(ctx); + char *dom_path; + char *tty_path; + char *tty; + int rc; + + dom_path = libxl__xs_get_dompath(gc, domid); + if (!dom_path) { + rc = ERROR_FAIL; + goto out; + } + + switch (type) { + case LIBXL_CONSOLE_TYPE_SERIAL: + tty_path = GCSPRINTF("%s/serial/0/tty", dom_path); + break; + case LIBXL_CONSOLE_TYPE_PV: + if (cons_num == 0) + tty_path = GCSPRINTF("%s/console/tty", dom_path); + else + tty_path = GCSPRINTF("%s/device/console/%d/tty", dom_path, + cons_num); + break; + default: + rc = ERROR_INVAL; + goto out; + } + + tty = libxl__xs_read(gc, XBT_NULL, tty_path); + if (!tty) { + LOGE(ERROR,"unable to read console tty path `%s''",tty_path); + rc = ERROR_FAIL; + goto out; + } + + *path = libxl__strdup(0, tty); + rc = 0; +out: + GC_FREE; + return rc; +} + +static int libxl__primary_console_find(libxl_ctx *ctx, uint32_t domid_vm, + uint32_t *domid, int *cons_num, + libxl_console_type *type) { GC_INIT(ctx); uint32_t stubdomid = libxl_get_stubdom_id(ctx, domid_vm); int rc; - if (stubdomid) - rc = libxl_console_exec(ctx, stubdomid, - STUBDOM_CONSOLE_SERIAL, LIBXL_CONSOLE_TYPE_PV); - else { + + if (stubdomid) { + *domid = stubdomid; + *cons_num = STUBDOM_CONSOLE_SERIAL; + *type = LIBXL_CONSOLE_TYPE_PV; + } else { switch (libxl__domain_type(gc, domid_vm)) { case LIBXL_DOMAIN_TYPE_HVM: - rc = libxl_console_exec(ctx, domid_vm, 0, LIBXL_CONSOLE_TYPE_SERIAL); + *domid = domid_vm; + *cons_num = 0; + *type = LIBXL_CONSOLE_TYPE_SERIAL; break; case LIBXL_DOMAIN_TYPE_PV: - rc = libxl_console_exec(ctx, domid_vm, 0, LIBXL_CONSOLE_TYPE_PV); + *domid = domid_vm; + *cons_num = 0; + *type = LIBXL_CONSOLE_TYPE_PV; break; case -1: - LOG(ERROR,"unable to get domain type for domid=%"PRIu32,domid_vm); - rc = ERROR_FAIL; + LOG(ERROR,"unable to get domain type for domid=%"PRIu32, domid_vm); + rc = ERROR_INVAL; + goto out; break; default: abort(); } } + + rc = 0; +out: GC_FREE; return rc; } +int libxl_primary_console_exec(libxl_ctx *ctx, uint32_t domid_vm) +{ + uint32_t domid; + int cons_num; + libxl_console_type type; + int rc; + + rc = libxl__primary_console_find(ctx, domid_vm, &domid, &cons_num, &type); + if ( rc ) return rc; + return libxl_console_exec(ctx, domid, cons_num, type); +} + +int libxl_primary_console_get_tty(libxl_ctx *ctx, uint32_t domid_vm, + char **path) +{ + uint32_t domid; + int cons_num; + libxl_console_type type; + int rc; + + rc = libxl__primary_console_find(ctx, domid_vm, &domid, &cons_num, &type); + if ( rc ) return rc; + return libxl_console_get_tty(ctx, domid, cons_num, type, path); +} + int libxl_vncviewer_exec(libxl_ctx *ctx, uint32_t domid, int autopass) { GC_INIT(ctx); diff -r 6bea63e6c780 -r 2586692a6d74 tools/libxl/libxl.h --- a/tools/libxl/libxl.h Sat Jun 02 08:39:45 2012 +0100 +++ b/tools/libxl/libxl.h Wed Jun 06 14:35:01 2012 +0800 @@ -570,6 +570,18 @@ int libxl_console_exec(libxl_ctx *ctx, u * guests using pygrub. */ int libxl_primary_console_exec(libxl_ctx *ctx, uint32_t domid_vm); +/* libxl_console_get_tty retrieves the specified domain''s console tty path + * and stores it in path. Caller is responsible for freeing the memory. + */ +int libxl_console_get_tty(libxl_ctx *ctx, uint32_t domid, int cons_num, + libxl_console_type type, char **path); + +/* libxl_primary_console_get_tty retrieves the specified domain''s primary + * console tty path and stores it in path. Caller is responsible for freeing + * the memory. + */ +int libxl_primary_console_get_tty(libxl_ctx *ctx, uint32_t domid_vm, char **path); + /* May be called with info_r == NULL to check for domain''s existance */ int libxl_domain_info(libxl_ctx*, libxl_dominfo *info_r, uint32_t domid);
Ian Campbell
2012-Jun-06 11:47 UTC
Re: [PATCH] [v4] libxl: Add API to retrieve domain console tty
On Wed, 2012-06-06 at 08:09 +0100, Bamvor Jian Zhang wrote:> This api retrieve domain console from xenstore. With this new api, it is easy > to implement "virsh console" command in libvirt libxl driver. > > Signed-off-by: Bamvor Jian Zhang <bjzhang@suse.com>Applied, thanks. I trimmed a bunch of trailing whitespace, please watch out next time.> Changes since v3: > * leave variable uninitialised at the top of the function in order to avoid > hiding the useful compiler warnings. > * using libxl__strdup instead of strdup in libxl_console_get_tty. benefit from > the error handling behavior. > libxl__strdup(0, tty) should be replaced by libxl__strdup(NOGC, tty) after > Ian Jackson commit his patch: "Do not pass NULL as gc_opt; introduce NOGC."I introduced a "#define NOGC NULL" in an earlier patch so we don''t miss converting any new instances to the proper scheme when Ian J''s patch goes in. I did s/0/NOGC on this patch as I applied it. Hope that''s ok.> > diff -r 6bea63e6c780 -r 2586692a6d74 tools/libxl/libxl.c > --- a/tools/libxl/libxl.c Sat Jun 02 08:39:45 2012 +0100 > +++ b/tools/libxl/libxl.c Wed Jun 06 14:35:01 2012 +0800 > @@ -1217,7 +1217,8 @@ out: > return rc; > } > > -int libxl_console_exec(libxl_ctx *ctx, uint32_t domid, int cons_num, libxl_console_type type) > +int libxl_console_exec(libxl_ctx *ctx, uint32_t domid, int cons_num, > + libxl_console_type type) > { > GC_INIT(ctx); > char *p = libxl__sprintf(gc, "%s/xenconsole", libxl__private_bindir_path()); > @@ -1243,34 +1244,116 @@ out: > return ERROR_FAIL; > } > > -int libxl_primary_console_exec(libxl_ctx *ctx, uint32_t domid_vm) > +int libxl_console_get_tty(libxl_ctx *ctx, uint32_t domid, int cons_num, > + libxl_console_type type, char **path) > +{ > + GC_INIT(ctx); > + char *dom_path; > + char *tty_path; > + char *tty; > + int rc; > + > + dom_path = libxl__xs_get_dompath(gc, domid); > + if (!dom_path) { > + rc = ERROR_FAIL; > + goto out; > + } > + > + switch (type) { > + case LIBXL_CONSOLE_TYPE_SERIAL: > + tty_path = GCSPRINTF("%s/serial/0/tty", dom_path); > + break; > + case LIBXL_CONSOLE_TYPE_PV: > + if (cons_num == 0) > + tty_path = GCSPRINTF("%s/console/tty", dom_path); > + else > + tty_path = GCSPRINTF("%s/device/console/%d/tty", dom_path, > + cons_num); > + break; > + default: > + rc = ERROR_INVAL; > + goto out; > + } > + > + tty = libxl__xs_read(gc, XBT_NULL, tty_path); > + if (!tty) { > + LOGE(ERROR,"unable to read console tty path `%s''",tty_path); > + rc = ERROR_FAIL; > + goto out; > + } > + > + *path = libxl__strdup(0, tty); > + rc = 0; > +out: > + GC_FREE; > + return rc; > +} > + > +static int libxl__primary_console_find(libxl_ctx *ctx, uint32_t domid_vm, > + uint32_t *domid, int *cons_num, > + libxl_console_type *type) > { > GC_INIT(ctx); > uint32_t stubdomid = libxl_get_stubdom_id(ctx, domid_vm); > int rc; > - if (stubdomid) > - rc = libxl_console_exec(ctx, stubdomid, > - STUBDOM_CONSOLE_SERIAL, LIBXL_CONSOLE_TYPE_PV); > - else { > + > + if (stubdomid) { > + *domid = stubdomid; > + *cons_num = STUBDOM_CONSOLE_SERIAL; > + *type = LIBXL_CONSOLE_TYPE_PV; > + } else { > switch (libxl__domain_type(gc, domid_vm)) { > case LIBXL_DOMAIN_TYPE_HVM: > - rc = libxl_console_exec(ctx, domid_vm, 0, LIBXL_CONSOLE_TYPE_SERIAL); > + *domid = domid_vm; > + *cons_num = 0; > + *type = LIBXL_CONSOLE_TYPE_SERIAL; > break; > case LIBXL_DOMAIN_TYPE_PV: > - rc = libxl_console_exec(ctx, domid_vm, 0, LIBXL_CONSOLE_TYPE_PV); > + *domid = domid_vm; > + *cons_num = 0; > + *type = LIBXL_CONSOLE_TYPE_PV; > break; > case -1: > - LOG(ERROR,"unable to get domain type for domid=%"PRIu32,domid_vm); > - rc = ERROR_FAIL; > + LOG(ERROR,"unable to get domain type for domid=%"PRIu32, domid_vm); > + rc = ERROR_INVAL; > + goto out; > break; > default: > abort(); > } > } > + > + rc = 0; > +out: > GC_FREE; > return rc; > } > > +int libxl_primary_console_exec(libxl_ctx *ctx, uint32_t domid_vm) > +{ > + uint32_t domid; > + int cons_num; > + libxl_console_type type; > + int rc; > + > + rc = libxl__primary_console_find(ctx, domid_vm, &domid, &cons_num, &type); > + if ( rc ) return rc; > + return libxl_console_exec(ctx, domid, cons_num, type); > +} > + > +int libxl_primary_console_get_tty(libxl_ctx *ctx, uint32_t domid_vm, > + char **path) > +{ > + uint32_t domid; > + int cons_num; > + libxl_console_type type; > + int rc; > + > + rc = libxl__primary_console_find(ctx, domid_vm, &domid, &cons_num, &type); > + if ( rc ) return rc; > + return libxl_console_get_tty(ctx, domid, cons_num, type, path); > +} > + > int libxl_vncviewer_exec(libxl_ctx *ctx, uint32_t domid, int autopass) > { > GC_INIT(ctx); > diff -r 6bea63e6c780 -r 2586692a6d74 tools/libxl/libxl.h > --- a/tools/libxl/libxl.h Sat Jun 02 08:39:45 2012 +0100 > +++ b/tools/libxl/libxl.h Wed Jun 06 14:35:01 2012 +0800 > @@ -570,6 +570,18 @@ int libxl_console_exec(libxl_ctx *ctx, u > * guests using pygrub. */ > int libxl_primary_console_exec(libxl_ctx *ctx, uint32_t domid_vm); > > +/* libxl_console_get_tty retrieves the specified domain''s console tty path > + * and stores it in path. Caller is responsible for freeing the memory. > + */ > +int libxl_console_get_tty(libxl_ctx *ctx, uint32_t domid, int cons_num, > + libxl_console_type type, char **path); > + > +/* libxl_primary_console_get_tty retrieves the specified domain''s primary > + * console tty path and stores it in path. Caller is responsible for freeing > + * the memory. > + */ > +int libxl_primary_console_get_tty(libxl_ctx *ctx, uint32_t domid_vm, char **path); > + > /* May be called with info_r == NULL to check for domain''s existance */ > int libxl_domain_info(libxl_ctx*, libxl_dominfo *info_r, > uint32_t domid);